From a99798a3123964ea97dc4462c04a82cdf2577840 Mon Sep 17 00:00:00 2001 From: lda Date: Sun, 19 May 2024 00:30:28 +0200 Subject: [PATCH] [ADD/WIP] Start abstracting aliasing --- src/Room.c | 156 ++++++++++++++++++++++++++++----------------- src/include/Room.h | 11 ++++ 2 files changed, 108 insertions(+), 59 deletions(-) diff --git a/src/Room.c b/src/Room.c index 9fc0994..5c9310e 100644 --- a/src/Room.c +++ b/src/Room.c @@ -181,67 +181,30 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s) } /* Custom alias */ - if (req->room_alias_name) + if (req->room_alias_name && !RoomResolveAlias(room->db, room->id)) { - DbRef *aliasesRef = DbLock(room->db, 1, "aliases"); - HashMap *aliasesJson; - if (!aliasesRef) - { - aliasesRef = DbCreate(room->db, 1, "aliases"); - } + CommonID full; + char *fullStr, *serverStr; - if (aliasesRef) - { - CommonID full; - char *fullStr, *serverStr; - HashMap *alias, *idObject; - Array *servers, *ids; + full.sigil = '#'; + full.local = req->room_alias_name; + full.server = s; + fullStr = ParserRecomposeCommonID(full); - full.sigil = '#'; - full.local = req->room_alias_name; - full.server = s; - - aliasesJson = DbJson(aliasesRef); - fullStr = ParserRecomposeCommonID(full); + serverStr = ParserRecomposeServerPart(room->creator); + + RoomAddAlias(room->db, fullStr, room->id, sender_str, serverStr); - servers = ArrayCreate(); - serverStr = ParserRecomposeServerPart(room->creator); - ArrayAdd(servers, JsonValueString(serverStr)); - Free(serverStr); + content = HashMapCreate(); + JsonSet(content, JsonValueString(fullStr), 1, "alias"); + event = RoomEventCreate( + sender_str, + "m.room.canonical_alias", "", content); + JsonFree(RoomEventSend(room, event)); + JsonFree(event); - alias = HashMapCreate(); - HashMapSet(alias, "createdBy", JsonValueString(sender_str)); - HashMapSet(alias, "id", JsonValueString(room->id)); - HashMapSet(alias, "servers", JsonValueArray(servers)); - - JsonValueFree(JsonSet( - aliasesJson, JsonValueObject(alias), 2, - "aliases", fullStr)); - if (!(idObject = - JsonValueAsObject(JsonGet(aliasesJson, 2, "id", room->id)))) - { - ids = ArrayCreate(); - idObject = HashMapCreate(); - HashMapSet(idObject, "aliases", JsonValueArray(ids)); - JsonSet( - aliasesJson, - JsonValueObject(idObject), - 2, "id", room->id); - } - ids = JsonValueAsArray(HashMapGet(idObject, "aliases")); - ArrayAdd(ids, JsonValueString(fullStr)); - - content = HashMapCreate(); - JsonSet(content, JsonValueString(fullStr), 1, "alias"); - event = RoomEventCreate( - sender_str, - "m.room.canonical_alias", "", content); - JsonFree(RoomEventSend(room, event)); - JsonFree(event); - - Free(fullStr); - DbUnlock(room->db, aliasesRef); - } + Free(fullStr); + Free(serverStr); } /* TODO: The rest of the events mandated by the specification on * POST /createRoom, and error management. */ @@ -582,9 +545,8 @@ PopulateEventV1(Room * room, HashMap * event, PduV1 * pdu, ServerPart serv) JsonDuplicate(JsonValueAsObject(JsonGet(event, 1, "content"))); pdu->room_id = StrDuplicate(room->id); pdu->signatures = HashMapCreate(); - pdu->depth = RoomGetDepth(room) + 1; /* TODO: Clamp this value. */ - pdu->depth = pdu->depth >= (int64_t) INT64_MAX ? - (int64_t) INT64_MAX : pdu->depth; + pdu->depth = RoomGetDepth(room) + 1; + pdu->depth = pdu->depth >= INT64_MAX ? INT64_MAX : pdu->depth; /* Create a random event ID for this PDU. * TODO: Optionally verify whenever it's already used, but that @@ -1804,3 +1766,79 @@ RoomGetDepth(Room *room) return max; } +void +RoomAddAlias(Db *db, char *roomAlias, char *roomId, char *sender, char *serv) +{ + DbRef *aliasRef; + HashMap *json, *alias, *idObject; + Array *servers, *ids; + if (!db || !roomAlias || !roomId || !sender || !serv) + { + return; + } + + aliasRef = DbLock(db, 1, "aliases"); + if (!aliasRef) + { + aliasRef = DbCreate(db, 1, "aliases"); + if (!aliasRef) + { + return; + } + } + + json = DbJson(aliasRef); + + servers = ArrayCreate(); + ArrayAdd(servers, JsonValueString(serv)); + + /* alias => ID */ + alias = HashMapCreate(); + JsonSet(alias, JsonValueString(roomId), 1, "id"); + JsonSet(alias, JsonValueString(sender), 1, "createdBy"); + JsonSet(alias, JsonValueArray(servers), 1, "servers"); + + JsonValueFree( + JsonSet(json, JsonValueObject(alias), 2, "aliases", roomAlias)); + + /* ID => alias(es) */ + if (!(idObject = + JsonValueAsObject(JsonGet(json, 2, "id", roomId)))) + { + ids = ArrayCreate(); + idObject = HashMapCreate(); + HashMapSet(idObject, "aliases", JsonValueArray(ids)); + JsonSet( + json, + JsonValueObject(idObject), + 2, "id", roomId); + } + ids = JsonValueAsArray(HashMapGet(idObject, "aliases")); + ArrayAdd(ids, JsonValueString(roomAlias)); + + DbUnlock(db, aliasRef); +} +char * +RoomResolveAlias(Db *db, char *roomAlias) +{ + DbRef *aliasRef; + HashMap *json; + char *ret; + if (!db || !roomAlias) + { + return NULL; + } + + aliasRef = DbLock(db, 1, "aliases"); + if (!aliasRef) + { + return NULL; + } + + json = DbJson(aliasRef); + ret = JsonValueAsString(JsonGet(json, 3, "aliases", roomAlias, "id")); + ret = StrDuplicate(ret); + + DbUnlock(db, aliasRef); + return ret; +} diff --git a/src/include/Room.h b/src/include/Room.h index feeec5a..67dc3ee 100644 --- a/src/include/Room.h +++ b/src/include/Room.h @@ -176,4 +176,15 @@ extern HashMap * RoomEventCreate(char *, char *, char *, HashMap *); */ extern uint64_t RoomGetDepth(Room *); +/** + * Tries to find an alias from room alias to an ID stored + * on the heap, or NULL if it does not exist. + */ +extern char * RoomResolveAlias(Db *, char *); + +/** + * Adds or overwrites a room alias. + */ +extern void RoomAddAlias(Db *, char *, char *, char *, char *); + #endif /* TELODENDRIA_ROOM_H */