#include #include #include #include #include #include #include #include #include static void ParseeMemberHandler(ParseeData *data, HashMap *event) { char *state_key = GrabString(event, 1, "state_key"); char *membership = GrabString(event, 2, "content", "membership"); char *room_id = GrabString(event, 1, "room_id"); char *sender = GrabString(event, 1, "sender"); char *chat_id; char *local = data->config->sender_localpart; const ParseeConfig *conf = data->config; if (StrEquals(membership, "invite") && ParseeIsPuppet(conf, state_key)) { DbRef *ref; HashMap *json; char *jid; bool direct = GrabBoolean(event, 2, "content", "is_direct"); bool bot = !strncmp(sender + 1, local, strlen(local)); ASJoin(conf, room_id, state_key); jid = ParseeDecodeLocalJID(conf, state_key); if (direct && !bot) { ref = DbCreate(data->db, 3, "rooms", room_id, "data"); json = DbJson(ref); HashMapSet(json, "is_direct", JsonValueBoolean(direct && !bot)); HashMapSet(json, "xmpp_user", JsonValueString(jid)); DbUnlock(data->db, ref); ParseePushDMRoom(data, sender, jid, room_id); } if (jid) { Free(jid); } } else if (StrEquals(membership, "join") && !ParseeIsPuppet(conf, state_key)) { char *jid = ParseeEncodeMXID(state_key); chat_id = ParseeGetFromRoomID(data, room_id); if (chat_id) { char *muc = ParseeGetMUCID(data, chat_id); char *rev = StrConcat(2, muc, "/parsee"); /* Make the user join the MUC */ XMPPJoinMUC(data->jabber, jid, rev); Free(rev); Free(muc); } Free(jid); Free(chat_id); } } static void ParseeBotHandler(ParseeData *data, HashMap *event) { char *msgtype = GrabString(event, 2, "content", "msgtype"); char *body = GrabString(event, 2, "content", "body"); char *id = GrabString(event, 1, "room_id"); char *ev_id = GrabString(event, 1, "event_id"); char *sender = GrabString(event, 1, "sender"); char *profile = StrConcat(4, "@", data->config->sender_localpart, ":", data->config->homeserver_host ); Command *cmd; if (StrEquals(msgtype, "m.notice")) { Free(profile); return; } if (*body != '!') { /* All commands are to be marked with a ! */ Free(ASSend( data->config, id, profile, "m.room.message", MatrixCreateNotice("Please enter a valid command") )); Free(profile); return; } /* TODO: Make an improvment. This is the bare minimum */ if (!StrEquals(sender, data->config->matrix_admin)) { Free(ASSend( data->config, id, profile, "m.room.message", MatrixCreateNotice("You are not the admin") )); Free(profile); return; } body++; cmd = CommandParse(body); { ParseeCmdArg arg; arg.data = data; arg.event = event; RouteCommand(data->handler, cmd, &arg); } end: Free(profile); CommandFree(cmd); } static void ParseeMessageHandler(ParseeData *data, HashMap *event) { XMPPComponent *jabber = data->jabber; DbRef *ref; HashMap *json; char *msgtype = GrabString(event, 2, "content", "msgtype"); char *body = GrabString(event, 2, "content", "body"); char *id = GrabString(event, 1, "room_id"); char *ev_id = GrabString(event, 1, "event_id"); char *sender = GrabString(event, 1, "sender"); char *chat_id, *muc_id, *jid; char *reply_id = MatrixGetReply(event); char *xepd = ParseeXMPPify(event); char *cmd_lp = data->config->sender_localpart; bool direct = false; chat_id = ParseeGetFromRoomID(data, id); ref = DbLock(data->db, 3, "rooms", id, "data"); json = DbJson(ref); direct = JsonValueAsBoolean(HashMapGet(json, "is_direct")); if (ParseeIsPuppet(data->config, sender) || ParseeManageBan(data, sender, id)) { DbUnlock(data->db, ref); Free(chat_id); Free(reply_id); Free(xepd); return; } if (!direct && !chat_id) { ParseeBotHandler(data, event); DbUnlock(data->db, ref); Free(chat_id); Free(reply_id); Free(xepd); return; } if (direct) { char *user = GrabString(json, 1, "xmpp_user"); char *local = ParseeEncodeMXID(sender); Log(LOG_INFO," Sending to %s as %s", user, local); XMPPSendPlain(jabber, local, user, body, "chat", NULL, NULL, ev_id, NULL, NULL); DbUnlock(data->db, ref); Free(chat_id); Free(local); Free(reply_id); Free(xepd); return; } DbUnlock(data->db, ref); /* Try to find the chat ID */ muc_id = ParseeGetMUCID(data, chat_id); if (!chat_id) { Free(reply_id); Free(xepd); return; } jid = ParseeEncodeMXID(sender); { /* TODO: Check the name's validity */ 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); char *unedited_id = MatrixGetEdit(event); char *origin_id = NULL; if (reply_id) { ParseeGetStanzaInfo(data, chat_id, reply_id, &stanza, &sender); } else if (unedited_id) { ParseeGetOrigin(data, chat_id, unedited_id, &origin_id); } XMPPJoinMUC(jabber, jid, rev); XMPPSendPlain( jabber, jid, muc_id, xepd ? xepd : body, "groupchat", stanza, sender, ev_id, unauth, origin_id ); Free(rev); Free(name); Free(stanza); Free(sender); Free(unauth); Free(origin_id); Free(unedited_id); } Free(chat_id); Free(muc_id); Free(jid); Free(reply_id); Free(xepd); } void ParseeEventHandler(ParseeData *data, HashMap *event) { char *event_type; if (!data || !event) { return; } event_type = GrabString(event, 1, "type"); if (StrEquals(event_type, "m.room.member")) { ParseeMemberHandler(data, event); return; } if (StrEquals(event_type, "m.room.message")) { ParseeMessageHandler(data, event); return; } }