forked from Telodendria/Telodendria
Compare commits
No commits in common. "a77be8b43730a1a871024212dfcf3ffa86b6249c" and "19359045e94badf6992f6ab83ca3fbdeb5797ec6" have entirely different histories.
a77be8b437
...
19359045e9
12 changed files with 106 additions and 370 deletions
11
configure
vendored
11
configure
vendored
|
@ -231,19 +231,15 @@ compile_schema() {
|
|||
install_out() {
|
||||
src="$1"
|
||||
out="$2"
|
||||
dir=$(dirname "$out")
|
||||
|
||||
echo "${TAB}mkdir -p \"$dir\""
|
||||
echo "${TAB}cp \"$src\" \"$out\""
|
||||
echo "${TAB}install -D \"$src\" \"$out\""
|
||||
}
|
||||
|
||||
install_man() {
|
||||
src="${OUT}/man/man3/${BIN_NAME}-$(basename $1 .h).3"
|
||||
out="$2"
|
||||
dir=$(dirname "$out")
|
||||
|
||||
echo "${TAB}mkdir -p \"$dir\""
|
||||
echo "${TAB}cp \"$src\" \"$out\""
|
||||
echo "${TAB}install -D \"$src\" \"$out\""
|
||||
}
|
||||
|
||||
uninstall_out() {
|
||||
|
@ -291,8 +287,7 @@ ${TAB}done
|
|||
${BIN_NAME}: ${OUT}/bin/${BIN_NAME}
|
||||
|
||||
install: ${BIN_NAME}
|
||||
${TAB}mkdir -p \$(PREFIX)/bin
|
||||
${TAB}cp ${OUT}/bin/${BIN_NAME} \$(PREFIX)/bin/${BIN_NAME}
|
||||
${TAB}install -D ${OUT}/bin/${BIN_NAME} \$(PREFIX)/bin/${BIN_NAME}
|
||||
|
||||
uninstall:
|
||||
${TAB}rm \$(PREFIX)/bin/${BIN_NAME}
|
||||
|
|
|
@ -46,7 +46,7 @@ HtmlBegin(Stream * stream, char *title)
|
|||
"<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\">"
|
||||
"<title>%s | Telodendria</title>"
|
||||
"<link rel=\"stylesheet\" href=\"/_matrix/static/telodendria.css\">"
|
||||
"<script src=\"/_matrix/static/telodendria.js\"></script>"
|
||||
"<script src=\"/_matrix/static/telodendria.js\"></script>"
|
||||
"</head>"
|
||||
"<body>"
|
||||
"<pre class=\"logo\">"
|
||||
|
|
|
@ -297,8 +297,7 @@ start:
|
|||
goto finish;
|
||||
}
|
||||
|
||||
if (!tConfig.log.timestampFormat ||
|
||||
!StrEquals(tConfig.log.timestampFormat, "default"))
|
||||
if (!tConfig.log.timestampFormat || !StrEquals(tConfig.log.timestampFormat, "default"))
|
||||
{
|
||||
LogConfigTimeStampFormatSet(LogConfigGlobal(), tConfig.log.timestampFormat);
|
||||
}
|
||||
|
|
291
src/Room.c
291
src/Room.c
|
@ -126,7 +126,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
|
|||
JsonValueFree(HashMapSet(content, key, JsonValueDuplicate(val)));
|
||||
}
|
||||
event = RoomEventCreate(sender_str, "m.room.create", "", content);
|
||||
JsonFree(RoomEventSend(room, event, NULL));
|
||||
JsonFree(RoomEventSend(room, event));
|
||||
JsonFree(event);
|
||||
UserAddJoin(user, room->id);
|
||||
|
||||
|
@ -134,7 +134,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
|
|||
content = HashMapCreate();
|
||||
JsonSet(content, JsonValueString("join"), 1, "membership");
|
||||
event = RoomEventCreate(sender_str, "m.room.member", sender_str, content);
|
||||
JsonFree(RoomEventSend(room, event, NULL));
|
||||
JsonFree(RoomEventSend(room, event));
|
||||
JsonFree(event);
|
||||
|
||||
/* m.room.power_levels */
|
||||
|
@ -155,7 +155,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
|
|||
HashMapSet(content, key, JsonValueDuplicate(val));
|
||||
}
|
||||
event = RoomEventCreate(sender_str, "m.room.power_levels", "", content);
|
||||
JsonFree(RoomEventSend(room, event, NULL));
|
||||
JsonFree(RoomEventSend(room, event));
|
||||
JsonFree(event);
|
||||
|
||||
/* Presets */
|
||||
|
@ -203,7 +203,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
|
|||
event = RoomEventCreate( \
|
||||
sender_str, \
|
||||
"m.room." #p, "", content); \
|
||||
JsonFree(RoomEventSend(room, event, NULL)); \
|
||||
JsonFree(RoomEventSend(room, event)); \
|
||||
JsonFree(event); \
|
||||
} \
|
||||
} \
|
||||
|
@ -227,7 +227,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
|
|||
}
|
||||
HashMapSet(rseObject, "sender", JsonValueString(sender_str));
|
||||
|
||||
JsonFree(RoomEventSend(room, rseObject, NULL));
|
||||
JsonFree(RoomEventSend(room, rseObject));
|
||||
JsonFree(rseObject);
|
||||
}
|
||||
|
||||
|
@ -237,7 +237,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
|
|||
content = HashMapCreate();
|
||||
JsonSet(content, JsonValueString(req->name), 1, "name");
|
||||
event = RoomEventCreate(sender_str, "m.room.name", "", content);
|
||||
JsonFree(RoomEventSend(room, event, NULL));
|
||||
JsonFree(RoomEventSend(room, event));
|
||||
JsonFree(event);
|
||||
}
|
||||
if (req->topic)
|
||||
|
@ -245,7 +245,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
|
|||
content = HashMapCreate();
|
||||
JsonSet(content, JsonValueString(req->topic), 1, "topic");
|
||||
event = RoomEventCreate(sender_str, "m.room.topic", "", content);
|
||||
JsonFree(RoomEventSend(room, event, NULL));
|
||||
JsonFree(RoomEventSend(room, event));
|
||||
JsonFree(event);
|
||||
}
|
||||
|
||||
|
@ -269,7 +269,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
|
|||
event = RoomEventCreate(
|
||||
sender_str,
|
||||
"m.room.canonical_alias", "", content);
|
||||
JsonFree(RoomEventSend(room, event, NULL));
|
||||
JsonFree(RoomEventSend(room, event));
|
||||
JsonFree(event);
|
||||
|
||||
Free(fullStr);
|
||||
|
@ -299,7 +299,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
|
|||
}
|
||||
|
||||
event = RoomEventCreate(sender_str, "m.room.power_levels", "", pl_content);
|
||||
JsonFree(RoomEventSend(room, event, NULL));
|
||||
JsonFree(RoomEventSend(room, event));
|
||||
JsonFree(event);
|
||||
|
||||
JsonValueFree(JsonSet(
|
||||
|
@ -688,7 +688,7 @@ PopulateEventV1(Room * room, HashMap * event, PduV1 * pdu, ServerPart serv)
|
|||
return false;
|
||||
}
|
||||
static bool
|
||||
AuthoriseCreateV1(PduV1 pdu, char **errp)
|
||||
AuthoriseCreateV1(PduV1 pdu)
|
||||
{
|
||||
bool ret = true;
|
||||
CommonID sender = { 0 }, room_id = { 0 };
|
||||
|
@ -696,20 +696,12 @@ AuthoriseCreateV1(PduV1 pdu, char **errp)
|
|||
|
||||
if (ArraySize(pdu.auth_events) > 0)
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Room creation event has auth events";
|
||||
}
|
||||
ret = false;
|
||||
goto finish;
|
||||
}
|
||||
if (!ParseCommonID(pdu.room_id, &room_id) ||
|
||||
!ParseCommonID(pdu.sender, &sender))
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Couldn't parse the sender/room ID";
|
||||
}
|
||||
ret = false;
|
||||
goto finish;
|
||||
}
|
||||
|
@ -717,20 +709,12 @@ AuthoriseCreateV1(PduV1 pdu, char **errp)
|
|||
id_serv = ParserRecomposeServerPart(room_id.server);
|
||||
if (!StrEquals(sender_serv, id_serv))
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Room is not properly namespaced";
|
||||
}
|
||||
ret = false;
|
||||
goto finish;
|
||||
}
|
||||
/* TODO: Check room_version as in step 1.3 */
|
||||
if (!HashMapGet(pdu.content, "creator"))
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Room creation event has auth events";
|
||||
}
|
||||
ret = false;
|
||||
goto finish;
|
||||
}
|
||||
|
@ -772,10 +756,7 @@ ValidAuthEventV1(PduV1 *auth_pdu, PduV1 *pdu)
|
|||
JsonValue *third_pid =
|
||||
JsonGet(pdu->content, 1, "third_party_invite");
|
||||
|
||||
/* The PDU's state_key is the target. So we check if if the
|
||||
* auth PDU would count as the target's membership. Was very fun to
|
||||
* find that out when I wanted to kick my 'yukari' alt. */
|
||||
if (IsState(auth_pdu, "m.room.member", pdu->state_key))
|
||||
if (IsState(auth_pdu, "m.room.member", auth_pdu->sender))
|
||||
{
|
||||
/* TODO: Check if it's the latest in terms of [pdu] */
|
||||
return true;
|
||||
|
@ -807,8 +788,6 @@ ValidAuthEventV1(PduV1 *auth_pdu, PduV1 *pdu)
|
|||
static bool
|
||||
VerifyPDUV1(PduV1 *auth_pdu)
|
||||
{
|
||||
/* TODO: The PDU could come from an unknown source, which may lack
|
||||
* the tools to verify softfailing(or a source that we may not trust)*/
|
||||
/* TODO:
|
||||
* https://spec.matrix.org/v1.7/server-server-api/
|
||||
* #checks-performed-on-receipt-of-a-pdu */
|
||||
|
@ -825,7 +804,7 @@ VerifyPDUV1(PduV1 *auth_pdu)
|
|||
* soft-failed */
|
||||
}
|
||||
static bool
|
||||
ConsiderAuthEventsV1(Room * room, PduV1 pdu, char **errp)
|
||||
ConsiderAuthEventsV1(Room * room, PduV1 pdu)
|
||||
{
|
||||
char *ignored;
|
||||
size_t i;
|
||||
|
@ -844,10 +823,6 @@ ConsiderAuthEventsV1(Room * room, PduV1 pdu, char **errp)
|
|||
{
|
||||
JsonFree(event);
|
||||
HashMapFree(state_keytype);
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Couldn't parse an auth event";
|
||||
}
|
||||
return false; /* Yeah... we aren't doing that. */
|
||||
}
|
||||
|
||||
|
@ -859,11 +834,6 @@ ConsiderAuthEventsV1(Room * room, PduV1 pdu, char **errp)
|
|||
if (HashMapGet(state_keytype, key_type_id))
|
||||
{
|
||||
/* Duplicate found! We actually ignore it's actual value. */
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Duplicate auth event was found";
|
||||
}
|
||||
|
||||
JsonFree(event);
|
||||
PduV1Free(&auth_pdu);
|
||||
|
||||
|
@ -881,10 +851,6 @@ ConsiderAuthEventsV1(Room * room, PduV1 pdu, char **errp)
|
|||
* described in the server specification, reject. */
|
||||
if (!ValidAuthEventV1(&auth_pdu, &pdu))
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Invalid authevent given.";
|
||||
}
|
||||
JsonFree(event);
|
||||
PduV1Free(&auth_pdu);
|
||||
HashMapFree(state_keytype);
|
||||
|
@ -895,10 +861,6 @@ ConsiderAuthEventsV1(Room * room, PduV1 pdu, char **errp)
|
|||
* TODO */
|
||||
if (!VerifyPDUV1(&auth_pdu))
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Event depends on rejected PDUs";
|
||||
}
|
||||
PduV1Free(&auth_pdu);
|
||||
JsonFree(event);
|
||||
HashMapFree(state_keytype);
|
||||
|
@ -916,10 +878,6 @@ ConsiderAuthEventsV1(Room * room, PduV1 pdu, char **errp)
|
|||
PduV1Free(&auth_pdu);
|
||||
}
|
||||
HashMapFree(state_keytype);
|
||||
if (!room_create && errp)
|
||||
{
|
||||
*errp = "Room creation event was not in the PDU's auth events";
|
||||
}
|
||||
return room_create; /* Step 2.4 is actually done here. */
|
||||
}
|
||||
static bool
|
||||
|
@ -957,24 +915,16 @@ end:
|
|||
return ret;
|
||||
}
|
||||
static bool
|
||||
AuthoriseAliasV1(PduV1 pdu, char **errp)
|
||||
AuthoriseAliasV1(PduV1 pdu)
|
||||
{
|
||||
/* Step 4.1: If event has no state_key, reject. */
|
||||
if (!pdu.state_key || StrEquals(pdu.state_key, ""))
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Step 4.1 fail: no state key in the alias";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/* Step 4.2: If sender's domain doesn't matches state_key, reject. */
|
||||
if (!VerifyServers(pdu.state_key, pdu.sender))
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Step 4.2 fail: alias domain doesnt match statekey";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -982,7 +932,7 @@ AuthoriseAliasV1(PduV1 pdu, char **errp)
|
|||
return true;
|
||||
}
|
||||
static bool
|
||||
AuthorizeInviteMembershipV1(Room * room, PduV1 pdu, State *state, char **errp)
|
||||
AuthorizeInviteMembershipV1(Room * room, PduV1 pdu, State *state)
|
||||
{
|
||||
int64_t invite_level;
|
||||
int64_t pdu_level;
|
||||
|
@ -997,20 +947,12 @@ AuthorizeInviteMembershipV1(Room * room, PduV1 pdu, State *state, char **errp)
|
|||
/* Step 5.3.1.1: If target user is banned, reject. */
|
||||
if (RoomUserHasMembership(room, state, pdu.state_key, "ban"))
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Step 5.3.1.1 fail: target is banned";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/* Step 5.3.1.2: If content.third_party_invite does not have a signed
|
||||
* property, reject. */
|
||||
if (!(signed_val = JsonGet(third_pi_obj, 1, "signed")))
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Step 5.3.1.2 fail: unsigned 3PII";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
signed_obj = JsonValueAsObject(signed_val);
|
||||
|
@ -1019,28 +961,16 @@ AuthorizeInviteMembershipV1(Room * room, PduV1 pdu, State *state, char **errp)
|
|||
* reject. */
|
||||
if (!(mxid = JsonGet(signed_obj, 1, "mxid")))
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Step 5.3.1.3 fail: no MXID in 3PII";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (!(token = JsonGet(signed_obj, 1, "token")))
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Step 5.3.1.3 fail: no token in 3PII";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Step 5.3.1.4: If mxid does not match state_key, reject. */
|
||||
if (!StrEquals(JsonValueAsString(mxid), pdu.state_key))
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Step 5.3.1.4 fail: 3PII's MXID != state_key";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1050,10 +980,6 @@ AuthorizeInviteMembershipV1(Room * room, PduV1 pdu, State *state, char **errp)
|
|||
state,
|
||||
"m.room.third_party_invite", JsonValueAsString(token))))
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Step 5.3.1.5 fail: no proper 3PII event";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
third_pi_event = RoomEventFetch(room, third_pi_id);
|
||||
|
@ -1063,10 +989,6 @@ AuthorizeInviteMembershipV1(Room * room, PduV1 pdu, State *state, char **errp)
|
|||
thirdpi_event_sender = JsonValueAsString(JsonGet(third_pi_event, 1, "sender"));
|
||||
if (!StrEquals(thirdpi_event_sender, pdu.sender))
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Step 5.3.1.6 fail: sender does not match 3PII";
|
||||
}
|
||||
JsonFree(third_pi_event);
|
||||
return false;
|
||||
}
|
||||
|
@ -1081,10 +1003,6 @@ AuthorizeInviteMembershipV1(Room * room, PduV1 pdu, State *state, char **errp)
|
|||
* - A list of public keys in the public_keys property. */
|
||||
|
||||
/* Step 5.3.1.8: Otherwise, reject. */
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Step 5.3.1.8 fail: signature check do not match";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1092,20 +1010,12 @@ AuthorizeInviteMembershipV1(Room * room, PduV1 pdu, State *state, char **errp)
|
|||
* reject. */
|
||||
if (!RoomUserHasMembership(room, state, pdu.sender, "join"))
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Step 5.3.2 fail: sender is not 'join'ed";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/* Step 5.3.3: If target user's current membership state is join or ban, reject. */
|
||||
/* Step 5.3.3: If target user’s current membership state is join or ban, reject. */
|
||||
if (RoomUserHasMembership(room, state, pdu.state_key, "join") ||
|
||||
RoomUserHasMembership(room, state, pdu.state_key, "ban"))
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Step 5.3.3 fail: target is 'join'|'ban'd";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1118,14 +1028,10 @@ AuthorizeInviteMembershipV1(Room * room, PduV1 pdu, State *state, char **errp)
|
|||
return true;
|
||||
}
|
||||
/* Step 5.3.5: Otherwise, reject. */
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Step 5.3.5 fail: sender has no permissions to do so";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
static bool
|
||||
AuthorizeLeaveMembershipV1(Room * room, PduV1 pdu, State *state, char **errp)
|
||||
AuthorizeLeaveMembershipV1(Room * room, PduV1 pdu, State *state)
|
||||
{
|
||||
int64_t ban_level = RoomMinPL(room, state, NULL, "ban");
|
||||
int64_t kick_level = RoomMinPL(room, state, NULL, "kick");
|
||||
|
@ -1136,26 +1042,15 @@ AuthorizeLeaveMembershipV1(Room * room, PduV1 pdu, State *state, char **errp)
|
|||
* that user's current membership state is invite or join. */
|
||||
if (StrEquals(pdu.sender, pdu.state_key))
|
||||
{
|
||||
bool flag =
|
||||
return
|
||||
RoomUserHasMembership(room, state, pdu.sender, "invite") ||
|
||||
RoomUserHasMembership(room, state, pdu.sender, "join");
|
||||
if (!flag && errp)
|
||||
{
|
||||
*errp = "Step 5.4.1 fail: user tries to leave but is "
|
||||
"~'invite' AND ~'join'.";
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
/* Step 5.4.2: If the sender's current membership state is not join,
|
||||
* reject. */
|
||||
if (!RoomUserHasMembership(room, state, pdu.sender, "join"))
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Step 5.4.2 fail: sender tries to kick but is "
|
||||
"~'invite'.";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1164,11 +1059,6 @@ AuthorizeLeaveMembershipV1(Room * room, PduV1 pdu, State *state, char **errp)
|
|||
if (RoomUserHasMembership(room, state, pdu.state_key, "ban") &&
|
||||
sender_level < ban_level)
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Step 5.4.3 fail: sender tries to unban but has no "
|
||||
"permissions to do so.";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1181,26 +1071,16 @@ AuthorizeLeaveMembershipV1(Room * room, PduV1 pdu, State *state, char **errp)
|
|||
}
|
||||
|
||||
/* Step 5.4.5: Otherwise, reject. */
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Step 5.4.5 fail: sender tried to kick but has no "
|
||||
"permissions to do so.";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
static bool
|
||||
AuthorizeBanMembershipV1(Room * room, PduV1 pdu, State *state, char **errp)
|
||||
AuthorizeBanMembershipV1(Room * room, PduV1 pdu, State *state)
|
||||
{
|
||||
int64_t ban_pl, pdu_pl, target_pl;
|
||||
|
||||
/* Step 5.5.1: If the sender's current membership state is not join, reject. */
|
||||
if (!RoomUserHasMembership(room, state, pdu.sender, "join"))
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Step 5.5.1 fail: sender tries to ban but is not "
|
||||
"'join'ed";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1216,15 +1096,10 @@ AuthorizeBanMembershipV1(Room * room, PduV1 pdu, State *state, char **errp)
|
|||
}
|
||||
|
||||
/* Step 5.5.3: Otherwise, reject. */
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Step 5.5.3 fail: sender tries to ban has no permissions to "
|
||||
"do so";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
static bool
|
||||
AuthorizeJoinMembershipV1(Room * room, PduV1 pdu, State *state, char **errp)
|
||||
AuthorizeJoinMembershipV1(Room * room, PduV1 pdu, State *state)
|
||||
{
|
||||
/* Step 5.2.1: If the only previous event is an m.room.create and the
|
||||
* state_key is the creator, allow. */
|
||||
|
@ -1257,20 +1132,11 @@ AuthorizeJoinMembershipV1(Room * room, PduV1 pdu, State *state, char **errp)
|
|||
/* Step 5.2.2: If the sender does not match state_key, reject. */
|
||||
if (!StrEquals(pdu.sender, pdu.state_key))
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Step 5.2.2 fail: sender does not match statekey "
|
||||
"on 'join'";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/* Step 5.2.3: If the sender is banned, reject. */
|
||||
if (RoomUserHasMembership(room, state, pdu.sender, "ban"))
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Step 5.2.2 fail: sender is banned on 'join'";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1287,16 +1153,11 @@ AuthorizeJoinMembershipV1(Room * room, PduV1 pdu, State *state, char **errp)
|
|||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Step 5.2.6: Otherwise, reject. */
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Step 5.2.6 fail: join_rule does not allow 'join'";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
static bool
|
||||
AuthoriseMemberV1(Room * room, PduV1 pdu, State *state, char **errp)
|
||||
AuthoriseMemberV1(Room * room, PduV1 pdu, State *state)
|
||||
{
|
||||
JsonValue *membership;
|
||||
char *membership_str;
|
||||
|
@ -1306,26 +1167,18 @@ AuthoriseMemberV1(Room * room, PduV1 pdu, State *state, char **errp)
|
|||
StrEquals(pdu.state_key, "") ||
|
||||
!(membership = JsonGet(pdu.content, 1, "membership")))
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Step 5.1 fail: broken membership's statekey/membership";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (JsonValueType(membership) != JSON_STRING)
|
||||
{
|
||||
/* Also check for the type */
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Step 5.1 fail: broken membership's membership";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
membership_str = JsonValueAsString(membership);
|
||||
#define JumpIfMembership(mem, func) do { \
|
||||
if (StrEquals(membership_str, mem)) \
|
||||
{ \
|
||||
return func(room, pdu, state, errp); \
|
||||
return func(room, pdu, state); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
@ -1522,7 +1375,7 @@ AuthorisePowerLevelsV1(Room * room, PduV1 pdu, State *state)
|
|||
return true;
|
||||
}
|
||||
bool
|
||||
RoomAuthoriseEventV1(Room * room, PduV1 pdu, State *state, char **errp)
|
||||
RoomAuthoriseEventV1(Room * room, PduV1 pdu, State *state)
|
||||
{
|
||||
HashMap *create_event;
|
||||
char *create_event_id;
|
||||
|
@ -1532,11 +1385,11 @@ RoomAuthoriseEventV1(Room * room, PduV1 pdu, State *state, char **errp)
|
|||
/* Step 1: If m.room.create */
|
||||
if (StrEquals(pdu.type, "m.room.create"))
|
||||
{
|
||||
return AuthoriseCreateV1(pdu, errp);
|
||||
return AuthoriseCreateV1(pdu);
|
||||
}
|
||||
|
||||
/* Step 2: Considering the event's auth_events. */
|
||||
if (!ConsiderAuthEventsV1(room, pdu, errp))
|
||||
if (!ConsiderAuthEventsV1(room, pdu))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@ -1550,11 +1403,6 @@ RoomAuthoriseEventV1(Room * room, PduV1 pdu, State *state, char **errp)
|
|||
if (!state || !create_event_id)
|
||||
{
|
||||
/* At this point, [create_event_id] has to exist */
|
||||
if (errp)
|
||||
{
|
||||
*errp = "No creation event in the state. Needless to say, "
|
||||
"your room is done for.";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
create_event = RoomEventFetch(room, create_event_id);
|
||||
|
@ -1568,10 +1416,6 @@ RoomAuthoriseEventV1(Room * room, PduV1 pdu, State *state, char **errp)
|
|||
char *p_sender = pdu.sender;
|
||||
if (!VerifyServers(c_sender, p_sender))
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Trying to access a room with m.federate off.";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1581,13 +1425,13 @@ RoomAuthoriseEventV1(Room * room, PduV1 pdu, State *state, char **errp)
|
|||
/* Step 4: If type is m.room.aliases */
|
||||
if (StrEquals(pdu.type, "m.room.aliases"))
|
||||
{
|
||||
return AuthoriseAliasV1(pdu, errp);
|
||||
return AuthoriseAliasV1(pdu);
|
||||
}
|
||||
|
||||
/* Step 5: If type is m.room.member */
|
||||
if (StrEquals(pdu.type, "m.room.member"))
|
||||
{
|
||||
return AuthoriseMemberV1(room, pdu, state, errp);
|
||||
return AuthoriseMemberV1(room, pdu, state);
|
||||
}
|
||||
/* Step 6: If the sender's current membership state is not join, reject. */
|
||||
if (!RoomUserHasMembership(room, state, pdu.sender, "join"))
|
||||
|
@ -1727,27 +1571,19 @@ EventFitsV1(PduV1 pdu)
|
|||
return ret;
|
||||
}
|
||||
static PduV1Status
|
||||
RoomGetEventStatusV1(Room *room, PduV1 *pdu, State *prev, bool client, char **errp)
|
||||
RoomGetEventStatusV1(Room *room, PduV1 *pdu, State *prev, bool client)
|
||||
{
|
||||
if (!room || !pdu || !prev)
|
||||
{
|
||||
if (errp)
|
||||
{
|
||||
*errp = "Illegal arguments given to RoomGetEventStatusV1";
|
||||
}
|
||||
return PDUV1_STATUS_DROPPED;
|
||||
}
|
||||
|
||||
if (!EventFitsV1(*pdu))
|
||||
{
|
||||
/* Reject this event as it is too large. */
|
||||
if (errp)
|
||||
{
|
||||
*errp = "PDU is too large to fit";
|
||||
}
|
||||
return PDUV1_STATUS_DROPPED;
|
||||
}
|
||||
if (!RoomAuthoriseEventV1(room, *pdu, prev, errp))
|
||||
if (!RoomAuthoriseEventV1(room, *pdu, prev))
|
||||
{
|
||||
/* Reject this event as the current state does not allow it.
|
||||
* TODO: Make the auth check function return a string showing the
|
||||
|
@ -1759,7 +1595,7 @@ RoomGetEventStatusV1(Room *room, PduV1 *pdu, State *prev, bool client, char **er
|
|||
{
|
||||
State *current = StateCurrent(room);
|
||||
|
||||
if (!RoomAuthoriseEventV1(room, *pdu, current, NULL))
|
||||
if (!RoomAuthoriseEventV1(room, *pdu, current))
|
||||
{
|
||||
StateFree(current);
|
||||
return PDUV1_STATUS_SOFTFAIL;
|
||||
|
@ -1770,7 +1606,7 @@ RoomGetEventStatusV1(Room *room, PduV1 *pdu, State *prev, bool client, char **er
|
|||
return PDUV1_STATUS_ACCEPTED;
|
||||
}
|
||||
static HashMap *
|
||||
RoomEventSendV1(Room * room, HashMap * event, char **errp)
|
||||
RoomEventSendV1(Room * room, HashMap * event)
|
||||
{
|
||||
PduV1 pdu = { 0 };
|
||||
HashMap *pdu_object = NULL;
|
||||
|
@ -1866,7 +1702,8 @@ RoomEventSendV1(Room * room, HashMap * event, char **errp)
|
|||
*/
|
||||
|
||||
/* TODO: For PDU events, we should verify their hashes. */
|
||||
status = RoomGetEventStatusV1(room, &pdu, state, client_event, errp);
|
||||
status = RoomGetEventStatusV1(room, &pdu, state, client_event);
|
||||
Log(LOG_DEBUG, "status='%s'", PduV1StatusToStr(status));
|
||||
if (status == PDUV1_STATUS_DROPPED)
|
||||
{
|
||||
goto finish;
|
||||
|
@ -1908,7 +1745,7 @@ RoomEventSendV3(Room * room, HashMap * event)
|
|||
return NULL;
|
||||
}
|
||||
HashMap *
|
||||
RoomEventSend(Room * room, HashMap * event, char **errp)
|
||||
RoomEventSend(Room * room, HashMap * event)
|
||||
{
|
||||
if (!room || !event)
|
||||
{
|
||||
|
@ -1917,7 +1754,7 @@ RoomEventSend(Room * room, HashMap * event, char **errp)
|
|||
if (room->version < 3)
|
||||
{
|
||||
/* Manage with PDUv1 */
|
||||
return RoomEventSendV1(room, event, errp);
|
||||
return RoomEventSendV1(room, event);
|
||||
}
|
||||
/* Manage with PDUv3 otherwise */
|
||||
return RoomEventSendV3(room, event);
|
||||
|
@ -2361,7 +2198,7 @@ RoomSendInvite(User *sender, bool direct, char *user, Room *room)
|
|||
JsonSet(content, JsonValueBoolean(direct), 1, "is_direct");
|
||||
JsonSet(content, JsonValueString("invite"), 1, "membership");
|
||||
event = RoomEventCreate(senderStr, "m.room.member", user, content);
|
||||
JsonFree(RoomEventSend(room, event, NULL));
|
||||
JsonFree(RoomEventSend(room, event));
|
||||
JsonFree(event);
|
||||
|
||||
/* TODO: Send to "local" invite list if user is local. */
|
||||
|
@ -2466,55 +2303,7 @@ end:
|
|||
}
|
||||
|
||||
bool
|
||||
RoomLeave(Room *room, User *user, char **errp)
|
||||
{
|
||||
CommonID *userId = NULL;
|
||||
char *userString = NULL;
|
||||
char *server = NULL;
|
||||
HashMap *content = NULL;
|
||||
HashMap *event = NULL;
|
||||
HashMap *pdu = NULL;
|
||||
bool ret = false;
|
||||
|
||||
if (!room || !user)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
server = ConfigGetServerName(room->db);
|
||||
if (!server)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
userId = UserIdParse(UserGetName(user), server);
|
||||
userId->sigil = '@';
|
||||
userString = ParserRecomposeCommonID(*userId);
|
||||
Free(server);
|
||||
server = NULL;
|
||||
|
||||
content = HashMapCreate();
|
||||
JsonSet(content, JsonValueString("leave"), 1, "membership");
|
||||
event = RoomEventCreate(userString, "m.room.member", userString, content);
|
||||
pdu = RoomEventSend(room, event, errp);
|
||||
|
||||
/* TODO: One ought to be extremely careful with managing users in those
|
||||
* scenarios, as the DB flushes do not sync. */
|
||||
ret = !!pdu;
|
||||
if (ret)
|
||||
{
|
||||
UserRemoveJoin(user, room->id);
|
||||
}
|
||||
UserIdFree(userId);
|
||||
JsonFree(event);
|
||||
JsonFree(pdu);
|
||||
if (userString)
|
||||
{
|
||||
Free(userString);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
bool
|
||||
RoomJoin(Room *room, User *user, char **errp)
|
||||
RoomJoin(Room *room, User *user)
|
||||
{
|
||||
CommonID *userId = NULL;
|
||||
char *userString = NULL;
|
||||
|
@ -2549,15 +2338,9 @@ RoomJoin(Room *room, User *user, char **errp)
|
|||
content = HashMapCreate();
|
||||
JsonSet(content, JsonValueString("join"), 1, "membership");
|
||||
event = RoomEventCreate(userString, "m.room.member", userString, content);
|
||||
pdu = RoomEventSend(room, event, errp);
|
||||
pdu = RoomEventSend(room, event);
|
||||
|
||||
/* TODO: One ought to be extremely careful with managing users in those
|
||||
* scenarios, as the DB flushes do not sync. */
|
||||
ret = !!pdu;
|
||||
if (ret)
|
||||
{
|
||||
UserAddJoin(user, room->id);
|
||||
}
|
||||
end:
|
||||
UserIdFree(userId);
|
||||
JsonFree(event);
|
||||
|
|
|
@ -82,7 +82,7 @@ RouterBuild(void)
|
|||
R("/_matrix/client/v3/rooms/(.*)/state/(.*)", RouteSendState);
|
||||
R("/_matrix/client/v3/rooms/(.*)/event/(.*)", RouteFetchEvent);
|
||||
R("/_matrix/client/v3/rooms/(.*)/(join|leave)", RouteJoinRoom);
|
||||
R("/_matrix/client/v3/rooms/(.*)/(kick|ban|unban)", RouteKickRoom);
|
||||
R("/_matrix/client/v3/rooms/(.*)/(kick|ban)", RouteKickRoom);
|
||||
R("/_matrix/client/v3/rooms/(.*)/messages", RouteMessages);
|
||||
|
||||
R("/_matrix/client/v3/join/(.*)", RouteJoinRoomAlias);
|
||||
|
|
|
@ -130,10 +130,11 @@ ROUTE_IMPL(RouteJoinRoom, path, argp)
|
|||
goto finish;
|
||||
}
|
||||
/* TODO: Custom reason parameter. */
|
||||
if (!RoomJoin(room, user, &err))
|
||||
if (!RoomJoin(room, user))
|
||||
{
|
||||
HttpResponseStatus(args->context, HTTP_UNAUTHORIZED);
|
||||
response = MatrixErrorCreate(M_BAD_STATE, err);
|
||||
err = "User could not be the room due to unknown reasons.";
|
||||
HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR);
|
||||
response = MatrixErrorCreate(M_UNKNOWN, err);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
@ -142,6 +143,9 @@ ROUTE_IMPL(RouteJoinRoom, path, argp)
|
|||
}
|
||||
else if (StrEquals(action, "leave"))
|
||||
{
|
||||
HashMap *membership, *content;
|
||||
HashMap *pduResponse;
|
||||
|
||||
if (!RoomContainsUser(room, sender))
|
||||
{
|
||||
err = "User is not already in the room.";
|
||||
|
@ -151,12 +155,25 @@ ROUTE_IMPL(RouteJoinRoom, path, argp)
|
|||
goto finish;
|
||||
}
|
||||
|
||||
if (!RoomLeave(room, user, &err))
|
||||
content = HashMapCreate();
|
||||
membership = RoomEventCreate(
|
||||
sender, "m.room.member", sender,
|
||||
content
|
||||
);
|
||||
|
||||
HashMapSet(content, "membership", JsonValueString("leave"));
|
||||
pduResponse = RoomEventSend(room, membership);
|
||||
if (!pduResponse)
|
||||
{
|
||||
HttpResponseStatus(args->context, HTTP_UNAUTHORIZED);
|
||||
response = MatrixErrorCreate(M_BAD_STATE, err);
|
||||
err = "Couldn't accept leave event";
|
||||
HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR);
|
||||
response = MatrixErrorCreate(M_UNKNOWN, err);
|
||||
|
||||
JsonFree(membership);
|
||||
goto finish;
|
||||
}
|
||||
JsonFree(pduResponse);
|
||||
JsonFree(membership);
|
||||
|
||||
response = HashMapCreate();
|
||||
}
|
||||
|
@ -196,7 +213,8 @@ ROUTE_IMPL(RouteKickRoom, path, argp)
|
|||
char *action = ArrayGet(path, 1);
|
||||
char *kicked = NULL, *reason = NULL;
|
||||
char *sender = NULL, *serverName = NULL;
|
||||
char *membershipState;
|
||||
char *membershipState = StrEquals(action, "kick") ?
|
||||
"leave" : "ban";
|
||||
|
||||
Room *room = NULL;
|
||||
|
||||
|
@ -208,26 +226,6 @@ ROUTE_IMPL(RouteKickRoom, path, argp)
|
|||
HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR);
|
||||
return MatrixErrorCreate(M_UNKNOWN, NULL);
|
||||
}
|
||||
|
||||
if (StrEquals(action, "kick"))
|
||||
{
|
||||
membershipState = "leave";
|
||||
}
|
||||
else if (StrEquals(action, "ban"))
|
||||
{
|
||||
membershipState = "ban";
|
||||
}
|
||||
else if (StrEquals(action, "unban"))
|
||||
{
|
||||
membershipState = "leave";
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Should be impossible */
|
||||
HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR);
|
||||
return MatrixErrorCreate(M_UNKNOWN, NULL);
|
||||
}
|
||||
|
||||
if (HttpRequestMethodGet(args->context) != HTTP_POST)
|
||||
{
|
||||
err = "Unknown request method.";
|
||||
|
@ -286,7 +284,7 @@ ROUTE_IMPL(RouteKickRoom, path, argp)
|
|||
response = MatrixErrorCreate(M_FORBIDDEN, err);
|
||||
goto finish;
|
||||
}
|
||||
if (RoomContainsUser(room, kicked) == StrEquals(action, "unban"))
|
||||
if (!RoomContainsUser(room, kicked))
|
||||
{
|
||||
err = "Victim is not present in the room";
|
||||
HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
|
||||
|
@ -307,11 +305,12 @@ ROUTE_IMPL(RouteKickRoom, path, argp)
|
|||
HashMapSet(content, "reason", JsonValueString(reason));
|
||||
}
|
||||
|
||||
pduResponse = RoomEventSend(room, membership, &err);
|
||||
pduResponse = RoomEventSend(room, membership);
|
||||
if (!pduResponse)
|
||||
{
|
||||
HttpResponseStatus(args->context, HTTP_UNAUTHORIZED);
|
||||
response = MatrixErrorCreate(M_BAD_STATE, err);
|
||||
err = "Couldn't accept event";
|
||||
HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR);
|
||||
response = MatrixErrorCreate(M_UNKNOWN, err);
|
||||
|
||||
JsonFree(membership);
|
||||
goto finish;
|
||||
|
|
|
@ -143,10 +143,11 @@ ROUTE_IMPL(RouteJoinRoomAlias, path, argp)
|
|||
goto finish;
|
||||
}
|
||||
/* TODO: Custom reason parameter. */
|
||||
if (!RoomJoin(room, user, &err))
|
||||
if (!RoomJoin(room, user))
|
||||
{
|
||||
HttpResponseStatus(args->context, HTTP_UNAUTHORIZED);
|
||||
response = MatrixErrorCreate(M_FORBIDDEN, err);
|
||||
err = "User could not be the room due to unknown reasons.";
|
||||
HttpResponseStatus(args->context, HTTP_INTERNAL_SERVER_ERROR);
|
||||
response = MatrixErrorCreate(M_UNKNOWN, err);
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ ROUTE_IMPL(RouteSendEvent, path, argp)
|
|||
|
||||
Room *room = NULL;
|
||||
|
||||
char *err = NULL;
|
||||
char *err;
|
||||
|
||||
if (!roomId || !eventType || !transId)
|
||||
{
|
||||
|
@ -123,11 +123,12 @@ ROUTE_IMPL(RouteSendEvent, path, argp)
|
|||
}
|
||||
|
||||
event = RoomEventCreate(sender, eventType, NULL, JsonDuplicate(request));
|
||||
filled = RoomEventSend(room, event, &err);
|
||||
filled = RoomEventSend(room, event);
|
||||
JsonFree(event);
|
||||
|
||||
if (!filled)
|
||||
{
|
||||
err = "User is not allowed to send event.";
|
||||
HttpResponseStatus(args->context, HTTP_UNAUTHORIZED);
|
||||
response = MatrixErrorCreate(M_FORBIDDEN, err);
|
||||
goto finish;
|
||||
|
@ -237,11 +238,12 @@ ROUTE_IMPL(RouteSendState, path, argp)
|
|||
eventType, stateKey ? stateKey : "",
|
||||
JsonDuplicate(request)
|
||||
);
|
||||
filled = RoomEventSend(room, event, &err);
|
||||
filled = RoomEventSend(room, event);
|
||||
JsonFree(event);
|
||||
|
||||
if (!filled)
|
||||
{
|
||||
err = "User is not allowed to send state.";
|
||||
HttpResponseStatus(args->context, HTTP_UNAUTHORIZED);
|
||||
response = MatrixErrorCreate(M_FORBIDDEN, err);
|
||||
goto finish;
|
||||
|
|
|
@ -63,7 +63,7 @@ SendMembership(Db *db, User *user)
|
|||
HashMapSet(content, "displayname", JsonValueString(displayname));
|
||||
HashMapSet(content, "avatar_url", JsonValueString(avatar_url));
|
||||
|
||||
JsonFree(RoomEventSend(room, membership, NULL));
|
||||
JsonFree(RoomEventSend(room, membership));
|
||||
JsonFree(membership);
|
||||
|
||||
RoomUnlock(room);
|
||||
|
|
|
@ -209,7 +209,7 @@ FixoutConflictV1(char *t, Room *room, State *R, HashMap *conflicts)
|
|||
char *msg;
|
||||
|
||||
PduV1FromJson(event, &pdu, &msg);
|
||||
if (RoomAuthoriseEventV1(room, pdu, R, NULL))
|
||||
if (RoomAuthoriseEventV1(room, pdu, R))
|
||||
{
|
||||
StateSet(R, pdu.type, pdu.state_key, pdu.event_id);
|
||||
}
|
||||
|
@ -289,7 +289,7 @@ StateResolveV1(Room * room, Array * states)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (RoomAuthoriseEventV1(room, pdu, R, NULL))
|
||||
if (RoomAuthoriseEventV1(room, pdu, R))
|
||||
{
|
||||
StateSet(R, pdu.type, pdu.state_key, pdu.event_id);
|
||||
PduV1Free(&pdu);
|
||||
|
|
71
src/User.c
71
src/User.c
|
@ -130,8 +130,9 @@ UserLock(Db * db, char *name)
|
|||
user->name = StrDuplicate(name);
|
||||
user->deviceId = NULL;
|
||||
|
||||
user->inviteRef = NULL;
|
||||
user->joinRef = NULL;
|
||||
user->inviteRef = DbLock(db, 3, "users", user->name, "invites");
|
||||
user->joinRef = DbLock(db, 3, "users", user->name, "joins");
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
|
@ -183,7 +184,7 @@ UserAuthenticate(Db * db, char *accessToken)
|
|||
bool
|
||||
UserUnlock(User * user)
|
||||
{
|
||||
bool refOk, joinOk, inviteOk;
|
||||
bool ret;
|
||||
Db *db;
|
||||
DbRef *ref;
|
||||
|
||||
|
@ -197,15 +198,14 @@ UserUnlock(User * user)
|
|||
Free(user->name);
|
||||
Free(user->deviceId);
|
||||
|
||||
refOk = DbUnlock(db, ref);
|
||||
joinOk = DbUnlock(db, user->joinRef);
|
||||
inviteOk = DbUnlock(db, user->inviteRef);
|
||||
|
||||
ret = DbUnlock(db, ref) &&
|
||||
DbUnlock(db, user->joinRef) &&
|
||||
DbUnlock(db, user->inviteRef);
|
||||
user->db = NULL;
|
||||
user->ref = NULL;
|
||||
Free(user);
|
||||
|
||||
return refOk && joinOk && inviteOk;
|
||||
return ret;
|
||||
}
|
||||
|
||||
User *
|
||||
|
@ -1033,7 +1033,6 @@ void
|
|||
UserAddInvite(User *user, char *roomId)
|
||||
{
|
||||
HashMap *data;
|
||||
Db *db = user ? user->db : NULL;
|
||||
if (!user || !roomId)
|
||||
{
|
||||
return;
|
||||
|
@ -1041,10 +1040,9 @@ UserAddInvite(User *user, char *roomId)
|
|||
|
||||
if (!user->inviteRef)
|
||||
{
|
||||
if (!(user->inviteRef = DbLock(db, 3, "users", user->name, "invites")))
|
||||
{
|
||||
user->inviteRef = DbCreate(db, 3, "users", user->name, "invites");
|
||||
}
|
||||
user->inviteRef = DbCreate(user->db,
|
||||
3, "users", user->name, "invites"
|
||||
);
|
||||
}
|
||||
|
||||
data = DbJson(user->inviteRef);
|
||||
|
@ -1056,19 +1054,11 @@ void
|
|||
UserRemoveInvite(User *user, char *roomId)
|
||||
{
|
||||
HashMap *data;
|
||||
Db *db = user ? user->db : NULL;
|
||||
if (!user || !roomId)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!user->inviteRef)
|
||||
{
|
||||
if (!(user->inviteRef = DbLock(db, 3, "users", user->name, "invites")))
|
||||
{
|
||||
user->inviteRef = DbCreate(db, 3, "users", user->name, "invites");
|
||||
}
|
||||
}
|
||||
data = DbJson(user->inviteRef);
|
||||
|
||||
JsonValueFree(HashMapDelete(data, roomId));
|
||||
|
@ -1078,7 +1068,6 @@ UserListInvites(User *user)
|
|||
{
|
||||
Array *arr;
|
||||
HashMap *data;
|
||||
Db *db = user ? user->db : NULL;
|
||||
|
||||
size_t i;
|
||||
if (!user)
|
||||
|
@ -1086,13 +1075,6 @@ UserListInvites(User *user)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (!user->inviteRef)
|
||||
{
|
||||
if (!(user->inviteRef = DbLock(db, 3, "users", user->name, "invites")))
|
||||
{
|
||||
user->inviteRef = DbCreate(db, 3, "users", user->name, "invites");
|
||||
}
|
||||
}
|
||||
data = DbJson(user->inviteRef);
|
||||
arr = HashMapKeys(data);
|
||||
for (i = 0; i < ArraySize(arr); i++)
|
||||
|
@ -1107,7 +1089,6 @@ void
|
|||
UserAddJoin(User *user, char *roomId)
|
||||
{
|
||||
HashMap *data;
|
||||
Db *db = user ? user->db : NULL;
|
||||
if (!user || !roomId)
|
||||
{
|
||||
return;
|
||||
|
@ -1115,15 +1096,15 @@ UserAddJoin(User *user, char *roomId)
|
|||
|
||||
if (!user->joinRef)
|
||||
{
|
||||
if (!(user->joinRef = DbLock(db, 3, "users", user->name, "joins")))
|
||||
{
|
||||
user->joinRef = DbCreate(db, 3, "users", user->name, "joins");
|
||||
}
|
||||
user->joinRef = DbCreate(user->db, 3, "users", user->name, "joins");
|
||||
}
|
||||
|
||||
data = DbJson(user->joinRef);
|
||||
|
||||
JsonValueFree(HashMapSet(data, roomId, JsonValueObject(HashMapCreate())));
|
||||
if (data && !HashMapGet(data, roomId))
|
||||
{
|
||||
JsonValueFree(HashMapSet(data, roomId, JsonValueNull()));
|
||||
}
|
||||
UserNotifyUser(user);
|
||||
}
|
||||
|
||||
|
@ -1131,20 +1112,11 @@ void
|
|||
UserRemoveJoin(User *user, char *roomId)
|
||||
{
|
||||
HashMap *data;
|
||||
Db *db = user ? user->db : NULL;
|
||||
if (!user || !roomId || !user->joinRef)
|
||||
if (!user || !roomId)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!user->joinRef)
|
||||
{
|
||||
if (!(user->joinRef = DbLock(db, 3, "users", user->name, "joins")))
|
||||
{
|
||||
user->joinRef = DbCreate(db, 3, "users", user->name, "joins");
|
||||
}
|
||||
}
|
||||
|
||||
data = DbJson(user->joinRef);
|
||||
|
||||
JsonValueFree(HashMapDelete(data, roomId));
|
||||
|
@ -1155,21 +1127,12 @@ UserListJoins(User *user)
|
|||
{
|
||||
Array *arr;
|
||||
HashMap *data;
|
||||
Db *db = user ? user->db : NULL;
|
||||
|
||||
size_t i;
|
||||
if (!user)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (!user->joinRef)
|
||||
{
|
||||
if (!(user->joinRef = DbLock(db, 3, "users", user->name, "joins")))
|
||||
{
|
||||
user->joinRef = DbCreate(db, 3, "users", user->name, "joins");
|
||||
}
|
||||
}
|
||||
|
||||
data = DbJson(user->joinRef);
|
||||
arr = HashMapKeys(data);
|
||||
|
||||
|
|
|
@ -144,7 +144,7 @@ extern int RoomPrevEventsSet(Room *, Array *);
|
|||
* the room version, which includes setting the
|
||||
* prev_events and auth_events fields correctly.
|
||||
*/
|
||||
extern HashMap * RoomEventSend(Room *, HashMap *, char **);
|
||||
extern HashMap * RoomEventSend(Room *, HashMap *);
|
||||
|
||||
/**
|
||||
* Sends an invite to a user in a room, and tries
|
||||
|
@ -170,7 +170,7 @@ extern HashMap * RoomEventClientify(HashMap *);
|
|||
* Verifies whenever an event(as a PDUv1) is
|
||||
* authorised by a room.
|
||||
*/
|
||||
extern bool RoomAuthoriseEventV1(Room *, PduV1, State *, char **);
|
||||
extern bool RoomAuthoriseEventV1(Room *, PduV1, State *);
|
||||
|
||||
/**
|
||||
* Gets the room's creator as a ServerPart. This value should
|
||||
|
@ -229,13 +229,7 @@ extern bool RoomCanJoin(Room *, char *);
|
|||
* Makes a local user join a room, and returns true if
|
||||
* the room was joined.
|
||||
*/
|
||||
extern bool RoomJoin(Room *, User *, char **);
|
||||
|
||||
/**
|
||||
* Makes a local user leave a room, and returns true if
|
||||
* the room was left.
|
||||
*/
|
||||
extern bool RoomLeave(Room *, User *, char **);
|
||||
extern bool RoomJoin(Room *, User *);
|
||||
|
||||
/**
|
||||
* Adds or overwrites a room alias.
|
||||
|
|
Loading…
Reference in a new issue