Begin prototyping User.h

This commit is contained in:
Jordan Bancino 2023-01-07 15:51:56 +00:00
parent 0f661f435f
commit 08b36c071c
8 changed files with 203 additions and 74 deletions

View file

@ -23,8 +23,11 @@ Milestone: v0.2.0
[ ] User API
[ ] Document UserInteractiveAuth (move docs from Matrix)
[ ] Document User
[ ] Move docs from Matrix to User for UserValidate
[ ] Document MemoryHexDump
[ ] Document String and remove old functions from Util
[ ] Document DbExists
Milestone: v1.0.0
-----------------

View file

@ -724,6 +724,28 @@ DbUnlock(Db * db, DbRef * ref)
return 1;
}
int
DbExists(Db * db, size_t nArgs,...)
{
va_list ap;
Array *args;
char *file;
int ret;
va_start(ap, nArgs);
args = ArrayFromVarArgs(nArgs, ap);
va_end(ap);
file = DbFileName(db, args);
ret = UtilLastModified(file);
Free(file);
ArrayFree(args);
return ret;
}
HashMap *
DbJson(DbRef * ref)
{

View file

@ -358,57 +358,3 @@ MatrixRateLimit(HttpServerContext * context, Db * db)
(void) db;
return NULL;
}
int
MatrixUserValidate(char *localpart, char *domain)
{
size_t maxLen = 255 - strlen(domain) - 1;
size_t i = 0;
while (localpart[i])
{
char c = localpart[i];
if (i > maxLen)
{
return 0;
}
if (!((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
(c == '.') || (c == '_') || (c == '=') || (c == '-') ||
(c == '/')))
{
return 0;
}
i++;
}
return 1;
}
int
MatrixHistoricalUserValidate(char *localpart, char *domain)
{
size_t maxLen = 255 - strlen(domain) - 1;
size_t i = 0;
while (localpart[i])
{
char c = localpart[i];
if (i > maxLen)
{
return 0;
}
if (!(c >= 0x21 && c <= 0x39) || (c >= 0x3B && c <= 0x7E))
{
return 0;
}
i++;
}
return 1;
}

View file

@ -29,6 +29,8 @@
#include <HashMap.h>
#include <String.h>
#include <Memory.h>
#include <User.h>
#include <UserInteractiveAuth.h>
ROUTE_IMPL(RouteRegister, args)
@ -49,6 +51,8 @@ ROUTE_IMPL(RouteRegister, args)
int inhibitLogin = 0;
char *deviceId = NULL;
Db *db = args->matrixArgs->db;
if (MATRIX_PATH_PARTS(args->path) == 0)
{
if (HttpRequestMethodGet(args->context) != HTTP_POST)
@ -82,15 +86,19 @@ ROUTE_IMPL(RouteRegister, args)
}
username = StringDuplicate(JsonValueAsString(val));
if (!MatrixUserValidate(username, args->matrixArgs->config->serverName))
if (!UserValidate(username, args->matrixArgs->config->serverName))
{
HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
response = MatrixErrorCreate(M_INVALID_USERNAME);
goto finish;
}
/* TODO: Check if username exists and throw error if it
* does */
if (UserExists(db, username))
{
HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
response = MatrixErrorCreate(M_USER_IN_USE);
goto finish;
}
}
response = UserInteractiveAuth(args->context,
@ -181,29 +189,29 @@ ROUTE_IMPL(RouteRegister, args)
refreshToken = JsonValueAsBoolean(val);
}
if (!username)
{
username = StringRandom(16);
}
if (!inhibitLogin && !deviceId)
{
deviceId = StringRandom(10);
}
/* These values are already set */
(void) password;
(void) refreshToken;
(void) inhibitLogin;
(void) username;
/* These may be NULL */
(void) initialDeviceDisplayName;
(void) username;
(void) deviceId;
/* TODO: Register new user here */
if (!inhibitLogin)
{
/* TODO: Log in user here and attach auth info to response */
}
finish:
Free(username);
Free(password);
Free(deviceId);
Free(initialDeviceDisplayName);
JsonFree(request);
}
else
@ -221,8 +229,21 @@ finish:
HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
response = MatrixErrorCreate(M_MISSING_PARAM);
}
/* TODO: Check if username is available */
else if (!UserValidate(username, args->matrixArgs->config->serverName))
{
HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
response = MatrixErrorCreate(M_INVALID_USERNAME);
}
else if (UserExists(db, username))
{
response = HashMapCreate();
HashMapSet(response, "available", JsonValueBoolean(1));
}
else
{
HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
response = MatrixErrorCreate(M_USER_IN_USE);
}
}
else if (HttpRequestMethodGet(args->context) == HTTP_POST &&
(MATRIX_PATH_EQUALS(pathPart, "email") ||

86
src/User.c Normal file
View file

@ -0,0 +1,86 @@
/*
* Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net>
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <User.h>
#include <string.h>
int
UserValidate(char *localpart, char *domain)
{
size_t maxLen = 255 - strlen(domain) - 1;
size_t i = 0;
while (localpart[i])
{
char c = localpart[i];
if (i > maxLen)
{
return 0;
}
if (!((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
(c == '.') || (c == '_') || (c == '=') || (c == '-') ||
(c == '/')))
{
return 0;
}
i++;
}
return 1;
}
int
UserHistoricalValidate(char *localpart, char *domain)
{
size_t maxLen = 255 - strlen(domain) - 1;
size_t i = 0;
while (localpart[i])
{
char c = localpart[i];
if (i > maxLen)
{
return 0;
}
if (!(c >= 0x21 && c <= 0x39) || (c >= 0x3B && c <= 0x7E))
{
return 0;
}
i++;
}
return 1;
}
int
UserExists(Db * db, char *name)
{
return DbExists(db, 2, "users", name);
}

View file

@ -53,6 +53,9 @@ extern DbRef *
extern int
DbUnlock(Db *, DbRef *);
extern int
DbExists(Db *, size_t,...);
extern HashMap *
DbJson(DbRef *);

View file

@ -86,10 +86,6 @@ extern HashMap *
extern HashMap *
MatrixRateLimit(HttpServerContext *, Db *);
extern int
MatrixUserValidate(char *, char *);
extern int
MatrixHistoricalUserValidate(char *, char *);
#endif

52
src/include/User.h Normal file
View file

@ -0,0 +1,52 @@
/*
* Copyright (C) 2022-2023 Jordan Bancino <@jordan:bancino.net>
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation files
* (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#ifndef TELODENDRIA_USER_H
#define TELODENDRIA_USER_H
#include <Db.h>
typedef struct User User;
extern int
UserValidate(char *, char *);
extern int
UserHistoricalValidate(char *, char *);
extern int
UserExists(Db *, char *name);
extern User *
UserCreate(Db *, char *name, char *password);
extern User *
UserLock(Db *, char *name);
extern int
UserUnlock(User *);
extern void
UserLogin(User *, char *name, char *password, char *deviceId, char *deviceDisplayName);
#endif /* TELODENDRIA_USER_H */