forked from Telodendria/Telodendria
Apply #43 with modifications.
This commit is contained in:
parent
1421c478fd
commit
c5bce0b14f
2
TODO.txt
2
TODO.txt
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
113
src/User.c
113
src/User.c
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
Loading…
Reference in New Issue