[ADD] Respect MIME, start bridging leaves/kicks

Wow, this one _wasn't_ pushed at 3AM, Outstanding.
This commit is contained in:
LDA 2024-07-07 17:30:48 +02:00
commit 43b3f8aaf5
8 changed files with 146 additions and 24 deletions

View file

@ -632,7 +632,7 @@ ASSetPL(const ParseeConfig *conf, char *id, HashMap *m)
}
char *
ASUpload(const ParseeConfig *c, Stream *from, unsigned int size)
ASUpload(const ParseeConfig *c, Stream *from, unsigned int size, char *mime)
{
char *size_str, *path, *ret, *user;
int i;
@ -640,7 +640,6 @@ ASUpload(const ParseeConfig *c, Stream *from, unsigned int size)
HashMap *reply;
if (!c || !from)
{
Log(LOG_INFO, "Obvious upload fail");
return NULL;
}
@ -655,6 +654,10 @@ ASUpload(const ParseeConfig *c, Stream *from, unsigned int size)
{
HttpRequestHeader(ctx, "Content-Length", size_str);
}
if (mime)
{
HttpRequestHeader(ctx, "Content-Type", mime);
}
HttpRequestSendHeaders(ctx);
for (i = 0; i < size; i++)
@ -739,7 +742,7 @@ ASReupload(const ParseeConfig *c, char *from, char **mime)
{
size = strtol(content_len, NULL, 10);
}
ret = ASUpload(c, HttpClientStream(ctx), size);
ret = ASUpload(c, HttpClientStream(ctx), size, mime ? *mime : NULL);
HttpClientContextFree(ctx);
UriFree(uri);

View file

@ -63,6 +63,35 @@ ParseeMemberHandler(ParseeData *data, HashMap *event)
Free(jid);
Free(chat_id);
}
else if (StrEquals(membership, "leave") && !ParseeIsPuppet(conf, state_key))
{
/* TODO: Manage bans */
XMPPComponent *jabber = data->jabber;
char *jid = ParseeEncodeMXID(state_key);
char *name = NULL, *rev = NULL, *muc_id = NULL;
char *reason = GrabString(event, 2, "content", "reason");
/* Try to find the chat ID */
chat_id = ParseeGetFromRoomID(data, room_id);
muc_id = ParseeGetMUCID(data, chat_id);
if (!chat_id)
{
goto end;
}
/* TODO: Check the name's validity */
name = ASGetName(data->config, room_id, state_key);
rev = StrConcat(4, muc_id, "/", name, "[p]");
XMPPLeaveMUC(jabber, jid, rev, reason);
end:
Free(chat_id);
Free(muc_id);
Free(name);
Free(rev);
Free(jid);
}
}
static void
ParseeBotHandler(ParseeData *data, HashMap *event)
@ -95,7 +124,6 @@ ParseeBotHandler(ParseeData *data, HashMap *event)
return;
}
/* TODO: Make an improvment. This is the bare minimum */
if (!ParseeIsAdmin(data, sender))
{
Free(ASSend(
@ -172,8 +200,6 @@ ParseeMessageHandler(ParseeData *data, HashMap *event)
return;
}
/* TODO: Reunite DM/MUC code to bring feature parity. */
type = direct ? "chat" : "groupchat";
user = GrabString(json, 1, "xmpp_user");
unauth = ParseeToUnauth(data, url);
@ -237,7 +263,7 @@ ParseeMessageHandler(ParseeData *data, HashMap *event)
stanza, sender, ev_id, unauth, origin_id,
xmpp_ident
);
/* Culprit */
if (direct)
{
ParseePushDMStanza(

View file

@ -48,6 +48,9 @@ RouteHead(RouteRoomAck, arr, argp)
char *creator = NULL, *muc_name = NULL, *chatid = NULL;
/* TODO: If an ACK request maps to a MUC that has a chat ID,
* DO NOT create a new one, and instead make a new mapping to
* the previous one. */
response = ASVerifyRequest(args);
if (response)
{
@ -67,7 +70,6 @@ RouteHead(RouteRoomAck, arr, argp)
if (ParseeManageBan(args->data, muc, NULL))
{
HttpResponseStatus(args->ctx, HTTP_METHOD_NOT_ALLOWED);
Log(LOG_INFO, "Nofly...");
response = MatrixCreateError(
"M_NOT_FOUND",
"XMPP MUC is banned from being accessed on this instance"
@ -94,7 +96,6 @@ RouteHead(RouteRoomAck, arr, argp)
);
if (!id)
{
Log(LOG_INFO, "No ID");
HttpResponseStatus(args->ctx, HTTP_INTERNAL_SERVER_ERROR);
response = MatrixCreateError(
"M_UNKNOWN",

View file

@ -176,6 +176,44 @@ XMPPSendMUC(XMPPComponent *comp, char *fr, char *as, char *to, char *msg, char *
pthread_mutex_unlock(&comp->write_lock);
}
void
XMPPLeaveMUC(XMPPComponent *comp, char *fr, char *muc, char *reason)
{
XMLElement *presence;
char *from, *id;
if (!comp || !fr || !muc)
{
return;
}
pthread_mutex_lock(&comp->write_lock);
presence = XMLCreateTag("presence");
XMLAddAttr(presence, "from", (from = StrConcat(3, fr, "@", comp->host)));
XMLAddAttr(presence, "to", muc);
XMLAddAttr(presence, "id", (id = StrRandom(8)));
XMLAddAttr(presence, "type", "unavailable");
if (reason)
{
XMLElement *status = XMLCreateTag("status");
XMLElement *string = XMLCreateText(reason);
XMLAddChild(status, string);
XMLAddChild(presence, status);
}
XMPPAnnotatePresence(presence);
XMLEncode(comp->stream, presence);
StreamFlush(comp->stream);
XMLFreeElement(presence);
Free(from);
Free(id);
pthread_mutex_unlock(&comp->write_lock);
}
void
XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc)
{
XMLElement *presence, *x;

View file

@ -822,7 +822,7 @@ IQResult(ParseeData *args, XMLElement *stanza)
/* TODO: Bound checks for a size limit. */
bdata = (char *) Base64Decode(base64, b64len);
datastream = StrStreamReaderN(bdata, length);
mxc = ASUpload(args->config, datastream, length);
mxc = ASUpload(args->config, datastream, length, "image/png");
jid = ParseeLookupJID(from);
from_matrix = ParseeEncodeJID(args->config, jid, false);
@ -859,34 +859,65 @@ IQResult(ParseeData *args, XMLElement *stanza)
if (photo)
{
XMLElement *binval = XMLookForUnique(photo, "BINVAL");
XMLElement *data = ArrayGet(binval->children, 0);
XMLElement *type = XMLookForUnique(photo, "TYPE");
XMLElement *data =
binval ? ArrayGet(binval->children, 0) : NULL;
XMLElement *tdata = type ? ArrayGet(type->children, 0) : NULL;
char *base64;
char *bdata;
size_t length, b64len;
Stream *datastream;
char *mxc, *from_matrix, *jid;
char *mxc = NULL, *from_matrix = NULL, *jid = NULL;
char *room = NULL;
if (!data || !data->data)
{
Log(LOG_ERR, "%s NOT FOUND", HashMapGet(stanza->attrs, "from"));
return;
}
/* Get the base64, decode it, and shove it in a nicely put
* MXC address */
base64 = data->data;
b64len = base64 ? strlen(base64) : 0;
length = Base64DecodedSize(base64, b64len);
bdata = Base64Decode(base64, b64len);
datastream = StrStreamReaderN(bdata, length);
mxc = ASUpload(args->config, datastream, length);
jid = ParseeLookupJID(HashMapGet(stanza->attrs, "from"));
from_matrix = ParseeEncodeJID(args->config, jid, false);
ASSetAvatar(args->config, from_matrix, mxc);
/* TODO: Check if already set. */
mxc = ASUpload(
args->config,
datastream,
length,
tdata ? tdata->data : NULL
);
Free(bdata);
StreamClose(datastream);
room = ParseeGetBridgedRoom(args, stanza);
jid = ParseeLookupJID(HashMapGet(stanza->attrs, "from"));
if (jid && !StrEquals(jid, HashMapGet(stanza->attrs, "from")))
{
from_matrix = ParseeEncodeJID(args->config, jid, false);
ASSetAvatar(args->config, from_matrix, mxc);
}
else if (room)
{
char *mask = StrConcat(4,
"@", args->config->sender_localpart,
":", args->config->homeserver_host
);
HashMap *obj = HashMapCreate();
HashMapSet(obj, "url", JsonValueString(mxc));
ASSetState(
args->config,
room, "m.room.avatar", "",
mask, obj
);
Free(mask);
}
Free(from_matrix);
Free(room);
Free(jid);
Free(mxc);
}
@ -1117,7 +1148,7 @@ PresenceStanza(ParseeData *args, XMLElement *stanza)
json = DbJson(avatars);
avatar_id = GrabString(json, 1, oid);
if (StrEquals(avatar_id, p_dat->data))
if (avatar_id && StrEquals(avatar_id, p_dat->data))
{
DbUnlock(args->db, avatars);
return;
@ -1142,6 +1173,24 @@ PresenceStanza(ParseeData *args, XMLElement *stanza)
XMLFreeElement(vcard_request);
Free(from);
}
/* TODO: Sending VCard on presence is slow and stalls the thread */
if (0)
{
XMPPComponent *jabber = args->jabber;
char *from = StrConcat(2, "parsee@", args->config->component_host);
XMLElement *vcard_request = CreateVCardRequest(
from, HashMapGet(stanza->attrs, "from")
);
pthread_mutex_lock(&jabber->write_lock);
XMLEncode(jabber->stream, vcard_request);
StreamFlush(jabber->stream);
pthread_mutex_unlock(&jabber->write_lock);
XMLFreeElement(vcard_request);
Free(from);
}
#undef MUC_USER_NS
}

View file

@ -63,7 +63,7 @@ extern void ASSetAvatar(const ParseeConfig *c, char *user, char *mxc);
extern char * ASGetName(const ParseeConfig *c, char *room, char *user);
/* Uploads data to Matrix to be used later */
extern char * ASUpload(const ParseeConfig *c, Stream *from, unsigned int size);
extern char * ASUpload(const ParseeConfig *c, Stream *from, unsigned int size, char *mime);
/* Reuploads a HTTP URL to Matrix, with an optional MIME type returned. */
extern char * ASReupload(const ParseeConfig *c, char *from, char **mime);

View file

@ -24,8 +24,9 @@ extern XMPPComponent * XMPPInitialiseCompStream(char *host, int port);
* after XMPPInitialiseCompStream. */
extern bool XMPPAuthenticateCompStream(XMPPComponent *comp, char *shared);
/* Makes a user join a MUC */
/* Makes a user join/leave a MUC */
extern void XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc);
extern void XMPPLeaveMUC(XMPPComponent *comp, char *fr, char *muc, char *r);
/* TODO: XMPP stuff, I don't fucking know, I'm not a Jabbernerd. */
extern void XMPPSendPlain(XMPPComponent *comp, char *fr, char *to, char *msg, char *type, char *rst, char *rse, char *event_id, char *oob, char *id);