[MOD/ADD] Use glob-like system for admins.

This commit is contained in:
LDA 2024-07-06 02:16:52 +02:00
commit 95aaa0dbc9
10 changed files with 154 additions and 13 deletions

49
src/Commands/Admin.c Normal file
View file

@ -0,0 +1,49 @@
#include <Routes.h>
#include <Cytoplasm/Cytoplasm.h>
#include <Cytoplasm/Memory.h>
#include <Cytoplasm/Str.h>
#include <Matrix.h>
#include <Bot.h>
#include <AS.h>
CommandHead(CmdAdmin, cmd, argp)
{
ParseeCmdArg *args = argp;
ParseeData *data = args->data;
HashMap *event = args->event;
char *glob;
BotInitialise();
BotRequired(glob);
{
DbRef *admins = DbLock(data->db, 1, "admins");
HashMap *json;
Array *list;
bool init = false;
if (!admins)
{
admins = DbCreate(data->db, 1, "admins");
}
json = DbJson(admins);
if (!(list = GrabArray(json, 1, "admins")))
{
list = ArrayCreate();
init = true;
}
ArrayAdd(list, JsonValueString(glob));
if (init)
{
HashMapSet(json, "admins", JsonValueArray(list));
}
DbUnlock(data->db, admins);
}
ReplySprintf("Added glob '%s'", glob);
end:
BotDestroy();
}

51
src/Glob.c Normal file
View file

@ -0,0 +1,51 @@
#include <Glob.h>
#include <Cytoplasm/Str.h>
#include <string.h>
bool
GlobMatches(char *rule, char *string)
{
char c1, c2;
if (!rule || !string)
{
return false;
}
while ((c1 = *rule))
{
char next = *(rule + 1);
c2 = *string;
switch (c1)
{
case '*':
/* TODO */
while ((c2 = *string) && (c2 != next))
{
string++;
}
if (next && !c2)
{
return false;
}
break;
case '?':
if (!c2)
{
return false;
}
string++;
break;
default:
if (c1 != c2)
{
return false;
}
string++;
break;
}
rule++;
}
return !*string;
}

View file

@ -13,6 +13,7 @@
#include <StringStream.h>
#include <Parsee.h>
#include <XMPP.h>
#include <Glob.h>
#include <XML.h>
#include <AS.h>

View file

@ -96,12 +96,12 @@ ParseeBotHandler(ParseeData *data, HashMap *event)
}
/* TODO: Make an improvment. This is the bare minimum */
if (!StrEquals(sender, data->config->matrix_admin))
if (!ParseeIsAdmin(data, sender))
{
Free(ASSend(
data->config, id, profile,
"m.room.message",
MatrixCreateNotice("You are not the admin")
MatrixCreateNotice("You are not authorised to do this.")
));
Free(profile);
return;

View file

@ -79,9 +79,6 @@ ParseeConfigLoad(char *conf)
CopyToStr(db_path, "db");
CopyToStr(jabber_admin, "jabber_admin");
CopyToStr(matrix_admin, "matrix_admin");
JsonFree(json);
StreamClose(stream);
}
@ -126,9 +123,6 @@ ParseeConfigFree(void)
Free(config->db_path);
Free(config->homeserver_host);
Free(config->jabber_admin);
Free(config->matrix_admin);
Free(config->as_token);
Free(config->hs_token);
Free(config->sender_localpart);

View file

@ -716,3 +716,34 @@ ParseeToUnauth(ParseeData *data, char *mxc)
UriFree(url);
return ret;
}
#include <Glob.h>
bool
ParseeIsAdmin(ParseeData *data, char *user)
{
DbRef *admins;
HashMap *json;
Array *values;
size_t i;
bool ret = false;
if (!data || !user)
{
return false;
}
admins = DbLock(data->db, 1, "admins");
json = DbJson(admins);
values = GrabArray(json, 1, "admins");
for (i = 0; i < ArraySize(values); i++)
{
char *glob = JsonValueAsString(ArrayGet(values, i));
if ((ret = GlobMatches(glob, user)))
{
break;
}
}
DbUnlock(data->db, admins);
return ret;
}

View file

@ -19,6 +19,7 @@
if (!prop) \
{ \
ReplyBasic("Field `" #prop "` REQUIRED."); \
goto end; \
}
#define BotDestroy() Free(profile)

10
src/include/Glob.h Normal file
View file

@ -0,0 +1,10 @@
#ifndef PARSEE_GLOB_H
#define PARSEE_GLOB_H
#include <stdbool.h>
/* Verifies if a string matches a rule, as specified in
* https://spec.matrix.org/v1.11/appendices/#glob-style-matching. */
extern bool GlobMatches(char *rule, char *string);
#endif

View file

@ -35,10 +35,6 @@ typedef struct ParseeConfig {
/* ------- DB -------- */
char *db_path;
/* ------- ADMIN ------- */
char *jabber_admin;
char *matrix_admin;
} ParseeConfig;
typedef struct ParseeData {
@ -217,4 +213,8 @@ extern bool ParseeManageBan(ParseeData *, char *user, char *room);
/* Same as ParseeVerifyStanza, but DMs */
extern bool ParseeVerifyDMStanza(ParseeData *data, char *room_id, char *id);
/* Checks if any user is an admin */
extern bool ParseeIsAdmin(ParseeData *data, char *user);
#endif

View file

@ -42,7 +42,7 @@ typedef struct ParseeCmdArg {
) \
X_COMMAND( \
"plumb-muc", CmdPlumb, \
"Plumbs an existing Matrix room to a MUC." \
"Plumbs an existing Matrix room to a MUC. " \
"You'll need to give the Parsee bot enough " \
"privileges, however. " \
) \
@ -50,6 +50,10 @@ typedef struct ParseeCmdArg {
"help", CmdHelp, \
"Shows the command list" \
) \
X_COMMAND( \
"adminify", CmdAdmin, \
"Adminifies a Matrix glob pattern." \
) \
X_COMMAND( \
"stats", CmdStats, \
"Shows some Parsee statistics." \