mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-13 18:25:10 +00:00
[ADD] Respect MIME, start bridging leaves/kicks
Wow, this one _wasn't_ pushed at 3AM, Outstanding.
This commit is contained in:
parent
4d055f3688
commit
43b3f8aaf5
8 changed files with 146 additions and 24 deletions
|
|
@ -10,7 +10,7 @@ Somewhat implemented XEPs:
|
||||||
IM platforms I won't mention), so this doesn't sound too bad to do
|
IM platforms I won't mention), so this doesn't sound too bad to do
|
||||||
HALF-IMPLEMENTED: Removing reacts won't work.
|
HALF-IMPLEMENTED: Removing reacts won't work.
|
||||||
~ https://xmpp.org/extensions/xep-0184.html
|
~ https://xmpp.org/extensions/xep-0184.html
|
||||||
no one wants to send me receipts :(((((((((((((
|
Only Matrix->XMPP as of now
|
||||||
|
|
||||||
For future XEPs:
|
For future XEPs:
|
||||||
- https://xmpp.org/extensions/xep-0421.html
|
- https://xmpp.org/extensions/xep-0421.html
|
||||||
|
|
@ -31,6 +31,10 @@ For future XEPs:
|
||||||
Stickers are great. Matrix and XMPP somewhat has support for them, so
|
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.
|
might be a nice-to-have, and also to push over XMPP support.
|
||||||
|
|
||||||
|
- https://xmpp.org/extensions/xep-0050.html
|
||||||
|
Ad-hoc commands that bridge maintainers can deal with XMPP-style are
|
||||||
|
also a nice to have.
|
||||||
|
|
||||||
ON STANDBY BECAUSE THESE HAVE BEEN TERRIBLE TO DEAL WITH AND WHO KEEPS WRITING
|
ON STANDBY BECAUSE THESE HAVE BEEN TERRIBLE TO DEAL WITH AND WHO KEEPS WRITING
|
||||||
THESE I WANT TO SEND THEM A NICE, BRIGHT GIFT:
|
THESE I WANT TO SEND THEM A NICE, BRIGHT GIFT:
|
||||||
(x) https://xmpp.org/extensions/xep-0084.html
|
(x) https://xmpp.org/extensions/xep-0084.html
|
||||||
|
|
|
||||||
9
src/AS.c
9
src/AS.c
|
|
@ -632,7 +632,7 @@ ASSetPL(const ParseeConfig *conf, char *id, HashMap *m)
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
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;
|
char *size_str, *path, *ret, *user;
|
||||||
int i;
|
int i;
|
||||||
|
|
@ -640,7 +640,6 @@ ASUpload(const ParseeConfig *c, Stream *from, unsigned int size)
|
||||||
HashMap *reply;
|
HashMap *reply;
|
||||||
if (!c || !from)
|
if (!c || !from)
|
||||||
{
|
{
|
||||||
Log(LOG_INFO, "Obvious upload fail");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -655,6 +654,10 @@ ASUpload(const ParseeConfig *c, Stream *from, unsigned int size)
|
||||||
{
|
{
|
||||||
HttpRequestHeader(ctx, "Content-Length", size_str);
|
HttpRequestHeader(ctx, "Content-Length", size_str);
|
||||||
}
|
}
|
||||||
|
if (mime)
|
||||||
|
{
|
||||||
|
HttpRequestHeader(ctx, "Content-Type", mime);
|
||||||
|
}
|
||||||
HttpRequestSendHeaders(ctx);
|
HttpRequestSendHeaders(ctx);
|
||||||
|
|
||||||
for (i = 0; i < size; i++)
|
for (i = 0; i < size; i++)
|
||||||
|
|
@ -739,7 +742,7 @@ ASReupload(const ParseeConfig *c, char *from, char **mime)
|
||||||
{
|
{
|
||||||
size = strtol(content_len, NULL, 10);
|
size = strtol(content_len, NULL, 10);
|
||||||
}
|
}
|
||||||
ret = ASUpload(c, HttpClientStream(ctx), size);
|
ret = ASUpload(c, HttpClientStream(ctx), size, mime ? *mime : NULL);
|
||||||
|
|
||||||
HttpClientContextFree(ctx);
|
HttpClientContextFree(ctx);
|
||||||
UriFree(uri);
|
UriFree(uri);
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,35 @@ ParseeMemberHandler(ParseeData *data, HashMap *event)
|
||||||
Free(jid);
|
Free(jid);
|
||||||
Free(chat_id);
|
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
|
static void
|
||||||
ParseeBotHandler(ParseeData *data, HashMap *event)
|
ParseeBotHandler(ParseeData *data, HashMap *event)
|
||||||
|
|
@ -95,7 +124,6 @@ ParseeBotHandler(ParseeData *data, HashMap *event)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Make an improvment. This is the bare minimum */
|
|
||||||
if (!ParseeIsAdmin(data, sender))
|
if (!ParseeIsAdmin(data, sender))
|
||||||
{
|
{
|
||||||
Free(ASSend(
|
Free(ASSend(
|
||||||
|
|
@ -172,8 +200,6 @@ ParseeMessageHandler(ParseeData *data, HashMap *event)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* TODO: Reunite DM/MUC code to bring feature parity. */
|
|
||||||
type = direct ? "chat" : "groupchat";
|
type = direct ? "chat" : "groupchat";
|
||||||
user = GrabString(json, 1, "xmpp_user");
|
user = GrabString(json, 1, "xmpp_user");
|
||||||
unauth = ParseeToUnauth(data, url);
|
unauth = ParseeToUnauth(data, url);
|
||||||
|
|
@ -237,7 +263,7 @@ ParseeMessageHandler(ParseeData *data, HashMap *event)
|
||||||
stanza, sender, ev_id, unauth, origin_id,
|
stanza, sender, ev_id, unauth, origin_id,
|
||||||
xmpp_ident
|
xmpp_ident
|
||||||
);
|
);
|
||||||
/* Culprit */
|
|
||||||
if (direct)
|
if (direct)
|
||||||
{
|
{
|
||||||
ParseePushDMStanza(
|
ParseePushDMStanza(
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,9 @@ RouteHead(RouteRoomAck, arr, argp)
|
||||||
char *creator = NULL, *muc_name = NULL, *chatid = NULL;
|
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);
|
response = ASVerifyRequest(args);
|
||||||
if (response)
|
if (response)
|
||||||
{
|
{
|
||||||
|
|
@ -67,7 +70,6 @@ RouteHead(RouteRoomAck, arr, argp)
|
||||||
if (ParseeManageBan(args->data, muc, NULL))
|
if (ParseeManageBan(args->data, muc, NULL))
|
||||||
{
|
{
|
||||||
HttpResponseStatus(args->ctx, HTTP_METHOD_NOT_ALLOWED);
|
HttpResponseStatus(args->ctx, HTTP_METHOD_NOT_ALLOWED);
|
||||||
Log(LOG_INFO, "Nofly...");
|
|
||||||
response = MatrixCreateError(
|
response = MatrixCreateError(
|
||||||
"M_NOT_FOUND",
|
"M_NOT_FOUND",
|
||||||
"XMPP MUC is banned from being accessed on this instance"
|
"XMPP MUC is banned from being accessed on this instance"
|
||||||
|
|
@ -94,7 +96,6 @@ RouteHead(RouteRoomAck, arr, argp)
|
||||||
);
|
);
|
||||||
if (!id)
|
if (!id)
|
||||||
{
|
{
|
||||||
Log(LOG_INFO, "No ID");
|
|
||||||
HttpResponseStatus(args->ctx, HTTP_INTERNAL_SERVER_ERROR);
|
HttpResponseStatus(args->ctx, HTTP_INTERNAL_SERVER_ERROR);
|
||||||
response = MatrixCreateError(
|
response = MatrixCreateError(
|
||||||
"M_UNKNOWN",
|
"M_UNKNOWN",
|
||||||
|
|
|
||||||
|
|
@ -176,6 +176,44 @@ XMPPSendMUC(XMPPComponent *comp, char *fr, char *as, char *to, char *msg, char *
|
||||||
pthread_mutex_unlock(&comp->write_lock);
|
pthread_mutex_unlock(&comp->write_lock);
|
||||||
}
|
}
|
||||||
void
|
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)
|
XMPPJoinMUC(XMPPComponent *comp, char *fr, char *muc)
|
||||||
{
|
{
|
||||||
XMLElement *presence, *x;
|
XMLElement *presence, *x;
|
||||||
|
|
|
||||||
|
|
@ -822,7 +822,7 @@ IQResult(ParseeData *args, XMLElement *stanza)
|
||||||
/* TODO: Bound checks for a size limit. */
|
/* TODO: Bound checks for a size limit. */
|
||||||
bdata = (char *) Base64Decode(base64, b64len);
|
bdata = (char *) Base64Decode(base64, b64len);
|
||||||
datastream = StrStreamReaderN(bdata, length);
|
datastream = StrStreamReaderN(bdata, length);
|
||||||
mxc = ASUpload(args->config, datastream, length);
|
mxc = ASUpload(args->config, datastream, length, "image/png");
|
||||||
|
|
||||||
jid = ParseeLookupJID(from);
|
jid = ParseeLookupJID(from);
|
||||||
from_matrix = ParseeEncodeJID(args->config, jid, false);
|
from_matrix = ParseeEncodeJID(args->config, jid, false);
|
||||||
|
|
@ -859,34 +859,65 @@ IQResult(ParseeData *args, XMLElement *stanza)
|
||||||
if (photo)
|
if (photo)
|
||||||
{
|
{
|
||||||
XMLElement *binval = XMLookForUnique(photo, "BINVAL");
|
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 *base64;
|
||||||
char *bdata;
|
char *bdata;
|
||||||
size_t length, b64len;
|
size_t length, b64len;
|
||||||
Stream *datastream;
|
Stream *datastream;
|
||||||
char *mxc, *from_matrix, *jid;
|
char *mxc = NULL, *from_matrix = NULL, *jid = NULL;
|
||||||
|
char *room = NULL;
|
||||||
if (!data || !data->data)
|
if (!data || !data->data)
|
||||||
{
|
{
|
||||||
|
Log(LOG_ERR, "%s NOT FOUND", HashMapGet(stanza->attrs, "from"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get the base64, decode it, and shove it in a nicely put
|
||||||
|
* MXC address */
|
||||||
base64 = data->data;
|
base64 = data->data;
|
||||||
b64len = base64 ? strlen(base64) : 0;
|
b64len = base64 ? strlen(base64) : 0;
|
||||||
length = Base64DecodedSize(base64, b64len);
|
length = Base64DecodedSize(base64, b64len);
|
||||||
|
|
||||||
bdata = Base64Decode(base64, b64len);
|
bdata = Base64Decode(base64, b64len);
|
||||||
datastream = StrStreamReaderN(bdata, length);
|
datastream = StrStreamReaderN(bdata, length);
|
||||||
mxc = ASUpload(args->config, datastream, length);
|
mxc = ASUpload(
|
||||||
|
args->config,
|
||||||
jid = ParseeLookupJID(HashMapGet(stanza->attrs, "from"));
|
datastream,
|
||||||
from_matrix = ParseeEncodeJID(args->config, jid, false);
|
length,
|
||||||
ASSetAvatar(args->config, from_matrix, mxc);
|
tdata ? tdata->data : NULL
|
||||||
|
);
|
||||||
/* TODO: Check if already set. */
|
|
||||||
|
|
||||||
Free(bdata);
|
Free(bdata);
|
||||||
StreamClose(datastream);
|
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(from_matrix);
|
||||||
|
Free(room);
|
||||||
Free(jid);
|
Free(jid);
|
||||||
Free(mxc);
|
Free(mxc);
|
||||||
}
|
}
|
||||||
|
|
@ -1117,7 +1148,7 @@ PresenceStanza(ParseeData *args, XMLElement *stanza)
|
||||||
json = DbJson(avatars);
|
json = DbJson(avatars);
|
||||||
|
|
||||||
avatar_id = GrabString(json, 1, oid);
|
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);
|
DbUnlock(args->db, avatars);
|
||||||
return;
|
return;
|
||||||
|
|
@ -1142,6 +1173,24 @@ PresenceStanza(ParseeData *args, XMLElement *stanza)
|
||||||
XMLFreeElement(vcard_request);
|
XMLFreeElement(vcard_request);
|
||||||
Free(from);
|
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
|
#undef MUC_USER_NS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ extern void ASSetAvatar(const ParseeConfig *c, char *user, char *mxc);
|
||||||
extern char * ASGetName(const ParseeConfig *c, char *room, char *user);
|
extern char * ASGetName(const ParseeConfig *c, char *room, char *user);
|
||||||
|
|
||||||
/* Uploads data to Matrix to be used later */
|
/* 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. */
|
/* Reuploads a HTTP URL to Matrix, with an optional MIME type returned. */
|
||||||
extern char * ASReupload(const ParseeConfig *c, char *from, char **mime);
|
extern char * ASReupload(const ParseeConfig *c, char *from, char **mime);
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,9 @@ extern XMPPComponent * XMPPInitialiseCompStream(char *host, int port);
|
||||||
* after XMPPInitialiseCompStream. */
|
* after XMPPInitialiseCompStream. */
|
||||||
extern bool XMPPAuthenticateCompStream(XMPPComponent *comp, char *shared);
|
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 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. */
|
/* 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);
|
extern void XMPPSendPlain(XMPPComponent *comp, char *fr, char *to, char *msg, char *type, char *rst, char *rse, char *event_id, char *oob, char *id);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue