Apply #43 with modifications.

This commit is contained in:
Jordan Bancino 2023-01-09 19:22:09 +00:00
parent 1421c478fd
commit c5bce0b14f
4 changed files with 125 additions and 7 deletions

View file

@ -20,7 +20,7 @@ Milestone: v0.2.0
[~] User registration [~] User registration
[x] Username validation [x] Username validation
[x] Password hashing [x] Password hashing
[ ] User API [~] User API
[ ] Document UserInteractiveAuth (move docs from Matrix) [ ] Document UserInteractiveAuth (move docs from Matrix)
[ ] Document User [ ] Document User

View file

@ -53,6 +53,8 @@ ROUTE_IMPL(RouteRegister, args)
Db *db = args->matrixArgs->db; Db *db = args->matrixArgs->db;
User *user = NULL;
if (MATRIX_PATH_PARTS(args->path) == 0) if (MATRIX_PATH_PARTS(args->path) == 0)
{ {
if (HttpRequestMethodGet(args->context) != HTTP_POST) if (HttpRequestMethodGet(args->context) != HTTP_POST)
@ -190,28 +192,28 @@ ROUTE_IMPL(RouteRegister, args)
} }
/* These values are already set */ /* These values are already set */
(void) password;
(void) refreshToken; (void) refreshToken;
(void) inhibitLogin; (void) inhibitLogin;
/* These may be NULL */ /* These may be NULL */
(void) initialDeviceDisplayName; (void) initialDeviceDisplayName;
(void) username;
(void) deviceId; (void) deviceId;
/* TODO: Register new user here */ user = UserCreate(db, username, password);
response = HashMapCreate();
HashMapSet(response, "user_id", JsonValueString(StrConcat(4, "@", UserGetName(user), ":", args->matrixArgs->config->serverName)));
HttpResponseStatus(args->context, HTTP_OK);
if (!inhibitLogin) if (!inhibitLogin)
{ {
/* TODO: Log in user here and attach auth info to response */ /* TODO: Log in user here and attach auth info to response */
} }
UserUnlock(user);
finish: finish:
Free(username); Free(username);
Free(password); Free(password);
Free(deviceId); Free(deviceId);
Free(initialDeviceDisplayName); Free(initialDeviceDisplayName);
JsonFree(request); JsonFree(request);
} }
else else

View file

@ -22,6 +22,11 @@
* SOFTWARE. * SOFTWARE.
*/ */
#include <User.h> #include <User.h>
#include <Util.h>
#include <Memory.h>
#include <Str.h>
#include <Sha2.h>
#include <Json.h>
#include <string.h> #include <string.h>
@ -29,6 +34,8 @@ struct User
{ {
Db *db; Db *db;
DbRef *ref; DbRef *ref;
char *name;
}; };
int int
@ -90,3 +97,109 @@ UserExists(Db * db, char *name)
{ {
return DbExists(db, 2, "users", name); return DbExists(db, 2, "users", name);
} }
User *
UserLock(Db * db, char *name)
{
User *user = NULL;
DbRef *ref = NULL;
if (!UserExists(db, name))
{
return NULL;
}
ref = DbLock(db, 2, "users", name);
user = Malloc(sizeof(User));
user->db = db;
user->ref = ref;
user->name = StrDuplicate(name);
return user;
}
int
UserUnlock(User * user)
{
if (!user)
{
return 0;
}
Free(user->name);
Free(user);
return DbUnlock(user->db, user->ref);
}
User *
UserCreate(Db * db, char *name, char *password)
{
User *user = NULL;
HashMap *json = NULL;
char *hash = NULL;
char *salt = NULL;
char *tmpstr = NULL;
unsigned long ts = UtilServerTs();
/* TODO: Put some sort of password policy(like for example at least
* 8 chars, or maybe check it's entropy)? */
if (!db || (name && UserExists(db, name)) || !password || !strlen(password))
{
/* User exists or cannot be registered, therefore, do NOT
* bother */
return NULL;
}
user = Malloc(sizeof(User));
user->db = db;
if (!name)
{
user->name = StrRandom(12);
}
else
{
user->name = StrDuplicate(name);
}
user->ref = DbCreate(db, 2, "users", user->name);
if (!user->ref)
{
/* The only scenario where I can see that occur is if for some
* strange reason, Db fails to create a file(e.g fs is full) */
Free(user->name);
Free(user);
return NULL;
}
json = DbJson(user->ref);
/* Generate stored password using a salt and SHA256 */
salt = StrRandom(16);
tmpstr = StrConcat(2, password, salt);
hash = Sha256(tmpstr);
Free(tmpstr);
HashMapSet(json, "salt", JsonValueString(salt));
HashMapSet(json, "hash", JsonValueString(hash));
HashMapSet(json, "created_on", JsonValueInteger(ts));
HashMapSet(json, "last_updated", JsonValueInteger(ts));
return user;
}
void
UserLogin(User * user, char *password, char *deviceId, char *deviceDisplayName)
{
/* TODO: Implement login */
(void) user;
(void) password;
(void) deviceId;
(void) deviceDisplayName;
}
char *
UserGetName(User * user)
{
return user ? user->name : NULL;
}

View file

@ -47,6 +47,9 @@ extern int
UserUnlock(User *); UserUnlock(User *);
extern void extern void
UserLogin(User *, char *name, char *password, char *deviceId, char *deviceDisplayName); UserLogin(User *, char *password, char *deviceId, char *deviceDisplayName);
extern char *
UserGetName(User *);
#endif /* TELODENDRIA_USER_H */ #endif /* TELODENDRIA_USER_H */