[ADD/WIP] Bridging Matrix redacts

I'll still need to consider making redacts from other people count as
"moderations", whatever that is to Gajim, instead of a "self-redact".

Also, _please_, support it if you _ever_ wish adoption, XMPP users!
This commit is contained in:
LDA 2024-07-08 14:36:52 +02:00
commit 3c26ee6d22
5 changed files with 174 additions and 2 deletions

View file

@ -149,6 +149,77 @@ ParseeBotHandler(ParseeData *data, HashMap *event)
Free(profile);
CommandFree(cmd);
}
static const char *
GetXMPPInformation(ParseeData *data, HashMap *event, char **from, char **to)
{
const char *type = NULL;
char *room_id = GrabString(event, 1, "room_id");
char *matrix_sender = GrabString(event, 1, "sender");
char *chat_id = NULL, *muc_id = NULL;
char *user;
DbRef *room_data;
HashMap *data_json;
XMPPComponent *jabber = data ? data->jabber : NULL;
bool direct = false;
if (!data || !event || !from || !to)
{
return NULL;
}
*from = NULL;
*to = NULL;
chat_id = ParseeGetFromRoomID(data, room_id);
room_data = DbLock(data->db, 3, "rooms", room_id, "data");
data_json = DbJson(room_data);
direct = GrabBoolean(data_json, 1, "is_direct");
type = direct ? "chat" : "groupchat";
user = GrabString(data_json, 1, "xmpp_user");
*from = ParseeEncodeMXID(matrix_sender);
if (direct)
{
*to = StrDuplicate(user);
Free(chat_id);
}
else
{
char *matrix_name, *muc_join_as;
muc_id = ParseeGetMUCID(data, chat_id);
if (!chat_id)
{
/* muc_id is already implied to be freed by this point */
Free(*from);
*from = NULL;
DbUnlock(data->db, room_data);
return NULL;
}
matrix_name = ASGetName(data->config, room_id, matrix_sender);
muc_join_as = StrConcat(4, muc_id, "/", matrix_name, "[p]");
XMPPJoinMUC(jabber, *from, muc_join_as);
*to = muc_id;
Free(matrix_name);
Free(muc_join_as);
}
Free(chat_id);
DbUnlock(data->db, room_data);
return type;
}
static void
ParseeMessageHandler(ParseeData *data, HashMap *event)
{
@ -316,9 +387,37 @@ ParseeEventHandler(ParseeData *data, HashMap *event)
}
else if (StrEquals(event_type, "m.room.redaction"))
{
Log(LOG_WARNING, "Unsupported event redaction %s", event_id);
char *from, *to;
char *redacted = GrabString(event, 1, "redacts");
char *redacted_stanza = NULL;
char *chat_id;
XMPPComponent *jabber = data->jabber;
const char *type = GetXMPPInformation(data, event, &from, &to);
chat_id = ParseeGetFromRoomID(data, room_id);
if (!ParseeGetOrigin(data, chat_id, redacted, &redacted_stanza))
{
ParseeGetDMOrigin(data, room_id, redacted, &redacted_stanza);
}
/* Some clients don't support retractions *at all*, which smell.
* This therefore serves as a fallback, just in case that fails. */
XMPPSendPlain(
jabber, from, to,
"[EDIT REDACT FROM PARSEE]",
(char *) type,
NULL, NULL, redacted,
NULL, redacted_stanza
);
XMPPRetract(jabber, from, to, (char *) type, redacted_stanza);
Free(redacted_stanza);
Free(chat_id);
Free(from);
Free(to);
/* TODO: Implement Matrix->XMPP redactions. */
}
}