forked from Telodendria/Telodendria
Compare commits
No commits in common. "33edd2ceaf6885d38d68aba8c141aa817179a1f3" and "8612aae24c06ebecdae1c855df7e327de5b80091" have entirely different histories.
33edd2ceaf
...
8612aae24c
15 changed files with 36 additions and 408 deletions
|
@ -1,62 +0,0 @@
|
||||||
{
|
|
||||||
"guard": "TELODENDRIA_KEY_UPLOAD_H",
|
|
||||||
"header": "Schema/KeyUpload.h",
|
|
||||||
"types": {
|
|
||||||
"DeviceKeys": {
|
|
||||||
"type": "struct",
|
|
||||||
"fields": {
|
|
||||||
"device_id": {
|
|
||||||
"type": "string",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
"user_id": {
|
|
||||||
"type": "string",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
"algorithms": {
|
|
||||||
"type": "[string]",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
"keys": {
|
|
||||||
"type": "{string}",
|
|
||||||
"required": true
|
|
||||||
},
|
|
||||||
"signatures": {
|
|
||||||
"//": "TODO: More complex j2s types.",
|
|
||||||
"//": "This is meant to be a map from user ID to ",
|
|
||||||
"//": "algo+device ID to a signature(string).",
|
|
||||||
"type": "object",
|
|
||||||
"required": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"KeyResponse": {
|
|
||||||
"type": "struct",
|
|
||||||
"fields": {
|
|
||||||
"one_time_key_counts": {
|
|
||||||
"type": "{integer}",
|
|
||||||
"required": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"KeyUploadRequest": {
|
|
||||||
"type": "struct",
|
|
||||||
"fields": {
|
|
||||||
"device_keys": {
|
|
||||||
"type": "DeviceKeys",
|
|
||||||
"required": false
|
|
||||||
},
|
|
||||||
"fallback_keys": {
|
|
||||||
"//": "This is a one-time key.",
|
|
||||||
"type": "object",
|
|
||||||
"required": false
|
|
||||||
},
|
|
||||||
"one_time_keys": {
|
|
||||||
"//": "This is a one-time key.",
|
|
||||||
"type": "object",
|
|
||||||
"required": false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -38,10 +38,6 @@
|
||||||
"redacted_because": {
|
"redacted_because": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": false
|
"required": false
|
||||||
},
|
|
||||||
"transaction_id": {
|
|
||||||
"type": "string",
|
|
||||||
"required": false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -68,7 +68,6 @@
|
||||||
"sender": { "type": "string", "required": true },
|
"sender": { "type": "string", "required": true },
|
||||||
"state_key": { "type": "string" },
|
"state_key": { "type": "string" },
|
||||||
"redacts": { "type": "string" },
|
"redacts": { "type": "string" },
|
||||||
"_unsigned": { "type": "object" },
|
|
||||||
"type": { "type": "string", "required": true }
|
"type": { "type": "string", "required": true }
|
||||||
},
|
},
|
||||||
"type": "struct"
|
"type": "struct"
|
||||||
|
@ -106,9 +105,6 @@
|
||||||
},
|
},
|
||||||
"rooms": {
|
"rooms": {
|
||||||
"type": "Rooms"
|
"type": "Rooms"
|
||||||
},
|
|
||||||
"device_one_time_keys_count": {
|
|
||||||
"type": "{integer}"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"type": "struct"
|
"type": "struct"
|
||||||
|
|
16
src/Room.c
16
src/Room.c
|
@ -348,11 +348,6 @@ RoomEventFetch(Room *room, char *id, bool prev)
|
||||||
"pdu_status",
|
"pdu_status",
|
||||||
JsonValueDuplicate(HashMapGet(DbJson(event_ref), "status"))
|
JsonValueDuplicate(HashMapGet(DbJson(event_ref), "status"))
|
||||||
));
|
));
|
||||||
JsonValueFree(HashMapSet(
|
|
||||||
unsign,
|
|
||||||
"transaction_id",
|
|
||||||
JsonValueDuplicate(HashMapGet(DbJson(event_ref), "transaction"))
|
|
||||||
));
|
|
||||||
ts = JsonValueAsInteger(HashMapGet(ret, "origin_server_ts"));
|
ts = JsonValueAsInteger(HashMapGet(ret, "origin_server_ts"));
|
||||||
JsonValueFree(HashMapSet(
|
JsonValueFree(HashMapSet(
|
||||||
unsign,
|
unsign,
|
||||||
|
@ -396,7 +391,7 @@ finish:
|
||||||
}
|
}
|
||||||
|
|
||||||
HashMap *
|
HashMap *
|
||||||
RoomEventCreate(char *sender, char *type, char *key, HashMap *c, char *txn)
|
RoomEventCreate(char *sender, char *type, char *key, HashMap *c)
|
||||||
{
|
{
|
||||||
HashMap *event;
|
HashMap *event;
|
||||||
if (!sender || !type || !c)
|
if (!sender || !type || !c)
|
||||||
|
@ -408,7 +403,6 @@ RoomEventCreate(char *sender, char *type, char *key, HashMap *c, char *txn)
|
||||||
JsonSet(event, JsonValueObject(c), 1, "content");
|
JsonSet(event, JsonValueObject(c), 1, "content");
|
||||||
JsonSet(event, JsonValueString(sender), 1, "sender");
|
JsonSet(event, JsonValueString(sender), 1, "sender");
|
||||||
JsonSet(event, JsonValueString(type), 1, "type");
|
JsonSet(event, JsonValueString(type), 1, "type");
|
||||||
JsonSet(event, JsonValueString(txn), 1, "transaction");
|
|
||||||
if (key)
|
if (key)
|
||||||
{
|
{
|
||||||
JsonSet(event, JsonValueString(key), 1, "state_key");
|
JsonSet(event, JsonValueString(key), 1, "state_key");
|
||||||
|
@ -563,7 +557,7 @@ RoomSendInvite(User *sender, bool direct, char *user, Room *room)
|
||||||
content = HashMapCreate();
|
content = HashMapCreate();
|
||||||
JsonSet(content, JsonValueBoolean(direct), 1, "is_direct");
|
JsonSet(content, JsonValueBoolean(direct), 1, "is_direct");
|
||||||
JsonSet(content, JsonValueString("invite"), 1, "membership");
|
JsonSet(content, JsonValueString("invite"), 1, "membership");
|
||||||
event = RoomEventCreate(senderStr, "m.room.member", user, content, NULL);
|
event = RoomEventCreate(senderStr, "m.room.member", user, content);
|
||||||
JsonFree(RoomEventSend(room, event, NULL));
|
JsonFree(RoomEventSend(room, event, NULL));
|
||||||
JsonFree(event);
|
JsonFree(event);
|
||||||
|
|
||||||
|
@ -698,7 +692,7 @@ RoomLeave(Room *room, User *user, char **errp)
|
||||||
|
|
||||||
content = HashMapCreate();
|
content = HashMapCreate();
|
||||||
JsonSet(content, JsonValueString("leave"), 1, "membership");
|
JsonSet(content, JsonValueString("leave"), 1, "membership");
|
||||||
event = RoomEventCreate(userString, "m.room.member", userString, content, NULL);
|
event = RoomEventCreate(userString, "m.room.member", userString, content);
|
||||||
pdu = RoomEventSend(room, event, errp);
|
pdu = RoomEventSend(room, event, errp);
|
||||||
|
|
||||||
/* TODO: One ought to be extremely careful with managing users in those
|
/* TODO: One ought to be extremely careful with managing users in those
|
||||||
|
@ -762,7 +756,7 @@ RoomRedact(Room *room, User *user, char *eventID, char *reason, char **errp)
|
||||||
HashMapSet(content, "reason", JsonValueString(reason));
|
HashMapSet(content, "reason", JsonValueString(reason));
|
||||||
event = RoomEventCreate(userString,
|
event = RoomEventCreate(userString,
|
||||||
"m.room.redaction", NULL,
|
"m.room.redaction", NULL,
|
||||||
content, NULL
|
content
|
||||||
);
|
);
|
||||||
HashMapSet(event, "redacts", JsonValueString(eventID));
|
HashMapSet(event, "redacts", JsonValueString(eventID));
|
||||||
pdu = RoomEventSend(room, event, errp);
|
pdu = RoomEventSend(room, event, errp);
|
||||||
|
@ -817,7 +811,7 @@ RoomJoin(Room *room, User *user, char **errp)
|
||||||
|
|
||||||
content = HashMapCreate();
|
content = HashMapCreate();
|
||||||
JsonSet(content, JsonValueString("join"), 1, "membership");
|
JsonSet(content, JsonValueString("join"), 1, "membership");
|
||||||
event = RoomEventCreate(userString, "m.room.member", userString, content, NULL);
|
event = RoomEventCreate(userString, "m.room.member", userString, content);
|
||||||
pdu = RoomEventSend(room, event, errp);
|
pdu = RoomEventSend(room, event, errp);
|
||||||
|
|
||||||
/* TODO: One ought to be extremely careful with managing users in those
|
/* TODO: One ought to be extremely careful with managing users in those
|
||||||
|
|
|
@ -97,7 +97,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
|
||||||
}
|
}
|
||||||
JsonValueFree(HashMapSet(content, key, JsonValueDuplicate(val)));
|
JsonValueFree(HashMapSet(content, key, JsonValueDuplicate(val)));
|
||||||
}
|
}
|
||||||
event = RoomEventCreate(sender_str, "m.room.create", "", content, NULL);
|
event = RoomEventCreate(sender_str, "m.room.create", "", content);
|
||||||
JsonFree(RoomEventSend(room, event, NULL));
|
JsonFree(RoomEventSend(room, event, NULL));
|
||||||
JsonFree(event);
|
JsonFree(event);
|
||||||
UserAddJoin(user, room->id);
|
UserAddJoin(user, room->id);
|
||||||
|
@ -105,7 +105,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
|
||||||
/* m.room.member */
|
/* m.room.member */
|
||||||
content = HashMapCreate();
|
content = HashMapCreate();
|
||||||
JsonSet(content, JsonValueString("join"), 1, "membership");
|
JsonSet(content, JsonValueString("join"), 1, "membership");
|
||||||
event = RoomEventCreate(sender_str, "m.room.member", sender_str, content, NULL);
|
event = RoomEventCreate(sender_str, "m.room.member", sender_str, content);
|
||||||
JsonFree(RoomEventSend(room, event, NULL));
|
JsonFree(RoomEventSend(room, event, NULL));
|
||||||
JsonFree(event);
|
JsonFree(event);
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
|
||||||
}
|
}
|
||||||
HashMapSet(content, key, JsonValueDuplicate(val));
|
HashMapSet(content, key, JsonValueDuplicate(val));
|
||||||
}
|
}
|
||||||
event = RoomEventCreate(sender_str, "m.room.power_levels", "", content, NULL);
|
event = RoomEventCreate(sender_str, "m.room.power_levels", "", content);
|
||||||
JsonFree(RoomEventSend(room, event, NULL));
|
JsonFree(RoomEventSend(room, event, NULL));
|
||||||
JsonFree(event);
|
JsonFree(event);
|
||||||
|
|
||||||
|
@ -174,7 +174,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
|
||||||
, 1, a); \
|
, 1, a); \
|
||||||
event = RoomEventCreate( \
|
event = RoomEventCreate( \
|
||||||
sender_str, \
|
sender_str, \
|
||||||
"m.room." #p, "", content, NULL); \
|
"m.room." #p, "", content); \
|
||||||
JsonFree(RoomEventSend(room, event, NULL)); \
|
JsonFree(RoomEventSend(room, event, NULL)); \
|
||||||
JsonFree(event); \
|
JsonFree(event); \
|
||||||
} \
|
} \
|
||||||
|
@ -208,7 +208,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
|
||||||
{
|
{
|
||||||
content = HashMapCreate();
|
content = HashMapCreate();
|
||||||
JsonSet(content, JsonValueString(req->name), 1, "name");
|
JsonSet(content, JsonValueString(req->name), 1, "name");
|
||||||
event = RoomEventCreate(sender_str, "m.room.name", "", content, NULL);
|
event = RoomEventCreate(sender_str, "m.room.name", "", content);
|
||||||
JsonFree(RoomEventSend(room, event, NULL));
|
JsonFree(RoomEventSend(room, event, NULL));
|
||||||
JsonFree(event);
|
JsonFree(event);
|
||||||
}
|
}
|
||||||
|
@ -216,7 +216,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
|
||||||
{
|
{
|
||||||
content = HashMapCreate();
|
content = HashMapCreate();
|
||||||
JsonSet(content, JsonValueString(req->topic), 1, "topic");
|
JsonSet(content, JsonValueString(req->topic), 1, "topic");
|
||||||
event = RoomEventCreate(sender_str, "m.room.topic", "", content, NULL);
|
event = RoomEventCreate(sender_str, "m.room.topic", "", content);
|
||||||
JsonFree(RoomEventSend(room, event, NULL));
|
JsonFree(RoomEventSend(room, event, NULL));
|
||||||
JsonFree(event);
|
JsonFree(event);
|
||||||
}
|
}
|
||||||
|
@ -240,7 +240,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
|
||||||
JsonSet(content, JsonValueString(fullStr), 1, "alias");
|
JsonSet(content, JsonValueString(fullStr), 1, "alias");
|
||||||
event = RoomEventCreate(
|
event = RoomEventCreate(
|
||||||
sender_str,
|
sender_str,
|
||||||
"m.room.canonical_alias", "", content, NULL);
|
"m.room.canonical_alias", "", content);
|
||||||
JsonFree(RoomEventSend(room, event, NULL));
|
JsonFree(RoomEventSend(room, event, NULL));
|
||||||
JsonFree(event);
|
JsonFree(event);
|
||||||
|
|
||||||
|
@ -270,7 +270,7 @@ RoomPopulate(Room *room, User *user, RoomCreateRequest *req, ServerPart s)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
event = RoomEventCreate(sender_str, "m.room.power_levels", "", pl_content, NULL);
|
event = RoomEventCreate(sender_str, "m.room.power_levels", "", pl_content);
|
||||||
JsonFree(RoomEventSend(room, event, NULL));
|
JsonFree(RoomEventSend(room, event, NULL));
|
||||||
JsonFree(event);
|
JsonFree(event);
|
||||||
|
|
||||||
|
|
|
@ -29,8 +29,6 @@ PopulateEventV1(Room * room, HashMap * event, PduV1 * pdu, ServerPart serv)
|
||||||
StrDuplicate(JsonValueAsString(JsonGet(event, 1, "type")));
|
StrDuplicate(JsonValueAsString(JsonGet(event, 1, "type")));
|
||||||
pdu->redacts =
|
pdu->redacts =
|
||||||
StrDuplicate(JsonValueAsString(JsonGet(event, 1, "redacts")));
|
StrDuplicate(JsonValueAsString(JsonGet(event, 1, "redacts")));
|
||||||
pdu->_unsigned.transaction_id =
|
|
||||||
StrDuplicate(JsonValueAsString(JsonGet(event, 1, "transaction")));
|
|
||||||
if (JsonGet(event, 1, "state_key"))
|
if (JsonGet(event, 1, "state_key"))
|
||||||
{
|
{
|
||||||
pdu->state_key =
|
pdu->state_key =
|
||||||
|
|
|
@ -242,11 +242,6 @@ RoomAddEventV1(Room *room, PduV1 pdu, PduV1Status status)
|
||||||
JsonValueArray(ArrayCreate()),
|
JsonValueArray(ArrayCreate()),
|
||||||
1, "next_events"
|
1, "next_events"
|
||||||
);
|
);
|
||||||
JsonSet(
|
|
||||||
DbJson(event_ref),
|
|
||||||
JsonValueString(pdu._unsigned.transaction_id),
|
|
||||||
1, "transaction"
|
|
||||||
);
|
|
||||||
|
|
||||||
DbUnlock(room->db, event_ref);
|
DbUnlock(room->db, event_ref);
|
||||||
Free(safe_id);
|
Free(safe_id);
|
||||||
|
@ -338,6 +333,13 @@ RoomAddEventV1(Room *room, PduV1 pdu, PduV1Status status)
|
||||||
|
|
||||||
/* If we have a membership change, then add it to the
|
/* If we have a membership change, then add it to the
|
||||||
* proper table. */
|
* proper table. */
|
||||||
|
{
|
||||||
|
CommonID *id = UserIdParse(pdu.sender, NULL);
|
||||||
|
User *user = UserLockID(room->db, id);
|
||||||
|
UserPushEvent(user, pdu_json);
|
||||||
|
UserUnlock(user);
|
||||||
|
UserIdFree(id);
|
||||||
|
}
|
||||||
if (relates_to && RelationFromJson(relates_to, &rel, &errp))
|
if (relates_to && RelationFromJson(relates_to, &rel, &errp))
|
||||||
{
|
{
|
||||||
DbRef *relate = DbLock(
|
DbRef *relate = DbLock(
|
||||||
|
|
|
@ -298,7 +298,7 @@ ROUTE_IMPL(RouteKickRoom, path, argp)
|
||||||
membership = RoomEventCreate(
|
membership = RoomEventCreate(
|
||||||
sender,
|
sender,
|
||||||
"m.room.member", kicked,
|
"m.room.member", kicked,
|
||||||
content, NULL
|
content
|
||||||
);
|
);
|
||||||
|
|
||||||
HashMapSet(content, "membership", JsonValueString(membershipState));
|
HashMapSet(content, "membership", JsonValueString(membershipState));
|
||||||
|
|
|
@ -34,105 +34,8 @@
|
||||||
#include <Room.h>
|
#include <Room.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <Schema/KeyUpload.h>
|
#include <Schema/Filter.h>
|
||||||
|
|
||||||
HashMap *
|
|
||||||
UploadKey(RouteArgs *args, User *user, KeyUploadRequest *req, char *sender)
|
|
||||||
{
|
|
||||||
char *deviceId = UserGetDeviceId(user);
|
|
||||||
KeyResponse response = { 0 };
|
|
||||||
HashMap *json;
|
|
||||||
char *fbKey;
|
|
||||||
JsonValue *fbValue;
|
|
||||||
size_t i;
|
|
||||||
if (!user || !req || !sender)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
Log(LOG_ERR, "did=%s", deviceId);
|
|
||||||
if (req->device_keys.user_id)
|
|
||||||
{
|
|
||||||
HashMap *publicKeys;
|
|
||||||
char *pkTag, *pk;
|
|
||||||
/* We have device key information */
|
|
||||||
if (!StrEquals(req->device_keys.user_id, sender))
|
|
||||||
{
|
|
||||||
HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
|
|
||||||
return MatrixErrorCreate(
|
|
||||||
M_UNAUTHORIZED, "Device key update has an invalid user ID"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (!StrEquals(req->device_keys.device_id, deviceId))
|
|
||||||
{
|
|
||||||
HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
|
|
||||||
return MatrixErrorCreate(
|
|
||||||
M_UNAUTHORIZED, "Device key update has an invalid device ID"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check the public key list */
|
|
||||||
publicKeys = req->device_keys.keys;
|
|
||||||
i = 0;
|
|
||||||
while (HashMapIterateReentrant(publicKeys, &pkTag, (void **) &pk, &i))
|
|
||||||
{
|
|
||||||
char *pktDID = strchr(pkTag, ':');
|
|
||||||
|
|
||||||
/* Maybe C does need NULL saturation */
|
|
||||||
pktDID = pktDID ? pktDID + 1 : NULL;
|
|
||||||
if (!StrEquals(pktDID, deviceId))
|
|
||||||
{
|
|
||||||
/* As far as I know, we're not meant to handle other devices'
|
|
||||||
* public keys */
|
|
||||||
HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
|
|
||||||
Log(LOG_ERR, "%s!=%s 1", pktDID, deviceId);
|
|
||||||
return MatrixErrorCreate(
|
|
||||||
M_UNAUTHORIZED, "Device key update has an invalid device ID"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
UserSetDeviceKeys(user, &req->device_keys);
|
|
||||||
}
|
|
||||||
|
|
||||||
UserClearFallbackKeys(user);
|
|
||||||
i = 0;
|
|
||||||
while (HashMapIterateReentrant(req->fallback_keys, &fbKey, (void **) &fbValue, &i))
|
|
||||||
{
|
|
||||||
char *fbKID = strchr(fbKey, ':');
|
|
||||||
size_t len = fbKID ? fbKID - fbKey : 0;
|
|
||||||
char algo[len + 1];
|
|
||||||
|
|
||||||
memcpy(algo, fbKey, len);
|
|
||||||
algo[len] = '\0';
|
|
||||||
|
|
||||||
/* Maybe C does need NULL saturation */
|
|
||||||
fbKID = fbKID ? fbKID + 1 : NULL;
|
|
||||||
|
|
||||||
UserAddKey(user, fbKey, fbValue, true);
|
|
||||||
(void) fbKID;
|
|
||||||
}
|
|
||||||
i = 0;
|
|
||||||
while (HashMapIterateReentrant(req->one_time_keys, &fbKey, (void **) &fbValue, &i))
|
|
||||||
{
|
|
||||||
char *fbKID = strchr(fbKey, ':');
|
|
||||||
size_t len = fbKID ? fbKID - fbKey : 0;
|
|
||||||
char algo[len + 1];
|
|
||||||
|
|
||||||
memcpy(algo, fbKey, len);
|
|
||||||
algo[len] = '\0';
|
|
||||||
|
|
||||||
/* Maybe C does need NULL saturation */
|
|
||||||
fbKID = fbKID ? fbKID + 1 : NULL;
|
|
||||||
|
|
||||||
UserAddKey(user, fbKey, fbValue, false);
|
|
||||||
(void) fbKID;
|
|
||||||
}
|
|
||||||
response.one_time_key_counts = UserGetOnetimeCounts(user);
|
|
||||||
UserNotifyUser(UserGetName(user));
|
|
||||||
json = KeyResponseToJson(&response);
|
|
||||||
KeyResponseFree(&response);
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
|
|
||||||
ROUTE_IMPL(RouteKeyQuery, path, argp)
|
ROUTE_IMPL(RouteKeyQuery, path, argp)
|
||||||
{
|
{
|
||||||
|
@ -142,14 +45,9 @@ ROUTE_IMPL(RouteKeyQuery, path, argp)
|
||||||
HashMap *request = NULL;
|
HashMap *request = NULL;
|
||||||
HashMap *response = NULL;
|
HashMap *response = NULL;
|
||||||
|
|
||||||
CommonID *id = NULL;
|
|
||||||
char *token = NULL;
|
|
||||||
User *user = NULL;
|
User *user = NULL;
|
||||||
|
char *token = NULL;
|
||||||
|
|
||||||
char *serverName = NULL;
|
|
||||||
char *sender = NULL;
|
|
||||||
|
|
||||||
char *method = ArrayGet(path, 0);
|
|
||||||
char *err;
|
char *err;
|
||||||
|
|
||||||
if (HttpRequestMethodGet(args->context) != HTTP_POST)
|
if (HttpRequestMethodGet(args->context) != HTTP_POST)
|
||||||
|
@ -173,11 +71,6 @@ ROUTE_IMPL(RouteKeyQuery, path, argp)
|
||||||
response = MatrixErrorCreate(M_UNKNOWN_TOKEN, NULL);
|
response = MatrixErrorCreate(M_UNKNOWN_TOKEN, NULL);
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
serverName = ConfigGetServerName(db);
|
|
||||||
id = UserIdParse(UserGetName(user), serverName);
|
|
||||||
id->sigil = '@';
|
|
||||||
sender = ParserRecomposeCommonID(*id);
|
|
||||||
|
|
||||||
request = JsonDecode(HttpServerStream(args->context));
|
request = JsonDecode(HttpServerStream(args->context));
|
||||||
if (!request)
|
if (!request)
|
||||||
{
|
{
|
||||||
|
@ -186,37 +79,10 @@ ROUTE_IMPL(RouteKeyQuery, path, argp)
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StrEquals(method, "upload"))
|
|
||||||
{
|
|
||||||
KeyUploadRequest upload = { 0 };
|
|
||||||
|
|
||||||
if (!KeyUploadRequestFromJson(request, &upload, &err))
|
|
||||||
{
|
|
||||||
HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
|
|
||||||
response = MatrixErrorCreate(M_BAD_JSON, err);
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((response = UploadKey(args, user, &upload, sender)))
|
|
||||||
{
|
|
||||||
KeyUploadRequestFree(&upload);
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
KeyUploadRequestFree(&upload);
|
|
||||||
}
|
|
||||||
else if (StrEquals(method, "query"))
|
|
||||||
{
|
|
||||||
/* TODO: Fetch a user's key information */
|
|
||||||
}
|
|
||||||
|
|
||||||
response = HashMapCreate();
|
response = HashMapCreate();
|
||||||
(void) path;
|
(void) path;
|
||||||
finish:
|
finish:
|
||||||
JsonFree(request);
|
JsonFree(request);
|
||||||
UserUnlock(user);
|
UserUnlock(user);
|
||||||
|
|
||||||
Free(serverName);
|
|
||||||
UserIdFree(id);
|
|
||||||
Free(sender);
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,7 +122,7 @@ ROUTE_IMPL(RouteSendEvent, path, argp)
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
event = RoomEventCreate(sender, eventType, NULL, JsonDuplicate(request), transId);
|
event = RoomEventCreate(sender, eventType, NULL, JsonDuplicate(request));
|
||||||
filled = RoomEventSend(room, event, &err);
|
filled = RoomEventSend(room, event, &err);
|
||||||
JsonFree(event);
|
JsonFree(event);
|
||||||
|
|
||||||
|
@ -266,7 +266,7 @@ ROUTE_IMPL(RouteSendState, path, argp)
|
||||||
event = RoomEventCreate(
|
event = RoomEventCreate(
|
||||||
sender,
|
sender,
|
||||||
eventType, stateKey ? stateKey : "",
|
eventType, stateKey ? stateKey : "",
|
||||||
JsonDuplicate(request), NULL
|
JsonDuplicate(request)
|
||||||
);
|
);
|
||||||
filled = RoomEventSend(room, event, &err);
|
filled = RoomEventSend(room, event, &err);
|
||||||
JsonFree(event);
|
JsonFree(event);
|
||||||
|
|
|
@ -139,17 +139,12 @@ ROUTE_IMPL(RouteSync, path, argp)
|
||||||
|
|
||||||
/* TODO: I only am manually parsing this because j2s does not support
|
/* TODO: I only am manually parsing this because j2s does not support
|
||||||
* a hashmap of unknown keys pointing to a known type. */
|
* a hashmap of unknown keys pointing to a known type. */
|
||||||
sync.rooms.invite = NULL;
|
sync.rooms.invite = HashMapCreate();
|
||||||
sync.rooms.join = NULL;
|
sync.rooms.join = HashMapCreate();
|
||||||
sync.account_data.events = NULL;
|
sync.account_data.events = ArrayCreate();
|
||||||
sync.device_one_time_keys_count = UserGetOnetimeCounts(user);
|
|
||||||
|
|
||||||
/* account data */
|
/* account data */
|
||||||
accountData = UserGetAccountDataSync(user, currBatch);
|
accountData = UserGetAccountDataSync(user, currBatch);
|
||||||
if (ArraySize(accountData) > 0)
|
|
||||||
{
|
|
||||||
sync.account_data.events = ArrayCreate();
|
|
||||||
}
|
|
||||||
for (i = 0; i < ArraySize(accountData); i++)
|
for (i = 0; i < ArraySize(accountData); i++)
|
||||||
{
|
{
|
||||||
char *key = ArrayGet(accountData, i);
|
char *key = ArrayGet(accountData, i);
|
||||||
|
@ -163,10 +158,6 @@ ROUTE_IMPL(RouteSync, path, argp)
|
||||||
|
|
||||||
/* invites */
|
/* invites */
|
||||||
invites = UserGetInvites(user, currBatch);
|
invites = UserGetInvites(user, currBatch);
|
||||||
if (ArraySize(invites) > 0)
|
|
||||||
{
|
|
||||||
sync.rooms.invite = HashMapCreate();
|
|
||||||
}
|
|
||||||
for (i = 0; i < ArraySize(invites); i++)
|
for (i = 0; i < ArraySize(invites); i++)
|
||||||
{
|
{
|
||||||
char *roomId = ArrayGet(invites, i);
|
char *roomId = ArrayGet(invites, i);
|
||||||
|
@ -180,7 +171,7 @@ ROUTE_IMPL(RouteSync, path, argp)
|
||||||
invited = Malloc(sizeof(*invited));
|
invited = Malloc(sizeof(*invited));
|
||||||
memset(invited, 0, sizeof(*invited));
|
memset(invited, 0, sizeof(*invited));
|
||||||
|
|
||||||
// TODO: Populate the invitestate
|
/* TODO: Populate the invitestate */
|
||||||
invited->invite_state.events = ArrayCreate();
|
invited->invite_state.events = ArrayCreate();
|
||||||
HashMapSet(sync.rooms.invite, roomId, invited);
|
HashMapSet(sync.rooms.invite, roomId, invited);
|
||||||
}
|
}
|
||||||
|
@ -188,12 +179,9 @@ ROUTE_IMPL(RouteSync, path, argp)
|
||||||
|
|
||||||
/* Joins */
|
/* Joins */
|
||||||
joins = UserGetJoins(user, currBatch);
|
joins = UserGetJoins(user, currBatch);
|
||||||
if (ArraySize(joins) > 0)
|
|
||||||
{
|
|
||||||
sync.rooms.join = HashMapCreate();
|
|
||||||
}
|
|
||||||
for (i = 0; i < ArraySize(joins); i++)
|
for (i = 0; i < ArraySize(joins); i++)
|
||||||
{
|
{
|
||||||
|
/* TODO: Rename these variables */
|
||||||
char *roomId = ArrayGet(joins, i);
|
char *roomId = ArrayGet(joins, i);
|
||||||
JoinedRooms *joined;
|
JoinedRooms *joined;
|
||||||
char *firstEvent = NULL;
|
char *firstEvent = NULL;
|
||||||
|
@ -242,8 +230,8 @@ ROUTE_IMPL(RouteSync, path, argp)
|
||||||
joined->timeline.prev_batch = UserNewMessageToken(
|
joined->timeline.prev_batch = UserNewMessageToken(
|
||||||
user, roomId, firstEvent
|
user, roomId, firstEvent
|
||||||
);
|
);
|
||||||
// TODO: Don't shove the entire state.
|
/* TODO: Don't shove the entire state.
|
||||||
// That's a recipe for disaster, especially on large rooms.
|
* That's a recipe for disaster, especially on large rooms. */
|
||||||
joined->state.events = ArrayCreate();
|
joined->state.events = ArrayCreate();
|
||||||
while (StateIterate(state, &type, &key, (void **) &id))
|
while (StateIterate(state, &type, &key, (void **) &id))
|
||||||
{
|
{
|
||||||
|
@ -265,13 +253,12 @@ ROUTE_IMPL(RouteSync, path, argp)
|
||||||
if (prevBatch)
|
if (prevBatch)
|
||||||
{
|
{
|
||||||
/* TODO: Should we be dropping syncs? */
|
/* TODO: Should we be dropping syncs? */
|
||||||
//UserDropSync(user, prevBatch);
|
UserDropSync(user, prevBatch);
|
||||||
nextBatch = UserInitSyncDiff(user);
|
nextBatch = UserInitSyncDiff(user);
|
||||||
}
|
}
|
||||||
sync.next_batch = nextBatch;
|
sync.next_batch = nextBatch;
|
||||||
response = SyncResponseToJson(&sync);
|
response = SyncResponseToJson(&sync);
|
||||||
SyncResponseFree(&sync);
|
SyncResponseFree(&sync);
|
||||||
(void) i;
|
|
||||||
finish:
|
finish:
|
||||||
FilterDestroy(filterData);
|
FilterDestroy(filterData);
|
||||||
UserUnlock(user);
|
UserUnlock(user);
|
||||||
|
|
|
@ -56,7 +56,7 @@ SendMembership(Db *db, User *user)
|
||||||
HashMap *content = HashMapCreate();
|
HashMap *content = HashMapCreate();
|
||||||
HashMap *membership = RoomEventCreate(
|
HashMap *membership = RoomEventCreate(
|
||||||
sender, "m.room.member", sender,
|
sender, "m.room.member", sender,
|
||||||
content, NULL
|
content
|
||||||
);
|
);
|
||||||
|
|
||||||
HashMapSet(content, "membership", JsonValueString("join"));
|
HashMapSet(content, "membership", JsonValueString("join"));
|
||||||
|
|
127
src/User.c
127
src/User.c
|
@ -1387,8 +1387,6 @@ UserPushEvent(User *user, HashMap *event)
|
||||||
|
|
||||||
UserPushJoinSync(user, roomId);
|
UserPushJoinSync(user, roomId);
|
||||||
|
|
||||||
/* TODO: In some very fun cases, this loop could be cosmically slow.
|
|
||||||
* Especially in the scale of 1.5k sync tokens. It can happen. */
|
|
||||||
entries = DbList(user->db, 3, "users", user->name, "sync");
|
entries = DbList(user->db, 3, "users", user->name, "sync");
|
||||||
for (i = 0; i < ArraySize(entries); i++)
|
for (i = 0; i < ArraySize(entries); i++)
|
||||||
{
|
{
|
||||||
|
@ -1535,7 +1533,6 @@ UserGetAccountDataSync(User *user, char *batch)
|
||||||
syncRef = DbLock(db, 4, "users", user->name, "sync", batch);
|
syncRef = DbLock(db, 4, "users", user->name, "sync", batch);
|
||||||
if (!syncRef)
|
if (!syncRef)
|
||||||
{
|
{
|
||||||
Log(LOG_ERR, "Tried to get batch=%s (user=%s), but it's gone?", batch, user->deviceId);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1861,7 +1858,7 @@ UserIsSyncOld(User *user, char *token)
|
||||||
dt = UtilTsMillis() - JsonValueAsInteger(HashMapGet(map, "creation"));
|
dt = UtilTsMillis() - JsonValueAsInteger(HashMapGet(map, "creation"));
|
||||||
|
|
||||||
DbUnlock(user->db, ref);
|
DbUnlock(user->db, ref);
|
||||||
return dt > (3 * 60 * 60 * 1000); /* Three hours of timeout. */
|
return dt > (3 * 24 * 60 * 60 * 1000); /* Three days of timeout. */
|
||||||
}
|
}
|
||||||
bool
|
bool
|
||||||
UserSyncExists(User *user, char *sync)
|
UserSyncExists(User *user, char *sync)
|
||||||
|
@ -2156,125 +2153,3 @@ UserSetAccountData(User *user, char *key, HashMap *obj)
|
||||||
|
|
||||||
UserPushAccountData(user, key);
|
UserPushAccountData(user, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
UserSetDeviceKeys(User *user, DeviceKeys *keys)
|
|
||||||
{
|
|
||||||
char *device;
|
|
||||||
HashMap *deviceObj;
|
|
||||||
if (!user || !keys)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
device = UserGetDeviceId(user);
|
|
||||||
deviceObj = JsonValueAsObject(HashMapGet(
|
|
||||||
UserGetDevices(user), device
|
|
||||||
));
|
|
||||||
if (!deviceObj)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonValueFree(HashMapSet(deviceObj, "deviceKeys", JsonValueObject(DeviceKeysToJson(keys))));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
UserClearFallbackKeys(User *user)
|
|
||||||
{
|
|
||||||
char *device;
|
|
||||||
HashMap *deviceObj;
|
|
||||||
if (!user)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
device = UserGetDeviceId(user);
|
|
||||||
deviceObj = JsonValueAsObject(HashMapGet(
|
|
||||||
UserGetDevices(user), device
|
|
||||||
));
|
|
||||||
if (!deviceObj)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!HashMapGet(deviceObj, "oneTimeKeys"))
|
|
||||||
{
|
|
||||||
JsonValueFree(HashMapSet(deviceObj,
|
|
||||||
"oneTimeKeys", JsonValueObject(HashMapCreate())
|
|
||||||
));
|
|
||||||
}
|
|
||||||
JsonValueFree(HashMapSet(deviceObj,
|
|
||||||
"fallbackKeys", JsonValueObject(HashMapCreate())
|
|
||||||
));
|
|
||||||
}
|
|
||||||
void
|
|
||||||
UserAddKey(User *user, char *algo, JsonValue *key, bool fb)
|
|
||||||
{
|
|
||||||
char *device;
|
|
||||||
HashMap *deviceObj, *method;
|
|
||||||
if (!user || !algo || !key)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
device = UserGetDeviceId(user);
|
|
||||||
deviceObj = JsonValueAsObject(HashMapGet(
|
|
||||||
UserGetDevices(user), device
|
|
||||||
));
|
|
||||||
if (!deviceObj)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
method = JsonValueAsObject(HashMapGet(
|
|
||||||
deviceObj, fb ? "fallbackKeys" : "oneTimeKeys"
|
|
||||||
));
|
|
||||||
JsonValueFree(HashMapSet(method, algo, JsonValueDuplicate(key)));
|
|
||||||
}
|
|
||||||
HashMap *
|
|
||||||
UserGetOnetimeCounts(User *user)
|
|
||||||
{
|
|
||||||
char *device, *algoKey;
|
|
||||||
HashMap *deviceObj, *otk, *ret;
|
|
||||||
void *ignore;
|
|
||||||
if (!user)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
device = UserGetDeviceId(user);
|
|
||||||
deviceObj = JsonValueAsObject(HashMapGet(
|
|
||||||
UserGetDevices(user), device
|
|
||||||
));
|
|
||||||
if (!deviceObj)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
otk = JsonValueAsObject(HashMapGet(
|
|
||||||
deviceObj, "oneTimeKeys"
|
|
||||||
));
|
|
||||||
ret = HashMapCreate();
|
|
||||||
while (HashMapIterate(otk, &algoKey, &ignore))
|
|
||||||
{
|
|
||||||
char *algo = StrDuplicate(algoKey);
|
|
||||||
char *end = strchr(algo, ':');
|
|
||||||
int64_t *ptr;
|
|
||||||
if (end)
|
|
||||||
{
|
|
||||||
*end = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(ptr = HashMapGet(ret, algo)))
|
|
||||||
{
|
|
||||||
ptr = Malloc(sizeof(*ptr));
|
|
||||||
*ptr = 0;
|
|
||||||
HashMapSet(ret, algo, ptr);
|
|
||||||
}
|
|
||||||
(*ptr)++;
|
|
||||||
Free(algo);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
|
@ -195,7 +195,7 @@ extern bool RoomAddEventV1(Room *, PduV1, PduV1Status);
|
||||||
* Creates a barebones JSON object to be sent to
|
* Creates a barebones JSON object to be sent to
|
||||||
* .Fn RoomEventFetch .
|
* .Fn RoomEventFetch .
|
||||||
*/
|
*/
|
||||||
extern HashMap * RoomEventCreate(char *, char *, char *, HashMap *, char *);
|
extern HashMap * RoomEventCreate(char *, char *, char *, HashMap *);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes an approximation of the PDU depth by looking at
|
* Computes an approximation of the PDU depth by looking at
|
||||||
|
|
|
@ -44,8 +44,6 @@
|
||||||
|
|
||||||
#include <Parser.h>
|
#include <Parser.h>
|
||||||
|
|
||||||
#include <Schema/KeyUpload.h>
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -524,26 +522,4 @@ extern HashMap * UserGetAccountData(User *, char *);
|
||||||
* Replaces an account data entry.
|
* Replaces an account data entry.
|
||||||
*/
|
*/
|
||||||
extern void UserSetAccountData(User *, char *, HashMap *);
|
extern void UserSetAccountData(User *, char *, HashMap *);
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the device key list.
|
|
||||||
*/
|
|
||||||
extern void UserSetDeviceKeys(User *, DeviceKeys *);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clears the fallback/one-time key list.
|
|
||||||
*/
|
|
||||||
extern void UserClearFallbackKeys(User *);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a one-time/fallback key.
|
|
||||||
*/
|
|
||||||
extern void UserAddKey(User *, char *, JsonValue *, bool);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a hashmap from algorithm to one-time key count as
|
|
||||||
* a pointer to the uint64_t.
|
|
||||||
* This is intended for /keys/upload. Please do not use this
|
|
||||||
* elsewhere */
|
|
||||||
extern HashMap * UserGetOnetimeCounts(User *);
|
|
||||||
#endif /* TELODENDRIA_USER_H */
|
#endif /* TELODENDRIA_USER_H */
|
||||||
|
|
Loading…
Reference in a new issue