From cacc72bf849831f1e59beff1c4527f2318ae98ec Mon Sep 17 00:00:00 2001 From: lda Date: Sun, 19 May 2024 15:17:56 +0200 Subject: [PATCH] [ADD/WIP] Basic preset code I still need to find a solution to a problem related to j2s. Right now I kind of want to have a way for users to send events from the endpoints. --- src/Room.c | 104 +++++++++++++++++++++++++++++++++- src/Routes/RouteCreateRoom.c | 14 ++++- src/Routes/RouteRoomAliases.c | 26 +++++---- src/include/Room.h | 12 ++++ 4 files changed, 141 insertions(+), 15 deletions(-) diff --git a/src/Room.c b/src/Room.c index 5c9310e..d13dfc9 100644 --- a/src/Room.c +++ b/src/Room.c @@ -88,6 +88,11 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s) JsonValue *val; size_t i; + char *join_rules_preset = NULL; + char *history_visibility_preset = NULL; + char *guest_access_preset = NULL; + /* TODO: Manage trusted private chat */ + sender.sigil = '@'; sender.local = UserGetName(user); sender.server = s; @@ -135,16 +140,59 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s) switch (req->preset) { case ROOM_CREATE_PUBLIC: - /* TODO */ + join_rules_preset = "public"; + history_visibility_preset = "shared"; + guest_access_preset = "forbidden"; break; case ROOM_CREATE_TRUSTED: /* TODO */ - break; + /* Fallthrough */ case ROOM_CREATE_PRIVATE: - /* TODO */ + join_rules_preset = "invite"; + history_visibility_preset = "shared"; + guest_access_preset = "can_join"; + break; + default: + switch (req->visibility) + { + case ROOM_PUBLIC: + join_rules_preset = "public"; + history_visibility_preset = "shared"; + guest_access_preset = "forbidden"; + break; + case ROOM_PRIVATE: + join_rules_preset = "invite"; + history_visibility_preset = "shared"; + guest_access_preset = "can_join"; + break; + } break; } + /* Write out presets */ +#define SetIfExistent(pset) do { \ + if (pset##_preset) \ + { \ + content = HashMapCreate(); \ + JsonSet( \ + content, \ + JsonValueString(join_rules_preset) \ + , 1, #pset); \ + event = RoomEventCreate( \ + sender_str, \ + "m.room." #pset, "", content); \ + JsonFree(RoomEventSend(room, event)); \ + JsonFree(event); \ + } \ + } \ + while (0) + + SetIfExistent(join_rules); + SetIfExistent(history_visibility); + SetIfExistent(guest_access); + /* TODO: On a trusted room, set invitees PLs to the owner's. */ +#undef SetIfExistent + /* User-provided initial states */ initial_states = req->initial_state; for (i = 0; i < ArraySize(initial_states); i++) @@ -1842,3 +1890,53 @@ RoomResolveAlias(Db *db, char *roomAlias) DbUnlock(db, aliasRef); return ret; } +Array * +RoomReverseAlias(Db *db, char *roomId) +{ + DbRef *aliasRef; + HashMap *json, *idObject; + Array *ret, *original; + size_t i; + if (!db || !roomId) + { + return NULL; + } + aliasRef = DbLock(db, 1, "aliases"); + if (!aliasRef) + { + return NULL; + } + json = DbJson(aliasRef); + if (!(idObject = + JsonValueAsObject(JsonGet(json, 2, "id", roomId)))) + { + DbUnlock(db, aliasRef); + return NULL; + } + original = JsonValueAsArray(HashMapGet(idObject, "aliases")); + ret = ArrayCreate(); + + for (i = 0; i < ArraySize(original); i++) + { + JsonValue *v = ArrayGet(original, i); + ArrayAdd(ret, StrDuplicate(JsonValueAsString(v))); + } + + DbUnlock(db, aliasRef); + return ret; +} + +void +RoomFreeReverse(Array *arr) +{ + size_t i; + if (!arr) + { + return; + } + for (i = 0; i < ArraySize(arr); i++) + { + Free(ArrayGet(arr, i)); + } + ArrayFree(arr); +} diff --git a/src/Routes/RouteCreateRoom.c b/src/Routes/RouteCreateRoom.c index 13ec494..376b498 100644 --- a/src/Routes/RouteCreateRoom.c +++ b/src/Routes/RouteCreateRoom.c @@ -80,7 +80,19 @@ ROUTE_IMPL(RouteCreateRoom, path, argp) response = MatrixErrorCreate(M_NOT_JSON, NULL); goto finish; } - + + /* j2s hack: Setting to a default value like that. + * It's definitely NOT good(you can't rely on enums to + * store values outside their limits in the C standard, + * and this line will need to be changed everytime the + * preset list is changed). + * + * I do believe a decent solution to this would be to + * add a 'default' type(maybe initialised to 0 so that + * memsets would work as intended), that *wouldn't* be + * returned by j2s itself. + * TODO. */ + parsed.preset = ROOM_CREATE_PRIVATE + 1; if (!RoomCreateRequestFromJson(request, &parsed, &err)) { HttpResponseStatus(args->context, HTTP_BAD_REQUEST); diff --git a/src/Routes/RouteRoomAliases.c b/src/Routes/RouteRoomAliases.c index 2fa97bf..0b6130e 100644 --- a/src/Routes/RouteRoomAliases.c +++ b/src/Routes/RouteRoomAliases.c @@ -31,6 +31,7 @@ #include #include +#include ROUTE_IMPL(RouteRoomAliases, path, argp) { @@ -40,16 +41,15 @@ ROUTE_IMPL(RouteRoomAliases, path, argp) char *msg; HashMap *response = NULL; - HashMap *aliases = NULL; - HashMap *reversealias = NULL; - JsonValue *val; + Array *alias = NULL, *arr; Db *db = args->matrixArgs->db; - DbRef *ref = NULL; User *user = NULL; + size_t i; + if (HttpRequestMethodGet(args->context) != HTTP_GET) { msg = "Route only accepts GET."; @@ -81,11 +81,10 @@ ROUTE_IMPL(RouteRoomAliases, path, argp) response = MatrixErrorCreate(M_FORBIDDEN, msg); goto finish; } + - ref = DbLock(db, 1, "aliases"); - aliases = DbJson(ref); - reversealias = JsonValueAsObject(JsonGet(aliases, 2, "id", roomId)); - if (!reversealias) + alias = RoomReverseAlias(db, roomId); + if (!alias) { /* We do not know about the room ID. */ msg = "Unknown room ID."; @@ -93,12 +92,17 @@ ROUTE_IMPL(RouteRoomAliases, path, argp) response = MatrixErrorCreate(M_INVALID_PARAM, msg); goto finish; } + arr = ArrayCreate(); + for (i = 0; i < ArraySize(alias); i++) + { + char *str = ArrayGet(alias, i); + ArrayAdd(arr, JsonValueString(str)); + } response = HashMapCreate(); - val = JsonGet(reversealias, 1, "aliases"); - HashMapSet(response, "aliases", JsonValueDuplicate(val)); + HashMapSet(response, "aliases", JsonValueArray(arr)); finish: - DbUnlock(db, ref); + RoomFreeReverse(alias); UserUnlock(user); return response; } diff --git a/src/include/Room.h b/src/include/Room.h index 67dc3ee..b5c54f0 100644 --- a/src/include/Room.h +++ b/src/include/Room.h @@ -182,6 +182,18 @@ extern uint64_t RoomGetDepth(Room *); */ extern char * RoomResolveAlias(Db *, char *); +/** + * Tries to resolve a list of aliases from a room ID into + * an array of strings stored on the heap. + */ +extern Array * RoomReverseAlias(Db *, char *); + +/** + * Frees the array returned by + * .Fn RoomReverseAlias . + */ +extern void RoomFreeReverse(Array *); + /** * Adds or overwrites a room alias. */