forked from Telodendria/Telodendria
[ADD/WIP] Start abstracting aliasing
This commit is contained in:
parent
e3c57d8f05
commit
a99798a312
2 changed files with 108 additions and 59 deletions
154
src/Room.c
154
src/Room.c
|
@ -181,67 +181,30 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Custom alias */
|
/* Custom alias */
|
||||||
if (req->room_alias_name)
|
if (req->room_alias_name && !RoomResolveAlias(room->db, room->id))
|
||||||
{
|
{
|
||||||
DbRef *aliasesRef = DbLock(room->db, 1, "aliases");
|
CommonID full;
|
||||||
HashMap *aliasesJson;
|
char *fullStr, *serverStr;
|
||||||
if (!aliasesRef)
|
|
||||||
{
|
|
||||||
aliasesRef = DbCreate(room->db, 1, "aliases");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aliasesRef)
|
full.sigil = '#';
|
||||||
{
|
full.local = req->room_alias_name;
|
||||||
CommonID full;
|
full.server = s;
|
||||||
char *fullStr, *serverStr;
|
fullStr = ParserRecomposeCommonID(full);
|
||||||
HashMap *alias, *idObject;
|
|
||||||
Array *servers, *ids;
|
|
||||||
|
|
||||||
full.sigil = '#';
|
serverStr = ParserRecomposeServerPart(room->creator);
|
||||||
full.local = req->room_alias_name;
|
|
||||||
full.server = s;
|
|
||||||
|
|
||||||
aliasesJson = DbJson(aliasesRef);
|
RoomAddAlias(room->db, fullStr, room->id, sender_str, serverStr);
|
||||||
fullStr = ParserRecomposeCommonID(full);
|
|
||||||
|
|
||||||
servers = ArrayCreate();
|
content = HashMapCreate();
|
||||||
serverStr = ParserRecomposeServerPart(room->creator);
|
JsonSet(content, JsonValueString(fullStr), 1, "alias");
|
||||||
ArrayAdd(servers, JsonValueString(serverStr));
|
event = RoomEventCreate(
|
||||||
Free(serverStr);
|
sender_str,
|
||||||
|
"m.room.canonical_alias", "", content);
|
||||||
|
JsonFree(RoomEventSend(room, event));
|
||||||
|
JsonFree(event);
|
||||||
|
|
||||||
alias = HashMapCreate();
|
Free(fullStr);
|
||||||
HashMapSet(alias, "createdBy", JsonValueString(sender_str));
|
Free(serverStr);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* TODO: The rest of the events mandated by the specification on
|
/* TODO: The rest of the events mandated by the specification on
|
||||||
* POST /createRoom, and error management. */
|
* POST /createRoom, and error management. */
|
||||||
|
@ -582,9 +545,8 @@ PopulateEventV1(Room * room, HashMap * event, PduV1 * pdu, ServerPart serv)
|
||||||
JsonDuplicate(JsonValueAsObject(JsonGet(event, 1, "content")));
|
JsonDuplicate(JsonValueAsObject(JsonGet(event, 1, "content")));
|
||||||
pdu->room_id = StrDuplicate(room->id);
|
pdu->room_id = StrDuplicate(room->id);
|
||||||
pdu->signatures = HashMapCreate();
|
pdu->signatures = HashMapCreate();
|
||||||
pdu->depth = RoomGetDepth(room) + 1; /* TODO: Clamp this value. */
|
pdu->depth = RoomGetDepth(room) + 1;
|
||||||
pdu->depth = pdu->depth >= (int64_t) INT64_MAX ?
|
pdu->depth = pdu->depth >= INT64_MAX ? INT64_MAX : pdu->depth;
|
||||||
(int64_t) INT64_MAX : pdu->depth;
|
|
||||||
|
|
||||||
/* Create a random event ID for this PDU.
|
/* Create a random event ID for this PDU.
|
||||||
* TODO: Optionally verify whenever it's already used, but that
|
* TODO: Optionally verify whenever it's already used, but that
|
||||||
|
@ -1804,3 +1766,79 @@ RoomGetDepth(Room *room)
|
||||||
|
|
||||||
return max;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -176,4 +176,15 @@ extern HashMap * RoomEventCreate(char *, char *, char *, HashMap *);
|
||||||
*/
|
*/
|
||||||
extern uint64_t RoomGetDepth(Room *);
|
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 */
|
#endif /* TELODENDRIA_ROOM_H */
|
||||||
|
|
Loading…
Reference in a new issue