[ADD/WIP/UNTESTED] Start doing filtering
Compile Telodendria / Compile Telodendria (x86, alpine-v3.19) (push) Has been cancelled Details
Compile Telodendria / Compile Telodendria (x86, debian-v12.4) (push) Has been cancelled Details
Compile Telodendria / Compile Telodendria (x86, freebsd-v14.0) (push) Has been cancelled Details
Compile Telodendria / Compile Telodendria (x86, netbsd-v9.3) (push) Has been cancelled Details
Compile Telodendria / Compile Telodendria (x86_64, alpine-v3.19) (push) Has been cancelled Details
Compile Telodendria / Compile Telodendria (x86_64, debian-v12.4) (push) Has been cancelled Details
Compile Telodendria / Compile Telodendria (x86_64, freebsd-v14.0) (push) Has been cancelled Details
Compile Telodendria / Compile Telodendria (x86_64, netbsd-v9.3) (push) Has been cancelled Details
Compile Telodendria / Compile Telodendria (x86_64, openbsd-v7.4) (push) Has been cancelled Details

Currently untested until I take some time, as I'm busy with something
else at the moment. I _really_, *really*, need to cleanup that code...
This commit is contained in:
LDA 2024-07-08 10:16:54 +02:00
parent e2d26c7f33
commit 7825559f1b
2 changed files with 72 additions and 10 deletions

View File

@ -50,8 +50,8 @@
#include <stdlib.h>
#include <string.h>
#define IsState(p, typ, key) (StrEquals(p->type, typ) && \
StrEquals(p->state_key, key))
#define IsState(p, typ, key) (StrEquals((p)->type, typ) && \
StrEquals((p)->state_key, key))
struct Room
{
@ -597,6 +597,7 @@ finish:
FinishState(pl);
}
/* Finds the power level of an user before [e_id] was sent. */
/* TODO: The creator should have PL100 by default. */
static int64_t
RoomUserPL(Room * room, HashMap *state, char *user)
{
@ -854,7 +855,7 @@ ConsiderAuthEventsV1(Room * room, PduV1 pdu)
/* Step 2.4: If there is no m.room.create event among the entries,
* reject. */
if (!room_create && IsState((&auth_pdu), "m.room.create", ""))
if (!room_create && IsState(&auth_pdu, "m.room.create", ""))
{
room_create = true; /* Here, we check for the opposite. */
}

View File

@ -26,6 +26,7 @@
#include <Routes.h>
#include <Schema/SyncResponse.h>
#include <Schema/Filter.h>
#include <Cytoplasm/HashMap.h>
#include <Cytoplasm/Memory.h>
@ -58,6 +59,28 @@ StripStateEventSync(HashMap *pdu)
return ret;
}
static bool
IsRoomFiltered(Filter *filter, char *roomID)
{
size_t i, count;
if (!filter || !roomID)
{
return false;
}
count = ArraySize(filter->room.not_rooms);
for (i = 0; i < count; i++)
{
char *notRoom = ArrayGet(filter->room.not_rooms, i);
if (StrEquals(roomID, notRoom))
{
return true;
}
}
/* TODO: Consider rooms */
return true;
}
ROUTE_IMPL(RouteSync, path, argp)
{
RouteArgs *args = argp;
@ -66,6 +89,7 @@ ROUTE_IMPL(RouteSync, path, argp)
HashMap *params = NULL;
HashMap *response = NULL;
SyncResponse sync = { 0 };
Filter filterData = { 0 };
Array *invites;
Array *joins;
@ -77,6 +101,7 @@ ROUTE_IMPL(RouteSync, path, argp)
char *nextBatch = NULL;
char *currBatch = NULL;
char *timeout = NULL;
char *filter = NULL;
char *err;
@ -111,8 +136,29 @@ ROUTE_IMPL(RouteSync, path, argp)
params = HttpRequestParams(args->context);
prevBatch = HashMapGet(params, "since");
timeout = HashMapGet(params, "timeout");
filter = HashMapGet(params, "filter");
timeoutDuration = atoi(timeout);
if (filter && *filter != '{')
{
/* The filter must be located in the database */
DbRef *filterRef = DbLock(db, 3,
"filters", UserGetName(user), filter
);
HashMap *filterJson = DbJson(filterRef);
if (!FilterFromJson(filterJson, &filterData, &err))
{
HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
response = MatrixErrorCreate(M_BAD_JSON, err);
DbUnlock(db, filterRef);
goto finish;
}
/* We now grabbed a filter JSON */
DbUnlock(db, filterRef);
}
if (!prevBatch)
{
@ -127,10 +173,9 @@ ROUTE_IMPL(RouteSync, path, argp)
UserUnlock(user);
/* TODO: Unlocking the user for other threads to notify us is not
* wise.
* Also, Telodendria will NOT reply to ^C while someone is executing
* a sync. */
/* TODO: Using pthreads' condition variables with a timeout would be
* the best way to proceed (as in Parsee's ParseeAwaitStanza function)
*/
while (passed < timeoutDuration)
{
if (UserGetNotification(name))
@ -158,6 +203,11 @@ ROUTE_IMPL(RouteSync, path, argp)
InvitedRooms invited = { 0 };
HashMap *invitedObject;
if (IsRoomFiltered(&filterData, roomId))
{
continue;
}
invited.invite_state.events = ArrayCreate();
invitedObject = InvitedRoomsToJson(&invited);
JsonSet(
@ -173,16 +223,26 @@ ROUTE_IMPL(RouteSync, path, argp)
joins = UserGetJoins(user, currBatch);
for (i = 0; i < ArraySize(joins); i++)
{
/* TODO: Rename these variables */
char *roomId = ArrayGet(joins, i);
Array *el = UserGetEvents(user, currBatch, roomId);
Array *el;
size_t j;
Room *r = RoomLock(db, roomId);
HashMap *state = StateCurrent(r);
Room *r;
HashMap *state;
char *firstEvent = NULL;
JoinedRooms joined = { 0 };
HashMap *joinedObj;
char *type, *key, *id;
if (IsRoomFiltered(&filterData, roomId))
{
continue;
}
el = UserGetEvents(user, currBatch, roomId);
r = RoomLock(db, roomId);
state = StateCurrent(r);
joined.timeline.events = ArrayCreate();
for (j = 0; j < ArraySize(el); j++)
@ -242,6 +302,7 @@ ROUTE_IMPL(RouteSync, path, argp)
response = SyncResponseToJson(&sync);
SyncResponseFree(&sync);
finish:
FilterFree(&filterData);
UserUnlock(user);
(void) path;
return response;