forked from Telodendria/Telodendria
[ADD/UNTESTED] Finalise powerlevels somewhat
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
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
Still too hacky for my taste...
This commit is contained in:
parent
878b294030
commit
3066a0e8a8
1 changed files with 173 additions and 4 deletions
177
src/Room.c
177
src/Room.c
|
@ -26,6 +26,7 @@
|
|||
#include <Cytoplasm/Array.h>
|
||||
#include <Cytoplasm/Json.h>
|
||||
/*#include "Cytoplasm/Stream.h"*/
|
||||
#include "Cytoplasm/HashMap.h"
|
||||
#include "Parser.h"
|
||||
#include "User.h"
|
||||
#include <Room.h>
|
||||
|
@ -846,7 +847,7 @@ AuthoriseMemberV1(Room * room, PduV1 pdu)
|
|||
/* Step 5.2: If membership is join. */
|
||||
JumpIfMembership("join", AuthorizeJoinMembershipV1);
|
||||
|
||||
/* Step 5.3: If membership is invite. TODO */
|
||||
/* Step 5.3: If membership is invite. */
|
||||
JumpIfMembership("invite", AuthorizeInviteMembershipV1);
|
||||
|
||||
/* Step 5.4: If membership is leave. */
|
||||
|
@ -862,9 +863,177 @@ AuthoriseMemberV1(Room * room, PduV1 pdu)
|
|||
static bool
|
||||
AuthorisePowerLevelsV1(Room * room, PduV1 pdu)
|
||||
{
|
||||
/* TODO: Implement this. */
|
||||
(void) room;
|
||||
(void) pdu;
|
||||
/* Step 10.1: If the users property in content is not an object with
|
||||
* keys that are valid user IDs with values that are integers
|
||||
* (or a string that is an integer), reject. */
|
||||
JsonValue *users = JsonGet(pdu.content, 1, "users");
|
||||
HashMap *users_o, *state, *prev_plevent;
|
||||
|
||||
char *user_id, *prev_pl_id, *ev_type;
|
||||
JsonValue *power_level, *ev_obj;
|
||||
|
||||
bool flag = true;
|
||||
int64_t userpl = RoomUserPL(room, pdu.event_id, pdu.sender);
|
||||
HashMap *event_obj;
|
||||
if (JsonValueType(users) != JSON_OBJECT)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
users_o = JsonValueAsObject(users);
|
||||
while (HashMapIterate(users_o, &user_id, (void **) &power_level))
|
||||
{
|
||||
CommonID as_cid;
|
||||
if (!flag)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!ParseCommonID(user_id, &as_cid))
|
||||
{
|
||||
flag = false;
|
||||
}
|
||||
if (as_cid.sigil != '@')
|
||||
{
|
||||
CommonIDFree(as_cid);
|
||||
flag = false;
|
||||
}
|
||||
|
||||
/* Verify powerlevels.
|
||||
* We'll use INT64_MAX as a sentinel value, as this isn't
|
||||
* a valid powervalue for the specification. */
|
||||
if (ParsePL(power_level, INT64_MAX) == INT64_MAX)
|
||||
{
|
||||
flag = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* HashMapIterate does not support breaking, so we just set a
|
||||
* flag to be used. */
|
||||
if (!flag)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Step 10.2: If there is no previous m.room.power_levels event
|
||||
* in the room, allow. */
|
||||
state = RoomStateGetID(room, pdu.event_id);
|
||||
if (!(prev_pl_id = StateGet(state, "m.room.power_levels", "")))
|
||||
{
|
||||
StateFree(state);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Step 10.3: For the properties users_default, events_default,
|
||||
* state_default, ban, redact, kick, invite, check if they were
|
||||
* added, changed or removed. For each found alteration: */
|
||||
prev_plevent = RoomEventFetch(room, prev_pl_id);
|
||||
#define CheckChange(prop) do \
|
||||
{ \
|
||||
JsonValue *old = \
|
||||
JsonGet(prev_plevent, 2, "content", prop);\
|
||||
JsonValue *new = \
|
||||
JsonGet(pdu.content, 1, prop); \
|
||||
int64_t oldv, newv; \
|
||||
if ((old && !new) || (!old && new) || \
|
||||
((oldv = JsonValueAsInteger(old)) != \
|
||||
(newv = JsonValueAsInteger(new)))) \
|
||||
{ \
|
||||
if (old && (oldv > userpl)) \
|
||||
{ \
|
||||
return false; \
|
||||
} \
|
||||
if (new && (newv > userpl)) \
|
||||
{ \
|
||||
return false; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
while(0)
|
||||
CheckChange("users_default");
|
||||
CheckChange("events_default");
|
||||
CheckChange("state_default");
|
||||
CheckChange("ban");
|
||||
CheckChange("redact");
|
||||
CheckChange("kick");
|
||||
CheckChange("invite");
|
||||
#undef CheckChange
|
||||
#define CheckPLOld(prop) \
|
||||
event_obj = \
|
||||
JsonValueAsObject(JsonGet(prev_plevent, 2, "content", prop)); \
|
||||
flag = true; \
|
||||
while (HashMapIterate(event_obj, &ev_type, (void **) &ev_obj)) \
|
||||
{ \
|
||||
JsonValue *new; \
|
||||
int64_t new_pl, old_pl; \
|
||||
\
|
||||
if (!flag) \
|
||||
{ \
|
||||
continue; \
|
||||
} \
|
||||
\
|
||||
new = JsonGet(pdu.content, 2, prop, ev_type); \
|
||||
old_pl = ParsePL(new, INT64_MAX); \
|
||||
if (((new_pl = ParsePL(new, INT64_MAX)) == INT64_MAX || \
|
||||
new_pl != old_pl) && old_pl > userpl) \
|
||||
{ \
|
||||
flag = false; \
|
||||
} \
|
||||
} \
|
||||
if (!flag) \
|
||||
{ \
|
||||
JsonFree(prev_plevent); \
|
||||
StateFree(state); \
|
||||
return false; \
|
||||
} \
|
||||
flag = true
|
||||
#define CheckPLNew(prop) \
|
||||
event_obj = \
|
||||
JsonValueAsObject(JsonGet(pdu.content, 1, prop)); \
|
||||
flag = true; \
|
||||
while (HashMapIterate(event_obj, &ev_type, (void **) &ev_obj)) \
|
||||
{ \
|
||||
JsonValue *old; \
|
||||
int64_t new_pl, old_pl; \
|
||||
\
|
||||
if (!flag) \
|
||||
{ \
|
||||
continue; \
|
||||
} \
|
||||
\
|
||||
old = JsonGet(prev_plevent, 3, "content", prop, ev_type); \
|
||||
new_pl = ParsePL(ev_obj, INT64_MAX); \
|
||||
if (((old_pl = ParsePL(old, INT64_MAX)) == INT64_MAX || \
|
||||
new_pl != old_pl) && new_pl > userpl) \
|
||||
{ \
|
||||
flag = false; \
|
||||
} \
|
||||
} \
|
||||
if (!flag) \
|
||||
{ \
|
||||
JsonFree(prev_plevent); \
|
||||
StateFree(state); \
|
||||
return false; \
|
||||
} \
|
||||
flag = true
|
||||
/* Step 10.4: For each entry being changed in, or removed from, the
|
||||
* events property:
|
||||
* - If the current value is greater than the sender's current
|
||||
* power level, reject. */
|
||||
CheckPLOld("events");
|
||||
|
||||
/* Step 10.5: For each entry being added to, or changed in, the events
|
||||
* property:
|
||||
* - If the new value is greater than the sender's current power level,
|
||||
* reject. */
|
||||
CheckPLNew("events");
|
||||
|
||||
/* Steps 10.6 and 10.7 are effectively the same. */
|
||||
CheckPLOld("users");
|
||||
CheckPLNew("users");
|
||||
#undef CheckPLOld
|
||||
#undef CheckPLNew
|
||||
/* Step 10.8: Otherwise, allow. */
|
||||
JsonFree(prev_plevent);
|
||||
StateFree(state);
|
||||
return true;
|
||||
}
|
||||
bool
|
||||
|
|
Loading…
Reference in a new issue