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 <Schema/Filter.h>
|
||||||
|
|
||||||
|
#include <Matrix.h>
|
||||||
|
|
||||||
/* Verifies whenever an item passes through a set of blacklisted and
|
/* Verifies whenever an item passes through a set of blacklisted and
|
||||||
* whitelisted groups(e.g "not_rooms"/"rooms"), and makes the calling
|
* whitelisted groups(e.g "not_rooms"/"rooms"), and makes the calling
|
||||||
* function return true/false if it is explicitely in a filtered list,
|
* function return true/false if it is explicitely in a filtered list,
|
||||||
|
@ -120,6 +122,52 @@ IsRoomFiltered(Filter *filter, char *roomID)
|
||||||
return false;
|
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! */
|
/* TODO: MORE FILTERS! */
|
||||||
HashMap *
|
HashMap *
|
||||||
FilterApply(Filter * filter, HashMap * event)
|
FilterApply(Filter * filter, HashMap * event)
|
||||||
|
@ -144,26 +192,31 @@ FilterApply(Filter * filter, HashMap * event)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
copy = JsonDuplicate(event);
|
|
||||||
|
|
||||||
|
copy = IncludeFields(filter->event_fields, event);
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Filter *
|
Filter *
|
||||||
FilterDecode(Db *db, char *user, char *filterStr)
|
FilterDecode(Db *db, char *user, char *filterStr, char **errp)
|
||||||
{
|
{
|
||||||
Filter *ret;
|
Filter *ret;
|
||||||
DbRef *filterRef;
|
DbRef *filterRef;
|
||||||
HashMap *filterObj;
|
HashMap *filterObj;
|
||||||
if (!db || !user || !filterStr)
|
if (!db || !user || !filterStr)
|
||||||
{
|
{
|
||||||
|
if (errp)
|
||||||
|
{
|
||||||
|
*errp =
|
||||||
|
"Internal error: Field required for FilterDecode is missing.";
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*filterStr != '{')
|
if (*filterStr != '{')
|
||||||
{
|
{
|
||||||
char *err; /* TODO: use error status somewhere... */
|
char *err;
|
||||||
|
|
||||||
filterRef = DbLock(db, 3, "filters", user, filterStr);
|
filterRef = DbLock(db, 3, "filters", user, filterStr);
|
||||||
filterObj = DbJson(filterRef);
|
filterObj = DbJson(filterRef);
|
||||||
|
@ -172,17 +225,24 @@ FilterDecode(Db *db, char *user, char *filterStr)
|
||||||
|
|
||||||
if (!FilterFromJson(filterObj, ret, &err))
|
if (!FilterFromJson(filterObj, ret, &err))
|
||||||
{
|
{
|
||||||
|
if (errp)
|
||||||
|
{
|
||||||
|
*errp = err;
|
||||||
|
}
|
||||||
DbUnlock(db, filterRef);
|
DbUnlock(db, filterRef);
|
||||||
Free(ret);
|
Free(ret);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
DbUnlock(db, filterRef);
|
DbUnlock(db, filterRef);
|
||||||
(void) err;
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Decode JSON here... */
|
/* TODO: Decode JSON here... */
|
||||||
|
if (errp)
|
||||||
|
{
|
||||||
|
*errp = "Unimplemented feature: decoding from a raw JSON object";
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
81
src/Matrix.c
81
src/Matrix.c
|
@ -428,3 +428,84 @@ MatrixGetJSON(HashMap *json, char *string)
|
||||||
}
|
}
|
||||||
return retVal;
|
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)
|
if (filter)
|
||||||
{
|
{
|
||||||
char *userName = UserGetName(user);
|
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);
|
HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
|
||||||
response = MatrixErrorCreate(M_BAD_JSON, err);
|
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
|
* 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
|
* Frees all memory created by
|
||||||
|
|
|
@ -163,4 +163,11 @@ extern HashMap * MatrixClientWellKnown(char *, char *);
|
||||||
*/
|
*/
|
||||||
extern JsonValue * MatrixGetJSON(HashMap *, 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
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue