forked from Telodendria/Telodendria
Make Telodendria compatible with latest Cytoplasm.
This also brings Telodendria to C99 compliance.
This commit is contained in:
parent
f2a4a64b27
commit
e62389aa14
13 changed files with 175 additions and 207 deletions
21
src/Config.c
21
src/Config.c
|
@ -30,7 +30,6 @@
|
|||
#include <Cytoplasm/Str.h>
|
||||
#include <Cytoplasm/Db.h>
|
||||
#include <Cytoplasm/Log.h>
|
||||
#include <Cytoplasm/Int64.h>
|
||||
#include <Cytoplasm/Util.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -59,7 +58,7 @@ ConfigParse(HashMap * config, Config *tConfig)
|
|||
|
||||
memset(tConfig, 0, sizeof(Config));
|
||||
|
||||
tConfig->maxCache = Int64Create(0, 0);
|
||||
tConfig->maxCache = 0;
|
||||
|
||||
if (!ConfigFromJson(config, tConfig, &tConfig->err))
|
||||
{
|
||||
|
@ -85,17 +84,17 @@ ConfigParse(HashMap * config, Config *tConfig)
|
|||
for (i = 0; i < ArraySize(tConfig->listen); i++)
|
||||
{
|
||||
ConfigListener *listener = ArrayGet(tConfig->listen, i);
|
||||
if (Int64Eq(listener->maxConnections, Int64Create(0, 0)))
|
||||
if (!listener->maxConnections)
|
||||
{
|
||||
listener->maxConnections = Int64Create(0, 32);
|
||||
listener->maxConnections = 32;
|
||||
}
|
||||
if (Int64Eq(listener->threads, Int64Create(0, 0)))
|
||||
if (!listener->threads)
|
||||
{
|
||||
listener->threads = Int64Create(0, 4);
|
||||
listener->threads = 4;
|
||||
}
|
||||
if (Int64Eq(listener->port, Int64Create(0, 0)))
|
||||
if (!listener->port)
|
||||
{
|
||||
listener->port = Int64Create(0, 8008);
|
||||
listener->port = 8008;
|
||||
}
|
||||
}
|
||||
tConfig->ok = 1;
|
||||
|
@ -148,9 +147,9 @@ ConfigCreateDefault(Db * db)
|
|||
/* Add simple listener without TLS. */
|
||||
config.listen = ArrayCreate();
|
||||
listener = Malloc(sizeof(ConfigListener));
|
||||
listener->maxConnections = Int64Create(0, 32);
|
||||
listener->port = Int64Create(0, 8008);
|
||||
listener->threads = Int64Create(0, 4);
|
||||
listener->maxConnections = 32;
|
||||
listener->port = 8008;
|
||||
listener->threads = 4;
|
||||
|
||||
ArrayAdd(config.listen, listener);
|
||||
|
||||
|
|
11
src/Main.c
11
src/Main.c
|
@ -36,14 +36,12 @@
|
|||
|
||||
#include <Cytoplasm/Args.h>
|
||||
#include <Cytoplasm/Memory.h>
|
||||
#include <Config.h>
|
||||
#include <Cytoplasm/Log.h>
|
||||
#include <Cytoplasm/HashMap.h>
|
||||
#include <Cytoplasm/Json.h>
|
||||
#include <Cytoplasm/HttpServer.h>
|
||||
#include <Cytoplasm/Db.h>
|
||||
#include <Cytoplasm/Cron.h>
|
||||
#include <Uia.h>
|
||||
#include <Cytoplasm/Util.h>
|
||||
#include <Cytoplasm/Str.h>
|
||||
|
||||
|
@ -52,6 +50,9 @@
|
|||
#include <User.h>
|
||||
#include <RegToken.h>
|
||||
#include <Routes.h>
|
||||
#include <Uia.h>
|
||||
#include <Config.h>
|
||||
|
||||
|
||||
static Array *httpServers;
|
||||
static volatile int restart;
|
||||
|
@ -248,7 +249,7 @@ start:
|
|||
}
|
||||
|
||||
token = StrRandom(32);
|
||||
info = RegTokenCreate(matrixArgs.db, token, NULL, UInt64Create(0, 0), Int64Create(0, 1), USER_ALL);
|
||||
info = RegTokenCreate(matrixArgs.db, token, NULL, /* expires */ 0, /* uses */ 1, USER_ALL);
|
||||
if (!info)
|
||||
{
|
||||
Free(token);
|
||||
|
@ -396,14 +397,14 @@ start:
|
|||
|
||||
if (args.flags & HTTP_FLAG_TLS)
|
||||
{
|
||||
if (UInt64Eq(UtilLastModified(serverCfg->tls.cert), UInt64Create(0, 0)))
|
||||
if (!UtilLastModified(serverCfg->tls.cert))
|
||||
{
|
||||
Log(LOG_ERR, "%s: %s", strerror(errno), serverCfg->tls.cert);
|
||||
exit = EXIT_FAILURE;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (UInt64Eq(UtilLastModified(serverCfg->tls.key), UInt64Create(0, 0)))
|
||||
if (UtilLastModified(serverCfg->tls.key))
|
||||
{
|
||||
Log(LOG_ERR, "%s: %s", strerror(errno), serverCfg->tls.key);
|
||||
exit = EXIT_FAILURE;
|
||||
|
|
101
src/Parser.c
101
src/Parser.c
|
@ -27,7 +27,6 @@
|
|||
|
||||
#include <Cytoplasm/Memory.h>
|
||||
#include <Cytoplasm/Str.h>
|
||||
#include <Cytoplasm/Int.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -38,7 +37,7 @@
|
|||
#define Iterate(s) (*(*s)++)
|
||||
|
||||
/* Parse an extended localpart */
|
||||
static int
|
||||
static bool
|
||||
ParseUserLocalpart(char **str, char **out)
|
||||
{
|
||||
char c;
|
||||
|
@ -47,7 +46,7 @@ ParseUserLocalpart(char **str, char **out)
|
|||
|
||||
if (!str || !out)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
/* An extended localpart contains every ASCII printable character,
|
||||
* except an ':'. */
|
||||
|
@ -60,7 +59,7 @@ ParseUserLocalpart(char **str, char **out)
|
|||
if (length < 1)
|
||||
{
|
||||
*str = start;
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
if (c == ':')
|
||||
{
|
||||
|
@ -71,8 +70,9 @@ ParseUserLocalpart(char **str, char **out)
|
|||
memcpy(*out, start, length);
|
||||
(*out)[length] = '\0';
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Parses an IPv4 address. */
|
||||
static int
|
||||
ParseIPv4(char **str, char **out)
|
||||
|
@ -102,14 +102,14 @@ ParseIPv4(char **str, char **out)
|
|||
{
|
||||
/* Current digit is too long for the spec! */
|
||||
*str = start;
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
memcpy(buffer, *str - digit - 1, digit);
|
||||
if (atoi(buffer) > 255)
|
||||
{
|
||||
/* Current digit is too large for the spec! */
|
||||
*str = start;
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
digit = 0;
|
||||
|
@ -118,20 +118,22 @@ ParseIPv4(char **str, char **out)
|
|||
if (c == '.' || digits != 3)
|
||||
{
|
||||
*str = start;
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
length = (size_t) (*str - start) - 1;
|
||||
*out = Malloc(length + 1);
|
||||
memcpy(*out, start, length);
|
||||
(*str)--;
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
static int
|
||||
|
||||
static bool
|
||||
IsIPv6Char(char c)
|
||||
{
|
||||
return isxdigit(c) || c == ':' || c == '.';
|
||||
return (isxdigit(c) || c == ':' || c == '.');
|
||||
}
|
||||
static int
|
||||
|
||||
static bool
|
||||
ParseIPv6(char **str, char **out)
|
||||
{
|
||||
char *start;
|
||||
|
@ -174,7 +176,7 @@ ParseIPv6(char **str, char **out)
|
|||
/* RFC3513 says the following:
|
||||
* > 'The "::" can only appear once in an address.' */
|
||||
*str = start;
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
if (digit < 1 || digit > 4)
|
||||
{
|
||||
|
@ -217,12 +219,13 @@ end:
|
|||
memset(*out, '\0', length + 1);
|
||||
memcpy(*out, start, length);
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
fail:
|
||||
*str = start;
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
static int
|
||||
|
||||
static bool
|
||||
ParseHostname(char **str, char **out)
|
||||
{
|
||||
char *start;
|
||||
|
@ -239,16 +242,16 @@ ParseHostname(char **str, char **out)
|
|||
if (length < 1 || length > 255)
|
||||
{
|
||||
*str = start;
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
length = (size_t) (*str - start) - 1;
|
||||
*out = Malloc(length + 1);
|
||||
memcpy(*out, start, length);
|
||||
(*str)--;
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int
|
||||
static bool
|
||||
ParseServerName(char **str, ServerPart *out)
|
||||
{
|
||||
char c;
|
||||
|
@ -261,7 +264,7 @@ ParseServerName(char **str, ServerPart *out)
|
|||
|
||||
if (!str || !out)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
start = *str;
|
||||
|
@ -284,7 +287,7 @@ ParseServerName(char **str, ServerPart *out)
|
|||
if (!host)
|
||||
{
|
||||
/* Can't parse a valid server name. */
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
/* Now, there's only 2 options: a ':', or the end(everything else.) */
|
||||
if (**str != ':')
|
||||
|
@ -292,7 +295,7 @@ ParseServerName(char **str, ServerPart *out)
|
|||
/* We're done. */
|
||||
out->hostname = host;
|
||||
out->port = NULL;
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
/* TODO: Separate this out */
|
||||
startPort = ++(*str);
|
||||
|
@ -305,7 +308,7 @@ ParseServerName(char **str, ServerPart *out)
|
|||
*str = start;
|
||||
Free(host);
|
||||
host = NULL;
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
port = Malloc(chars + 1);
|
||||
|
@ -316,24 +319,26 @@ ParseServerName(char **str, ServerPart *out)
|
|||
Free(port);
|
||||
Free(host);
|
||||
*str = start;
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
out->hostname = host;
|
||||
out->port = port;
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
int
|
||||
|
||||
bool
|
||||
ParseServerPart(char *str, ServerPart *part)
|
||||
{
|
||||
/* This is a wrapper behind the internal ParseServerName. */
|
||||
if (!str || !part)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
return ParseServerName(&str, part);
|
||||
}
|
||||
|
||||
void
|
||||
ServerPartFree(ServerPart part)
|
||||
{
|
||||
|
@ -347,20 +352,20 @@ ServerPartFree(ServerPart part)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
bool
|
||||
ParseCommonID(char *str, CommonID *id)
|
||||
{
|
||||
char sigil;
|
||||
|
||||
if (!str || !id)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* There must at least be 2 chararacters: the sigil and a string.*/
|
||||
if (strlen(str) < 2)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
sigil = *str++;
|
||||
|
@ -369,7 +374,7 @@ ParseCommonID(char *str, CommonID *id)
|
|||
*/
|
||||
if ((sigil == '#' || sigil == '@') && strlen(str) > 255)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
id->sigil = sigil;
|
||||
id->local = NULL;
|
||||
|
@ -383,7 +388,7 @@ ParseCommonID(char *str, CommonID *id)
|
|||
* accepting it all. */
|
||||
if (!ParseUserLocalpart(&str, &id->local))
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
if (*str == ':')
|
||||
{
|
||||
|
@ -392,9 +397,9 @@ ParseCommonID(char *str, CommonID *id)
|
|||
{
|
||||
Free(id->local);
|
||||
id->local = NULL;
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case '!':
|
||||
|
@ -403,23 +408,23 @@ ParseCommonID(char *str, CommonID *id)
|
|||
case '@':
|
||||
if (!ParseUserLocalpart(&str, &id->local))
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
if (*str++ != ':')
|
||||
{
|
||||
Free(id->local);
|
||||
id->local = NULL;
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
if (!ParseServerName(&str, &id->server))
|
||||
{
|
||||
Free(id->local);
|
||||
id->local = NULL;
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -431,15 +436,18 @@ CommonIDFree(CommonID id)
|
|||
}
|
||||
ServerPartFree(id.server);
|
||||
}
|
||||
int
|
||||
|
||||
bool
|
||||
ValidCommonID(char *str, char sigil)
|
||||
{
|
||||
CommonID id;
|
||||
int ret;
|
||||
bool ret;
|
||||
|
||||
memset(&id, 0, sizeof(CommonID));
|
||||
|
||||
if (!str)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
ret = ParseCommonID(str, &id) && id.sigil == sigil;
|
||||
|
@ -447,6 +455,7 @@ ValidCommonID(char *str, char sigil)
|
|||
CommonIDFree(id);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *
|
||||
ParserRecomposeServerPart(ServerPart serverPart)
|
||||
{
|
||||
|
@ -460,6 +469,7 @@ ParserRecomposeServerPart(ServerPart serverPart)
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *
|
||||
ParserRecomposeCommonID(CommonID id)
|
||||
{
|
||||
|
@ -485,15 +495,18 @@ ParserRecomposeCommonID(CommonID id)
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
int
|
||||
|
||||
bool
|
||||
ParserServerNameEquals(ServerPart serverPart, char *str)
|
||||
{
|
||||
char *idServer;
|
||||
int ret;
|
||||
bool ret;
|
||||
|
||||
if (!str)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
idServer = ParserRecomposeServerPart(serverPart);
|
||||
|
||||
ret = StrEquals(idServer, str);
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include <Cytoplasm/Json.h>
|
||||
#include <Cytoplasm/Util.h>
|
||||
#include <Cytoplasm/Str.h>
|
||||
#include <Cytoplasm/Int64.h>
|
||||
#include <Cytoplasm/Log.h>
|
||||
|
||||
#include <User.h>
|
||||
|
@ -40,9 +39,9 @@ int
|
|||
RegTokenValid(RegTokenInfo * token)
|
||||
{
|
||||
HashMap *tokenJson;
|
||||
Int64 uses, used;
|
||||
int64_t uses, used;
|
||||
|
||||
UInt64 expiration;
|
||||
uint64_t expiration;
|
||||
|
||||
if (!token || !RegTokenExists(token->db, token->name))
|
||||
{
|
||||
|
@ -54,9 +53,7 @@ RegTokenValid(RegTokenInfo * token)
|
|||
used = JsonValueAsInteger(HashMapGet(tokenJson, "used"));
|
||||
expiration = JsonValueAsInteger(HashMapGet(tokenJson, "expires_on"));
|
||||
|
||||
return (UInt64Eq(expiration, UInt64Create(0, 0)) ||
|
||||
UInt64Geq(UtilServerTs(), expiration)) &&
|
||||
(Int64Eq(uses, Int64Neg(Int64Create(0, 1))) || Int64Lt(used, uses));
|
||||
return (!expiration || (UtilTsMillis() < expiration)) && (uses == -1 || used < uses);
|
||||
}
|
||||
void
|
||||
RegTokenUse(RegTokenInfo * token)
|
||||
|
@ -68,13 +65,12 @@ RegTokenUse(RegTokenInfo * token)
|
|||
return;
|
||||
}
|
||||
|
||||
if (Int64Geq(token->uses, Int64Create(0, 0)) &&
|
||||
Int64Geq(token->used, token->uses))
|
||||
if (token->uses >= 0 && token->used >= token->uses)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
token->used = Int64Add(token->used, Int64Create(0, 1));
|
||||
token->used++;
|
||||
|
||||
/* Write the information to the hashmap */
|
||||
tokenJson = DbJson(token->ref);
|
||||
|
@ -199,11 +195,11 @@ RegTokenVerify(char *token)
|
|||
}
|
||||
|
||||
RegTokenInfo *
|
||||
RegTokenCreate(Db * db, char *name, char *owner, UInt64 expires, Int64 uses, int privileges)
|
||||
RegTokenCreate(Db * db, char *name, char *owner, uint64_t expires, int64_t uses, int privileges)
|
||||
{
|
||||
RegTokenInfo *ret;
|
||||
|
||||
UInt64 timestamp = UtilServerTs();
|
||||
uint64_t timestamp = UtilTsMillis();
|
||||
|
||||
if (!db || !name)
|
||||
{
|
||||
|
@ -213,13 +209,13 @@ RegTokenCreate(Db * db, char *name, char *owner, UInt64 expires, Int64 uses, int
|
|||
/* -1 indicates infinite uses; zero and all positive values are a
|
||||
* valid number of uses; althought zero would be rather useless.
|
||||
* Anything less than -1 doesn't make sense. */
|
||||
if (Int64Lt(uses, Int64Neg(Int64Create(0, 1))))
|
||||
if (uses < -1)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Verify the token */
|
||||
if (!RegTokenVerify(name) || (UInt64Gt(expires, UInt64Create(0, 0)) && UInt64Lt(expires, timestamp)))
|
||||
if (!RegTokenVerify(name) || ((expires > 0) && (expires < timestamp)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
@ -235,7 +231,7 @@ RegTokenCreate(Db * db, char *name, char *owner, UInt64 expires, Int64 uses, int
|
|||
}
|
||||
ret->name = StrDuplicate(name);
|
||||
ret->created_by = StrDuplicate(owner);
|
||||
ret->used = Int64Create(0, 0);
|
||||
ret->used = 0;
|
||||
ret->uses = uses;
|
||||
ret->created_on = timestamp;
|
||||
ret->expires_on = expires;
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
*/
|
||||
#include <Routes.h>
|
||||
|
||||
#include <Cytoplasm/Int64.h>
|
||||
#include <User.h>
|
||||
#include <Cytoplasm/Memory.h>
|
||||
#include <Cytoplasm/Str.h>
|
||||
|
@ -86,24 +85,11 @@ ROUTE_IMPL(RouteProcControl, path, argp)
|
|||
if (StrEquals(op, "stats"))
|
||||
{
|
||||
size_t allocated = MemoryAllocated();
|
||||
Int64 a;
|
||||
|
||||
response = HashMapCreate();
|
||||
|
||||
if (sizeof(size_t) == sizeof(Int64))
|
||||
{
|
||||
UInt32 high = (UInt32) (allocated >> 32);
|
||||
UInt32 low = (UInt32) (allocated);
|
||||
|
||||
a = Int64Create(high, low);
|
||||
}
|
||||
else
|
||||
{
|
||||
a = Int64Create(0, allocated);
|
||||
}
|
||||
|
||||
HashMapSet(response, "version", JsonValueString(TELODENDRIA_VERSION));
|
||||
HashMapSet(response, "memory_allocated", JsonValueInteger(a));
|
||||
HashMapSet(response, "memory_allocated", JsonValueInteger(allocated));
|
||||
|
||||
goto finish;
|
||||
}
|
||||
|
|
|
@ -40,8 +40,6 @@ ROUTE_IMPL(RouteRequestToken, path, argp)
|
|||
|
||||
RequestToken reqTok;
|
||||
|
||||
Int64 minusOne = Int64Neg(Int64Create(0, 1));
|
||||
|
||||
reqTok.client_secret = NULL;
|
||||
reqTok.next_link = NULL;
|
||||
reqTok.id_access_token = NULL;
|
||||
|
@ -51,7 +49,7 @@ ROUTE_IMPL(RouteRequestToken, path, argp)
|
|||
reqTok.country = NULL;
|
||||
reqTok.phone_number = NULL;
|
||||
|
||||
reqTok.send_attempt = minusOne;
|
||||
reqTok.send_attempt = -1;
|
||||
|
||||
if (HttpRequestMethodGet(args->context) != HTTP_POST)
|
||||
{
|
||||
|
@ -90,7 +88,7 @@ ROUTE_IMPL(RouteRequestToken, path, argp)
|
|||
goto finish;
|
||||
}
|
||||
|
||||
if (Int64Eq(reqTok.send_attempt, minusOne))
|
||||
if (reqTok.send_attempt == -1)
|
||||
{
|
||||
msg = "Invalid or inexistent 'send_attempt'";
|
||||
HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
|
||||
|
|
|
@ -133,7 +133,7 @@ TelodendriaPrintHeader(void)
|
|||
Log(LOG_INFO, "%s", TelodendriaHeader[i]);
|
||||
}
|
||||
|
||||
Log(LOG_INFO, "Telodendria v" TELODENDRIA_VERSION " (%s v%s)", CytoplasmGetName(), CytoplasmGetVersion());
|
||||
Log(LOG_INFO, "Telodendria v" TELODENDRIA_VERSION " (Cytoplasm v%s)", CytoplasmGetVersionStr());
|
||||
Log(LOG_INFO, "");
|
||||
Log(LOG_INFO,
|
||||
"Copyright (C) 2024 Jordan Bancino <@jordan:bancino.net>");
|
||||
|
|
|
@ -135,7 +135,7 @@ BuildResponse(Array * flows, Db * db, HashMap ** response, char *session, DbRef
|
|||
|
||||
json = DbJson(ref);
|
||||
HashMapSet(json, "completed", JsonValueArray(ArrayCreate()));
|
||||
HashMapSet(json, "last_access", JsonValueInteger(UtilServerTs()));
|
||||
HashMapSet(json, "last_access", JsonValueInteger(UtilTsMillis()));
|
||||
DbUnlock(db, ref);
|
||||
|
||||
HashMapSet(*response, "completed", JsonValueArray(ArrayCreate()));
|
||||
|
@ -452,7 +452,7 @@ UiaComplete(Array * flows, HttpServerContext * context, Db * db,
|
|||
|
||||
finish:
|
||||
ArrayFree(possibleNext);
|
||||
JsonValueFree(HashMapSet(dbJson, "last_access", JsonValueInteger(UtilServerTs())));
|
||||
JsonValueFree(HashMapSet(dbJson, "last_access", JsonValueInteger(UtilTsMillis())));
|
||||
DbUnlock(db, dbRef);
|
||||
return ret;
|
||||
}
|
||||
|
@ -498,7 +498,7 @@ UiaCleanup(MatrixHttpHandlerArgs * args)
|
|||
char *session = ArrayGet(sessions, i);
|
||||
DbRef *ref = DbLock(args->db, 2, "user_interactive", session);
|
||||
|
||||
UInt64 lastAccess;
|
||||
uint64_t lastAccess;
|
||||
|
||||
if (!ref)
|
||||
{
|
||||
|
@ -513,7 +513,7 @@ UiaCleanup(MatrixHttpHandlerArgs * args)
|
|||
|
||||
/* If last access was greater than 15 minutes ago, remove this
|
||||
* session */
|
||||
if (UInt64Gt(UInt64Sub(UtilServerTs(), lastAccess), UInt64Create(0, 1000 * 60 * 15)))
|
||||
if ((UtilTsMillis() - lastAccess) > (1000 * 60 * 15))
|
||||
{
|
||||
DbDelete(args->db, 2, "user_interactive", session);
|
||||
Log(LOG_DEBUG, "Deleted session %s", session);
|
||||
|
|
119
src/User.c
119
src/User.c
|
@ -28,8 +28,6 @@
|
|||
#include <Cytoplasm/Str.h>
|
||||
#include <Cytoplasm/Sha.h>
|
||||
#include <Cytoplasm/Json.h>
|
||||
#include <Cytoplasm/Int64.h>
|
||||
#include <Cytoplasm/UInt64.h>
|
||||
|
||||
#include <Parser.h>
|
||||
|
||||
|
@ -44,7 +42,7 @@ struct User
|
|||
char *deviceId;
|
||||
};
|
||||
|
||||
int
|
||||
bool
|
||||
UserValidate(char *localpart, char *domain)
|
||||
{
|
||||
size_t maxLen = 255 - strlen(domain) - 1;
|
||||
|
@ -56,23 +54,23 @@ UserValidate(char *localpart, char *domain)
|
|||
|
||||
if (i > maxLen)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||
|
||||
(c == '.') || (c == '_') || (c == '=') || (c == '-') ||
|
||||
(c == '/')))
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
bool
|
||||
UserHistoricalValidate(char *localpart, char *domain)
|
||||
{
|
||||
size_t maxLen = 255 - strlen(domain) - 1;
|
||||
|
@ -84,21 +82,21 @@ UserHistoricalValidate(char *localpart, char *domain)
|
|||
|
||||
if (i > maxLen)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!((c >= 0x21 && c <= 0x39) || (c >= 0x3B && c <= 0x7E)))
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
bool
|
||||
UserExists(Db * db, char *name)
|
||||
{
|
||||
return DbExists(db, 2, "users", name);
|
||||
|
@ -133,7 +131,7 @@ UserAuthenticate(Db * db, char *accessToken)
|
|||
|
||||
char *userName;
|
||||
char *deviceId;
|
||||
UInt64 expires;
|
||||
uint64_t expires;
|
||||
|
||||
if (!db || !accessToken)
|
||||
{
|
||||
|
@ -157,8 +155,7 @@ UserAuthenticate(Db * db, char *accessToken)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (UInt64Neq(expires, UInt64Create(0, 0)) &&
|
||||
UInt64Geq(UtilServerTs(), expires))
|
||||
if (expires && UtilTsMillis() >= expires)
|
||||
{
|
||||
UserUnlock(user);
|
||||
DbUnlock(db, atRef);
|
||||
|
@ -171,14 +168,14 @@ UserAuthenticate(Db * db, char *accessToken)
|
|||
return user;
|
||||
}
|
||||
|
||||
int
|
||||
bool
|
||||
UserUnlock(User * user)
|
||||
{
|
||||
int ret;
|
||||
bool ret;
|
||||
|
||||
if (!user)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
Free(user->name);
|
||||
|
@ -196,7 +193,7 @@ UserCreate(Db * db, char *name, char *password)
|
|||
User *user = NULL;
|
||||
HashMap *json = NULL;
|
||||
|
||||
UInt64 ts = UtilServerTs();
|
||||
uint64_t ts = UtilTsMillis();
|
||||
|
||||
/* TODO: Put some sort of password policy(like for example at least
|
||||
* 8 chars, or maybe check it's entropy)? */
|
||||
|
@ -233,7 +230,7 @@ UserCreate(Db * db, char *name, char *password)
|
|||
|
||||
json = DbJson(user->ref);
|
||||
HashMapSet(json, "createdOn", JsonValueInteger(ts));
|
||||
HashMapSet(json, "deactivated", JsonValueBoolean(0));
|
||||
HashMapSet(json, "deactivated", JsonValueBoolean(false));
|
||||
|
||||
return user;
|
||||
}
|
||||
|
@ -356,7 +353,7 @@ UserGetDeviceId(User * user)
|
|||
return user ? user->deviceId : NULL;
|
||||
}
|
||||
|
||||
int
|
||||
bool
|
||||
UserCheckPassword(User * user, char *password)
|
||||
{
|
||||
HashMap *json;
|
||||
|
@ -368,11 +365,11 @@ UserCheckPassword(User * user, char *password)
|
|||
char *hashedPwd;
|
||||
char *tmp;
|
||||
|
||||
int result;
|
||||
bool result;
|
||||
|
||||
if (!user || !password)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
json = DbJson(user->ref);
|
||||
|
@ -382,7 +379,7 @@ UserCheckPassword(User * user, char *password)
|
|||
|
||||
if (!storedHash || !salt)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
tmp = StrConcat(2, password, salt);
|
||||
|
@ -398,7 +395,7 @@ UserCheckPassword(User * user, char *password)
|
|||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
bool
|
||||
UserSetPassword(User * user, char *password)
|
||||
{
|
||||
HashMap *json;
|
||||
|
@ -410,7 +407,7 @@ UserSetPassword(User * user, char *password)
|
|||
|
||||
if (!user || !password)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
json = DbJson(user->ref);
|
||||
|
@ -428,10 +425,10 @@ UserSetPassword(User * user, char *password)
|
|||
Free(hashBytes);
|
||||
Free(tmpstr);
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
bool
|
||||
UserDeactivate(User * user, char * from, char * reason)
|
||||
{
|
||||
HashMap *json;
|
||||
|
@ -439,7 +436,7 @@ UserDeactivate(User * user, char * from, char * reason)
|
|||
|
||||
if (!user)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* By default, it's the target's username */
|
||||
|
@ -450,7 +447,7 @@ UserDeactivate(User * user, char * from, char * reason)
|
|||
|
||||
json = DbJson(user->ref);
|
||||
|
||||
JsonValueFree(HashMapSet(json, "deactivated", JsonValueBoolean(1)));
|
||||
JsonValueFree(HashMapSet(json, "deactivated", JsonValueBoolean(true)));
|
||||
|
||||
val = JsonValueString(from);
|
||||
JsonValueFree(JsonSet(json, val, 2, "deactivate", "by"));
|
||||
|
@ -460,38 +457,38 @@ UserDeactivate(User * user, char * from, char * reason)
|
|||
JsonValueFree(JsonSet(json, val, 2, "deactivate", "reason"));
|
||||
}
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
bool
|
||||
UserReactivate(User * user)
|
||||
{
|
||||
HashMap *json;
|
||||
|
||||
if (!user)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
json = DbJson(user->ref);
|
||||
|
||||
|
||||
JsonValueFree(HashMapSet(json, "deactivated", JsonValueBoolean(0)));
|
||||
JsonValueFree(HashMapSet(json, "deactivated", JsonValueBoolean(false)));
|
||||
|
||||
JsonValueFree(HashMapDelete(json, "deactivate"));
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
bool
|
||||
UserDeactivated(User * user)
|
||||
{
|
||||
HashMap *json;
|
||||
|
||||
if (!user)
|
||||
{
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
json = DbJson(user->ref);
|
||||
|
@ -537,17 +534,17 @@ UserAccessTokenGenerate(User * user, char *deviceId, int withRefresh)
|
|||
|
||||
if (withRefresh)
|
||||
{
|
||||
token->lifetime = Int64Create(0, 1000 * 60 * 60 * 24 * 7); /* 1 Week */
|
||||
token->lifetime = 1000 * 60 * 60 * 24 * 7; /* 1 Week */
|
||||
}
|
||||
else
|
||||
{
|
||||
token->lifetime = Int64Create(0, 0);
|
||||
token->lifetime = 0;
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
int
|
||||
bool
|
||||
UserAccessTokenSave(Db * db, UserAccessToken * token)
|
||||
{
|
||||
DbRef *ref;
|
||||
|
@ -555,14 +552,14 @@ UserAccessTokenSave(Db * db, UserAccessToken * token)
|
|||
|
||||
if (!token)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
ref = DbCreate(db, 3, "tokens", "access", token->string);
|
||||
|
||||
if (!ref)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
json = DbJson(ref);
|
||||
|
@ -570,9 +567,9 @@ UserAccessTokenSave(Db * db, UserAccessToken * token)
|
|||
HashMapSet(json, "user", JsonValueString(token->user));
|
||||
HashMapSet(json, "device", JsonValueString(token->deviceId));
|
||||
|
||||
if (Int64Neq(token->lifetime, Int64Create(0, 0)))
|
||||
if (token->lifetime)
|
||||
{
|
||||
HashMapSet(json, "expires", JsonValueInteger(UInt64Add(UtilServerTs(), token->lifetime)));
|
||||
HashMapSet(json, "expires", JsonValueInteger(UtilTsMillis() + token->lifetime));
|
||||
}
|
||||
|
||||
return DbUnlock(db, ref);
|
||||
|
@ -592,7 +589,7 @@ UserAccessTokenFree(UserAccessToken * token)
|
|||
Free(token);
|
||||
}
|
||||
|
||||
int
|
||||
bool
|
||||
UserDeleteToken(User * user, char *token)
|
||||
{
|
||||
char *username;
|
||||
|
@ -610,14 +607,14 @@ UserDeleteToken(User * user, char *token)
|
|||
|
||||
if (!user || !token)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
db = user->db;
|
||||
/* First check if the token even exists */
|
||||
if (!DbExists(db, 3, "tokens", "access", token))
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If it does, get it's username. */
|
||||
|
@ -625,7 +622,7 @@ UserDeleteToken(User * user, char *token)
|
|||
|
||||
if (!tokenRef)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
tokenJson = DbJson(tokenRef);
|
||||
username = JsonValueAsString(HashMapGet(tokenJson, "user"));
|
||||
|
@ -635,7 +632,7 @@ UserDeleteToken(User * user, char *token)
|
|||
{
|
||||
/* Token does not match user, do not delete it */
|
||||
DbUnlock(db, tokenRef);
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
userJson = DbJson(user->ref);
|
||||
|
@ -643,7 +640,7 @@ UserDeleteToken(User * user, char *token)
|
|||
|
||||
if (!deviceObj)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Delete refresh token, if present */
|
||||
|
@ -657,17 +654,17 @@ UserDeleteToken(User * user, char *token)
|
|||
deletedVal = HashMapDelete(deviceObj, deviceId);
|
||||
if (!deletedVal)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
JsonValueFree(deletedVal);
|
||||
|
||||
/* Delete the access token. */
|
||||
if (!DbUnlock(db, tokenRef) || !DbDelete(db, 3, "tokens", "access", token))
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
char *
|
||||
|
@ -699,7 +696,7 @@ UserSetProfile(User * user, char *name, char *val)
|
|||
JsonValueFree(JsonSet(json, JsonValueString(val), 2, "profile", name));
|
||||
}
|
||||
|
||||
int
|
||||
bool
|
||||
UserDeleteTokens(User * user, char *exempt)
|
||||
{
|
||||
HashMap *devices;
|
||||
|
@ -708,13 +705,13 @@ UserDeleteTokens(User * user, char *exempt)
|
|||
|
||||
if (!user)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
devices = JsonValueAsObject(HashMapGet(DbJson(user->ref), "devices"));
|
||||
if (!devices)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
while (HashMapIterate(devices, &deviceId, (void **) &deviceObj))
|
||||
|
@ -741,7 +738,7 @@ UserDeleteTokens(User * user, char *exempt)
|
|||
JsonValueFree(HashMapDelete(devices, deviceId));
|
||||
}
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -755,30 +752,30 @@ UserGetPrivileges(User * user)
|
|||
return UserDecodePrivileges(JsonValueAsArray(HashMapGet(DbJson(user->ref), "privileges")));
|
||||
}
|
||||
|
||||
int
|
||||
bool
|
||||
UserSetPrivileges(User * user, int privileges)
|
||||
{
|
||||
JsonValue *val;
|
||||
|
||||
if (!user)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!privileges)
|
||||
{
|
||||
JsonValueFree(HashMapDelete(DbJson(user->ref), "privileges"));
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
val = JsonValueArray(UserEncodePrivileges(privileges));
|
||||
if (!val)
|
||||
{
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
JsonValueFree(HashMapSet(DbJson(user->ref), "privileges", val));
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#ifndef TELODENDRIA_PARSER_H
|
||||
#define TELODENDRIA_PARSER_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/***
|
||||
* @Nm Parser
|
||||
* @Nd Functions for dealing with grammars found in Matrix
|
||||
|
@ -58,17 +60,17 @@ typedef struct CommonID {
|
|||
* Parses a common identifier, as per the Common Identifier Format as defined
|
||||
* by the [matrix] specification.
|
||||
*/
|
||||
extern int ParseCommonID(char *, CommonID *);
|
||||
extern bool ParseCommonID(char *, CommonID *);
|
||||
|
||||
/**
|
||||
* Parses the server part in a common identifier.
|
||||
*/
|
||||
extern int ParseServerPart(char *, ServerPart *);
|
||||
extern bool ParseServerPart(char *, ServerPart *);
|
||||
|
||||
/**
|
||||
* Checks whenever the string is a valid common ID with the correct sigil.
|
||||
*/
|
||||
extern int ValidCommonID(char *, char);
|
||||
extern bool ValidCommonID(char *, char);
|
||||
|
||||
/**
|
||||
* Frees a CommonID's values. Note that it doesn't free the CommonID itself.
|
||||
|
@ -100,7 +102,7 @@ extern char * ParserRecomposeServerPart(ServerPart);
|
|||
/**
|
||||
* Compares whenever a ServerName is equivalent to a server name string.
|
||||
*/
|
||||
extern int ParserServerNameEquals(ServerPart, char *);
|
||||
extern bool ParserServerNameEquals(ServerPart, char *);
|
||||
|
||||
|
||||
#endif /* TELODENDRIA_PARSER_H */
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
*/
|
||||
|
||||
#include <Cytoplasm/Db.h>
|
||||
#include <Cytoplasm/Int64.h>
|
||||
|
||||
#include <Schema/RegToken.h>
|
||||
|
||||
|
@ -78,7 +77,7 @@ extern RegTokenInfo * RegTokenGetInfo(Db *, char *);
|
|||
* structure will be returned. Otherwise, NULL will be returned.
|
||||
*/
|
||||
extern RegTokenInfo *
|
||||
RegTokenCreate(Db *, char *, char *, UInt64, Int64, int);
|
||||
RegTokenCreate(Db *, char *, char *, uint64_t, int64_t, int);
|
||||
|
||||
/**
|
||||
* Free the memory associated with the registration token. This should
|
||||
|
|
|
@ -39,12 +39,13 @@
|
|||
* users, among many other tasks.
|
||||
*/
|
||||
|
||||
#include <Cytoplasm/Int64.h>
|
||||
#include <Cytoplasm/Db.h>
|
||||
#include <Cytoplasm/Json.h>
|
||||
|
||||
#include <Parser.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* Many functions here operate on an opaque user structure.
|
||||
*/
|
||||
|
@ -77,7 +78,7 @@ typedef struct UserAccessToken
|
|||
char *user;
|
||||
char *string;
|
||||
char *deviceId;
|
||||
Int64 lifetime;
|
||||
uint64_t lifetime;
|
||||
} UserAccessToken;
|
||||
|
||||
/**
|
||||
|
@ -98,7 +99,7 @@ typedef struct UserLoginInfo
|
|||
* the local part is allowed to be. This function is used to ensure
|
||||
* that client-provided Matrix IDs are valid on this server.
|
||||
*/
|
||||
extern int UserValidate(char *, char *);
|
||||
extern bool UserValidate(char *, char *);
|
||||
|
||||
/**
|
||||
* This function behaves just like
|
||||
|
@ -109,13 +110,13 @@ extern int UserValidate(char *, char *);
|
|||
* spec compliant but remain in use since before the new restrictions
|
||||
* were put in place.
|
||||
*/
|
||||
extern int UserHistoricalValidate(char *, char *);
|
||||
extern bool UserHistoricalValidate(char *, char *);
|
||||
|
||||
/**
|
||||
* Determine whether the user identified by the specified localpart
|
||||
* exists in the database.
|
||||
*/
|
||||
extern int UserExists(Db *, char *);
|
||||
extern bool UserExists(Db *, char *);
|
||||
|
||||
/**
|
||||
* Create a new user with the specified localpart and password, in
|
||||
|
@ -146,7 +147,7 @@ extern User * UserAuthenticate(Db *, char *);
|
|||
* .Fn DbUnlock
|
||||
* under the hood.
|
||||
*/
|
||||
extern int UserUnlock(User *);
|
||||
extern bool UserUnlock(User *);
|
||||
|
||||
/**
|
||||
* Log in a user. This function takes the user's password, desired
|
||||
|
@ -179,13 +180,13 @@ extern char * UserGetDeviceId(User *);
|
|||
* does not store passwords in plain text, so this function hashes the
|
||||
* password and checks it against what is stored in the database.
|
||||
*/
|
||||
extern int UserCheckPassword(User *, char *);
|
||||
extern bool UserCheckPassword(User *, char *);
|
||||
|
||||
/**
|
||||
* Reset the given user's password by hashing a plain text password and
|
||||
* storing it in the database.
|
||||
*/
|
||||
extern int UserSetPassword(User *, char *);
|
||||
extern bool UserSetPassword(User *, char *);
|
||||
|
||||
/**
|
||||
* Immediately deactivate the given user account such that it can no
|
||||
|
@ -198,21 +199,21 @@ extern int UserSetPassword(User *, char *);
|
|||
* responsible for deactivating the target user is NULL, then it is
|
||||
* set to the target's own name.
|
||||
*/
|
||||
extern int UserDeactivate(User *, char *, char *);
|
||||
extern bool UserDeactivate(User *, char *, char *);
|
||||
|
||||
/**
|
||||
* Reactivates the given user account if it has been deactvated with
|
||||
* .Fn UserDeactivate ,
|
||||
* otherwise, it simply doesn't do anything.
|
||||
*/
|
||||
extern int UserReactivate(User *);
|
||||
extern bool UserReactivate(User *);
|
||||
|
||||
/**
|
||||
* Return a boolean value indicating whether or not the user was
|
||||
* deactivated using
|
||||
* .Fn UserDeactivate .
|
||||
*/
|
||||
extern int UserDeactivated(User *);
|
||||
extern bool UserDeactivated(User *);
|
||||
|
||||
/**
|
||||
* Fetches the devices that belong to the user, in JSON format,
|
||||
|
@ -233,7 +234,7 @@ extern UserAccessToken * UserAccessTokenGenerate(User *, char *, int);
|
|||
* Write the specified access token to the database, returning a
|
||||
* boolean value indicating success.
|
||||
*/
|
||||
extern int UserAccessTokenSave(Db *, UserAccessToken *);
|
||||
extern bool UserAccessTokenSave(Db *, UserAccessToken *);
|
||||
|
||||
/**
|
||||
* Free the memory associated with the given access token.
|
||||
|
@ -243,7 +244,7 @@ extern void UserAccessTokenFree(UserAccessToken *);
|
|||
/**
|
||||
* Delete a specific access token by name.
|
||||
*/
|
||||
extern int UserDeleteToken(User *, char *);
|
||||
extern bool UserDeleteToken(User *, char *);
|
||||
|
||||
/**
|
||||
* Get a string property from the user's profile given the specified
|
||||
|
@ -262,7 +263,7 @@ extern void UserSetProfile(User *, char *, char *);
|
|||
* except for the one provided by name, unless NULL is provided for
|
||||
* the name.
|
||||
*/
|
||||
extern int UserDeleteTokens(User *, char *);
|
||||
extern bool UserDeleteTokens(User *, char *);
|
||||
|
||||
/**
|
||||
* Get the current privileges of the user as a packed bit field. Use
|
||||
|
@ -274,7 +275,7 @@ extern int UserGetPrivileges(User *);
|
|||
/**
|
||||
* Set the privileges of the user.
|
||||
*/
|
||||
extern int UserSetPrivileges(User *, int);
|
||||
extern bool UserSetPrivileges(User *, int);
|
||||
|
||||
/**
|
||||
* Decode the JSON that represents the user privileges into a packed
|
||||
|
|
|
@ -70,41 +70,17 @@ query(char *select, HashMap * json, int canonical)
|
|||
{
|
||||
if (StrEquals(keyName + 1, "length"))
|
||||
{
|
||||
UInt64 len;
|
||||
uint64_t len;
|
||||
|
||||
switch (JsonValueType(val))
|
||||
{
|
||||
case JSON_ARRAY:
|
||||
if (sizeof(size_t) == sizeof(UInt64))
|
||||
{
|
||||
size_t slen = ArraySize(JsonValueAsArray(val));
|
||||
UInt32 high = slen >> 32;
|
||||
UInt32 low = slen;
|
||||
|
||||
len = UInt64Create(high, low);
|
||||
}
|
||||
else
|
||||
{
|
||||
len = UInt64Create(0, ArraySize(JsonValueAsArray(val)));
|
||||
}
|
||||
|
||||
len = ArraySize(JsonValueAsArray(val));
|
||||
val = JsonValueInteger(len);
|
||||
ArrayAdd(cleanUp, val);
|
||||
break;
|
||||
case JSON_STRING:
|
||||
if (sizeof(size_t) == sizeof(UInt64))
|
||||
{
|
||||
size_t slen = strlen(JsonValueAsString(val));
|
||||
UInt32 high = slen >> 32;
|
||||
UInt32 low = slen;
|
||||
|
||||
len = UInt64Create(high, low);
|
||||
}
|
||||
else
|
||||
{
|
||||
len = UInt64Create(0, strlen(JsonValueAsString(val)));
|
||||
}
|
||||
|
||||
len = strlen(JsonValueAsString(val));
|
||||
val = JsonValueInteger(len);
|
||||
ArrayAdd(cleanUp, val);
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue