[ADD/WIP] Start abstracting aliasing

This commit is contained in:
lda 2024-05-19 00:30:28 +02:00
parent e3c57d8f05
commit a99798a312
2 changed files with 108 additions and 59 deletions

View file

@ -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;
}

View file

@ -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 */