forked from Telodendria/Telodendria
[ADD/WIP] Filtering some event fields(somewhat)
Some checks failed
Compile Telodendria / Compile Telodendria (x86, alpine-v3.19) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, debian-v12.4) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, freebsd-v14.0) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, netbsd-v9.3) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, alpine-v3.19) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, debian-v12.4) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, freebsd-v14.0) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, netbsd-v9.3) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, openbsd-v7.4) (push) Has been cancelled
Some checks failed
Compile Telodendria / Compile Telodendria (x86, alpine-v3.19) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, debian-v12.4) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, freebsd-v14.0) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, netbsd-v9.3) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, alpine-v3.19) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, debian-v12.4) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, freebsd-v14.0) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, netbsd-v9.3) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, openbsd-v7.4) (push) Has been cancelled
This commit is contained in:
parent
123aa0b23a
commit
3e5d9dbe62
5 changed files with 156 additions and 8 deletions
68
src/Filter.c
68
src/Filter.c
|
@ -32,6 +32,8 @@
|
|||
|
||||
#include <Schema/Filter.h>
|
||||
|
||||
#include <Matrix.h>
|
||||
|
||||
/* Verifies whenever an item passes through a set of blacklisted and
|
||||
* whitelisted groups(e.g "not_rooms"/"rooms"), and makes the calling
|
||||
* function return true/false if it is explicitely in a filtered list,
|
||||
|
@ -120,6 +122,52 @@ IsRoomFiltered(Filter *filter, char *roomID)
|
|||
return false;
|
||||
}
|
||||
|
||||
static HashMap *
|
||||
IncludeFields(Array * fields, HashMap * event)
|
||||
{
|
||||
HashMap *cpy;
|
||||
size_t i, len;
|
||||
if (!event)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!fields)
|
||||
{
|
||||
return JsonDuplicate(event);
|
||||
}
|
||||
|
||||
cpy = HashMapCreate();
|
||||
|
||||
/* NOTE: We intentionally add some fields due to some requirements
|
||||
* around certain schemas. The specification does find such behavior
|
||||
* compliant:
|
||||
* > "[...] A server may include more fields than were requested." */
|
||||
#define CopyField(field) \
|
||||
HashMapSet(cpy, field, JsonValueDuplicate(HashMapGet(event, field)))
|
||||
|
||||
CopyField("event_id");
|
||||
CopyField("origin_server_ts");
|
||||
CopyField("sender");
|
||||
CopyField("type");
|
||||
len = ArraySize(fields);
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
char *field = ArrayGet(fields, i);
|
||||
JsonValue *val = JsonValueDuplicate(MatrixGetJSON(event, field));
|
||||
|
||||
JsonValueFree(MatrixSetJSON(cpy, field, val));
|
||||
}
|
||||
|
||||
/* Only copy it if not already present. */
|
||||
if (!HashMapGet(cpy, "content"))
|
||||
{
|
||||
CopyField("content");
|
||||
}
|
||||
|
||||
#undef CopyField
|
||||
return cpy;
|
||||
}
|
||||
/* TODO: MORE FILTERS! */
|
||||
HashMap *
|
||||
FilterApply(Filter * filter, HashMap * event)
|
||||
|
@ -144,26 +192,31 @@ FilterApply(Filter * filter, HashMap * event)
|
|||
{
|
||||
return NULL;
|
||||
}
|
||||
copy = JsonDuplicate(event);
|
||||
|
||||
copy = IncludeFields(filter->event_fields, event);
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
Filter *
|
||||
FilterDecode(Db *db, char *user, char *filterStr)
|
||||
FilterDecode(Db *db, char *user, char *filterStr, char **errp)
|
||||
{
|
||||
Filter *ret;
|
||||
DbRef *filterRef;
|
||||
HashMap *filterObj;
|
||||
if (!db || !user || !filterStr)
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp =
|
||||
"Internal error: Field required for FilterDecode is missing.";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (*filterStr != '{')
|
||||
{
|
||||
char *err; /* TODO: use error status somewhere... */
|
||||
char *err;
|
||||
|
||||
filterRef = DbLock(db, 3, "filters", user, filterStr);
|
||||
filterObj = DbJson(filterRef);
|
||||
|
@ -172,17 +225,24 @@ FilterDecode(Db *db, char *user, char *filterStr)
|
|||
|
||||
if (!FilterFromJson(filterObj, ret, &err))
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = err;
|
||||
}
|
||||
DbUnlock(db, filterRef);
|
||||
Free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DbUnlock(db, filterRef);
|
||||
(void) err;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* TODO: Decode JSON here... */
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Unimplemented feature: decoding from a raw JSON object";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
81
src/Matrix.c
81
src/Matrix.c
|
@ -428,3 +428,84 @@ MatrixGetJSON(HashMap *json, char *string)
|
|||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
JsonValue *
|
||||
MatrixSetJSON(HashMap *json, char *string, JsonValue *new)
|
||||
{
|
||||
JsonValue *retVal;
|
||||
HashMap *currentObj;
|
||||
char *field, *fieldTemp;
|
||||
size_t i, length;
|
||||
|
||||
if (!json || !string || !new)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
currentObj = json;
|
||||
retVal = NULL;
|
||||
length = strlen(string);
|
||||
field = NULL;
|
||||
|
||||
#define Append(ch) do \
|
||||
{ \
|
||||
char chb[2] = { ch, 0 }; \
|
||||
fieldTemp = field; \
|
||||
field = StrConcat(2, field, chb); \
|
||||
Free(fieldTemp); \
|
||||
} while (0)
|
||||
|
||||
/* We include the 0-terminator as a valid separator. */
|
||||
for (i = 0; i < length + 1; i++)
|
||||
{
|
||||
char currentChar = string[i];
|
||||
char escape;
|
||||
if (currentChar == '\\' && (escape = string[i+1]))
|
||||
{
|
||||
if (escape != '.' && escape != '\\')
|
||||
{
|
||||
Append('\\');
|
||||
}
|
||||
Append(escape);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
else if (currentChar == '.' || currentChar == '\0')
|
||||
{
|
||||
if (!field || !currentObj)
|
||||
{
|
||||
Free(field);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (currentChar == '.')
|
||||
{
|
||||
retVal = HashMapGet(currentObj, field);
|
||||
if (!retVal)
|
||||
{
|
||||
retVal = JsonValueObject(HashMapCreate());
|
||||
HashMapSet(currentObj, field, retVal);
|
||||
}
|
||||
currentObj = JsonValueAsObject(retVal);
|
||||
|
||||
Free(field);
|
||||
field = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
retVal = HashMapSet(currentObj, field, new);
|
||||
Free(field);
|
||||
field = NULL;
|
||||
continue;
|
||||
}
|
||||
Append(currentChar);
|
||||
}
|
||||
#undef Append
|
||||
|
||||
if (field)
|
||||
{
|
||||
/* This is weird. */
|
||||
Free(field);
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
|
|
@ -121,9 +121,8 @@ ROUTE_IMPL(RouteSync, path, argp)
|
|||
if (filter)
|
||||
{
|
||||
char *userName = UserGetName(user);
|
||||
if (!(filterData = FilterDecode(db, userName, filter)))
|
||||
if (!(filterData = FilterDecode(db, userName, filter, &err)))
|
||||
{
|
||||
err = "Couldn't decode filter given in";
|
||||
HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
|
||||
response = MatrixErrorCreate(M_BAD_JSON, err);
|
||||
}
|
||||
|
|
|
@ -55,9 +55,10 @@ extern bool IsRoomFiltered(Filter *, char *);
|
|||
|
||||
/**
|
||||
* Decodes a filter from a JSON stream to decode or an ID that was
|
||||
* registered using the filter API.
|
||||
* registered using the filter API, and may return an optional error
|
||||
* string, if not set to NULL.
|
||||
*/
|
||||
extern Filter * FilterDecode(Db *, char *, char *);
|
||||
extern Filter * FilterDecode(Db *, char *, char *, char **);
|
||||
|
||||
/**
|
||||
* Frees all memory created by
|
||||
|
|
|
@ -163,4 +163,11 @@ extern HashMap * MatrixClientWellKnown(char *, char *);
|
|||
*/
|
||||
extern JsonValue * MatrixGetJSON(HashMap *, char *);
|
||||
|
||||
/**
|
||||
* Sets a value given a dot-separated path (see
|
||||
* .Fn MatrixGetJSON
|
||||
* for more information).
|
||||
*/
|
||||
extern JsonValue * MatrixSetJSON(HashMap *, char *, JsonValue *);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue