From cc0072df0e6907aa3dd3a97a6acad31f86549f38 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Mon, 11 Jun 2018 22:43:19 -0700 Subject: [PATCH] modules: Add preliminary m_room_canonical_alias protocol suite. --- modules/Makefile.am | 2 + modules/m_room_canonical_alias.cc | 119 ++++++++++++++++++++++++++++++ modules/vm.cc | 6 +- 3 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 modules/m_room_canonical_alias.cc diff --git a/modules/Makefile.am b/modules/Makefile.am index 11215ab75..50fa90046 100644 --- a/modules/Makefile.am +++ b/modules/Makefile.am @@ -89,6 +89,7 @@ m_room_create_la_SOURCES = m_room_create.cc m_room_member_la_SOURCES = m_room_member.cc m_room_join_rules_la_SOURCES = m_room_join_rules.cc m_room_history_visibility_la_SOURCES = m_room_history_visibility.cc +m_room_canonical_alias_la_SOURCES = m_room_canonical_alias.cc m_module_LTLIBRARIES = \ m_noop.la \ @@ -100,6 +101,7 @@ m_module_LTLIBRARIES = \ m_room_member.la \ m_room_join_rules.la \ m_room_history_visibility.la \ + m_room_canonical_alias.la \ ### ############################################################################### diff --git a/modules/m_room_canonical_alias.cc b/modules/m_room_canonical_alias.cc new file mode 100644 index 000000000..e8c02aa42 --- /dev/null +++ b/modules/m_room_canonical_alias.cc @@ -0,0 +1,119 @@ +// 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 +{ + "Matrix m.room.canonical_alias" +}; + +const m::room::id::buf +alias_room_id +{ + "alias", ircd::my_host() +}; + +const m::room +alias_room +{ + alias_room_id +}; + +void +_changed_canonical_alias(const m::event &event) +{ + const m::room::alias &alias + { + unquote(at<"content"_>(event).at("alias")) + }; + + const m::room::id &room_id + { + at<"room_id"_>(event) + }; + + const auto event_id + { + send(alias_room, m::me.user_id, "ircd.alias", alias, json::strung{event}) + }; + + log::info + { + "Changed canonical alias of %s to %s by %s with %s => %s", + string_view{room_id}, + string_view{alias}, + json::get<"sender"_>(event), + json::get<"event_id"_>(event), + string_view{event_id} + }; +} + +const m::hookfn<> +_changed_canonical_alias_hookfn +{ + _changed_canonical_alias, + { + { "_site", "vm.notify" }, + { "type", "m.room.canonical_alias" }, + } +}; + +void +_can_change_canonical_alias(const m::event &event) +{ + const m::room::id &room_id + { + at<"room_id"_>(event) + }; + + const m::room::alias &alias + { + unquote(at<"content"_>(event).at("alias")) + }; + + const m::room room + { + room_id + }; + + bool has_alias{false}; + room.get(std::nothrow, "m.room.aliases", alias.host(), [&alias, &has_alias] + (const m::event &event) + { + const json::array &aliases + { + json::get<"content"_>(event).at("aliases") + }; + + for(auto it(begin(aliases)); it != end(aliases) && !has_alias; ++it) + if(unquote(*it) == alias) + has_alias = true; + }); + + if(!has_alias) + throw m::ACCESS_DENIED + { + "Cannot set canonical alias '%s' because it is not an alias in '%s'", + string_view{alias}, + string_view{room_id} + }; +} + +const m::hookfn<> +_can_change_canonical_alias_hookfn +{ + _can_change_canonical_alias, + { + { "_site", "vm.eval" }, + { "type", "m.room.canonical_alias" }, + } +}; diff --git a/modules/vm.cc b/modules/vm.cc index 70073025f..e026b8250 100644 --- a/modules/vm.cc +++ b/modules/vm.cc @@ -78,6 +78,7 @@ void ircd::m::vm::fini() { m::modules.erase("vm_fetch"s); + assert(eval::list.empty()); id::event::buf event_id; const auto current_sequence @@ -114,6 +115,7 @@ ircd::m::vm::eval__commit_room(eval &eval, // Note that the regular opts is unconditionally overridden because the // user should have provided copts instead. + assert(!eval.opts || eval.opts == eval.copts); eval.opts = eval.copts; // Set a member pointer to the json::iov currently being composed. This @@ -256,6 +258,7 @@ ircd::m::vm::eval__commit(eval &eval, // Note that the regular opts is unconditionally overridden because the // user should have provided copts instead. + assert(!eval.opts || eval.opts == eval.copts); eval.opts = eval.copts; // Set a member pointer to the json::iov currently being composed. This @@ -648,7 +651,7 @@ ircd::m::vm::_eval_pdu(eval &eval, }; eval.txn = &txn; - const unwind cleartxn{[&eval] + const unwind clear{[&eval] { eval.txn = nullptr; }}; @@ -736,6 +739,7 @@ ircd::m::vm::_eval_pdu(eval &eval, void ircd::m::vm::write(eval &eval) { + assert(eval.txn); auto &txn(*eval.txn); if(eval.opts->debuglog_accept) log::debug