forked from lda/telodendria
Apply #43 with modifications.
This commit is contained in:
parent
1421c478fd
commit
c5bce0b14f
4 changed files with 125 additions and 7 deletions
2
TODO.txt
2
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
|
||||
|
|
|
@ -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
|
||||
|
|
113
src/User.c
113
src/User.c
|
@ -22,6 +22,11 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
#include <User.h>
|
||||
#include <Util.h>
|
||||
#include <Memory.h>
|
||||
#include <Str.h>
|
||||
#include <Sha2.h>
|
||||
#include <Json.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue