From 46489b50e60b54abcafdfc13e2c42762795e39bf Mon Sep 17 00:00:00 2001 From: LDA Date: Fri, 28 Jun 2024 13:11:33 +0200 Subject: [PATCH] [ADD/WIP] Basic moderation You now can ban people, yoohoo! --- src/AS.c | 35 ++++++++++++++ src/MatrixEventHandler.c | 102 ++++++++++++++++++++++++++++++++++++--- src/Parsee/Config.c | 6 +++ src/include/AS.h | 3 ++ src/include/Parsee.h | 4 ++ 5 files changed, 142 insertions(+), 8 deletions(-) diff --git a/src/AS.c b/src/AS.c index 9106d8c..5cf82bb 100644 --- a/src/AS.c +++ b/src/AS.c @@ -118,6 +118,41 @@ ASPing(const ParseeConfig *conf) JsonFree(json); } void +ASBan(const ParseeConfig *conf, char *id, char *banned) +{ + HttpClientContext *ctx = NULL; + HashMap *json = NULL; + char *path, *bridge; + if (!conf || !id || !banned) + { + return; + } + + bridge = StrConcat(4, + "@", conf->sender_localpart, + ":", conf->homeserver_host + ); + path = StrConcat(5, + "/_matrix/client/v3/rooms/", id, "/ban", + "?user_id=", bridge + ); + Free(bridge); + + ctx = ParseeCreateRequest( + conf, + HTTP_POST, path + ); + Free(path); + json = HashMapCreate(); + HashMapSet(json, "user_id", JsonValueString(banned)); + HashMapSet(json, "reason", JsonValueString("Parsee felt jealous.")); + ASAuthenticateRequest(conf, ctx); + ParseeSetRequestJSON(ctx, json); + + HttpClientContextFree(ctx); + JsonFree(json); +} +void ASJoin(const ParseeConfig *conf, char *id, char *masquerade) { HttpClientContext *ctx = NULL; diff --git a/src/MatrixEventHandler.c b/src/MatrixEventHandler.c index 051d732..4b9e758 100644 --- a/src/MatrixEventHandler.c +++ b/src/MatrixEventHandler.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -17,6 +18,7 @@ ParseeMemberHandler(ParseeData *data, HashMap *event) char *room_id = GrabString(event, 1, "room_id"); char *sender = GrabString(event, 1, "sender"); char *chat_id; + char *local = data->config->sender_localpart; const ParseeConfig *conf = data->config; if (StrEquals(membership, "invite") && ParseeIsPuppet(conf, state_key)) @@ -24,13 +26,14 @@ ParseeMemberHandler(ParseeData *data, HashMap *event) DbRef *ref; HashMap *json; char *jid; + bool bot = !strncmp(sender + 1, local, strlen(local)); ASJoin(conf, room_id, state_key); jid = ParseeDecodeLocalJID(conf, state_key); ref = DbCreate(data->db, 3, "rooms", room_id, "data"); json = DbJson(ref); - HashMapSet(json, "is_direct", JsonValueBoolean(true)); + HashMapSet(json, "is_direct", JsonValueBoolean(!bot)); HashMapSet(json, "xmpp_user", JsonValueString(jid)); DbUnlock(data->db, ref); @@ -59,6 +62,74 @@ ParseeMemberHandler(ParseeData *data, HashMap *event) } } static void +ParseeBotHandler(ParseeData *data, HashMap *event) +{ + char *msgtype = GrabString(event, 2, "content", "msgtype"); + char *body = GrabString(event, 2, "content", "body"); + char *id = GrabString(event, 1, "room_id"); + char *ev_id = GrabString(event, 1, "event_id"); + char *sender = GrabString(event, 1, "sender"); + char *profile = StrConcat(4, + "@", data->config->sender_localpart, + ":", data->config->homeserver_host + ); + + if (StrEquals(msgtype, "m.notice")) + { + Free(profile); + return; + } + + if (*body != '!') + { + /* All commands are to be marked with a ! */ + Free(ASSend( + data->config, id, profile, + "m.room.message", + MatrixCreateNotice("Please enter a valid command") + )); + Free(profile); + return; + } + + /* TODO: Make an improvment. This is the bare minimum */ + if (!StrEquals(sender, data->config->matrix_admin)) + { + Free(ASSend( + data->config, id, profile, + "m.room.message", + MatrixCreateNotice("You are not the admin") + )); + Free(profile); + return; + } + body++; +#define BAN_USER "ban-user " + if (!strncmp(body, BAN_USER, strlen(BAN_USER))) + { + char user[256] = { 0 }; + char room[256] = { 0 }; + char *msg; + + body += strlen(BAN_USER); + if (sscanf(body, "%255s %255s", &user, &room) != 2) + { + goto end; + } + ASBan(data->config, room, user); + + msg = StrConcat(3, "Banning '", user, "'..."); + Free(ASSend( + data->config, id, profile, + "m.room.message", + MatrixCreateNotice(msg) + )); + Free(msg); + } +end: + Free(profile); +} +static void ParseeMessageHandler(ParseeData *data, HashMap *event) { XMPPComponent *jabber = data->jabber; @@ -73,21 +144,36 @@ ParseeMessageHandler(ParseeData *data, HashMap *event) char *chat_id, *muc_id, *jid; char *reply_id = MatrixGetReply(event); char *xepd = ParseeXMPPify(event); + char *cmd_lp = data->config->sender_localpart; bool direct = false; - if (ParseeIsPuppet(data->config, sender)) - { - Free(reply_id); - Free(xepd); - return; - } + chat_id = ParseeGetFromRoomID(data, id); ref = DbLock(data->db, 3, "rooms", id, "data"); json = DbJson(ref); direct = JsonValueAsBoolean(HashMapGet(json, "is_direct")); DbUnlock(data->db, ref); + if (ParseeIsPuppet(data->config, sender)) + { + Free(chat_id); + Free(reply_id); + Free(xepd); + return; + } + + if (!direct && !chat_id) + { + ParseeBotHandler(data, event); + + Free(chat_id); + Free(reply_id); + Free(xepd); + return; + } + + if (direct) { char *user = GrabString(json, 1, "xmpp_user"); @@ -95,6 +181,7 @@ ParseeMessageHandler(ParseeData *data, HashMap *event) XMPPSendPlain(jabber, local, user, body, NULL, NULL, NULL, ev_id, NULL); + Free(chat_id); Free(local); Free(reply_id); Free(xepd); @@ -102,7 +189,6 @@ ParseeMessageHandler(ParseeData *data, HashMap *event) } /* Try to find the chat ID */ - chat_id = ParseeGetFromRoomID(data, id); muc_id = ParseeGetMUCID(data, chat_id); if (!chat_id) { diff --git a/src/Parsee/Config.c b/src/Parsee/Config.c index dbf4590..ed333db 100644 --- a/src/Parsee/Config.c +++ b/src/Parsee/Config.c @@ -79,6 +79,9 @@ ParseeConfigLoad(char *conf) CopyToStr(db_path, "db"); + CopyToStr(jabber_admin, "jabber_admin"); + CopyToStr(matrix_admin, "matrix_admin"); + JsonFree(json); StreamClose(stream); } @@ -122,6 +125,9 @@ ParseeConfigFree(void) Free(config->shared_comp_secret); Free(config->db_path); Free(config->homeserver_host); + + Free(config->jabber_admin); + Free(config->matrix_admin); Free(config->as_token); Free(config->hs_token); diff --git a/src/include/AS.h b/src/include/AS.h index 11f21d4..49d9757 100644 --- a/src/include/AS.h +++ b/src/include/AS.h @@ -26,6 +26,9 @@ extern void ASPing(const ParseeConfig *); * as. */ extern void ASJoin(const ParseeConfig *, char *, char *); +/* Bans from a room a specific user */ +extern void ASBan(const ParseeConfig *, char *, char *); + /* Finds an event from a room ID and event ID */ extern HashMap * ASFind(const ParseeConfig *, char *, char *); diff --git a/src/include/Parsee.h b/src/include/Parsee.h index c97b90c..16649f0 100644 --- a/src/include/Parsee.h +++ b/src/include/Parsee.h @@ -34,6 +34,10 @@ typedef struct ParseeConfig { /* ------- DB -------- */ char *db_path; + + /* ------- ADMIN ------- */ + char *jabber_admin; + char *matrix_admin; } ParseeConfig; typedef struct ParseeData {