[FIX/WIP] Encapsulate PDUs

Note that I just broke compatibility. Sorry.
This commit is contained in:
LDA 2024-09-27 18:13:54 +02:00
parent 1369064683
commit 01d170ce39
5 changed files with 60 additions and 27 deletions

2
.gitmodules vendored
View file

@ -1,3 +1,3 @@
[submodule "Cytoplasm"] [submodule "Cytoplasm"]
path = Cytoplasm path = Cytoplasm
url = https://git.telodendria.io/Telodendria/Cytoplasm url = https://git.telodendria.io/Telodendria/Cytoplasm.git

@ -1 +1 @@
Subproject commit 346b912a0633cceac10780b8a103f6c89b5ba89f Subproject commit 4f316ff7b3a955b831ca4aefb8679ddf3396a7d0

View file

@ -271,9 +271,10 @@ CreateSafeID(char *unsafe_id)
HashMap * HashMap *
RoomEventFetch(Room *room, char *id) RoomEventFetch(Room *room, char *id)
{ {
HashMap *ret, *unsign;
DbRef *event_ref; DbRef *event_ref;
HashMap *ret;
char *safe_id; char *safe_id;
uint64_t ts;
if (!room || !id) if (!room || !id)
{ {
@ -289,7 +290,28 @@ RoomEventFetch(Room *room, char *id)
ret = NULL; ret = NULL;
goto finish; goto finish;
} }
ret = JsonDuplicate(DbJson(event_ref)); ret = JsonDuplicate(JsonValueAsObject(HashMapGet(DbJson(event_ref), "pdu")));
unsign = JsonValueAsObject(HashMapGet(ret, "unsigned"));
/* Overwrite a few unsigned properties on the fly. */
JsonValueFree(HashMapSet(
unsign,
"next_events",
JsonValueDuplicate(HashMapGet(DbJson(event_ref), "next_events"))
));
JsonValueFree(HashMapSet(
unsign,
"pdu_status",
JsonValueDuplicate(HashMapGet(DbJson(event_ref), "pdu_status"))
));
ts = JsonValueAsInteger(HashMapGet(ret, "origin_server_ts"));
JsonValueFree(HashMapSet(
unsign,
"age",
JsonValueInteger(UtilTsMillis() - ts)
));
DbUnlock(room->db, event_ref); DbUnlock(room->db, event_ref);
finish: finish:
Free(safe_id); Free(safe_id);

View file

@ -209,7 +209,7 @@ RedactPDU1(HashMap *obj, HashMap *redactor)
ArrayFree(keys); ArrayFree(keys);
} }
bool bool
RoomAddEventV1(Room *room, PduV1 pdu) RoomAddEventV1(Room *room, PduV1 pdu, PduV1Status status)
{ {
DbRef *event_ref; DbRef *event_ref;
Array *prev_events = NULL, *leaves = NULL; Array *prev_events = NULL, *leaves = NULL;
@ -219,7 +219,7 @@ RoomAddEventV1(Room *room, PduV1 pdu)
size_t i; size_t i;
if (!room || room->version >= 3 || if (!room || room->version >= 3 ||
pdu._unsigned.pdu_status == PDUV1_STATUS_DROPPED) status == PDUV1_STATUS_DROPPED)
{ {
return false; return false;
} }
@ -229,14 +229,26 @@ RoomAddEventV1(Room *room, PduV1 pdu)
event_ref = DbCreate(room->db, 4, "rooms", room->id, "events", safe_id); event_ref = DbCreate(room->db, 4, "rooms", room->id, "events", safe_id);
pdu_json = PduV1ToJson(&pdu); pdu_json = PduV1ToJson(&pdu);
DbJsonSet(event_ref, pdu_json); /* TODO: Use those values concretely. */
pdu._unsigned.pdu_status = status;
JsonSet(DbJson(event_ref), JsonValueObject(pdu_json), 1, "pdu");
pdu_json = NULL;
JsonSet(
DbJson(event_ref),
JsonValueString(PduV1StatusToStr(status)),
1, "status"
);
JsonSet(
DbJson(event_ref),
JsonValueArray(ArrayCreate()),
1, "next_events"
);
DbUnlock(room->db, event_ref); DbUnlock(room->db, event_ref);
JsonFree(pdu_json);
Free(safe_id); Free(safe_id);
/* Only accepted PDUs get to do the news */ /* Only accepted PDUs get to do the news */
if (pdu._unsigned.pdu_status == PDUV1_STATUS_ACCEPTED) if (status == PDUV1_STATUS_ACCEPTED)
{ {
/* Remove managed leaves here. */ /* Remove managed leaves here. */
leaves_json = DbJson(room->leaves_ref); leaves_json = DbJson(room->leaves_ref);
@ -289,30 +301,27 @@ RoomAddEventV1(Room *room, PduV1 pdu)
PduV1 prev_pdu = { 0 }; PduV1 prev_pdu = { 0 };
HashMap *prev_object = NULL; HashMap *prev_object = NULL;
Array *next_events = NULL; Array *next_events = NULL;
HashMap *refObj = NULL;
HashMap *pduObj = NULL;
/* TODO: This confuses me! */
event_ref = DbLock(room->db, 4, "rooms", room->id, "events", id); event_ref = DbLock(room->db, 4, "rooms", room->id, "events", id);
PduV1FromJson(DbJson(event_ref), &prev_pdu, &error); refObj = DbJson(event_ref);
pduObj = JsonValueAsObject(HashMapGet(refObj, "pdu"));
PduV1FromJson(pduObj, &prev_pdu, &error);
/* Update the next events view. Note that this works even if next_events = JsonValueAsArray(HashMapGet(refObj, "next_events"));
* the event is soft-failed/rejected. */ ArrayAdd(next_events, JsonValueString(pdu.event_id));
if (!prev_pdu._unsigned.next_events)
{
prev_pdu._unsigned.next_events = ArrayCreate();
}
next_events = prev_pdu._unsigned.next_events;
ArrayAdd(next_events, StrDuplicate(pdu.event_id));
prev_object = PduV1ToJson(&prev_pdu); prev_object = PduV1ToJson(&prev_pdu);
DbJsonSet(event_ref, prev_object); JsonValueFree(HashMapSet(refObj, "pdu", JsonValueObject(prev_object)));
JsonFree(prev_object);
PduV1Free(&prev_pdu); PduV1Free(&prev_pdu);
DbUnlock(room->db, event_ref); DbUnlock(room->db, event_ref);
} }
/* Accepted PDUs should be the only one that users should be /* Accepted PDUs should be the only one that users should be
* notified about. */ * notified about. */
if (pdu._unsigned.pdu_status == PDUV1_STATUS_ACCEPTED) if (status == PDUV1_STATUS_ACCEPTED)
{ {
State *state; State *state;
char *type, *state_key, *event_id; char *type, *state_key, *event_id;
@ -357,7 +366,10 @@ RoomAddEventV1(Room *room, PduV1 pdu)
"events", redacted "events", redacted
); );
RedactPDU1(DbJson(eventRef), pdu_json); RedactPDU1(
JsonValueAsObject(HashMapGet(DbJson(eventRef), "pdu")),
pdu_json
);
DbUnlock(room->db, eventRef); DbUnlock(room->db, eventRef);
} }
@ -485,11 +497,10 @@ RoomEventSendV1(Room * room, HashMap * event, char **errp)
{ {
goto finish; goto finish;
} }
pdu._unsigned.pdu_status = status;
StateFree(state); StateFree(state);
RoomAddEventV1(room, pdu); RoomAddEventV1(room, pdu, status);
state = NULL; state = NULL;
valid = true; valid = true;

View file

@ -188,7 +188,7 @@ extern ServerPart RoomGetCreator(Room *);
* Puts a PDUv1 into the event list, while updating the leaf * Puts a PDUv1 into the event list, while updating the leaf
* list. * list.
*/ */
extern bool RoomAddEventV1(Room *, PduV1); extern bool RoomAddEventV1(Room *, PduV1, PduV1Status);
/** /**
* Creates a barebones JSON object to be sent to * Creates a barebones JSON object to be sent to