From 1d7fce8368a83e26934ffe20194a3708115728ca Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Sat, 12 May 2018 16:00:37 -0700 Subject: [PATCH] ircd::m: Reorg filter interface and linkage related. --- include/ircd/m/filter.h | 9 +- include/ircd/m/user.h | 7 ++ ircd/Makefile.am | 1 - ircd/m/filter.cc | 199 ---------------------------------- ircd/m/m.cc | 197 +++++++++++++++++++++++++++++++++ modules/client/user/filter.cc | 65 ++++++++++- modules/client/user/user.h | 11 ++ 7 files changed, 279 insertions(+), 210 deletions(-) delete mode 100644 ircd/m/filter.cc diff --git a/include/ircd/m/filter.h b/include/ircd/m/filter.h index 2b39e0881..447dbfc82 100644 --- a/include/ircd/m/filter.h +++ b/include/ircd/m/filter.h @@ -91,15 +91,8 @@ struct ircd::m::filter > { using super_type::tuple; - using super_type::operator=; - - using closure = std::function; - - static bool get(std::nothrow_t, const user &, const string_view &filter_id, const closure &); - static void get(const user &, const string_view &filter_id, const closure &); - static string_view set(const mutable_buffer &id, const user &, const json::object &filter); - filter(const user &, const string_view &filter_id, const mutable_buffer &); + using super_type::operator=; }; #pragma GCC diagnostic pop diff --git a/include/ircd/m/user.h b/include/ircd/m/user.h index 47096f0f5..fb11e8bc0 100644 --- a/include/ircd/m/user.h +++ b/include/ircd/m/user.h @@ -57,6 +57,13 @@ struct ircd::m::user json::object account_data(const mutable_buffer &out, const string_view &type) const; //nothrow event::id::buf account_data(const m::user &sender, const string_view &type, const json::object &value); + using filter_closure = std::function; + bool filter(std::nothrow_t, const string_view &filter_id, const filter_closure &) const; + void filter(const string_view &filter_id, const filter_closure &) const; + std::string filter(std::nothrow_t, const string_view &filter_id) const; + std::string filter(const string_view &filter_id) const; + event::id::buf filter(const json::object &filter, const mutable_buffer &id); + bool is_active() const; event::id::buf deactivate(); event::id::buf activate(); diff --git a/ircd/Makefile.am b/ircd/Makefile.am index 8459201c0..db37f5eee 100644 --- a/ircd/Makefile.am +++ b/ircd/Makefile.am @@ -108,7 +108,6 @@ libircd_la_SOURCES = \ m/dbs.cc \ m/state.cc \ m/room.cc \ - m/filter.cc \ m/request.cc \ m/v1.cc \ m/m.cc \ diff --git a/ircd/m/filter.cc b/ircd/m/filter.cc deleted file mode 100644 index 1926fd626..000000000 --- a/ircd/m/filter.cc +++ /dev/null @@ -1,199 +0,0 @@ -// 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. - -//TODO: globular expression -bool -ircd::m::match(const room_event_filter &filter, - const event &event) -{ - for(const auto &room_id : json::get<"not_rooms"_>(filter)) - if(at<"room_id"_>(event) == unquote(room_id)) - return false; - - if(empty(json::get<"rooms"_>(filter))) - return match(event_filter{filter}, event); - - for(const auto &room_id : json::get<"rooms"_>(filter)) - if(at<"room_id"_>(event) == unquote(room_id)) - return match(event_filter{filter}, event); - - return false; -} - -//TODO: globular expression -bool -ircd::m::match(const event_filter &filter, - const event &event) -{ - for(const auto &type : json::get<"not_types"_>(filter)) - if(at<"type"_>(event) == unquote(type)) - return false; - - for(const auto &sender : json::get<"not_senders"_>(filter)) - if(at<"sender"_>(event) == unquote(sender)) - return false; - - if(empty(json::get<"senders"_>(filter)) && empty(json::get<"types"_>(filter))) - return true; - - if(empty(json::get<"senders"_>(filter))) - { - for(const auto &type : json::get<"types"_>(filter)) - if(at<"type"_>(event) == unquote(type)) - return true; - - return false; - } - - if(empty(json::get<"types"_>(filter))) - { - for(const auto &sender : json::get<"senders"_>(filter)) - if(at<"sender"_>(event) == unquote(sender)) - return true; - - return false; - } - - return true; -} - -// -// filter -// - -ircd::m::filter::filter(const user &user, - const string_view &filter_id, - const mutable_buffer &buf) -{ - get(user, filter_id, [this, &buf] - (const json::object &filter) - { - const size_t len - { - copy(buf, string_view{filter}) - }; - - new (this) m::filter - { - json::object - { - data(buf), len - } - }; - }); -} - -ircd::string_view -ircd::m::filter::set(const mutable_buffer &idbuf, - const user &user, - const json::object &filter) -{ - const auto user_room_id - { - user.room_id() - }; - - const m::room room - { - user_room_id - }; - - const sha256::buf hash - { - sha256{filter} - }; - - const string_view filter_id - { - b64encode_unpadded(idbuf, hash) - }; - - send(room, user.user_id, "ircd.filter", filter_id, filter); - return filter_id; -} - -void -ircd::m::filter::get(const user &user, - const string_view &filter_id, - const closure &closure) -{ - if(!get(std::nothrow, user, filter_id, closure)) - throw m::NOT_FOUND - { - "Filter not found" - }; -} - -bool -ircd::m::filter::get(std::nothrow_t, - const user &user, - const string_view &filter_id, - const closure &closure) -{ - const auto user_room_id - { - user.room_id() - }; - - const m::room room - { - user_room_id - }; - - return room.get(std::nothrow, "ircd.filter", filter_id, [&closure] - (const m::event &event) - { - const json::object &content - { - at<"content"_>(event) - }; - - closure(content); - }); -} - -// -// room_filter -// - -ircd::m::room_filter::room_filter(const mutable_buffer &buf, - const json::members &members) -:super_type::tuple -{ - json::stringify(mutable_buffer{buf}, members) -} -{ -} - -// -// room_event_filter -// - -ircd::m::room_event_filter::room_event_filter(const mutable_buffer &buf, - const json::members &members) -:super_type::tuple -{ - json::stringify(mutable_buffer{buf}, members) -} -{ -} - -// -// event_filter -// - -ircd::m::event_filter::event_filter(const mutable_buffer &buf, - const json::members &members) -:super_type::tuple -{ - json::stringify(mutable_buffer{buf}, members) -} -{ -} diff --git a/ircd/m/m.cc b/ircd/m/m.cc index a7fbd8437..42bd8ee8d 100644 --- a/ircd/m/m.cc +++ b/ircd/m/m.cc @@ -1430,6 +1430,132 @@ ircd::m::events::for_each(const uint64_t &start, return true; } +/////////////////////////////////////////////////////////////////////////////// +// +// m/filter.h +// + +//TODO: globular expression +bool +ircd::m::match(const room_event_filter &filter, + const event &event) +{ + for(const auto &room_id : json::get<"not_rooms"_>(filter)) + if(at<"room_id"_>(event) == unquote(room_id)) + return false; + + if(empty(json::get<"rooms"_>(filter))) + return match(event_filter{filter}, event); + + for(const auto &room_id : json::get<"rooms"_>(filter)) + if(at<"room_id"_>(event) == unquote(room_id)) + return match(event_filter{filter}, event); + + return false; +} + +//TODO: globular expression +bool +ircd::m::match(const event_filter &filter, + const event &event) +{ + for(const auto &type : json::get<"not_types"_>(filter)) + if(at<"type"_>(event) == unquote(type)) + return false; + + for(const auto &sender : json::get<"not_senders"_>(filter)) + if(at<"sender"_>(event) == unquote(sender)) + return false; + + if(empty(json::get<"senders"_>(filter)) && empty(json::get<"types"_>(filter))) + return true; + + if(empty(json::get<"senders"_>(filter))) + { + for(const auto &type : json::get<"types"_>(filter)) + if(at<"type"_>(event) == unquote(type)) + return true; + + return false; + } + + if(empty(json::get<"types"_>(filter))) + { + for(const auto &sender : json::get<"senders"_>(filter)) + if(at<"sender"_>(event) == unquote(sender)) + return true; + + return false; + } + + return true; +} + +// +// filter +// + +ircd::m::filter::filter(const user &user, + const string_view &filter_id, + const mutable_buffer &buf) +{ + get(user, filter_id, [this, &buf] + (const json::object &filter) + { + const size_t len + { + copy(buf, string_view{filter}) + }; + + new (this) m::filter + { + json::object + { + data(buf), len + } + }; + }); +} + +// +// room_filter +// + +ircd::m::room_filter::room_filter(const mutable_buffer &buf, + const json::members &members) +:super_type::tuple +{ + json::stringify(mutable_buffer{buf}, members) +} +{ +} + +// +// room_event_filter +// + +ircd::m::room_event_filter::room_event_filter(const mutable_buffer &buf, + const json::members &members) +:super_type::tuple +{ + json::stringify(mutable_buffer{buf}, members) +} +{ +} + +// +// event_filter +// + +ircd::m::event_filter::event_filter(const mutable_buffer &buf, + const json::members &members) +:super_type::tuple +{ + json::stringify(mutable_buffer{buf}, members) +} +{ +} + /////////////////////////////////////////////////////////////////////////////// // // m/rooms.h @@ -1679,6 +1805,77 @@ const return function(*this); } +ircd::m::event::id::buf +ircd::m::user::filter(const json::object &filter, + const mutable_buffer &idbuf) +{ + using prototype = event::id::buf (const m::user &, const json::object &, const mutable_buffer &); + + static import function + { + "client_user", "filter_set" + }; + + return function(*this, filter, idbuf); +} + +std::string +ircd::m::user::filter(const string_view &filter_id) +const +{ + std::string ret; + filter(filter_id, [&ret] + (const json::object &filter) + { + ret.assign(data(filter), size(filter)); + }); + + return ret; +} + +std::string +ircd::m::user::filter(std::nothrow_t, + const string_view &filter_id) +const +{ + std::string ret; + filter(std::nothrow, filter_id, [&ret] + (const json::object &filter) + { + ret.assign(data(filter), size(filter)); + }); + + return ret; +} + +void +ircd::m::user::filter(const string_view &filter_id, + const filter_closure &closure) +const +{ + if(!filter(std::nothrow, filter_id, closure)) + throw m::NOT_FOUND + { + "Filter '%s' not found", filter_id + }; +} + +bool +ircd::m::user::filter(std::nothrow_t, + const string_view &filter_id, + const filter_closure &closure) +const +{ + using prototype = bool (std::nothrow_t, const m::user &, const string_view &, const filter_closure &); + + static import function + { + "client_user", "filter_get" + }; + + return function(std::nothrow, *this, filter_id, closure); +} + ircd::m::event::id::buf ircd::m::user::account_data(const m::user &sender, const string_view &type, diff --git a/modules/client/user/filter.cc b/modules/client/user/filter.cc index 5f52cabd2..b6e576585 100644 --- a/modules/client/user/filter.cc +++ b/modules/client/user/filter.cc @@ -23,7 +23,12 @@ get__filter(client &client, url::decode(request.parv[2], filter_id_buf) }; - m::filter::get(user_id, filter_id, [&client] + const m::user user + { + user_id + }; + + user.filter(filter_id, [&client] (const json::object &filter) { resource::response @@ -94,10 +99,15 @@ post__filter(client &client, json::get<"presence"_>(request) }; + m::user user + { + user_id + }; + char filter_id_buf[64]; const auto filter_id { - m::filter::set(filter_id_buf, user_id, request.body) + user.filter(request.body, filter_id_buf) }; return resource::response @@ -108,3 +118,54 @@ post__filter(client &client, } }; } + +m::event::id::buf +filter_set(const m::user &user, + const json::object &filter, + const mutable_buffer &idbuf) +{ + const m::user::room user_room + { + user + }; + + const sha256::buf hash + { + sha256{filter} + }; + + const string_view filter_id + { + b64encode_unpadded(idbuf, hash) + }; + + //TODO: ABA + if(user_room.has("ircd.filter", filter_id)) + return {}; + + //TODO: ABA + return send(user_room, user.user_id, "ircd.filter", filter_id, filter); +} + +bool +filter_get(std::nothrow_t, + const m::user &user, + const string_view &filter_id, + const m::user::filter_closure &closure) +{ + const m::user::room user_room + { + user + }; + + return user_room.get(std::nothrow, "ircd.filter", filter_id, [&closure] + (const m::event &event) + { + const json::object &content + { + at<"content"_>(event) + }; + + closure(content); + }); +} diff --git a/modules/client/user/user.h b/modules/client/user/user.h index 9875f096f..6697d71b2 100644 --- a/modules/client/user/user.h +++ b/modules/client/user/user.h @@ -15,6 +15,17 @@ extern ircd::resource user_resource; // filter.cc // +extern "C" bool +filter_get(std::nothrow_t, + const ircd::m::user &, + const ircd::string_view &filter_id, + const ircd::m::user::filter_closure &); + +extern "C" ircd::m::event::id::buf +filter_set(const ircd::m::user &, + const ircd::json::object &filter, + const ircd::mutable_buffer &idbuf); + ircd::resource::response get__filter(ircd::client &, const ircd::resource::request &,