Begin implementing user privileges.
This commit is contained in:
parent
768ecda41a
commit
4ee66ae3c7
6 changed files with 169 additions and 4 deletions
|
@ -1,4 +1,4 @@
|
|||
.Dd $Mdocdate: March 4 2023 $
|
||||
.Dd $Mdocdate: April 16 2023 $
|
||||
.Dt ADMIN 7
|
||||
.Os Telodendria Project
|
||||
.Sh NAME
|
||||
|
@ -49,6 +49,11 @@ endpoint.
|
|||
.It Dv ISSUE_TOKENS
|
||||
This allows users to create, modify and delete registration
|
||||
tokens.
|
||||
.It Dv CONFIG
|
||||
Users with this privilege can modify Telodendria's configuration.
|
||||
.It Dv GRANT_PRIVILEGES
|
||||
Users with this privilege can modify their own privileges or
|
||||
the privileges of others.
|
||||
.It Dv ALL
|
||||
Users with this privilege can use
|
||||
.Em any
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include <Json.h>
|
||||
#include <Util.h>
|
||||
#include <Str.h>
|
||||
#include <User.h>
|
||||
|
||||
int
|
||||
RegTokenValid(RegTokenInfo * token)
|
||||
|
@ -139,6 +140,9 @@ RegTokenGetInfo(Db * db, char *token)
|
|||
ret->used =
|
||||
JsonValueAsInteger(HashMapGet(tokenJson, "used"));
|
||||
|
||||
ret->grants =
|
||||
UserDecodePrivileges(HashMapGet(tokenJson, "grants"));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -192,7 +196,7 @@ RegTokenVerify(char *token)
|
|||
}
|
||||
|
||||
RegTokenInfo *
|
||||
RegTokenCreate(Db * db, char *name, char *owner, unsigned long expires, int uses)
|
||||
RegTokenCreate(Db * db, char *name, char *owner, unsigned long expires, int uses, int privileges)
|
||||
{
|
||||
RegTokenInfo *ret;
|
||||
HashMap *tokenJson;
|
||||
|
@ -233,6 +237,7 @@ RegTokenCreate(Db * db, char *name, char *owner, unsigned long expires, int uses
|
|||
ret->uses = uses;
|
||||
ret->created = timestamp;
|
||||
ret->expires = expires;
|
||||
ret->grants = privileges;
|
||||
|
||||
/* Write user info to database. */
|
||||
tokenJson = DbJson(ret->ref);
|
||||
|
@ -246,6 +251,7 @@ RegTokenCreate(Db * db, char *name, char *owner, unsigned long expires, int uses
|
|||
JsonValueInteger(ret->used));
|
||||
HashMapSet(tokenJson, "uses",
|
||||
JsonValueInteger(ret->uses));
|
||||
HashMapSet(tokenJson, "grants", UserEncodePrivileges(privileges));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ ROUTE_IMPL(RouteUserProfile, path, argp)
|
|||
strcmp(entry, "avatar_url") == 0)
|
||||
{
|
||||
/* Check if user has privilege to do that action. */
|
||||
if (!strcmp(userId->localpart, UserGetName(user)))
|
||||
if (strcmp(userId->localpart, UserGetName(user)) == 0)
|
||||
{
|
||||
value = JsonValueAsString(HashMapGet(request, entry));
|
||||
/* TODO: Make UserSetProfile notify other
|
||||
|
|
134
src/User.c
134
src/User.c
|
@ -688,6 +688,140 @@ UserDeleteTokens(User * user, char *exempt)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
UserGetPrivileges(User *user)
|
||||
{
|
||||
if (!user)
|
||||
{
|
||||
return USER_NONE;
|
||||
}
|
||||
|
||||
return UserDecodePrivileges(HashMapGet(DbJson(user->ref), "privileges"));
|
||||
}
|
||||
|
||||
int
|
||||
UserSetPrivileges(User *user, int privileges)
|
||||
{
|
||||
JsonValue *val;
|
||||
|
||||
if (!user)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!privileges)
|
||||
{
|
||||
JsonValueFree(HashMapDelete(DbJson(user->ref), "privileges"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
val = UserEncodePrivileges(privileges);
|
||||
if (!val)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
JsonValueFree(HashMapSet(DbJson(user->ref), "privileges", val));
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
UserDecodePrivileges(JsonValue *val)
|
||||
{
|
||||
int privileges = USER_NONE;
|
||||
|
||||
size_t i;
|
||||
Array *arr;
|
||||
|
||||
if (!val)
|
||||
{
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (JsonValueType(val) == JSON_ARRAY)
|
||||
{
|
||||
arr = JsonValueAsArray(val);
|
||||
for (i = 0; i < ArraySize(arr); i++)
|
||||
{
|
||||
val = ArrayGet(arr, i);
|
||||
if (!val || JsonValueType(val) != JSON_STRING)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
privileges |= UserDecodePrivilege(JsonValueAsString(val));
|
||||
}
|
||||
}
|
||||
|
||||
finish:
|
||||
return privileges;
|
||||
}
|
||||
|
||||
int
|
||||
UserDecodePrivilege(const char *p)
|
||||
{
|
||||
if (!p)
|
||||
{
|
||||
return USER_NONE;
|
||||
}
|
||||
else if (strcmp(p, "ALL") == 0)
|
||||
{
|
||||
return USER_ALL;
|
||||
}
|
||||
else if (strcmp(p, "DEACTIVATE") == 0)
|
||||
{
|
||||
return USER_DEACTIVATE;
|
||||
}
|
||||
else if (strcmp(p, "ISSUE_TOKENS") == 0)
|
||||
{
|
||||
return USER_ISSUE_TOKENS;
|
||||
}
|
||||
else if (strcmp(p, "CONFIG") == 0)
|
||||
{
|
||||
return USER_CONFIG;
|
||||
}
|
||||
else if (strcmp(p, "GRANT_PRIVILEGES") == 0)
|
||||
{
|
||||
return USER_GRANT_PRIVILEGES;
|
||||
}
|
||||
else
|
||||
{
|
||||
return USER_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
JsonValue *
|
||||
UserEncodePrivileges(int privileges)
|
||||
{
|
||||
Array *arr = ArrayCreate();
|
||||
if (!arr)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (privileges & USER_ALL)
|
||||
{
|
||||
ArrayAdd(arr, JsonValueString("ALL"));
|
||||
goto finish;
|
||||
}
|
||||
|
||||
#define A(priv, as) \
|
||||
if (privileges & priv) \
|
||||
{ \
|
||||
ArrayAdd(arr, JsonValueString(as)); \
|
||||
}
|
||||
|
||||
A(USER_DEACTIVATE, "DEACTIVATE");
|
||||
A(USER_ISSUE_TOKENS, "ISSUE_TOKENS");
|
||||
A(USER_CONFIG, "CONFIG");
|
||||
A(USER_GRANT_PRIVILEGES, "GRANT_PRIVILEGES");
|
||||
|
||||
#undef A
|
||||
|
||||
finish:
|
||||
return JsonValueArray(arr);
|
||||
}
|
||||
|
||||
UserId *
|
||||
UserIdParse(char *id, char *defaultServer)
|
||||
{
|
||||
|
|
|
@ -40,6 +40,8 @@ typedef struct RegTokenInfo
|
|||
unsigned long created;
|
||||
unsigned long expires;
|
||||
|
||||
int grants; /* privileges */
|
||||
|
||||
} RegTokenInfo;
|
||||
|
||||
|
||||
|
@ -56,7 +58,7 @@ extern RegTokenInfo *
|
|||
RegTokenGetInfo(Db *, char *);
|
||||
|
||||
extern RegTokenInfo *
|
||||
RegTokenCreate(Db *, char *, char *, unsigned long, int);
|
||||
RegTokenCreate(Db *, char *, char *, unsigned long, int, int);
|
||||
|
||||
extern void
|
||||
RegTokenFree(RegTokenInfo *);
|
||||
|
|
|
@ -28,6 +28,14 @@
|
|||
|
||||
#include <Json.h>
|
||||
|
||||
#define USER_DEACTIVATE (1 << 0)
|
||||
#define USER_ISSUE_TOKENS (1 << 1)
|
||||
#define USER_CONFIG (1 << 2)
|
||||
#define USER_GRANT_PRIVILEGES (1 << 3)
|
||||
|
||||
#define USER_NONE 0
|
||||
#define USER_ALL ((1 << 4) - 1)
|
||||
|
||||
typedef struct User User;
|
||||
|
||||
typedef struct UserAccessToken
|
||||
|
@ -113,6 +121,16 @@ extern void
|
|||
extern int
|
||||
UserDeleteTokens(User *, char *);
|
||||
|
||||
extern int UserGetPrivileges(User *);
|
||||
|
||||
extern int UserSetPrivileges(User *, int);
|
||||
|
||||
extern int UserDecodePrivileges(JsonValue *);
|
||||
|
||||
extern JsonValue *UserEncodePrivileges(int);
|
||||
|
||||
extern int UserDecodePrivilege(const char *);
|
||||
|
||||
extern UserId *
|
||||
UserIdParse(char *, char *);
|
||||
|
||||
|
|
Loading…
Reference in a new issue