forked from Telodendria/Telodendria
Apply #64: Registration tokens.
This commit is contained in:
parent
76bfa120ee
commit
ae97d8116c
8 changed files with 495 additions and 15 deletions
10
TODO.txt
10
TODO.txt
|
@ -44,11 +44,11 @@ Milestone: v0.3.0
|
||||||
[ ] /_telodendria/admin/config endpoint
|
[ ] /_telodendria/admin/config endpoint
|
||||||
[ ] Refactor TelodendriaConfig to just Config (ConfigLock() and ConfigUnlock())
|
[ ] Refactor TelodendriaConfig to just Config (ConfigLock() and ConfigUnlock())
|
||||||
|
|
||||||
[ ] Client-Server API
|
[~] Client-Server API
|
||||||
[ ] 4: Token-based user registration
|
[x] 4: Token-based user registration
|
||||||
[ ] Implement user-interactive auth flow
|
[x] Implement user-interactive auth flow
|
||||||
[ ] Token validity endpoint
|
[x] Token validity endpoint
|
||||||
[ ] Add m.login.registration_token to registration endpoint
|
[x] Add m.login.registration_token to registration endpoint
|
||||||
flow
|
flow
|
||||||
- Ensure that registration tokens can be used even if
|
- Ensure that registration tokens can be used even if
|
||||||
registration is disabled.
|
registration is disabled.
|
||||||
|
|
251
src/RegToken.c
Normal file
251
src/RegToken.c
Normal file
|
@ -0,0 +1,251 @@
|
||||||
|
/*
|
||||||
|
* 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 <RegToken.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include <Memory.h>
|
||||||
|
#include <Json.h>
|
||||||
|
#include <Util.h>
|
||||||
|
#include <Str.h>
|
||||||
|
|
||||||
|
int
|
||||||
|
RegTokenValid(RegTokenInfo * token)
|
||||||
|
{
|
||||||
|
HashMap *tokenJson;
|
||||||
|
int uses, used;
|
||||||
|
|
||||||
|
unsigned long expiration;
|
||||||
|
|
||||||
|
if (!token || !RegTokenExists(token->db, token->name))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenJson = DbJson(token->ref);
|
||||||
|
uses = JsonValueAsInteger(HashMapGet(tokenJson, "uses"));
|
||||||
|
used = JsonValueAsInteger(HashMapGet(tokenJson, "used"));
|
||||||
|
expiration = JsonValueAsInteger(HashMapGet(tokenJson, "expires_on"));
|
||||||
|
|
||||||
|
return (!expiration || (UtilServerTs() <= expiration)) &&
|
||||||
|
(uses == -1 || used < uses);
|
||||||
|
}
|
||||||
|
void
|
||||||
|
RegTokenUse(RegTokenInfo * token)
|
||||||
|
{
|
||||||
|
HashMap *tokenJson;
|
||||||
|
|
||||||
|
if (!token || !RegTokenExists(token->db, token->name))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token->uses >= 0 && token->used >= token->uses)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
token->used++;
|
||||||
|
|
||||||
|
/* Write the information to the hashmap */
|
||||||
|
tokenJson = DbJson(token->ref);
|
||||||
|
JsonValueFree(HashMapSet(tokenJson, "used", JsonValueInteger(token->used)));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
RegTokenExists(Db * db, char *token)
|
||||||
|
{
|
||||||
|
if (!token || !db)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return DbExists(db, 3, "tokens", "registration", token);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
RegTokenDelete(RegTokenInfo * token)
|
||||||
|
{
|
||||||
|
if (!token || !RegTokenClose(token))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!DbDelete(token->db, 3, "tokens", "registration", token->name))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Free(token->name);
|
||||||
|
Free(token->owner);
|
||||||
|
Free(token);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegTokenInfo *
|
||||||
|
RegTokenGetInfo(Db * db, char *token)
|
||||||
|
{
|
||||||
|
RegTokenInfo *ret;
|
||||||
|
|
||||||
|
DbRef *tokenRef;
|
||||||
|
HashMap *tokenJson;
|
||||||
|
|
||||||
|
if (!RegTokenExists(db, token))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenRef = DbLock(db, 3, "tokens", "registration", token);
|
||||||
|
if (!tokenRef)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
tokenJson = DbJson(tokenRef);
|
||||||
|
ret = Malloc(sizeof(RegTokenInfo));
|
||||||
|
|
||||||
|
ret->db = db;
|
||||||
|
ret->ref = tokenRef;
|
||||||
|
|
||||||
|
ret->owner =
|
||||||
|
StrDuplicate(JsonValueAsString(HashMapGet(tokenJson, "created_by")));
|
||||||
|
ret->name = StrDuplicate(token);
|
||||||
|
|
||||||
|
ret->expires =
|
||||||
|
JsonValueAsInteger(HashMapGet(tokenJson, "expires_on"));
|
||||||
|
ret->created =
|
||||||
|
JsonValueAsInteger(HashMapGet(tokenJson, "created_on"));
|
||||||
|
|
||||||
|
ret->uses =
|
||||||
|
JsonValueAsInteger(HashMapGet(tokenJson, "uses"));
|
||||||
|
ret->used =
|
||||||
|
JsonValueAsInteger(HashMapGet(tokenJson, "used"));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RegTokenFree(RegTokenInfo * tokeninfo)
|
||||||
|
{
|
||||||
|
if (tokeninfo)
|
||||||
|
{
|
||||||
|
Free(tokeninfo->name);
|
||||||
|
Free(tokeninfo->owner);
|
||||||
|
Free(tokeninfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int
|
||||||
|
RegTokenClose(RegTokenInfo * tokeninfo)
|
||||||
|
{
|
||||||
|
if (!tokeninfo)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return DbUnlock(tokeninfo->db, tokeninfo->ref);
|
||||||
|
}
|
||||||
|
static int
|
||||||
|
RegTokenVerify(char *token)
|
||||||
|
{
|
||||||
|
size_t i, size;
|
||||||
|
char c;
|
||||||
|
|
||||||
|
if (!token)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* The spec says the following: "The token required for this
|
||||||
|
* authentication [...] is an opaque string with maximum length of
|
||||||
|
* 64 characters in the range [A-Za-z0-9._~-]." */
|
||||||
|
if ((size = strlen(token)) > 64)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for (i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
c = token[i];
|
||||||
|
if (!(isalnum(c) || c == '0' || c == '_' || c == '~' || c == '-'))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegTokenInfo *
|
||||||
|
RegTokenCreate(Db * db, char *name, char *owner, unsigned long expires, int uses)
|
||||||
|
{
|
||||||
|
RegTokenInfo *ret;
|
||||||
|
HashMap *tokenJson;
|
||||||
|
|
||||||
|
unsigned long timestamp = UtilServerTs();
|
||||||
|
|
||||||
|
if (!db || !name || !owner)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* -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 (uses < -1)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Verify the token */
|
||||||
|
if (!RegTokenVerify(name) || (expires > 0 && expires < timestamp))
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ret = Malloc(sizeof(RegTokenInfo));
|
||||||
|
/* Set the token's properties */
|
||||||
|
ret->db = db;
|
||||||
|
ret->ref = DbCreate(db, 3, "tokens", "registration", name);
|
||||||
|
if (!ret->ref)
|
||||||
|
{
|
||||||
|
/* RegToken already exists or some weird fs error */
|
||||||
|
Free(ret);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ret->name = StrDuplicate(name);
|
||||||
|
ret->owner = StrDuplicate(owner);
|
||||||
|
ret->used = 0;
|
||||||
|
ret->uses = uses;
|
||||||
|
ret->created = timestamp;
|
||||||
|
ret->expires = expires;
|
||||||
|
|
||||||
|
/* Write user info to database. */
|
||||||
|
tokenJson = DbJson(ret->ref);
|
||||||
|
HashMapSet(tokenJson, "created_by",
|
||||||
|
JsonValueString(ret->owner));
|
||||||
|
HashMapSet(tokenJson, "created_on",
|
||||||
|
JsonValueInteger(ret->created));
|
||||||
|
HashMapSet(tokenJson, "expires_on",
|
||||||
|
JsonValueInteger(ret->expires));
|
||||||
|
HashMapSet(tokenJson, "used",
|
||||||
|
JsonValueInteger(ret->used));
|
||||||
|
HashMapSet(tokenJson, "uses",
|
||||||
|
JsonValueInteger(ret->uses));
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -109,10 +109,50 @@ ROUTE_IMPL(RouteMatrix, args)
|
||||||
Free(pathPart);
|
Free(pathPart);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
else if (MATRIX_PATH_EQUALS(pathPart, "v1"))
|
||||||
|
{
|
||||||
|
/* TODO: This *really* does not look good. */
|
||||||
|
Free(pathPart);
|
||||||
|
pathPart = MATRIX_PATH_POP(args->path);
|
||||||
|
if (MATRIX_PATH_EQUALS(pathPart, "register"))
|
||||||
|
{
|
||||||
|
Free(pathPart);
|
||||||
|
pathPart = MATRIX_PATH_POP(args->path);
|
||||||
|
if (MATRIX_PATH_EQUALS(pathPart, "m.login.registration_token"))
|
||||||
|
{
|
||||||
|
Free(pathPart);
|
||||||
|
pathPart = MATRIX_PATH_POP(args->path);
|
||||||
|
if (MATRIX_PATH_EQUALS(pathPart, "validity"))
|
||||||
|
{
|
||||||
|
Free(pathPart);
|
||||||
|
response = RouteTokenValid(args);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Free(pathPart);
|
Free(pathPart);
|
||||||
HttpResponseStatus(args->context, HTTP_NOT_FOUND);
|
HttpResponseStatus(args->context, HTTP_NOT_FOUND);
|
||||||
return MatrixErrorCreate(M_NOT_FOUND);
|
return MatrixErrorCreate(M_NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Free(pathPart);
|
||||||
|
HttpResponseStatus(args->context, HTTP_NOT_FOUND);
|
||||||
|
return MatrixErrorCreate(M_NOT_FOUND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Free(pathPart);
|
||||||
|
HttpResponseStatus(args->context, HTTP_NOT_FOUND);
|
||||||
|
return MatrixErrorCreate(M_NOT_FOUND);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Free(pathPart);
|
||||||
|
HttpResponseStatus(args->context, HTTP_NOT_FOUND);
|
||||||
|
return MatrixErrorCreate(M_NOT_FOUND);
|
||||||
|
}
|
||||||
|
return response;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,21 @@
|
||||||
#include <User.h>
|
#include <User.h>
|
||||||
#include <Uia.h>
|
#include <Uia.h>
|
||||||
|
|
||||||
|
static Array *
|
||||||
|
RouteRegisterRegFlow(void)
|
||||||
|
{
|
||||||
|
Array *response = ArrayCreate();
|
||||||
|
|
||||||
|
if (!response)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayAdd(response, UiaStageBuild("m.login.registration_token", NULL));
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
ROUTE_IMPL(RouteRegister, args)
|
ROUTE_IMPL(RouteRegister, args)
|
||||||
{
|
{
|
||||||
HashMap *request = NULL;
|
HashMap *request = NULL;
|
||||||
|
@ -73,13 +88,6 @@ ROUTE_IMPL(RouteRegister, args)
|
||||||
return MatrixErrorCreate(M_NOT_JSON);
|
return MatrixErrorCreate(M_NOT_JSON);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(args->matrixArgs->config->flags & TELODENDRIA_REGISTRATION))
|
|
||||||
{
|
|
||||||
HttpResponseStatus(args->context, HTTP_FORBIDDEN);
|
|
||||||
response = MatrixErrorCreate(M_FORBIDDEN);
|
|
||||||
goto finish;
|
|
||||||
}
|
|
||||||
|
|
||||||
val = HashMapGet(request, "username");
|
val = HashMapGet(request, "username");
|
||||||
if (val)
|
if (val)
|
||||||
{
|
{
|
||||||
|
@ -107,9 +115,12 @@ ROUTE_IMPL(RouteRegister, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
uiaFlows = ArrayCreate();
|
uiaFlows = ArrayCreate();
|
||||||
ArrayAdd(uiaFlows, UiaDummyFlow());
|
ArrayAdd(uiaFlows, RouteRegisterRegFlow());
|
||||||
|
|
||||||
/* TODO: Add registration token flow */
|
if (args->matrixArgs->config->flags & TELODENDRIA_REGISTRATION)
|
||||||
|
{
|
||||||
|
ArrayAdd(uiaFlows, UiaDummyFlow());
|
||||||
|
}
|
||||||
|
|
||||||
uiaResult = UiaComplete(uiaFlows, args->context,
|
uiaResult = UiaComplete(uiaFlows, args->context,
|
||||||
args->matrixArgs->db, request, &response,
|
args->matrixArgs->db, request, &response,
|
||||||
|
|
82
src/Routes/RouteTokenValid.c
Normal file
82
src/Routes/RouteTokenValid.c
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
/*
|
||||||
|
* 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 <Routes.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <RegToken.h>
|
||||||
|
#include <Json.h>
|
||||||
|
#include <HashMap.h>
|
||||||
|
#include <Str.h>
|
||||||
|
|
||||||
|
ROUTE_IMPL(RouteTokenValid, args)
|
||||||
|
{
|
||||||
|
Db *db = args->matrixArgs->db;
|
||||||
|
|
||||||
|
HashMap *response = NULL;
|
||||||
|
HashMap *request = NULL;
|
||||||
|
|
||||||
|
RegTokenInfo *info = NULL;
|
||||||
|
|
||||||
|
char *tokenstr;
|
||||||
|
|
||||||
|
if (HttpRequestMethodGet(args->context) != HTTP_GET)
|
||||||
|
{
|
||||||
|
HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
|
||||||
|
return MatrixErrorCreate(M_UNRECOGNIZED);
|
||||||
|
}
|
||||||
|
request = JsonDecode(HttpStream(args->context));
|
||||||
|
if (!request)
|
||||||
|
{
|
||||||
|
HttpResponseStatus(args->context, HTTP_BAD_REQUEST);
|
||||||
|
return MatrixErrorCreate(M_NOT_JSON);
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenstr = JsonValueAsString(HashMapGet(request, "token"));
|
||||||
|
if (!tokenstr || !RegTokenExists(db, tokenstr))
|
||||||
|
{
|
||||||
|
response = HashMapCreate();
|
||||||
|
JsonFree(request);
|
||||||
|
HashMapSet(response, "valid", JsonValueBoolean(0));
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
info = RegTokenGetInfo(db, tokenstr);
|
||||||
|
response = HashMapCreate();
|
||||||
|
if (!RegTokenValid(info))
|
||||||
|
{
|
||||||
|
JsonFree(request);
|
||||||
|
RegTokenClose(info);
|
||||||
|
RegTokenFree(info);
|
||||||
|
HashMapSet(response, "valid", JsonValueBoolean(0));
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegTokenClose(info);
|
||||||
|
RegTokenFree(info);
|
||||||
|
HashMapSet(response, "valid", JsonValueBoolean(1));
|
||||||
|
JsonFree(request);
|
||||||
|
return response;
|
||||||
|
}
|
26
src/Uia.c
26
src/Uia.c
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <RegToken.h>
|
||||||
#include <Memory.h>
|
#include <Memory.h>
|
||||||
#include <Array.h>
|
#include <Array.h>
|
||||||
#include <Json.h>
|
#include <Json.h>
|
||||||
|
@ -390,7 +391,30 @@ UiaComplete(Array * flows, HttpServerContext * context, Db * db,
|
||||||
}
|
}
|
||||||
else if (strcmp(authType, "m.login.registration_token") == 0)
|
else if (strcmp(authType, "m.login.registration_token") == 0)
|
||||||
{
|
{
|
||||||
/* TODO */
|
RegTokenInfo *tokenInfo;
|
||||||
|
|
||||||
|
char *token = JsonValueAsString(HashMapGet(auth, "token"));
|
||||||
|
|
||||||
|
if (!RegTokenExists(db, token))
|
||||||
|
{
|
||||||
|
HttpResponseStatus(context, HTTP_UNAUTHORIZED);
|
||||||
|
ret = BuildResponse(flows, db, response, session, dbRef);
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
tokenInfo = RegTokenGetInfo(db, token);
|
||||||
|
if (!RegTokenValid(tokenInfo))
|
||||||
|
{
|
||||||
|
RegTokenClose(tokenInfo);
|
||||||
|
RegTokenFree(tokenInfo);
|
||||||
|
|
||||||
|
HttpResponseStatus(context, HTTP_UNAUTHORIZED);
|
||||||
|
ret = BuildResponse(flows, db, response, session, dbRef);
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
/* Use the token, and then close it. */
|
||||||
|
RegTokenUse(tokenInfo);
|
||||||
|
RegTokenClose(tokenInfo);
|
||||||
|
RegTokenFree(tokenInfo);
|
||||||
}
|
}
|
||||||
else if (strcmp(authType, "m.login.recaptcha") == 0)
|
else if (strcmp(authType, "m.login.recaptcha") == 0)
|
||||||
{
|
{
|
||||||
|
|
70
src/include/RegToken.h
Normal file
70
src/include/RegToken.h
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
/*
|
||||||
|
* 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_REGTOKEN_H
|
||||||
|
#define TELODENDRIA_REGTOKEN_H
|
||||||
|
|
||||||
|
#include <Db.h>
|
||||||
|
|
||||||
|
typedef struct RegTokenInfo
|
||||||
|
{
|
||||||
|
Db *db;
|
||||||
|
DbRef *ref;
|
||||||
|
|
||||||
|
char *name;
|
||||||
|
char *owner;
|
||||||
|
|
||||||
|
int used;
|
||||||
|
int uses;
|
||||||
|
|
||||||
|
unsigned long created;
|
||||||
|
unsigned long expires;
|
||||||
|
|
||||||
|
} RegTokenInfo;
|
||||||
|
|
||||||
|
|
||||||
|
extern void
|
||||||
|
RegTokenUse(RegTokenInfo *);
|
||||||
|
|
||||||
|
extern int
|
||||||
|
RegTokenExists(Db *, char *);
|
||||||
|
|
||||||
|
extern int
|
||||||
|
RegTokenDelete(RegTokenInfo *);
|
||||||
|
|
||||||
|
extern RegTokenInfo *
|
||||||
|
RegTokenGetInfo(Db *, char *);
|
||||||
|
|
||||||
|
extern RegTokenInfo *
|
||||||
|
RegTokenCreate(Db *, char *, char *, unsigned long, int);
|
||||||
|
|
||||||
|
extern void
|
||||||
|
RegTokenFree(RegTokenInfo *);
|
||||||
|
|
||||||
|
extern int
|
||||||
|
RegTokenValid(RegTokenInfo *);
|
||||||
|
|
||||||
|
extern int
|
||||||
|
RegTokenClose(RegTokenInfo *);
|
||||||
|
|
||||||
|
#endif
|
|
@ -67,6 +67,8 @@ ROUTE(RouteRegister); /* /_matrix/client/(r0|v3)/register */
|
||||||
ROUTE(RouteRefresh); /* /_matrix/client/(r0|v3)/refresh */
|
ROUTE(RouteRefresh); /* /_matrix/client/(r0|v3)/refresh */
|
||||||
ROUTE(RouteWhoami); /* /_matrix/client/(r0|v3)/whoami */
|
ROUTE(RouteWhoami); /* /_matrix/client/(r0|v3)/whoami */
|
||||||
|
|
||||||
|
ROUTE(RouteTokenValid); /* /_matrix/client/v1/register/m.login.registration_token/validity */
|
||||||
|
|
||||||
#undef ROUTE
|
#undef ROUTE
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue