forked from Telodendria/Telodendria
[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
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:
parent
dfb950bc7f
commit
5b51d9159e
1 changed files with 74 additions and 31 deletions
105
src/User.c
105
src/User.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue