mirror of
https://forge.fsky.io/lda/Parsee.git
synced 2026-03-13 18:45:11 +00:00
[ADD/WIP] Matrix<->XMPP DMs.
There is still this fun issue with the blocking XML parser leaking memory on pthread_cancel, I'll try to deal with that later, maybe with a test stanza. I also apologise for swearing in the last commit. I promise it won't happen again, Prosody.
This commit is contained in:
parent
bdb4fd2f68
commit
2cc4b0ed17
11 changed files with 325 additions and 63 deletions
33
src/AS.c
33
src/AS.c
|
|
@ -24,7 +24,6 @@ ASVerifyRequest(ParseeHttpArg *arg)
|
||||||
|
|
||||||
if (!authorisation || strncmp(authorisation, "Bearer ", 7))
|
if (!authorisation || strncmp(authorisation, "Bearer ", 7))
|
||||||
{
|
{
|
||||||
Log(LOG_INFO, "Bad auth %s", authorisation);
|
|
||||||
HttpResponseStatus(arg->ctx, HTTP_FORBIDDEN);
|
HttpResponseStatus(arg->ctx, HTTP_FORBIDDEN);
|
||||||
ret = MatrixCreateError("M_MISSING_TOKEN", "No 'hs_token' given in.");
|
ret = MatrixCreateError("M_MISSING_TOKEN", "No 'hs_token' given in.");
|
||||||
goto end;
|
goto end;
|
||||||
|
|
@ -42,7 +41,7 @@ end:
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ASAuthenticateRequest(ParseeConfig *data, HttpClientContext *ctx)
|
ASAuthenticateRequest(const ParseeConfig *data, HttpClientContext *ctx)
|
||||||
{
|
{
|
||||||
char *bearer;
|
char *bearer;
|
||||||
if (!data || !ctx)
|
if (!data || !ctx)
|
||||||
|
|
@ -55,7 +54,7 @@ ASAuthenticateRequest(ParseeConfig *data, HttpClientContext *ctx)
|
||||||
Free(bearer);
|
Free(bearer);
|
||||||
}
|
}
|
||||||
bool
|
bool
|
||||||
ASRegisterUser(ParseeConfig *conf, char *user)
|
ASRegisterUser(const ParseeConfig *conf, char *user)
|
||||||
{
|
{
|
||||||
HttpClientContext *ctx = NULL;
|
HttpClientContext *ctx = NULL;
|
||||||
HashMap *json = NULL;
|
HashMap *json = NULL;
|
||||||
|
|
@ -100,7 +99,6 @@ ASPing(const ParseeConfig *conf)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log(LOG_NOTICE, "Pinging...");
|
|
||||||
path = StrConcat(3,
|
path = StrConcat(3,
|
||||||
"/_matrix/client/v1/appservice/",
|
"/_matrix/client/v1/appservice/",
|
||||||
"Parsee%20XMPP",
|
"Parsee%20XMPP",
|
||||||
|
|
@ -118,14 +116,13 @@ ASPing(const ParseeConfig *conf)
|
||||||
JsonFree(json);
|
JsonFree(json);
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
ASJoin(ParseeConfig *conf, char *id, char *masquerade)
|
ASJoin(const ParseeConfig *conf, char *id, char *masquerade)
|
||||||
{
|
{
|
||||||
HttpClientContext *ctx = NULL;
|
HttpClientContext *ctx = NULL;
|
||||||
HashMap *json = NULL;
|
HashMap *json = NULL;
|
||||||
char *path;
|
char *path;
|
||||||
if (!conf || !id || !masquerade)
|
if (!conf || !id || !masquerade)
|
||||||
{
|
{
|
||||||
Log(LOG_ERR, "Bad values %p %p", conf, id);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -134,7 +131,6 @@ ASJoin(ParseeConfig *conf, char *id, char *masquerade)
|
||||||
"user_id=", masquerade
|
"user_id=", masquerade
|
||||||
);
|
);
|
||||||
|
|
||||||
Log(LOG_INFO, "%s", path);
|
|
||||||
ctx = ParseeCreateRequest(
|
ctx = ParseeCreateRequest(
|
||||||
conf,
|
conf,
|
||||||
HTTP_POST, path
|
HTTP_POST, path
|
||||||
|
|
@ -148,40 +144,29 @@ ASJoin(ParseeConfig *conf, char *id, char *masquerade)
|
||||||
JsonFree(json);
|
JsonFree(json);
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
ASSend(ParseeConfig *conf, char *id, char *user, char *type, HashMap *c)
|
ASSend(const ParseeConfig *conf, char *id, char *user, char *type, HashMap *c)
|
||||||
{
|
{
|
||||||
HttpClientContext *ctx = NULL;
|
HttpClientContext *ctx = NULL;
|
||||||
HashMap *json = NULL, *params_obj;
|
|
||||||
Stream *s;
|
|
||||||
char *path, *params;
|
char *path, *params;
|
||||||
char *txn;
|
char *txn;
|
||||||
if (!conf || !id || !type || !c)
|
if (!conf || !id || !type || !user || !c)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
txn = StrRandom(16);
|
txn = StrRandom(16);
|
||||||
params_obj = HashMapCreate();
|
path = StrConcat(9,
|
||||||
if (user)
|
|
||||||
{
|
|
||||||
HashMapSet(params_obj, "user_id", user);
|
|
||||||
}
|
|
||||||
params = HttpParamEncode(params_obj);
|
|
||||||
HashMapFree(params_obj);
|
|
||||||
path = StrConcat(8,
|
|
||||||
"/_matrix/client/v3/rooms/",
|
"/_matrix/client/v3/rooms/",
|
||||||
id, "/send/", type, "/", txn, "?",
|
id, "/send/", type, "/", txn, "?",
|
||||||
params
|
"user_id=", user
|
||||||
);
|
);
|
||||||
Log(LOG_INFO, "Sending %s", path);
|
|
||||||
Free(params);
|
|
||||||
Free(txn);
|
Free(txn);
|
||||||
|
|
||||||
ctx = ParseeCreateRequest(conf, HTTP_PUT, path);
|
ctx = ParseeCreateRequest(conf, HTTP_PUT, path);
|
||||||
Free(path);
|
Free(path);
|
||||||
json = HashMapCreate();
|
|
||||||
ASAuthenticateRequest(conf, ctx);
|
ASAuthenticateRequest(conf, ctx);
|
||||||
Log(LOG_INFO, "%d", ParseeSetRequestJSON(ctx, c));
|
ParseeSetRequestJSON(ctx, c);
|
||||||
|
|
||||||
HttpClientContextFree(ctx);
|
HttpClientContextFree(ctx);
|
||||||
JsonFree(c);
|
JsonFree(c);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ ParseeRequest(HttpServerContext *ctx, void *argp)
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpClientContext *
|
HttpClientContext *
|
||||||
ParseeCreateRequest(ParseeConfig *conf, HttpRequestMethod meth, char *path)
|
ParseeCreateRequest(const ParseeConfig *conf, HttpRequestMethod meth, char *path)
|
||||||
{
|
{
|
||||||
HttpClientContext *ctx;
|
HttpClientContext *ctx;
|
||||||
if (!conf || !path)
|
if (!conf || !path)
|
||||||
|
|
|
||||||
10
src/Main.c
10
src/Main.c
|
|
@ -1,6 +1,7 @@
|
||||||
#include <Cytoplasm/HttpServer.h>
|
#include <Cytoplasm/HttpServer.h>
|
||||||
#include <Cytoplasm/Log.h>
|
#include <Cytoplasm/Log.h>
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
|
|
@ -10,6 +11,7 @@
|
||||||
#include <AS.h>
|
#include <AS.h>
|
||||||
|
|
||||||
static HttpServer *server = NULL;
|
static HttpServer *server = NULL;
|
||||||
|
static pthread_t xmpp_thr;
|
||||||
static void
|
static void
|
||||||
SignalHandler(int signal)
|
SignalHandler(int signal)
|
||||||
{
|
{
|
||||||
|
|
@ -26,6 +28,7 @@ SignalHandler(int signal)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
HttpServerStop(server);
|
HttpServerStop(server);
|
||||||
|
pthread_cancel(xmpp_thr);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -59,7 +62,6 @@ Main(void)
|
||||||
parsee_conf->shared_comp_secret
|
parsee_conf->shared_comp_secret
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Log(LOG_INFO, "HS token: %s", parsee_conf->hs_token);
|
|
||||||
|
|
||||||
ASRegisterUser(parsee_conf, parsee_conf->sender_localpart);
|
ASRegisterUser(parsee_conf, parsee_conf->sender_localpart);
|
||||||
|
|
||||||
|
|
@ -70,6 +72,12 @@ Main(void)
|
||||||
conf.handlerArgs = ParseeInitData(jabber);
|
conf.handlerArgs = ParseeInitData(jabber);
|
||||||
conf.handler = ParseeRequest;
|
conf.handler = ParseeRequest;
|
||||||
|
|
||||||
|
if (pthread_create(&xmpp_thr, NULL, ParseeXMPPThread, conf.handlerArgs))
|
||||||
|
{
|
||||||
|
Log(LOG_ERR, "Couldn't start XMPP listener thread.");
|
||||||
|
/* TODO: Die */
|
||||||
|
}
|
||||||
|
|
||||||
sigAction.sa_handler = SignalHandler;
|
sigAction.sa_handler = SignalHandler;
|
||||||
sigfillset(&sigAction.sa_mask);
|
sigfillset(&sigAction.sa_mask);
|
||||||
sigAction.sa_flags = SA_RESTART;
|
sigAction.sa_flags = SA_RESTART;
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ ParseeMemberHandler(ParseeData *data, HashMap *event)
|
||||||
char *state_key = GrabString(event, 1, "state_key");
|
char *state_key = GrabString(event, 1, "state_key");
|
||||||
char *membership = GrabString(event, 2, "content", "membership");
|
char *membership = GrabString(event, 2, "content", "membership");
|
||||||
char *room_id = GrabString(event, 1, "room_id");
|
char *room_id = GrabString(event, 1, "room_id");
|
||||||
|
char *sender = GrabString(event, 1, "sender");
|
||||||
const ParseeConfig *conf = data->config;
|
const ParseeConfig *conf = data->config;
|
||||||
Log(LOG_INFO, "Membership '%s'->'%s'", state_key, membership);
|
Log(LOG_INFO, "Membership '%s'->'%s'", state_key, membership);
|
||||||
|
|
||||||
|
|
@ -23,28 +24,22 @@ ParseeMemberHandler(ParseeData *data, HashMap *event)
|
||||||
DbRef *ref;
|
DbRef *ref;
|
||||||
HashMap *json;
|
HashMap *json;
|
||||||
char *jid;
|
char *jid;
|
||||||
Log(LOG_INFO, "Looks like %s was invited to %s",
|
|
||||||
state_key,
|
|
||||||
room_id
|
|
||||||
);
|
|
||||||
ASJoin(conf, room_id, state_key);
|
ASJoin(conf, room_id, state_key);
|
||||||
ref = DbCreate(data->db, 3, "rooms", room_id, "data");
|
|
||||||
json = DbJson(ref);
|
|
||||||
|
|
||||||
Log(LOG_INFO, "Grabbing JID");
|
|
||||||
jid = ParseeDecodeLocalJID(conf, state_key);
|
jid = ParseeDecodeLocalJID(conf, state_key);
|
||||||
|
|
||||||
Log(LOG_INFO, "JID: %s", jid);
|
ref = DbCreate(data->db, 3, "rooms", room_id, "data");
|
||||||
|
json = DbJson(ref);
|
||||||
HashMapSet(json, "is_direct", JsonValueBoolean(true));
|
HashMapSet(json, "is_direct", JsonValueBoolean(true));
|
||||||
HashMapSet(json, "xmpp_user", JsonValueString(jid));
|
HashMapSet(json, "xmpp_user", JsonValueString(jid));
|
||||||
|
DbUnlock(data->db, ref);
|
||||||
|
|
||||||
|
ParseePushDMRoom(data, sender, jid, room_id);
|
||||||
/* Pretend everything is a dm, ignoring is_direct */
|
/* Pretend everything is a dm, ignoring is_direct */
|
||||||
if (jid)
|
if (jid)
|
||||||
{
|
{
|
||||||
Free(jid);
|
Free(jid);
|
||||||
}
|
}
|
||||||
DbUnlock(data->db, ref);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void
|
static void
|
||||||
|
|
@ -59,9 +54,16 @@ ParseeMessageHandler(ParseeData *data, HashMap *event)
|
||||||
char *id = GrabString(event, 1, "room_id");
|
char *id = GrabString(event, 1, "room_id");
|
||||||
char *sender = GrabString(event, 1, "sender");
|
char *sender = GrabString(event, 1, "sender");
|
||||||
|
|
||||||
|
if (ParseeIsPuppet(data->config, sender))
|
||||||
|
{
|
||||||
|
Log(LOG_INFO, "Do not bridge the puppet");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
ref = DbLock(data->db, 3, "rooms", id, "data");
|
ref = DbLock(data->db, 3, "rooms", id, "data");
|
||||||
json = DbJson(ref);
|
json = DbJson(ref);
|
||||||
|
|
||||||
|
|
||||||
if (JsonValueAsBoolean(HashMapGet(json, "is_direct")))
|
if (JsonValueAsBoolean(HashMapGet(json, "is_direct")))
|
||||||
{
|
{
|
||||||
char *user = GrabString(json, 1, "xmpp_user");
|
char *user = GrabString(json, 1, "xmpp_user");
|
||||||
|
|
@ -85,11 +87,6 @@ ParseeEventHandler(ParseeData *data, HashMap *event)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log(LOG_INFO, "Event by '%s', with type '%s'",
|
|
||||||
JsonValueAsString(HashMapGet(event, "sender")),
|
|
||||||
JsonValueAsString(HashMapGet(event, "type"))
|
|
||||||
);
|
|
||||||
|
|
||||||
event_type = GrabString(event, 1, "type");
|
event_type = GrabString(event, 1, "type");
|
||||||
if (StrEquals(event_type, "m.room.member"))
|
if (StrEquals(event_type, "m.room.member"))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
172
src/ParseeUser.c
172
src/ParseeUser.c
|
|
@ -1,9 +1,13 @@
|
||||||
#include <Parsee.h>
|
#include <Parsee.h>
|
||||||
|
|
||||||
#include <Cytoplasm/Memory.h>
|
#include <Cytoplasm/Memory.h>
|
||||||
|
#include <Cytoplasm/Json.h>
|
||||||
#include <Cytoplasm/Str.h>
|
#include <Cytoplasm/Str.h>
|
||||||
#include <Cytoplasm/Log.h>
|
#include <Cytoplasm/Sha.h>
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ParseeIsPuppet(const ParseeConfig *conf, char *user)
|
ParseeIsPuppet(const ParseeConfig *conf, char *user)
|
||||||
|
|
@ -99,6 +103,54 @@ ParseeDecodeLocalJID(const ParseeConfig *c, char *mxid)
|
||||||
/* Until the ':', data_start now is an encoded JID */
|
/* Until the ':', data_start now is an encoded JID */
|
||||||
return DecodeJID(data_start, ':');
|
return DecodeJID(data_start, ':');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
ParseeEncodeJID(const ParseeConfig *c, char *jid)
|
||||||
|
{
|
||||||
|
char *ret, *tmp;
|
||||||
|
size_t i;
|
||||||
|
if (!c || !jid)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = StrConcat(2, c->namespace_base, "_l_");
|
||||||
|
for (i = 0; i < strlen(jid); i++)
|
||||||
|
{
|
||||||
|
const char *HEX = "0123456789abcdef";
|
||||||
|
char cpy = jid[i];
|
||||||
|
char cs[4] = { 0 };
|
||||||
|
cs[0] = cpy;
|
||||||
|
if (*cs == '/')
|
||||||
|
{
|
||||||
|
/* RID: Break everything and die. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (islower(*cs) || isalpha(*cs) || *cs == '_' ||
|
||||||
|
*cs == '=' || *cs == '-' || *cs == '/' ||
|
||||||
|
*cs == '+' || *cs == '.')
|
||||||
|
{
|
||||||
|
tmp = ret;
|
||||||
|
ret = StrConcat(2, ret, cs);
|
||||||
|
Free(tmp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Hex encode everything */
|
||||||
|
cs[0] = '=';
|
||||||
|
cs[1] = HEX[(cpy >> 4) & 0xF];
|
||||||
|
cs[2] = HEX[(cpy >> 0) & 0xF];
|
||||||
|
tmp = ret;
|
||||||
|
ret = StrConcat(2, ret, cs);
|
||||||
|
Free(tmp);
|
||||||
|
}
|
||||||
|
tmp = ret;
|
||||||
|
ret = StrConcat(4, "@", ret, ":", c->homeserver_host);
|
||||||
|
Free(tmp);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
ParseeGetLocal(char *mxid)
|
ParseeGetLocal(char *mxid)
|
||||||
{
|
{
|
||||||
|
|
@ -129,6 +181,8 @@ ParseeGetLocal(char *mxid)
|
||||||
|
|
||||||
return cpy;
|
return cpy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO: More robust system */
|
||||||
char *
|
char *
|
||||||
ParseeEncodeMXID(char *mxid)
|
ParseeEncodeMXID(char *mxid)
|
||||||
{
|
{
|
||||||
|
|
@ -155,3 +209,119 @@ ParseeEncodeMXID(char *mxid)
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
char *
|
||||||
|
ParseeDecodeMXID(char *mxid)
|
||||||
|
{
|
||||||
|
char *ret;
|
||||||
|
size_t i;
|
||||||
|
if (!mxid)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ret = Malloc(strlen(mxid) + 1);
|
||||||
|
for (i = 0; i < strlen(mxid) + 1; i++)
|
||||||
|
{
|
||||||
|
char src = mxid[i];
|
||||||
|
if (src == '%')
|
||||||
|
{
|
||||||
|
src = '@';
|
||||||
|
}
|
||||||
|
else if (src == '=')
|
||||||
|
{
|
||||||
|
src = ':';
|
||||||
|
}
|
||||||
|
else if (src == '@')
|
||||||
|
{
|
||||||
|
ret[i] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ret[i] = src;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
char *
|
||||||
|
ParseeGetDMID(char *mxid, char *jid)
|
||||||
|
{
|
||||||
|
char *concat, *sha;
|
||||||
|
unsigned char *raw;
|
||||||
|
if (!mxid || !jid)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
jid = ParseeTrimJID(jid);
|
||||||
|
concat = StrConcat(2, mxid, jid);
|
||||||
|
raw = Sha1(concat);
|
||||||
|
sha = ShaToHex(raw);
|
||||||
|
|
||||||
|
Free(concat);
|
||||||
|
Free(raw);
|
||||||
|
Free(jid);
|
||||||
|
|
||||||
|
return sha;
|
||||||
|
}
|
||||||
|
char *
|
||||||
|
ParseeFindDMRoom(ParseeData *data, char *mxid, char *jid)
|
||||||
|
{
|
||||||
|
DbRef *ref;
|
||||||
|
HashMap *j;
|
||||||
|
char *room, *dmid;
|
||||||
|
if (!data || !mxid || !jid)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
dmid = ParseeGetDMID(mxid, jid);
|
||||||
|
ref = DbLock(data->db, 2, "users", dmid);
|
||||||
|
j = DbJson(ref);
|
||||||
|
|
||||||
|
room = StrDuplicate(JsonValueAsString(HashMapGet(j, "room")));
|
||||||
|
|
||||||
|
DbUnlock(data->db, ref);
|
||||||
|
Free(dmid);
|
||||||
|
return room;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ParseePushDMRoom(ParseeData *d, char *mxid, char *jid, char *r)
|
||||||
|
{
|
||||||
|
DbRef *ref;
|
||||||
|
HashMap *j;
|
||||||
|
char *dmid;
|
||||||
|
if (!d || !mxid || !jid || !r)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dmid = ParseeGetDMID(mxid, jid);
|
||||||
|
ref = DbCreate(d->db, 2, "users", dmid);
|
||||||
|
j = DbJson(ref);
|
||||||
|
|
||||||
|
HashMapSet(j, "room", JsonValueString(r));
|
||||||
|
|
||||||
|
DbUnlock(d->db, ref);
|
||||||
|
Free(dmid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
ParseeTrimJID(char *jid)
|
||||||
|
{
|
||||||
|
char *ret;
|
||||||
|
size_t i;
|
||||||
|
if (!jid)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = StrDuplicate(jid);
|
||||||
|
for (i = 0; i < strlen(ret); i++)
|
||||||
|
{
|
||||||
|
if (ret[i] == '/')
|
||||||
|
{
|
||||||
|
ret[i] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,11 +13,9 @@ RouteHead(RouteTxns, arr, argp)
|
||||||
Array *events;
|
Array *events;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
Log(LOG_INFO, "Caught one!");
|
|
||||||
response = ASVerifyRequest(args);
|
response = ASVerifyRequest(args);
|
||||||
if (response)
|
if (response)
|
||||||
{
|
{
|
||||||
Log(LOG_INFO, ":(");
|
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
if (HttpRequestMethodGet(args->ctx) != HTTP_PUT)
|
if (HttpRequestMethodGet(args->ctx) != HTTP_PUT)
|
||||||
|
|
@ -30,7 +28,6 @@ RouteHead(RouteTxns, arr, argp)
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log(LOG_INFO, "Caught a decent one!");
|
|
||||||
RequestJSON();
|
RequestJSON();
|
||||||
|
|
||||||
/* TODO: Do a thing with these. */
|
/* TODO: Do a thing with these. */
|
||||||
|
|
@ -44,7 +41,6 @@ RouteHead(RouteTxns, arr, argp)
|
||||||
/* TODO: Store TXN ID somewhere so that we can commit
|
/* TODO: Store TXN ID somewhere so that we can commit
|
||||||
* "Epic Matrix Idempotency" */
|
* "Epic Matrix Idempotency" */
|
||||||
|
|
||||||
Log(LOG_INFO, "OK!");
|
|
||||||
response = HashMapCreate();
|
response = HashMapCreate();
|
||||||
end:
|
end:
|
||||||
JsonFree(request);
|
JsonFree(request);
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,5 @@
|
||||||
#include <XML.h>
|
#include <XML.h>
|
||||||
|
|
||||||
#include <Cytoplasm/Log.h>
|
|
||||||
|
|
||||||
/* TODO: The rest of all that. */
|
|
||||||
|
|
||||||
XMLElement *
|
XMLElement *
|
||||||
XMLDecode(Stream *stream, bool autofree)
|
XMLDecode(Stream *stream, bool autofree)
|
||||||
{
|
{
|
||||||
|
|
@ -27,12 +23,12 @@ XMLDecode(Stream *stream, bool autofree)
|
||||||
stack = ArrayCreate();
|
stack = ArrayCreate();
|
||||||
while ((event = XMLCrank(lexer)) && (!ret || ArraySize(stack)))
|
while ((event = XMLCrank(lexer)) && (!ret || ArraySize(stack)))
|
||||||
{
|
{
|
||||||
|
bool flag = false;
|
||||||
switch (event->type)
|
switch (event->type)
|
||||||
{
|
{
|
||||||
case XML_LEXER_STARTELEM:
|
case XML_LEXER_STARTELEM:
|
||||||
/* Create a new element that will populated. */
|
/* Create a new element that will populated. */
|
||||||
top = XMLCreateTag(event->element);
|
top = XMLCreateTag(event->element);
|
||||||
Log(LOG_INFO, "<%s>", top->name);
|
|
||||||
XMLAddChild(peek(), top);
|
XMLAddChild(peek(), top);
|
||||||
while (HashMapIterate(event->attrs, &key, (void **) &val))
|
while (HashMapIterate(event->attrs, &key, (void **) &val))
|
||||||
{
|
{
|
||||||
|
|
@ -50,7 +46,6 @@ XMLDecode(Stream *stream, bool autofree)
|
||||||
/* Create a new element that will populated. */
|
/* Create a new element that will populated. */
|
||||||
top = XMLCreateTag(event->element);
|
top = XMLCreateTag(event->element);
|
||||||
XMLAddChild(peek(), top);
|
XMLAddChild(peek(), top);
|
||||||
Log(LOG_INFO, "<%s />", top->name);
|
|
||||||
while (HashMapIterate(event->attrs, &key, (void **) &val))
|
while (HashMapIterate(event->attrs, &key, (void **) &val))
|
||||||
{
|
{
|
||||||
XMLAddAttr(top, key, val);
|
XMLAddAttr(top, key, val);
|
||||||
|
|
@ -65,11 +60,25 @@ XMLDecode(Stream *stream, bool autofree)
|
||||||
/* Fallthrough */
|
/* Fallthrough */
|
||||||
case XML_LEXER_ENDELEM:
|
case XML_LEXER_ENDELEM:
|
||||||
/* Pop out an element out of the DOM. */
|
/* Pop out an element out of the DOM. */
|
||||||
Log(LOG_INFO, "</>");
|
|
||||||
pop();
|
pop();
|
||||||
|
if (!ArraySize(stack))
|
||||||
|
{
|
||||||
|
XMLFreeEvent(event);
|
||||||
|
event = NULL;
|
||||||
|
flag = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case XML_LEXER_DATA:
|
||||||
|
top = XMLCreateText(event->data);
|
||||||
|
XMLAddChild(peek(), top);
|
||||||
break;
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
if (flag)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
XMLFreeEvent(event);
|
XMLFreeEvent(event);
|
||||||
event = NULL;
|
event = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -658,8 +658,6 @@ XMLParseAttQuote(XMLexer *lexer)
|
||||||
|
|
||||||
point = XMLInitialiseBuffer(lexer);
|
point = XMLInitialiseBuffer(lexer);
|
||||||
|
|
||||||
/* TODO: My Prosody is actually trolling me.
|
|
||||||
* GIVE ME A FUCKING STREAM ID YOU RETARD. */
|
|
||||||
while ((c = XMLGetc(lexer)))
|
while ((c = XMLGetc(lexer)))
|
||||||
{
|
{
|
||||||
if (!IsNormalQ(c))
|
if (!IsNormalQ(c))
|
||||||
|
|
|
||||||
75
src/XMPPThread.c
Normal file
75
src/XMPPThread.c
Normal file
|
|
@ -0,0 +1,75 @@
|
||||||
|
#include <Parsee.h>
|
||||||
|
|
||||||
|
#include <Cytoplasm/Memory.h>
|
||||||
|
#include <Cytoplasm/Log.h>
|
||||||
|
#include <Cytoplasm/Str.h>
|
||||||
|
|
||||||
|
#include <Matrix.h>
|
||||||
|
#include <XMPP.h>
|
||||||
|
#include <XML.h>
|
||||||
|
#include <AS.h>
|
||||||
|
|
||||||
|
void *
|
||||||
|
ParseeXMPPThread(void *argp)
|
||||||
|
{
|
||||||
|
ParseeData *args = argp;
|
||||||
|
XMPPComponent *jabber = args->jabber;
|
||||||
|
XMLElement *stanza = NULL;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
/* TODO: pthread cancelation points */
|
||||||
|
XMLElement *body = NULL;
|
||||||
|
XMLElement *data = NULL;
|
||||||
|
char *to, *room, *from, *from_matrix;
|
||||||
|
|
||||||
|
/* Decoding XML is blocking, which will cause memory issues when we
|
||||||
|
* want to murder this thread.
|
||||||
|
* We could ping the server, and die on a "response" stanza, however.
|
||||||
|
*/
|
||||||
|
stanza = XMLDecode(jabber->stream, false);
|
||||||
|
if (!stanza)
|
||||||
|
{
|
||||||
|
ASSend(
|
||||||
|
args->config, "!jdHnoKgHCm51ujbw:ari.lt", "_parsee_bridge",
|
||||||
|
"m.room.message", MatrixCreateNotice("Hi.")
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (StrEquals(stanza->name, "message"))
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < ArraySize(stanza->children); i++)
|
||||||
|
{
|
||||||
|
XMLElement *child = ArrayGet(stanza->children, i);
|
||||||
|
if (StrEquals(child->name, "body"))
|
||||||
|
{
|
||||||
|
body = child;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!body)
|
||||||
|
{
|
||||||
|
XMLFreeElement(stanza);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
to = ParseeDecodeMXID(HashMapGet(stanza->attrs, "to"));
|
||||||
|
from = HashMapGet(stanza->attrs, "from");
|
||||||
|
from_matrix = ParseeEncodeJID(args->config, from);
|
||||||
|
room = ParseeFindDMRoom(args, to, from);
|
||||||
|
data = ArrayGet(body->children, 0);
|
||||||
|
|
||||||
|
/* TODO: Manage that out. $[to] corresponds to a Matrix
|
||||||
|
* user, which we need to find the */
|
||||||
|
ASSend(
|
||||||
|
args->config, room, from_matrix,
|
||||||
|
"m.room.message", MatrixCreateNotice(data->data)
|
||||||
|
);
|
||||||
|
Free(from_matrix);
|
||||||
|
Free(room);
|
||||||
|
Free(to);
|
||||||
|
}
|
||||||
|
XMLFreeElement(stanza);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
@ -13,21 +13,21 @@ extern HashMap * ASVerifyRequest(ParseeHttpArg *);
|
||||||
|
|
||||||
/* Authenticates a request with the correct as_token.
|
/* Authenticates a request with the correct as_token.
|
||||||
* It does not send the request, however. */
|
* It does not send the request, however. */
|
||||||
extern void ASAuthenticateRequest(ParseeConfig *, HttpClientContext *);
|
extern void ASAuthenticateRequest(const ParseeConfig *, HttpClientContext *);
|
||||||
|
|
||||||
/* Registers an user through the Application Service API. Returns
|
/* Registers an user through the Application Service API. Returns
|
||||||
* true if the user was created. */
|
* true if the user was created. */
|
||||||
extern bool ASRegisterUser(ParseeConfig *, char *);
|
extern bool ASRegisterUser(const ParseeConfig *, char *);
|
||||||
|
|
||||||
/* Pings the homeserver to get attention. */
|
/* Pings the homeserver to get attention. */
|
||||||
extern void ASPing(const ParseeConfig *);
|
extern void ASPing(const ParseeConfig *);
|
||||||
|
|
||||||
/* Joins a room from an ID and a given user we want to masquerade
|
/* Joins a room from an ID and a given user we want to masquerade
|
||||||
* as. */
|
* as. */
|
||||||
extern void ASJoin(ParseeConfig *, char *, char *);
|
extern void ASJoin(const ParseeConfig *, char *, char *);
|
||||||
|
|
||||||
/* Sends a message event with a specific type and body.
|
/* Sends a message event with a specific type and body.
|
||||||
* Said body is freed during the function's execution. */
|
* Said body is freed during the function's execution. */
|
||||||
extern void ASSend(ParseeConfig *, char *, char *, char *, HashMap *);
|
extern void ASSend(const ParseeConfig *, char *, char *, char *, HashMap *);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -62,10 +62,7 @@ extern void ParseeConfigFree(void);
|
||||||
extern ParseeData * ParseeInitData(XMPPComponent *);
|
extern ParseeData * ParseeInitData(XMPPComponent *);
|
||||||
extern void ParseeFreeData(ParseeData *);
|
extern void ParseeFreeData(ParseeData *);
|
||||||
|
|
||||||
/* HTTP server handler for Parsee, takes in a config. */
|
extern HttpClientContext * ParseeCreateRequest(const ParseeConfig *, HttpRequestMethod, char *);
|
||||||
extern void ParseeRequest(HttpServerContext *, void *);
|
|
||||||
|
|
||||||
extern HttpClientContext * ParseeCreateRequest(ParseeConfig *, HttpRequestMethod, char *);
|
|
||||||
|
|
||||||
/* Sends headers, and writes the JSON object. */
|
/* Sends headers, and writes the JSON object. */
|
||||||
extern HttpStatus ParseeSetRequestJSON(HttpClientContext *, HashMap *);
|
extern HttpStatus ParseeSetRequestJSON(HttpClientContext *, HashMap *);
|
||||||
|
|
@ -79,9 +76,36 @@ extern bool ParseeIsPuppet(const ParseeConfig *, char *);
|
||||||
/* Decodes a local JID for a user into a string. */
|
/* Decodes a local JID for a user into a string. */
|
||||||
extern char * ParseeDecodeLocalJID(const ParseeConfig *, char *);
|
extern char * ParseeDecodeLocalJID(const ParseeConfig *, char *);
|
||||||
|
|
||||||
|
/* Encodes a JID into a Parsee localpart */
|
||||||
|
extern char * ParseeEncodeJID(const ParseeConfig *, char *);
|
||||||
|
|
||||||
/* Gets the localpart of a MXID */
|
/* Gets the localpart of a MXID */
|
||||||
extern char * ParseeGetLocal(char *);
|
extern char * ParseeGetLocal(char *);
|
||||||
|
|
||||||
/* Encodes an MXID to a valid Jabber ID head */
|
/* Encodes an MXID to a valid Jabber ID head */
|
||||||
extern char * ParseeEncodeMXID(char *);
|
extern char * ParseeEncodeMXID(char *);
|
||||||
|
|
||||||
|
/* Decodes a Jabber ID head into a valid MXID */
|
||||||
|
extern char * ParseeDecodeMXID(char *);
|
||||||
|
|
||||||
|
|
||||||
|
/* HTTP server handler for Parsee, takes in a config. */
|
||||||
|
extern void ParseeRequest(HttpServerContext *, void *);
|
||||||
|
|
||||||
|
/* A pthread callback used for listening to a component */
|
||||||
|
extern void * ParseeXMPPThread(void *data);
|
||||||
|
|
||||||
|
|
||||||
|
/* Finds the room a DM is associated to, from a Matrix user and a Jabber
|
||||||
|
* ID. */
|
||||||
|
extern char * ParseeFindDMRoom(ParseeData *data, char *mxid, char *jid);
|
||||||
|
|
||||||
|
/* Gets a DM ID from a Matrix and Jabber user */
|
||||||
|
extern char * ParseeGetDMID(char *mxid, char *jid);
|
||||||
|
|
||||||
|
/* Creates a DM mapping in the database */
|
||||||
|
extern void ParseePushDMRoom(ParseeData *, char *mxid, char *jid, char *r);
|
||||||
|
|
||||||
|
/* Trims the component from a JID */
|
||||||
|
extern char * ParseeTrimJID(char *jid);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue