From e21785afcb4d36736f4a1632bdfc1dadff1212ce Mon Sep 17 00:00:00 2001 From: LDA Date: Fri, 28 Jun 2024 11:09:21 +0200 Subject: [PATCH] [ADD] Bare JIDs, use room nicks --- XEPS-TBD.TXT | 16 ++++++--- src/AS.c | 30 +++++++++++++++-- src/Main.c | 4 +++ src/MatrixEventHandler.c | 4 +-- src/Parsee/JIDTable.c | 71 ++++++++++++++++++++++++++++++++++++++++ src/Parsee/User.c | 4 --- src/XMPPThread.c | 32 ++++++++++++++++-- src/include/Parsee.h | 6 ++++ 8 files changed, 151 insertions(+), 16 deletions(-) create mode 100644 src/Parsee/JIDTable.c diff --git a/XEPS-TBD.TXT b/XEPS-TBD.TXT index dfcdf4d..ac7ac08 100644 --- a/XEPS-TBD.TXT +++ b/XEPS-TBD.TXT @@ -1,20 +1,26 @@ XEPs current supported are in src/XMPPThread.c, at the IQ disco advertising. -For future XEPs: +Somewhat implemented XEPs: ~ https://xmpp.org/extensions/xep-0444.html This allows reactions, which Matrix also has support to. The two systems don't seem *too* restrictive on one-another (unlike some - IM platforms I won't mention), so this doesn't sound too bad. - HALF-IMPLEMENTED + IM platforms I won't mention), so this doesn't sound too bad to do + HALF-IMPLEMENTED: Removing stickers won't work. + +For future XEPs: - https://xmpp.org/extensions/xep-0118.html Informations on what a user is listening to. Matrix doesn't have good support for status, to be frank. Clients (including KappaChat) should consider having more support for those, rather than it being - stuck as a FluffyChat/Nheko feature. - If any client devs hear this, please consider adding these, + stuck as a FluffyChat/Nheko feature for the good of the entire federation. + As such, if _any_ client devs hear this, please consider adding these, (especially if you're a smElement employee!) - https://xmpp.org/extensions/xep-0084.html Avatar support would be extremely useful, if just a QoL improvment. Matrix and XMPP both have support for these. + + - https://xmpp.org/extensions/xep-0449.html + Stickers are great. Matrix and XMPP somewhat has support for them, so + might be a nice-to-have, and also to push over XMPP support. diff --git a/src/AS.c b/src/AS.c index ee94fc8..9106d8c 100644 --- a/src/AS.c +++ b/src/AS.c @@ -326,6 +326,7 @@ ASGetName(const ParseeConfig *c, char *room, char *user) HttpClientContext *ctx; HashMap *reply; char *path, *ret; + char *u2 = user; if (!c || !user) { return NULL; @@ -354,12 +355,37 @@ ASGetName(const ParseeConfig *c, char *room, char *user) if (!ret) { - ret = StrDuplicate(user); + ret = StrDuplicate(u2); } return ret; } + user = HttpUrlEncode(user); + room = HttpUrlEncode(room); + path = StrConcat(4, + "/_matrix/client/v3/rooms/", room, + "/state/m.room.member/", user + ); + ctx = ParseeCreateRequest(c, HTTP_GET, path); + Free(user); + Free(room); + ASAuthenticateRequest(c, ctx); + HttpRequestSendHeaders(ctx); + HttpRequestSend(ctx); - return NULL; + reply = JsonDecode(HttpClientStream(ctx)); + + ret = StrDuplicate( + JsonValueAsString(HashMapGet(reply, "displayname")) + ); + HttpClientContextFree(ctx); + JsonFree(reply); + Free(path); + + if (!ret) + { + ret = StrDuplicate(u2); + } + return ret; } char * ASUpload(const ParseeConfig *c, Stream *from, unsigned int size) diff --git a/src/Main.c b/src/Main.c index 850092b..dd14916 100644 --- a/src/Main.c +++ b/src/Main.c @@ -63,6 +63,9 @@ Main(void) goto end; } } + + Log(LOG_NOTICE, "Creating JID table..."); + ParseeInitialiseJIDTable(); Log(LOG_NOTICE, "Setting up local Matrix user..."); ASRegisterUser(parsee_conf, parsee_conf->sender_localpart); @@ -111,5 +114,6 @@ end: CronStop(cron); CronFree(cron); ParseeFreeData(conf.handlerArgs); + ParseeDestroyJIDTable(); return 0; } diff --git a/src/MatrixEventHandler.c b/src/MatrixEventHandler.c index 3475a7d..051d732 100644 --- a/src/MatrixEventHandler.c +++ b/src/MatrixEventHandler.c @@ -113,8 +113,8 @@ ParseeMessageHandler(ParseeData *data, HashMap *event) jid = ParseeEncodeMXID(sender); { /* TODO: Check the name's validity */ - char *name = ASGetName(data->config, NULL, sender); - char *rev = StrConcat(3, muc_id, "/", name); + char *name = ASGetName(data->config, id, sender); + char *rev = StrConcat(4, muc_id, "/", name, "[p]"); char *stanza = NULL, *sender = NULL; char *url = GrabString(event, 2, "content", "url"); char *unauth = ParseeToUnauth(data, url); diff --git a/src/Parsee/JIDTable.c b/src/Parsee/JIDTable.c new file mode 100644 index 0000000..765b1d6 --- /dev/null +++ b/src/Parsee/JIDTable.c @@ -0,0 +1,71 @@ +#include + +#include +#include +#include +#include + +static pthread_mutex_t lock; +static HashMap *jid_table = NULL; + +void +ParseeInitialiseJIDTable(void) +{ + if (jid_table) + { + return; + } + pthread_mutex_init(&lock, NULL); + pthread_mutex_lock(&lock); + jid_table = HashMapCreate(); + pthread_mutex_unlock(&lock); +} +void +ParseePushJIDTable(char *muc, char *bare) +{ + if (!muc || !bare || !jid_table) + { + return; + } + pthread_mutex_lock(&lock); + bare = ParseeTrimJID(bare); + Free(HashMapSet(jid_table, muc, bare)); + pthread_mutex_unlock(&lock); +} +char * +ParseeLookupJID(char *muc) +{ + char *bare; + if (!muc || !jid_table) + { + return NULL; + } + pthread_mutex_lock(&lock); + bare = StrDuplicate(HashMapGet(jid_table, muc)); + pthread_mutex_unlock(&lock); + + if (!bare) + { + bare = StrDuplicate(muc); + } + return bare; +} +void +ParseeDestroyJIDTable(void) +{ + char *key; + void *val; + if (!jid_table) + { + return; + } + pthread_mutex_lock(&lock); + while (HashMapIterate(jid_table, &key, &val)) + { + Free(val); + } + HashMapFree(jid_table); + jid_table = NULL; + pthread_mutex_unlock(&lock); + pthread_mutex_destroy(&lock); +} diff --git a/src/Parsee/User.c b/src/Parsee/User.c index 259ba07..2390217 100644 --- a/src/Parsee/User.c +++ b/src/Parsee/User.c @@ -576,7 +576,6 @@ ParseeGetStanzaInfo(ParseeData *data, char *chat_id, char *ev, char **st, char * bool ret = false; if (!data || !chat_id || !ev || !st || !se) { - Log(LOG_INFO, "%p %p %p %p %p", data, chat_id, ev, st, se); return false; } @@ -584,7 +583,6 @@ ParseeGetStanzaInfo(ParseeData *data, char *chat_id, char *ev, char **st, char * j = DbJson(ref); if (!ref) { - Log(LOG_INFO, "LF"); goto end; } @@ -592,7 +590,6 @@ ParseeGetStanzaInfo(ParseeData *data, char *chat_id, char *ev, char **st, char * event = JsonValueAsObject(JsonGet(j, 2, "events", ev)); if (!event) { - Log(LOG_INFO, "EF %s", ev); goto end; } *st = StrDuplicate(JsonValueAsString(HashMapGet(event, "stanza"))); @@ -618,7 +615,6 @@ ParseeToUnauth(ParseeData *data, char *mxc) url = UriParse(mxc); if (!url) { - Log(LOG_ERR, "cant parse %s", mxc); return NULL; } if (!StrEquals(url->proto, "mxc")) diff --git a/src/XMPPThread.c b/src/XMPPThread.c index 7eb6ef9..fdcf41f 100644 --- a/src/XMPPThread.c +++ b/src/XMPPThread.c @@ -42,7 +42,7 @@ MessageStanza(ParseeData *args, XMLElement *stanza) XMLElement *body = NULL; XMLElement *data = NULL; - char *to, *room, *from, *from_matrix; + char *to, *room, *from, *from_matrix, *decode_from; char *chat_id, *mroom_id; size_t i; body = XMLookForUnique(stanza, "body"); @@ -54,7 +54,8 @@ MessageStanza(ParseeData *args, XMLElement *stanza) to = ParseeDecodeMXID(HashMapGet(stanza->attrs, "to")); from = HashMapGet(stanza->attrs, "from"); - from_matrix = ParseeEncodeJID(args->config, from, true); + decode_from = ParseeLookupJID(from); + from_matrix = ParseeEncodeJID(args->config, decode_from, true); room = ParseeFindDMRoom(args, to, from); data = ArrayGet(body->children, 0); @@ -68,7 +69,7 @@ MessageStanza(ParseeData *args, XMLElement *stanza) if (mroom_id && !XMPPIsParseeStanza(stanza)) { char *res = ParseeGetResource(from); - char *encoded = ParseeEncodeJID(args->config, from, false); + char *encoded = ParseeEncodeJID(args->config, decode_from, false); char *s_id_str = XMPPGetStanzaID(stanza); char *o_id_str = XMPPGetOriginID(stanza); char *id_str = HashMapGet(stanza->attrs, "id"); @@ -167,6 +168,7 @@ MessageStanza(ParseeData *args, XMLElement *stanza) Free(chat_id); Free(mroom_id); Free(from_matrix); + Free(decode_from); Free(room); Free(to); @@ -254,6 +256,29 @@ IQStanza(ParseeData *args, XMLElement *stanza) #undef OnType } +static void +PresenceStanza(ParseeData *args, XMLElement *stanza) +{ +#define MUC_USER_NS "http://jabber.org/protocol/muc#user" + XMLElement *user_info; + if ((user_info = XMLookForTKV(stanza, "x", "xmlns", MUC_USER_NS))) + { + XMLElement *item = XMLookForUnique(user_info, "item"); + char *jid = item ? HashMapGet(item->attrs, "jid") : NULL; + char *oid = HashMapGet(stanza->attrs, "from"); + + if (jid) + { + 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 +} + void * ParseeXMPPThread(void *argp) { @@ -274,6 +299,7 @@ ParseeXMPPThread(void *argp) if (StrEquals(stanza->name, "presence")) { /* TODO: Manage presence */ + PresenceStanza(args, stanza); XMLFreeElement(stanza); continue; } diff --git a/src/include/Parsee.h b/src/include/Parsee.h index 0953a21..c97b90c 100644 --- a/src/include/Parsee.h +++ b/src/include/Parsee.h @@ -173,5 +173,11 @@ extern char * ParseeXMPPify(HashMap *event); extern char * ParseeEventFromID(ParseeData *d, char *c_id, char *ori_id); extern char * ParseeEventFromSID(ParseeData *d, char *c_id, char *ori_id); +/* Gets a Parsee "shim" link to an MXC, usable as unauth for a limited time */ extern char * ParseeToUnauth(ParseeData *data, char *mxc); + +extern void ParseeInitialiseJIDTable(void); +extern void ParseePushJIDTable(char *muc, char *bare); +extern char *ParseeLookupJID(char *muc); +extern void ParseeDestroyJIDTable(void); #endif