[ADD/WIP/UNTESTED] Start doing filtering
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

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

View file

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