forked from Telodendria/Telodendria
Compare commits
No commits in common. "cacc72bf849831f1e59beff1c4527f2318ae98ec" and "e3c57d8f054a3af1878ecaf95918eb1ae57965d8" have entirely different histories.
cacc72bf84
...
e3c57d8f05
4 changed files with 74 additions and 249 deletions
260
src/Room.c
260
src/Room.c
|
@ -88,11 +88,6 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
|
||||||
JsonValue *val;
|
JsonValue *val;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
char *join_rules_preset = NULL;
|
|
||||||
char *history_visibility_preset = NULL;
|
|
||||||
char *guest_access_preset = NULL;
|
|
||||||
/* TODO: Manage trusted private chat */
|
|
||||||
|
|
||||||
sender.sigil = '@';
|
sender.sigil = '@';
|
||||||
sender.local = UserGetName(user);
|
sender.local = UserGetName(user);
|
||||||
sender.server = s;
|
sender.server = s;
|
||||||
|
@ -140,59 +135,16 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
|
||||||
switch (req->preset)
|
switch (req->preset)
|
||||||
{
|
{
|
||||||
case ROOM_CREATE_PUBLIC:
|
case ROOM_CREATE_PUBLIC:
|
||||||
join_rules_preset = "public";
|
/* TODO */
|
||||||
history_visibility_preset = "shared";
|
|
||||||
guest_access_preset = "forbidden";
|
|
||||||
break;
|
break;
|
||||||
case ROOM_CREATE_TRUSTED:
|
case ROOM_CREATE_TRUSTED:
|
||||||
/* TODO */
|
/* TODO */
|
||||||
/* Fallthrough */
|
|
||||||
case ROOM_CREATE_PRIVATE:
|
|
||||||
join_rules_preset = "invite";
|
|
||||||
history_visibility_preset = "shared";
|
|
||||||
guest_access_preset = "can_join";
|
|
||||||
break;
|
break;
|
||||||
default:
|
case ROOM_CREATE_PRIVATE:
|
||||||
switch (req->visibility)
|
/* TODO */
|
||||||
{
|
|
||||||
case ROOM_PUBLIC:
|
|
||||||
join_rules_preset = "public";
|
|
||||||
history_visibility_preset = "shared";
|
|
||||||
guest_access_preset = "forbidden";
|
|
||||||
break;
|
|
||||||
case ROOM_PRIVATE:
|
|
||||||
join_rules_preset = "invite";
|
|
||||||
history_visibility_preset = "shared";
|
|
||||||
guest_access_preset = "can_join";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write out presets */
|
|
||||||
#define SetIfExistent(pset) do { \
|
|
||||||
if (pset##_preset) \
|
|
||||||
{ \
|
|
||||||
content = HashMapCreate(); \
|
|
||||||
JsonSet( \
|
|
||||||
content, \
|
|
||||||
JsonValueString(join_rules_preset) \
|
|
||||||
, 1, #pset); \
|
|
||||||
event = RoomEventCreate( \
|
|
||||||
sender_str, \
|
|
||||||
"m.room." #pset, "", content); \
|
|
||||||
JsonFree(RoomEventSend(room, event)); \
|
|
||||||
JsonFree(event); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
while (0)
|
|
||||||
|
|
||||||
SetIfExistent(join_rules);
|
|
||||||
SetIfExistent(history_visibility);
|
|
||||||
SetIfExistent(guest_access);
|
|
||||||
/* TODO: On a trusted room, set invitees PLs to the owner's. */
|
|
||||||
#undef SetIfExistent
|
|
||||||
|
|
||||||
/* User-provided initial states */
|
/* 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++)
|
||||||
|
@ -229,30 +181,67 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Custom alias */
|
/* Custom alias */
|
||||||
if (req->room_alias_name && !RoomResolveAlias(room->db, room->id))
|
if (req->room_alias_name)
|
||||||
{
|
{
|
||||||
CommonID full;
|
DbRef *aliasesRef = DbLock(room->db, 1, "aliases");
|
||||||
char *fullStr, *serverStr;
|
HashMap *aliasesJson;
|
||||||
|
if (!aliasesRef)
|
||||||
|
{
|
||||||
|
aliasesRef = DbCreate(room->db, 1, "aliases");
|
||||||
|
}
|
||||||
|
|
||||||
full.sigil = '#';
|
if (aliasesRef)
|
||||||
full.local = req->room_alias_name;
|
{
|
||||||
full.server = s;
|
CommonID full;
|
||||||
fullStr = ParserRecomposeCommonID(full);
|
char *fullStr, *serverStr;
|
||||||
|
HashMap *alias, *idObject;
|
||||||
|
Array *servers, *ids;
|
||||||
|
|
||||||
serverStr = ParserRecomposeServerPart(room->creator);
|
full.sigil = '#';
|
||||||
|
full.local = req->room_alias_name;
|
||||||
RoomAddAlias(room->db, fullStr, room->id, sender_str, serverStr);
|
full.server = s;
|
||||||
|
|
||||||
|
aliasesJson = DbJson(aliasesRef);
|
||||||
|
fullStr = ParserRecomposeCommonID(full);
|
||||||
|
|
||||||
content = HashMapCreate();
|
servers = ArrayCreate();
|
||||||
JsonSet(content, JsonValueString(fullStr), 1, "alias");
|
serverStr = ParserRecomposeServerPart(room->creator);
|
||||||
event = RoomEventCreate(
|
ArrayAdd(servers, JsonValueString(serverStr));
|
||||||
sender_str,
|
Free(serverStr);
|
||||||
"m.room.canonical_alias", "", content);
|
|
||||||
JsonFree(RoomEventSend(room, event));
|
|
||||||
JsonFree(event);
|
|
||||||
|
|
||||||
Free(fullStr);
|
alias = HashMapCreate();
|
||||||
Free(serverStr);
|
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, and error management. */
|
* POST /createRoom, and error management. */
|
||||||
|
@ -593,8 +582,9 @@ 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;
|
pdu->depth = RoomGetDepth(room) + 1; /* TODO: Clamp this value. */
|
||||||
pdu->depth = pdu->depth >= INT64_MAX ? INT64_MAX : pdu->depth;
|
pdu->depth = pdu->depth >= (int64_t) INT64_MAX ?
|
||||||
|
(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
|
||||||
|
@ -1814,129 +1804,3 @@ 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;
|
|
||||||
}
|
|
||||||
Array *
|
|
||||||
RoomReverseAlias(Db *db, char *roomId)
|
|
||||||
{
|
|
||||||
DbRef *aliasRef;
|
|
||||||
HashMap *json, *idObject;
|
|
||||||
Array *ret, *original;
|
|
||||||
size_t i;
|
|
||||||
if (!db || !roomId)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
aliasRef = DbLock(db, 1, "aliases");
|
|
||||||
if (!aliasRef)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
json = DbJson(aliasRef);
|
|
||||||
if (!(idObject =
|
|
||||||
JsonValueAsObject(JsonGet(json, 2, "id", roomId))))
|
|
||||||
{
|
|
||||||
DbUnlock(db, aliasRef);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
original = JsonValueAsArray(HashMapGet(idObject, "aliases"));
|
|
||||||
ret = ArrayCreate();
|
|
||||||
|
|
||||||
for (i = 0; i < ArraySize(original); i++)
|
|
||||||
{
|
|
||||||
JsonValue *v = ArrayGet(original, i);
|
|
||||||
ArrayAdd(ret, StrDuplicate(JsonValueAsString(v)));
|
|
||||||
}
|
|
||||||
|
|
||||||
DbUnlock(db, aliasRef);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RoomFreeReverse(Array *arr)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
if (!arr)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (i = 0; i < ArraySize(arr); i++)
|
|
||||||
{
|
|
||||||
Free(ArrayGet(arr, i));
|
|
||||||
}
|
|
||||||
ArrayFree(arr);
|
|
||||||
}
|
|
||||||
|
|
|
@ -80,19 +80,7 @@ ROUTE_IMPL(RouteCreateRoom, path, argp)
|
||||||
response = MatrixErrorCreate(M_NOT_JSON, NULL);
|
response = MatrixErrorCreate(M_NOT_JSON, NULL);
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* j2s hack: Setting to a default value like that.
|
|
||||||
* It's definitely NOT good(you can't rely on enums to
|
|
||||||
* store values outside their limits in the C standard,
|
|
||||||
* and this line will need to be changed everytime the
|
|
||||||
* preset list is changed).
|
|
||||||
*
|
|
||||||
* I do believe a decent solution to this would be to
|
|
||||||
* add a 'default' type(maybe initialised to 0 so that
|
|
||||||
* memsets would work as intended), that *wouldn't* be
|
|
||||||
* returned by j2s itself.
|
|
||||||
* TODO. */
|
|
||||||
parsed.preset = ROOM_CREATE_PRIVATE + 1;
|
|
||||||
if (!RoomCreateRequestFromJson(request, &parsed, &err))
|
if (!RoomCreateRequestFromJson(request, &parsed, &err))
|
||||||
{
|
{
|
||||||
HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
|
HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
|
||||||
|
|
|
@ -31,7 +31,6 @@
|
||||||
|
|
||||||
#include <Matrix.h>
|
#include <Matrix.h>
|
||||||
#include <User.h>
|
#include <User.h>
|
||||||
#include <Room.h>
|
|
||||||
|
|
||||||
ROUTE_IMPL(RouteRoomAliases, path, argp)
|
ROUTE_IMPL(RouteRoomAliases, path, argp)
|
||||||
{
|
{
|
||||||
|
@ -41,15 +40,16 @@ ROUTE_IMPL(RouteRoomAliases, path, argp)
|
||||||
char *msg;
|
char *msg;
|
||||||
|
|
||||||
HashMap *response = NULL;
|
HashMap *response = NULL;
|
||||||
|
HashMap *aliases = NULL;
|
||||||
|
HashMap *reversealias = NULL;
|
||||||
|
|
||||||
Array *alias = NULL, *arr;
|
JsonValue *val;
|
||||||
|
|
||||||
Db *db = args->matrixArgs->db;
|
Db *db = args->matrixArgs->db;
|
||||||
|
DbRef *ref = NULL;
|
||||||
|
|
||||||
User *user = NULL;
|
User *user = NULL;
|
||||||
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (HttpRequestMethodGet(args->context) != HTTP_GET)
|
if (HttpRequestMethodGet(args->context) != HTTP_GET)
|
||||||
{
|
{
|
||||||
msg = "Route only accepts GET.";
|
msg = "Route only accepts GET.";
|
||||||
|
@ -81,10 +81,11 @@ ROUTE_IMPL(RouteRoomAliases, path, argp)
|
||||||
response = MatrixErrorCreate(M_FORBIDDEN, msg);
|
response = MatrixErrorCreate(M_FORBIDDEN, msg);
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
alias = RoomReverseAlias(db, roomId);
|
ref = DbLock(db, 1, "aliases");
|
||||||
if (!alias)
|
aliases = DbJson(ref);
|
||||||
|
reversealias = JsonValueAsObject(JsonGet(aliases, 2, "id", roomId));
|
||||||
|
if (!reversealias)
|
||||||
{
|
{
|
||||||
/* We do not know about the room ID. */
|
/* We do not know about the room ID. */
|
||||||
msg = "Unknown room ID.";
|
msg = "Unknown room ID.";
|
||||||
|
@ -92,17 +93,12 @@ ROUTE_IMPL(RouteRoomAliases, path, argp)
|
||||||
response = MatrixErrorCreate(M_INVALID_PARAM, msg);
|
response = MatrixErrorCreate(M_INVALID_PARAM, msg);
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
arr = ArrayCreate();
|
|
||||||
for (i = 0; i < ArraySize(alias); i++)
|
|
||||||
{
|
|
||||||
char *str = ArrayGet(alias, i);
|
|
||||||
ArrayAdd(arr, JsonValueString(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
response = HashMapCreate();
|
response = HashMapCreate();
|
||||||
HashMapSet(response, "aliases", JsonValueArray(arr));
|
val = JsonGet(reversealias, 1, "aliases");
|
||||||
|
HashMapSet(response, "aliases", JsonValueDuplicate(val));
|
||||||
finish:
|
finish:
|
||||||
RoomFreeReverse(alias);
|
DbUnlock(db, ref);
|
||||||
UserUnlock(user);
|
UserUnlock(user);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,27 +176,4 @@ 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 *);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tries to resolve a list of aliases from a room ID into
|
|
||||||
* an array of strings stored on the heap.
|
|
||||||
*/
|
|
||||||
extern Array * RoomReverseAlias(Db *, char *);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Frees the array returned by
|
|
||||||
* .Fn RoomReverseAlias .
|
|
||||||
*/
|
|
||||||
extern void RoomFreeReverse(Array *);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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