From 4d055f3688a2e7603a76c67b253afdbb6b454dcc Mon Sep 17 00:00:00 2001 From: LDA Date: Sun, 7 Jul 2024 01:21:51 +0200 Subject: [PATCH] [ADD/WIP] Do leaves right, PLwerk --- src/AS.c | 44 +++++++++++++++++++++++++++ src/XMPPThread.c | 78 ++++++++++++++++++++++++++++++++++++++++++------ src/include/AS.h | 1 + 3 files changed, 114 insertions(+), 9 deletions(-) diff --git a/src/AS.c b/src/AS.c index bc72892..ee012fb 100644 --- a/src/AS.c +++ b/src/AS.c @@ -273,6 +273,50 @@ ASJoin(const ParseeConfig *conf, char *id, char *masquerade) return ret; } void +ASLeave(const ParseeConfig *conf, char *id, char *masquerade) +{ + HttpClientContext *ctx = NULL; + HashMap *json = NULL; + char *path; + if (!conf || !id) + { + return; + } + + if (!masquerade) + { + char *raw = StrConcat(4, + "@", conf->sender_localpart, + ":", conf->homeserver_host + ); + masquerade = HttpUrlEncode(raw); + Free(raw); + } + else + { + masquerade = HttpUrlEncode(masquerade); + } + id = HttpUrlEncode(id); + path = StrConcat(5, + "/_matrix/client/v3/rooms/", id, "/leave?", + "user_id=", masquerade + ); + + ctx = ParseeCreateRequest( + conf, + HTTP_POST, path + ); + Free(path); + json = HashMapCreate(); + ASAuthenticateRequest(conf, ctx); + ParseeSetRequestJSON(ctx, json); + JsonFree(json); + + HttpClientContextFree(ctx); + Free(masquerade); + Free(id); +} +void ASSetState(const ParseeConfig *conf, char *id, char *type, char *key, char *mask, HashMap *state) { HttpClientContext *ctx = NULL; diff --git a/src/XMPPThread.c b/src/XMPPThread.c index ccbe63b..8ab6ada 100644 --- a/src/XMPPThread.c +++ b/src/XMPPThread.c @@ -998,31 +998,87 @@ PresenceStanza(ParseeData *args, XMLElement *stanza) if ((user_info = XMLookForTKV(stanza, "x", "xmlns", MUC_USER_NS))) { XMLElement *item = XMLookForUnique(user_info, "item"); + XMLElement *status = XMLookForUnique(user_info, "status"); +#define IsStatus(code) (status && \ + StrEquals(HashMapGet(status->attrs, "code"), #code)) char *jid = item ? HashMapGet(item->attrs, "jid") : NULL; char *from; char *type = HashMapGet(stanza->attrs, "type"); + char *room = ParseeGetBridgedRoom(args, stanza); + char *decode_from = ParseeLookupJID(oid); + char *from_matrix = ParseeDecodeMXID(decode_from); + char *affiliation = HashMapGet(item->attrs, "affiliation"); + int power_level = 0; + + if (!from_matrix || *from_matrix != '@') + { + Free(from_matrix); + from_matrix = ParseeEncodeJID(args->config, decode_from, false); + } + /* TODO: Use affiliation to set PL */ + if (StrEquals(affiliation, "owner")) + { + power_level = 98; + } + else if (StrEquals(affiliation, "admin")) + { + power_level = 51; + } + else if (StrEquals(affiliation, "member")) + { + power_level = 0; + } + else if (StrEquals(affiliation, "outcast")) + { + power_level = -1; + } + + /* Set the user's PL */ + if (room) + { + HashMap *powers = ASGetPL(args->config, room); + int64_t level = GrabInteger(powers, 2, "users", from_matrix); + + if (powers && level != power_level) + { + HashMap *users = GrabObject(powers, 1, "users"); + JsonValue *val = JsonValueInteger(power_level); + JsonValueFree(HashMapSet(users, + from_matrix, val + )); + ASSetPL(args->config, room, powers); + } + else + { + JsonFree(powers); + } + } if (StrEquals(type, "unavailable")) { /* TODO: Treat as a ban if the role is outcast. * Modify the code to be more accurate later. */ - char *room = ParseeGetBridgedRoom(args, stanza); - char *decode_from = ParseeLookupJID(oid); - char *from_matrix = ParseeDecodeMXID(decode_from); - char *affiliation = HashMapGet(item->attrs, "affiliation"); - if (StrEquals(affiliation, "outcast")) + /* If not an MXID, use the Parsee user */ + + if (IsStatus(301)) { ASBan(args->config, room, from_matrix); } - else + else if (IsStatus(307)) { ASKick(args->config, room, from_matrix); } + else if (IsStatus(303)) + { + /* TODO: This is a nick change. */ + Log(LOG_WARNING, "Nick change not implemented."); + } + else + { + ASLeave(args->config, room, from_matrix); + } - Free(decode_from); - Free(from_matrix); - Free(room); } if (jid) @@ -1030,7 +1086,11 @@ PresenceStanza(ParseeData *args, XMLElement *stanza) ParseePushJIDTable(oid, jid); } from = StrConcat(2, "parsee@", args->config->component_host); + Free(from); + Free(decode_from); + Free(from_matrix); + Free(room); } else if (vc) { diff --git a/src/include/AS.h b/src/include/AS.h index bbfef07..069d3ad 100644 --- a/src/include/AS.h +++ b/src/include/AS.h @@ -29,6 +29,7 @@ extern char * ASJoin(const ParseeConfig *, char *, char *); /* Bans from a room a specific user */ extern void ASBan(const ParseeConfig *, char *, char *); extern void ASKick(const ParseeConfig *, char *, char *); +extern void ASLeave(const ParseeConfig *, char *, char *); /* Invites from a room a specific user */ extern void ASInvite(const ParseeConfig *, char *, char *);