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/Array.h>
|
||||||
#include <Cytoplasm/Json.h>
|
#include <Cytoplasm/Json.h>
|
||||||
/*#include "Cytoplasm/Stream.h"*/
|
/*#include "Cytoplasm/Stream.h"*/
|
||||||
|
#include "Cytoplasm/HashMap.h"
|
||||||
#include "Parser.h"
|
#include "Parser.h"
|
||||||
#include "User.h"
|
#include "User.h"
|
||||||
#include <Room.h>
|
#include <Room.h>
|
||||||
|
@ -846,7 +847,7 @@ AuthoriseMemberV1(Room * room, PduV1 pdu)
|
||||||
/* Step 5.2: If membership is join. */
|
/* Step 5.2: If membership is join. */
|
||||||
JumpIfMembership("join", AuthorizeJoinMembershipV1);
|
JumpIfMembership("join", AuthorizeJoinMembershipV1);
|
||||||
|
|
||||||
/* Step 5.3: If membership is invite. TODO */
|
/* Step 5.3: If membership is invite. */
|
||||||
JumpIfMembership("invite", AuthorizeInviteMembershipV1);
|
JumpIfMembership("invite", AuthorizeInviteMembershipV1);
|
||||||
|
|
||||||
/* Step 5.4: If membership is leave. */
|
/* Step 5.4: If membership is leave. */
|
||||||
|
@ -862,9 +863,177 @@ AuthoriseMemberV1(Room * room, PduV1 pdu)
|
||||||
static bool
|
static bool
|
||||||
AuthorisePowerLevelsV1(Room * room, PduV1 pdu)
|
AuthorisePowerLevelsV1(Room * room, PduV1 pdu)
|
||||||
{
|
{
|
||||||
/* TODO: Implement this. */
|
/* Step 10.1: If the users property in content is not an object with
|
||||||
(void) room;
|
* keys that are valid user IDs with values that are integers
|
||||||
(void) pdu;
|
* (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;
|
return true;
|
||||||
}
|
}
|
||||||
bool
|
bool
|
||||||
|
|
Loading…
Reference in a new issue