From c5bce0b14fd861bf60a0837b764d2a2c21c6c5bd Mon Sep 17 00:00:00 2001 From: Jordan Bancino Date: Mon, 9 Jan 2023 19:22:09 +0000 Subject: [PATCH] Apply #43 with modifications. --- TODO.txt | 2 +- src/Routes/RouteRegister.c | 12 ++-- src/User.c | 113 +++++++++++++++++++++++++++++++++++++ src/include/User.h | 5 +- 4 files changed, 125 insertions(+), 7 deletions(-) diff --git a/TODO.txt b/TODO.txt index bb8173e..a2ed5b3 100644 --- a/TODO.txt +++ b/TODO.txt @@ -20,7 +20,7 @@ Milestone: v0.2.0 [~] User registration [x] Username validation [x] Password hashing - [ ] User API + [~] User API [ ] Document UserInteractiveAuth (move docs from Matrix) [ ] Document User diff --git a/src/Routes/RouteRegister.c b/src/Routes/RouteRegister.c index b49c340..5503a1b 100644 --- a/src/Routes/RouteRegister.c +++ b/src/Routes/RouteRegister.c @@ -53,6 +53,8 @@ ROUTE_IMPL(RouteRegister, args) Db *db = args->matrixArgs->db; + User *user = NULL; + if (MATRIX_PATH_PARTS(args->path) == 0) { if (HttpRequestMethodGet(args->context) != HTTP_POST) @@ -190,28 +192,28 @@ ROUTE_IMPL(RouteRegister, args) } /* These values are already set */ - (void) password; (void) refreshToken; (void) inhibitLogin; /* These may be NULL */ (void) initialDeviceDisplayName; - (void) username; (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) { /* TODO: Log in user here and attach auth info to response */ } + UserUnlock(user); finish: Free(username); Free(password); Free(deviceId); Free(initialDeviceDisplayName); - JsonFree(request); } else diff --git a/src/User.c b/src/User.c index 9461746..b1e51b6 100644 --- a/src/User.c +++ b/src/User.c @@ -22,6 +22,11 @@ * SOFTWARE. */ #include +#include +#include +#include +#include +#include #include @@ -29,6 +34,8 @@ struct User { Db *db; DbRef *ref; + + char *name; }; int @@ -90,3 +97,109 @@ UserExists(Db * db, char *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; +} diff --git a/src/include/User.h b/src/include/User.h index 30bea41..d047519 100644 --- a/src/include/User.h +++ b/src/include/User.h @@ -47,6 +47,9 @@ extern int UserUnlock(User *); 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 */