From ad9a5f731ae1a542f018655557a1a7fd3342c936 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Tue, 3 Apr 2018 12:59:44 -0700 Subject: [PATCH] modules/m_room_member: Eval foreign invites; committer in modules/client/rooms/invite. --- modules/client/rooms/invite.cc | 92 ++++++++++++++++++++++++++++++++++ modules/m_room_member.cc | 51 +++++++++++++++++++ 2 files changed, 143 insertions(+) diff --git a/modules/client/rooms/invite.cc b/modules/client/rooms/invite.cc index 19701d956..e6edacab2 100644 --- a/modules/client/rooms/invite.cc +++ b/modules/client/rooms/invite.cc @@ -17,6 +17,9 @@ invite__room_user(const m::room &, const m::user::id &target, const m::user::id &sender); +extern "C" m::event::id::buf +invite__foreign(const m::event &); + resource::response post__invite(client &client, const resource::request &request, @@ -68,3 +71,92 @@ invite__room_user(const m::room &room, return commit(room, event, content); } + +m::event::id::buf +invite__foreign(const m::event &event) +{ + const auto &event_id + { + at<"event_id"_>(event) + }; + + const auto &room_id + { + at<"room_id"_>(event) + }; + + const m::user::id &target + { + at<"state_key"_>(event) + }; + + const unique_buffer bufs + { + 148_KiB + }; + + mutable_buffer buf{bufs}; + const auto proto + { + json::stringify(buf, event) + }; + + m::v1::invite::opts opts; + opts.remote = target.host(); + m::v1::invite request + { + room_id, event_id, proto, buf, std::move(opts) + }; + + request.wait(seconds(10)); //TODO: conf + request.get(); + + const json::array &response + { + request.in.content + }; + + const http::code &rcode + { + http::code(lex_cast(response.at(0))) + }; + + if(rcode != http::OK) + throw http::error + { + rcode + }; + + const json::object &robject + { + response.at(1) + }; + + const m::event &revent + { + robject.at("event") + }; + + if(!verify(revent, target.host())) + throw m::error + { + http::UNAUTHORIZED, "M_INVITE_UNSIGNED", + "Invitee's host '%s' did not sign the invite.", + target.host() + }; + + if(!verify(revent, my_host())) + throw m::error + { + http::FORBIDDEN, "M_INVITE_MODIFIED", + "Invite event no longer verified by our signature.", + target.host() + }; + + m::vm::opts vmopts; + vmopts.non_conform.set(m::event::conforms::MISSING_PREV_STATE); + vmopts.infolog_accept = true; + + m::vm::eval(revent, vmopts); + return at<"event_id"_>(revent); +} diff --git a/modules/m_room_member.cc b/modules/m_room_member.cc index 8b5661e1a..c21ca2447 100644 --- a/modules/m_room_member.cc +++ b/modules/m_room_member.cc @@ -49,3 +49,54 @@ _join_room_hookfn }, _join_room }; + +using invite_foreign_proto = m::event::id::buf (const m::event &); +m::import +invite__foreign +{ + "client_rooms", "invite__foreign" +}; + +static void +invite_foreign(const m::event &event) +{ + const m::room::id &room_id + { + at<"room_id"_>(event) + }; + + const m::user::id &target + { + at<"state_key"_>(event) + }; + + const auto target_host + { + target.host() + }; + + const m::room::origins origins + { + room_id + }; + + if(origins.has(target_host)) + return; + + const auto eid + { + invite__foreign(event) + }; + +} + +const m::hook +invite_foreign_hookfn +{ + { + { "_site", "vm.commit" }, + { "type", "m.room.member" }, + { "membership", "invite" }, + }, + invite_foreign +};