[ADD/WIP] Basic alias system.
Some checks are pending
Compile Telodendria / Compile Telodendria (x86, alpine-v3.19) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86, debian-v12.4) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86, freebsd-v14.0) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86, netbsd-v9.3) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86_64, alpine-v3.19) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86_64, debian-v12.4) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86_64, freebsd-v14.0) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86_64, netbsd-v9.3) (push) Waiting to run
Compile Telodendria / Compile Telodendria (x86_64, openbsd-v7.4) (push) Waiting to run

NOTE: I *need* to write an Alias API(and also manage clashes proper.)
This commit is contained in:
lda 2024-05-18 21:24:30 +02:00
parent 7ee35fcc28
commit e3c57d8f05

View file

@ -78,48 +78,15 @@ GenerateRoomId(ServerPart s)
return string; return string;
} }
static void
Room * RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
RoomCreate(Db * db, User *user, RoomCreateRequest * req, ServerPart s)
{ {
Room *room;
char *version_string, *full_creator;
int version_num = 1;
HashMap *json;
HashMap *event, *content;
CommonID sender; CommonID sender;
char *sender_str, *key; char *sender_str, *key;
JsonValue *val; HashMap *content, *event, *override;
HashMap *override;
Array *initial_states; Array *initial_states;
JsonValue *val;
size_t i; size_t i;
if (!db || !req || !user)
{
return NULL;
}
version_string = req->room_version;
if (version_string)
{
/* TODO: Eventually use something else than room version 1 by
* default, and maybe add a config parameter. */
version_num = atoi(version_string);
version_num = version_num == 0 ? 1 : version_num;
}
room = Malloc(sizeof(Room));
room->db = db;
room->creator.hostname = s.hostname ? StrDuplicate(s.hostname) : NULL;
room->creator.port = s.port ? StrDuplicate(s.port) : NULL;
room->id = GenerateRoomId(s);
room->version = version_num;
room->state_ref = DbCreate(db, 3, "rooms", room->id, "state");
room->leaves_ref = DbCreate(db, 3, "rooms", room->id, "leaves");
json = DbJson(room->leaves_ref);
JsonSet(json, JsonValueArray(ArrayCreate()), 1, "leaves");
full_creator = ParserRecomposeServerPart(room->creator);
JsonSet(json, JsonValueString(full_creator), 1, "creator");
Free(full_creator);
sender.sigil = '@'; sender.sigil = '@';
sender.local = UserGetName(user); sender.local = UserGetName(user);
@ -164,8 +131,21 @@ RoomCreate(Db * db, User *user, RoomCreateRequest * req, ServerPart s)
JsonFree(RoomEventSend(room, event)); JsonFree(RoomEventSend(room, event));
JsonFree(event); JsonFree(event);
/* TODO: Events set by the preset */ /* Presets */
/* TODO: Events in initial_state */ switch (req->preset)
{
case ROOM_CREATE_PUBLIC:
/* TODO */
break;
case ROOM_CREATE_TRUSTED:
/* TODO */
break;
case ROOM_CREATE_PRIVATE:
/* TODO */
break;
}
/* User-provided initial states */
initial_states = req->initial_state; initial_states = req->initial_state;
for (i = 0; i < ArraySize(initial_states); i++) for (i = 0; i < ArraySize(initial_states); i++)
{ {
@ -181,6 +161,8 @@ RoomCreate(Db * db, User *user, RoomCreateRequest * req, ServerPart s)
JsonFree(RoomEventSend(room, rseObject)); JsonFree(RoomEventSend(room, rseObject));
JsonFree(rseObject); JsonFree(rseObject);
} }
/* Name and topic. */
if (req->name) if (req->name)
{ {
content = HashMapCreate(); content = HashMapCreate();
@ -197,10 +179,112 @@ RoomCreate(Db * db, User *user, RoomCreateRequest * req, ServerPart s)
JsonFree(RoomEventSend(room, event)); JsonFree(RoomEventSend(room, event));
JsonFree(event); JsonFree(event);
} }
/* Custom alias */
if (req->room_alias_name)
{
DbRef *aliasesRef = DbLock(room->db, 1, "aliases");
HashMap *aliasesJson;
if (!aliasesRef)
{
aliasesRef = DbCreate(room->db, 1, "aliases");
}
if (aliasesRef)
{
CommonID full;
char *fullStr, *serverStr;
HashMap *alias, *idObject;
Array *servers, *ids;
full.sigil = '#';
full.local = req->room_alias_name;
full.server = s;
aliasesJson = DbJson(aliasesRef);
fullStr = ParserRecomposeCommonID(full);
servers = ArrayCreate();
serverStr = ParserRecomposeServerPart(room->creator);
ArrayAdd(servers, JsonValueString(serverStr));
Free(serverStr);
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);
}
}
/* TODO: The rest of the events mandated by the specification on /* TODO: The rest of the events mandated by the specification on
* POST /createRoom. */ * POST /createRoom, and error management. */
Free(sender_str); Free(sender_str);
}
Room *
RoomCreate(Db * db, User *user, RoomCreateRequest * req, ServerPart s)
{
Room *room;
char *version_string, *full_creator;
int version_num = 1;
HashMap *json;
if (!db || !req || !user)
{
return NULL;
}
version_string = req->room_version;
if (version_string)
{
/* TODO: Eventually use something else than room version 1 by
* default, and maybe add a config parameter. */
version_num = atoi(version_string);
version_num = version_num == 0 ? 1 : version_num;
}
room = Malloc(sizeof(Room));
room->db = db;
room->creator.hostname = s.hostname ? StrDuplicate(s.hostname) : NULL;
room->creator.port = s.port ? StrDuplicate(s.port) : NULL;
room->id = GenerateRoomId(s);
room->version = version_num;
room->state_ref = DbCreate(db, 3, "rooms", room->id, "state");
room->leaves_ref = DbCreate(db, 3, "rooms", room->id, "leaves");
json = DbJson(room->leaves_ref);
JsonSet(json, JsonValueArray(ArrayCreate()), 1, "leaves");
full_creator = ParserRecomposeServerPart(room->creator);
JsonSet(json, JsonValueString(full_creator), 1, "creator");
Free(full_creator);
RoomPopulate(room, user, req, s);
return room; return room;
} }
@ -499,9 +583,8 @@ PopulateEventV1(Room * room, HashMap * event, PduV1 * pdu, ServerPart serv)
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; /* TODO: Clamp this value. */
pdu->depth = pdu->depth = pdu->depth >= (int64_t) INT64_MAX ?
pdu->depth >= (int64_t) UINT64_MAX ? (int64_t) INT64_MAX : pdu->depth;
(int64_t) UINT64_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