[MOD] Stateless /message tokins
Some checks failed
Compile Telodendria / Compile Telodendria (x86, alpine-v3.19) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, debian-v12.4) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, freebsd-v14.0) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86, netbsd-v9.3) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, alpine-v3.19) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, debian-v12.4) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, freebsd-v14.0) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, netbsd-v9.3) (push) Has been cancelled
Compile Telodendria / Compile Telodendria (x86_64, openbsd-v7.4) (push) Has been cancelled

This commit is contained in:
LDA 2024-08-28 19:55:04 +02:00
parent dfb950bc7f
commit 5b51d9159e

View file

@ -24,11 +24,12 @@
*/
#include <Cytoplasm/Db.h>
#include <User.h>
#include <Cytoplasm/Util.h>
#include <Cytoplasm/Memory.h>
#include <Cytoplasm/Base64.h>
#include <Cytoplasm/Util.h>
#include <Cytoplasm/Json.h>
#include <Cytoplasm/Str.h>
#include <Cytoplasm/Sha.h>
#include <Cytoplasm/Json.h>
#include <Cytoplasm/Log.h>
#include <Parser.h>
@ -233,7 +234,10 @@ UserCreate(Db * db, char *name, char *password)
if (!name)
{
user->name = StrRandom(12);
char *casing = StrRandom(12);
user->name = StrLower(casing);
Free(casing);
}
else
{
@ -1501,28 +1505,74 @@ UserGetEvents(User *user, char *batch, char *roomId)
return ret;
}
static char *
EncodeMessageToken(char *room, char *event)
{
size_t roomLen = room ? strlen(room) : 0;
size_t eventLen = event ? strlen(event) : 0;
size_t sum = roomLen + 1 + eventLen;
char concatenation[sum + 8];
if (!room || !event)
{
return NULL;
}
/* TODO: Consider setting an HMAC/signature to be sure
* that the token isn't forged. */
memcpy(concatenation, room, roomLen);
concatenation[roomLen] = '|';
memcpy(concatenation + roomLen + 1, event, eventLen);
return Base64Encode(concatenation, sum);
}
static bool
DecodeMessageToken(char *tokin, char **room, char **event)
{
char *token, *nultoken;
char *off;
size_t len, roomLen;
if (!tokin || !room || !event)
{
return false;
}
*room = NULL;
*event = NULL;
len = Base64DecodedSize(tokin, strlen(tokin));
token = Base64Decode(tokin, strlen(tokin));
nultoken = Malloc(len + 1);
memcpy(nultoken, token, len);
nultoken[len] = '\0';
Free(token);
if (!(off = strchr(nultoken, '|')))
{
Free(nultoken);
return false;
}
roomLen = off - nultoken;
*room = Malloc(roomLen + 1);
memcpy(*room, nultoken, roomLen);
(*room)[roomLen] = '\0';
*event = StrDuplicate(off + 1);
Free(nultoken);
return true;
}
char *
UserNewMessageToken(User *user, char *room, char *event)
{
DbRef *messageRef;
HashMap *json;
char *messageToken;
if (!user || !room || !event)
{
return NULL;
}
messageToken = StrRandom(16);
messageRef = DbCreate(user->db,
4, "users", user->name, "msg", messageToken
);
json = DbJson(messageRef);
HashMapSet(json, "room", JsonValueString(room));
HashMapSet(json, "from", JsonValueString(event));
DbUnlock(user->db, messageRef);
/* TODO: User checks, HMACs */
messageToken = EncodeMessageToken(room, event);
return messageToken;
}
@ -1531,10 +1581,8 @@ UserFetchMessages(User *user, int n, char *token, char **next)
{
Array *messages = NULL;
Array *nexts = NULL;
DbRef *messageRef;
HashMap *json;
Room *room;
char *roomId;
char *roomId, *eId;
size_t i;
bool limited = false;
@ -1551,24 +1599,19 @@ UserFetchMessages(User *user, int n, char *token, char **next)
dir = true;
}
messageRef = DbLock(user->db,
4, "users", user->name, "msg", token
);
json = DbJson(messageRef);
if (!messageRef)
if (!DecodeMessageToken(token, &roomId, &eId))
{
/* Regenerate a new one */
return NULL;
}
roomId = JsonValueAsString(HashMapGet(json, "room"));
room = RoomLock(user->db, roomId);
/* TODO (very important): CHECK IF THE USER IS ABLE TO SEE
* HISTORY. THROUGHOUT THE STEPS HERE. */
if (!room)
{
DbUnlock(user->db, messageRef);
Free(roomId);
Free(eId);
return NULL;
}
@ -1576,9 +1619,7 @@ UserFetchMessages(User *user, int n, char *token, char **next)
messages = ArrayCreate();
/* A stack of elements to deal with the DAG. */
ArrayAdd(nexts,
StrDuplicate(JsonValueAsString(HashMapGet(json, "from")))
);
ArrayAdd(nexts, StrDuplicate(eId));
for (i = 0; i < (size_t) n && ArraySize(nexts); i++)
{
char *curr = ArrayDelete(nexts, ArraySize(nexts) - 1);
@ -1588,7 +1629,8 @@ UserFetchMessages(User *user, int n, char *token, char **next)
Free(curr);
/* Push event into our message list. */
/* Push event into our message list.
* TODO: Check if the user has the right to see the event/room. */
ArrayAdd(messages, event);
prevEvents = JsonValueAsArray(HashMapGet(event, "prev_events"));
@ -1627,12 +1669,13 @@ UserFetchMessages(User *user, int n, char *token, char **next)
*next = UserNewMessageToken(user, roomId, eId);
}
DbUnlock(user->db, messageRef);
for (i = 0; i < ArraySize(messages); i++)
{
HashMap *e = ArrayGet(messages, i);
ArraySet(messages, i, JsonValueObject(e));
}
Free(roomId);
Free(eId);
return messages;
}