From f434f7aa875d0f2ba7b09a21ec1636588fe8141b Mon Sep 17 00:00:00 2001 From: LDA Date: Fri, 28 Jun 2024 20:27:35 +0200 Subject: [PATCH] [ADD/WIP] No-fly list for Matrix users Imagine being in Parsee jail. --- src/MatrixEventHandler.c | 53 +++++++++++++++++++++++++++++++++++++++- src/Parsee/Data.c | 51 +++++++++++++++++++++++++++++++++++--- src/XMPPThread.c | 28 +++++++++------------ src/include/Parsee.h | 8 ++++++ 4 files changed, 120 insertions(+), 20 deletions(-) diff --git a/src/MatrixEventHandler.c b/src/MatrixEventHandler.c index 4b9e758..a397eca 100644 --- a/src/MatrixEventHandler.c +++ b/src/MatrixEventHandler.c @@ -105,6 +105,8 @@ ParseeBotHandler(ParseeData *data, HashMap *event) } body++; #define BAN_USER "ban-user " +#define BAN_LIST "ban-list " +#define LS_USERS "ls-flying" if (!strncmp(body, BAN_USER, strlen(BAN_USER))) { char user[256] = { 0 }; @@ -126,6 +128,54 @@ ParseeBotHandler(ParseeData *data, HashMap *event) )); Free(msg); } + else if (!strncmp(body, LS_USERS, strlen(LS_USERS))) + { + DbRef *listed = DbLock(data->db, 1, "global_bans"); + HashMap *json = DbJson(listed); + char *str = NULL, *tmp = NULL, *banned; + JsonValue *val; + + while (HashMapIterate(json, &banned, (void **) &val)) + { + tmp = str; + str = StrConcat(4, str, "- ", banned, "\n"); + Free(tmp); + } + + Free(ASSend( + data->config, id, profile, + "m.room.message", + MatrixCreateNotice("No-fly listed users:") + )); + Free(ASSend( + data->config, id, profile, + "m.room.message", + MatrixCreateNotice(str) + )); + + Free(str); + DbUnlock(data->db, listed); + } + else if (!strncmp(body, BAN_LIST, strlen(BAN_LIST))) + { + char user[256] = { 0 }; + char *msg; + + body += strlen(BAN_USER); + if (sscanf(body, "%255s", &user) != 1) + { + goto end; + } + + msg = StrConcat(3, "Banning '", user, "'..."); + Free(ASSend( + data->config, id, profile, + "m.room.message", + MatrixCreateNotice(msg) + )); + Free(msg); + ParseeGlobalBan(data, user); + } end: Free(profile); } @@ -155,7 +205,8 @@ ParseeMessageHandler(ParseeData *data, HashMap *event) direct = JsonValueAsBoolean(HashMapGet(json, "is_direct")); DbUnlock(data->db, ref); - if (ParseeIsPuppet(data->config, sender)) + if (ParseeIsPuppet(data->config, sender) || + ParseeManageBan(data, sender, id)) { Free(chat_id); Free(reply_id); diff --git a/src/Parsee/Data.c b/src/Parsee/Data.c index 28a7e73..58d9ab1 100644 --- a/src/Parsee/Data.c +++ b/src/Parsee/Data.c @@ -102,9 +102,9 @@ ParseeCleanup(void *datp) } \ while (0) - CleanupField(stanza, 15 MINUTES); - CleanupField(event, 15 MINUTES); - CleanupField(id, 15 MINUTES); + CleanupField(stanza, 1 HOURS); + CleanupField(event, 1 HOURS); + CleanupField(id, 1 HOURS); DbUnlock(data->db, ref); } @@ -516,3 +516,48 @@ end: DbUnlock(data->db, ref); return ret; } +void +ParseeGlobalBan(ParseeData *data, char *user) +{ + DbRef *ref; + HashMap *j; + if (!data || !user) + { + return; + } + + ref = DbLock(data->db, 1, "global_bans"); + if (!ref) + { + ref = DbCreate(data->db, 1, "global_bans"); + } + + j = DbJson(ref); + + JsonValueFree(HashMapSet(j, user, JsonValueObject(HashMapCreate()))); + + DbUnlock(data->db, ref); +} +bool +ParseeManageBan(ParseeData *data, char *user, char *room) +{ + DbRef *ref; + HashMap *j; + bool banned; + if (!data || !user) + { + return false; + } + + ref = DbLock(data->db, 1, "global_bans"); + j = DbJson(ref); + banned = !!HashMapGet(j, user); + DbUnlock(data->db, ref); + + if (banned && room) + { + ASBan(data->config, room, user); + } + + return banned; +} diff --git a/src/XMPPThread.c b/src/XMPPThread.c index fdcf41f..2eaea67 100644 --- a/src/XMPPThread.c +++ b/src/XMPPThread.c @@ -12,6 +12,16 @@ #include #include +#define IQ_ADVERT \ + AdvertiseSimple("http://jabber.org/protocol/chatstates") \ + AdvertiseSimple("urn:xmpp:message-correct:0") \ + AdvertiseSimple("urn:xmpp:reactions:0") \ + AdvertiseSimple("urn:xmpp:styling:0") \ + AdvertiseSimple("urn:xmpp:reply:0") \ + AdvertiseSimple("urn:xmpp:sid:0") \ + AdvertiseSimple("jabber:x:oob") \ + AdvertiseSimple("urn:parsee:x-parsee:0") \ + AdvertiseSimple("urn:parsee:jealousy:0") static pthread_mutex_t cond_var_lock = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t cond_var = PTHREAD_COND_INITIALIZER; @@ -59,7 +69,6 @@ MessageStanza(ParseeData *args, XMLElement *stanza) room = ParseeFindDMRoom(args, to, from); data = ArrayGet(body->children, 0); - /* TODO: Consider having rich messages. */ chat_id = ParseeGetFromMUCID(args, from); mroom_id = ParseeGetRoomID(args, chat_id); if (room) @@ -76,7 +85,6 @@ MessageStanza(ParseeData *args, XMLElement *stanza) char *event_id = NULL; char *replaced = XMPPGetReplacedID(stanza); - /* TODO: Create smarter puppet names */ if (ParseeVerifyStanza(args, chat_id, s_id_str) && !replaced) { XMLElement *oob, *oob_data; @@ -203,18 +211,10 @@ IQDiscoGet(ParseeData *args, XMPPComponent *jabber, XMLElement *stanza) XMLAddAttr(feature, "var", f); \ XMLAddChild(query, feature); \ } \ - while (0) + while (0); - AdvertiseSimple("urn:xmpp:message-correct:0"); - AdvertiseSimple("urn:xmpp:reactions:0"); - AdvertiseSimple("urn:xmpp:styling:0"); - AdvertiseSimple("urn:xmpp:reply:0"); - AdvertiseSimple("urn:xmpp:sid:0"); - AdvertiseSimple("jabber:x:oob"); - - AdvertiseSimple("urn:parsee:x-parsee:0"); - AdvertiseSimple("urn:parsee:jealousy:0"); /* TODO: Advertise more things */ + IQ_ADVERT #undef AdvertiseSimple } XMLAddChild(iq_reply, query); @@ -271,10 +271,6 @@ PresenceStanza(ParseeData *args, XMLElement *stanza) { ParseePushJIDTable(oid, jid); } - /* TODO: Make proper mapping in some sort of soft-DB. - * I am saying soft-DB, because this does not need to be - * stored inside the actual database, as we retrieve it at - * startup everytime from the service anyways. */ } #undef MUC_USER_NS } diff --git a/src/include/Parsee.h b/src/include/Parsee.h index 16649f0..89bee51 100644 --- a/src/include/Parsee.h +++ b/src/include/Parsee.h @@ -184,4 +184,12 @@ extern void ParseeInitialiseJIDTable(void); extern void ParseePushJIDTable(char *muc, char *bare); extern char *ParseeLookupJID(char *muc); extern void ParseeDestroyJIDTable(void); + +/* Globally bans a Matrix user from ever interacting with Parsee, and bans + * them from bridged rooms where the bot has administrator. */ +extern void ParseeGlobalBan(ParseeData *, char *user); + +/* Verifies if a user was globally banned. If so, then apply actions to the + * room ID */ +extern bool ParseeManageBan(ParseeData *, char *user, char *room); #endif