[ADD/WIP] Added more events at init-time
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

This commit is contained in:
lda 2024-05-18 16:39:51 +02:00
parent e36f4357ab
commit ecb18dc7b2
4 changed files with 100 additions and 49 deletions

View file

@ -43,6 +43,7 @@
#include <CanonicalJson.h> #include <CanonicalJson.h>
#include <Parser.h> #include <Parser.h>
#include <State.h> #include <State.h>
#include <Event.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -85,6 +86,11 @@ RoomCreate(Db * db, User *user, RoomCreateRequest * req, ServerPart s)
char *version_string, *full_creator; char *version_string, *full_creator;
int version_num = 1; int version_num = 1;
HashMap *json; HashMap *json;
HashMap *event, *content;
CommonID sender;
char *sender_str, *key;
JsonValue *val;
HashMap *override;
if (!db || !req || !user) if (!db || !req || !user)
{ {
return NULL; return NULL;
@ -113,58 +119,71 @@ RoomCreate(Db * db, User *user, RoomCreateRequest * req, ServerPart s)
JsonSet(json, JsonValueString(full_creator), 1, "creator"); JsonSet(json, JsonValueString(full_creator), 1, "creator");
Free(full_creator); Free(full_creator);
sender.sigil = '@';
sender.local = UserGetName(user);
sender.server = s;
sender_str = ParserRecomposeCommonID(sender);
/* m.room.create */
content = HashMapCreate();
if (room->version <= 10)
{ {
HashMap *event = HashMapCreate(); JsonSet(content, JsonValueString(sender_str), 1, "creator");
HashMap *content = HashMapCreate(); }
event = RoomEventCreate(sender_str, "m.room.create", "", content);
CommonID sender; JsonFree(RoomEventSend(room, event));
char *sender_str; JsonFree(event);
sender.sigil = '@'; /* m.room.member */
sender.local = UserGetName(user); content = HashMapCreate();
sender.server = s; JsonSet(content, JsonValueString("join"), 1, "membership");
sender_str = ParserRecomposeCommonID(sender); event = RoomEventCreate(sender_str, "m.room.member", sender_str, content);
JsonFree(RoomEventSend(room, event));
JsonFree(event);
JsonSet(event, JsonValueString(sender_str), 1, "sender"); /* m.room.power_levels */
if (room->version <= 10) content = HashMapCreate();
JsonSet(
content,
JsonValueInteger(100),
2, "users", sender_str);
override = req->power_level_content_override;
while (override && HashMapIterate(override, &key, (void **) &val))
{
JsonValue *main = HashMapGet(content, key);
if (main)
{ {
JsonSet(content, JsonValueString(sender_str), 1, "creator"); HashMapDelete(content, key);
JsonValueFree(main);
} }
Free(sender_str); HashMapSet(content, key, JsonValueDuplicate(val));
JsonSet(event, JsonValueString("m.room.create"), 1, "type"); }
JsonSet(event, JsonValueString(""), 1, "state_key"); event = RoomEventCreate(sender_str, "m.room.power_levels", "", content);
JsonFree(RoomEventSend(room, event));
JsonFree(event);
JsonSet(event, JsonValueObject(content), 1, "content"); /* TODO: Events set by the preset */
/* TODO: Events in initial_state */
if (req->name)
{
content = HashMapCreate();
JsonSet(content, JsonValueString(req->name), 1, "name");
event = RoomEventCreate(sender_str, "m.room.name", "", content);
JsonFree(RoomEventSend(room, event)); JsonFree(RoomEventSend(room, event));
JsonFree(event); JsonFree(event);
} }
if (req->topic)
{ {
HashMap *event = HashMapCreate(); content = HashMapCreate();
HashMap *content = HashMapCreate(); JsonSet(content, JsonValueString(req->topic), 1, "topic");
event = RoomEventCreate(sender_str, "m.room.topic", "", content);
CommonID sender;
char *sender_str;
sender.sigil = '@';
sender.local = UserGetName(user);
sender.server = s;
sender_str = ParserRecomposeCommonID(sender);
JsonSet(event, JsonValueString(sender_str), 1, "sender");
JsonSet(content, JsonValueString("join"), 1, "membership");
JsonSet(event, JsonValueString("m.room.member"), 1, "type");
JsonSet(event, JsonValueString(sender_str), 1, "state_key");
Free(sender_str);
JsonSet(event, JsonValueObject(content), 1, "content");
JsonFree(RoomEventSend(room, event)); JsonFree(RoomEventSend(room, event));
JsonFree(event); JsonFree(event);
} }
/* TODO: The rest of the events mandated by the specification on /* TODO: The rest of the events mandated by the specification on
* POST /createRoom. Also clean up that code, so that it is more * POST /createRoom. */
* straightforward(and short). */
Free(sender_str);
return room; return room;
} }
@ -377,7 +396,7 @@ RoomMinPL(Room * room, HashMap *state, char *type, char *act)
HashMap *pl = NULL; HashMap *pl = NULL;
JsonValue *val; JsonValue *val;
char *id_pl; char *id_pl;
int64_t ret, def; int64_t ret = 0, def = 0;
if (!room || !state || !act) if (!room || !state || !act)
{ {
return 0; return 0;
@ -415,7 +434,7 @@ RoomUserPL(Room * room, HashMap *state, char *user)
{ {
HashMap *pl = NULL; HashMap *pl = NULL;
char *id_pl; char *id_pl;
int64_t ret, def; int64_t ret = 0, def = 0;
if (!room || !state || !user) if (!room || !state || !user)
{ {
@ -1024,6 +1043,7 @@ AuthorisePowerLevelsV1(Room * room, PduV1 pdu, HashMap *state)
{ {
CommonIDFree(as_cid); CommonIDFree(as_cid);
flag = false; flag = false;
continue;
} }
/* Verify powerlevels. /* Verify powerlevels.
@ -1032,7 +1052,10 @@ AuthorisePowerLevelsV1(Room * room, PduV1 pdu, HashMap *state)
if (ParsePL(power_level, INT64_MAX) == INT64_MAX) if (ParsePL(power_level, INT64_MAX) == INT64_MAX)
{ {
flag = false; flag = false;
CommonIDFree(as_cid);
continue;
} }
CommonIDFree(as_cid);
} }
/* HashMapIterate does not support breaking, so we just set a /* HashMapIterate does not support breaking, so we just set a
@ -1059,10 +1082,11 @@ AuthorisePowerLevelsV1(Room * room, PduV1 pdu, HashMap *state)
JsonGet(prev_plevent, 2, "content", prop);\ JsonGet(prev_plevent, 2, "content", prop);\
JsonValue *new = \ JsonValue *new = \
JsonGet(pdu.content, 1, prop); \ JsonGet(pdu.content, 1, prop); \
int64_t oldv, newv; \ int64_t oldv = 0, newv = 0; \
oldv = JsonValueAsInteger(old); \
newv = JsonValueAsInteger(new); \
if ((old && !new) || (!old && new) || \ if ((old && !new) || (!old && new) || \
((oldv = JsonValueAsInteger(old)) != \ (oldv != newv)) \
(newv = JsonValueAsInteger(new)))) \
{ \ { \
if (old && (oldv > userpl)) \ if (old && (oldv > userpl)) \
{ \ { \
@ -1243,7 +1267,7 @@ RoomAuthoriseEventV1(Room * room, PduV1 pdu, HashMap *state)
return false; return false;
} }
/* Step 9: If the event has a state_key that starts with an @ and does /* Step (9): If the event has a state_key that starts with an @ and does
* not match the sender, reject. */ * not match the sender, reject. */
if (pdu.state_key && *pdu.state_key == '@') if (pdu.state_key && *pdu.state_key == '@')
{ {
@ -1286,8 +1310,8 @@ RoomAuthoriseEventV1(Room * room, PduV1 pdu, HashMap *state)
/* Step 12: Otherwise, allow. */ /* Step 12: Otherwise, allow. */
return true; return true;
} }
static char * char *
RoomHashEvent(HashMap * pdu_json) EventContentHash(HashMap * pdu_json)
{ {
HashMap * copy = JsonDuplicate(pdu_json); HashMap * copy = JsonDuplicate(pdu_json);
char *hash; char *hash;
@ -1303,7 +1327,7 @@ static char *
RoomHashEventV1(PduV1 pdu) RoomHashEventV1(PduV1 pdu)
{ {
HashMap *json = PduV1ToJson(&pdu); HashMap *json = PduV1ToJson(&pdu);
char *sha = RoomHashEvent(json); char *sha = EventContentHash(json);
JsonFree(json); JsonFree(json);
return sha; return sha;
@ -1617,3 +1641,23 @@ RoomAddEventV1(Room *room, PduV1 pdu)
return true; return true;
} }
HashMap *
RoomEventCreate(char *sender, char *type, char *key, HashMap *c)
{
HashMap *event;
if (!sender || !type || !c)
{
return NULL;
}
event = HashMapCreate();
JsonSet(event, JsonValueObject(c), 1, "content");
JsonSet(event, JsonValueString(sender), 1, "sender");
JsonSet(event, JsonValueString(type), 1, "type");
if (key)
{
JsonSet(event, JsonValueString(key), 1, "state_key");
}
return event;
}

View file

@ -40,7 +40,7 @@ ROUTE_IMPL(RouteCreateRoom, path, argp)
HashMap *response; HashMap *response;
Room *room = NULL; Room *room = NULL;
Db *db = args->matrixArgs->db; Db *db = args->matrixArgs->db;
RoomCreateRequest parsed; RoomCreateRequest parsed = { 0 };
User *user = NULL; User *user = NULL;
Config cfg; Config cfg;
ServerPart server; ServerPart server;
@ -112,5 +112,6 @@ finish:
UserUnlock(user); UserUnlock(user);
ConfigUnlock(&cfg); ConfigUnlock(&cfg);
ServerPartFree(server); ServerPartFree(server);
RoomCreateRequestFree(&parsed);
return response; return response;
} }

View file

@ -81,7 +81,7 @@ StateResolveV1(Room * room, Array * states)
{ {
HashMap *R = HashMapCreate(); HashMap *R = HashMapCreate();
HashMap *conflicts = HashMapCreate(); HashMap *conflicts = HashMapCreate();
Array *events, *types, *conflicting; Array *events = NULL, *types = NULL, *conflicting = NULL;
size_t i; size_t i;
ssize_t j; ssize_t j;

View file

@ -164,4 +164,10 @@ extern ServerPart RoomGetCreator(Room *);
*/ */
extern bool RoomAddEventV1(Room *, PduV1); extern bool RoomAddEventV1(Room *, PduV1);
/**
* Creates a barebones JSON object to be sent to
* .Fn RoomEventFetch .
*/
extern HashMap * RoomEventCreate(char *, char *, char *, HashMap *);
#endif /* TELODENDRIA_ROOM_H */ #endif /* TELODENDRIA_ROOM_H */