From d2d6ba0f18a81e12b2b44779e7d421bdd7fba8c9 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Tue, 3 Apr 2018 17:16:15 -0700 Subject: [PATCH] modules/federation: Add send_leave endpoint handler. --- modules/Makefile.am | 2 + modules/federation/send_leave.cc | 132 +++++++++++++++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 modules/federation/send_leave.cc diff --git a/modules/Makefile.am b/modules/Makefile.am index b2b34d513..f3a18b2a3 100644 --- a/modules/Makefile.am +++ b/modules/Makefile.am @@ -248,6 +248,7 @@ federation_federation_send_join_la_SOURCES = federation/send_join.cc federation_federation_state_ids_la_SOURCES = federation/state_ids.cc federation_federation_state_la_SOURCES = federation/state.cc federation_federation_make_leave_la_SOURCES = federation/make_leave.cc +federation_federation_send_leave_la_SOURCES = federation/send_leave.cc federation_module_LTLIBRARIES = \ federation/federation_send.la \ @@ -263,6 +264,7 @@ federation_module_LTLIBRARIES = \ federation/federation_state_ids.la \ federation/federation_state.la \ federation/federation_make_leave.la \ + federation/federation_send_leave.la \ ### ############################################################################### diff --git a/modules/federation/send_leave.cc b/modules/federation/send_leave.cc new file mode 100644 index 000000000..aaac50c0f --- /dev/null +++ b/modules/federation/send_leave.cc @@ -0,0 +1,132 @@ +// Matrix Construct +// +// Copyright (C) Matrix Construct Developers, Authors & Contributors +// Copyright (C) 2016-2018 Jason Volk +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice is present in all copies. The +// full license for this software is available in the LICENSE file. + +using namespace ircd; + +mapi::header +IRCD_MODULE +{ + "Federation :Send leave event" +}; + +const string_view +send_leave_description +{R"( + +Inject a leave event into a room originating from a server without any joined +users in that room. + +)"}; + +resource +send_leave_resource +{ + "/_matrix/federation/v1/send_leave/", + { + send_leave_description, + resource::DIRECTORY + } +}; + +resource::response +put__send_leave(client &client, + const resource::request &request) +{ + if(request.parv.size() < 1) + throw m::NEED_MORE_PARAMS + { + "room_id path parameter required" + }; + + m::room::id::buf room_id + { + url::decode(request.parv[0], room_id) + }; + + if(!my_host(room_id.host())) + throw m::error + { + http::FORBIDDEN, "M_INVALID_ROOM_ID", + "Can only send_leave for rooms on my host '%s'", + my_host() + }; + + if(request.parv.size() < 2) + throw m::NEED_MORE_PARAMS + { + "event_id path parameter required" + }; + + m::event::id::buf event_id + { + url::decode(request.parv[1], event_id) + }; + + const m::event event + { + request + }; + + if(at<"event_id"_>(event) != event_id) + throw m::error + { + http::NOT_MODIFIED, "M_MISMATCH_EVENT_ID", + "ID of event in request body does not match path parameter." + }; + + if(at<"room_id"_>(event) != room_id) + throw m::error + { + http::NOT_MODIFIED, "M_MISMATCH_ROOM_ID", + "ID of room in request body does not match path parameter." + }; + + if(json::get<"type"_>(event) != "m.room.member") + throw m::error + { + http::NOT_MODIFIED, "M_INVALID_TYPE", + "Event type must be m.room.member" + }; + + if(json::get<"membership"_>(event) != "leave") + throw m::error + { + http::NOT_MODIFIED, "M_INVALID_MEMBERSHIP", + "Event membership state must be 'leave'." + }; + + if(unquote(json::get<"content"_>(event).get("membership")) != "leave") + throw m::error + { + http::NOT_MODIFIED, "M_INVALID_CONTENT_MEMBERSHIP", + "Event content.membership state must be 'leave'." + }; + + m::vm::opts vmopts; + vmopts.non_conform.set(m::event::conforms::MISSING_PREV_STATE); + m::vm::eval eval + { + event, vmopts + }; + + return resource::response + { + client, http::OK + }; +} + +resource::method +method_put +{ + send_leave_resource, "PUT", put__send_leave, + { + method_put.VERIFY_ORIGIN + } +};