diff --git a/include/ircd/m/event/auth.h b/include/ircd/m/event/auth.h index 79779bc07..f23c9b76c 100644 --- a/include/ircd/m/event/auth.h +++ b/include/ircd/m/event/auth.h @@ -46,25 +46,23 @@ struct ircd::m::event::auth::refs refs(const event::idx &idx) :idx{idx} - { - assert(idx); - } + {} }; struct ircd::m::event::auth::chain { + using closure_bool = std::function; + event::idx idx; - public: - using closure_bool = std::function &)>; + static bool for_each(const auth::chain &, const closure_bool &); + public: bool for_each(const closure_bool &) const; bool has(const string_view &type) const noexcept; size_t depth() const noexcept; chain(const event::idx &idx) :idx{idx} - { - assert(idx); - } + {} }; diff --git a/ircd/m_event.cc b/ircd/m_event.cc index 6b118bdce..7a20b9560 100644 --- a/ircd/m_event.cc +++ b/ircd/m_event.cc @@ -1433,7 +1433,7 @@ ircd::m::event::auth::chain::depth() const noexcept { size_t ret(0); - for_each([&ret](const auto &) + for_each([&ret](const auto &, const auto &) { ++ret; return true; @@ -1448,15 +1448,9 @@ const noexcept { bool ret(false); for_each([&type, &ret] - (const vector_view &v) + (const auto &, const auto &event) { - for(auto it(begin(v)); !ret && it != end(v); ++it) - m::get(std::nothrow, *it, "type", [&type, &ret] - (const string_view &value) - { - ret = type == value; - }); - + ret = type == json::get<"type"_>(event); return !ret; }); @@ -1467,8 +1461,21 @@ bool ircd::m::event::auth::chain::for_each(const closure_bool &closure) const { - assert(idx); - return true; + return chain::for_each(*this, closure); +} + +bool +ircd::m::event::auth::chain::for_each(const auth::chain &c, + const closure_bool &closure) +{ + using prototype = bool (const auth::chain &, const closure_bool &); + + static mods::import call + { + "m_event", "ircd::m::event::auth::chain::for_each" + }; + + return call(c, closure); } /////////////////////////////////////////////////////////////////////////////// diff --git a/modules/console.cc b/modules/console.cc index 488a082a5..dded9d50b 100644 --- a/modules/console.cc +++ b/modules/console.cc @@ -5921,6 +5921,36 @@ console_cmd__event__visible(opt &out, const string_view &line) return true; } +bool +console_cmd__event__auth(opt &out, const string_view &line) +{ + const params param{line, " ", + { + "event_id" + }}; + + const m::event::id &event_id + { + param.at("event_id") + }; + + const m::event::auth::chain ac + { + m::index(event_id) + }; + + ac.for_each([&out](const auto &idx, const auto &event) + { + out << idx + << " " << pretty_oneline(event) + << std::endl; + + return true; + }); + + return true; +} + bool console_cmd__event__refs__rebuild(opt &out, const string_view &line) { diff --git a/modules/m_event.cc b/modules/m_event.cc index 43ac10981..8207d56b3 100644 --- a/modules/m_event.cc +++ b/modules/m_event.cc @@ -562,6 +562,53 @@ ircd::m::pretty_oneline(std::ostream &s, return s; } +bool +IRCD_MODULE_EXPORT +ircd::m::event::auth::chain::for_each(const auth::chain &c, + const closure_bool &closure) +{ + m::event::fetch e, a; + std::set ae; + std::deque aq {c.idx}; do + { + const auto idx(aq.front()); + aq.pop_front(); + if(!seek(e, idx, std::nothrow)) + continue; + + const m::event::prev prev{e}; + const auto count(prev.auth_events_count()); + for(size_t i(0); i < count && i < 4; ++i) + { + const auto &auth_event_id(prev.auth_event(i)); + const auto &auth_event_idx(index(auth_event_id, std::nothrow)); + if(!auth_event_idx) + continue; + + auto it(ae.lower_bound(auth_event_idx)); + if(it == end(ae) || *it != auth_event_idx) + { + seek(a, auth_event_idx, std::nothrow); + ae.emplace_hint(it, auth_event_idx); + if(a.valid) + aq.emplace_back(auth_event_idx); + } + } + } + while(!aq.empty()); + + for(const auto &idx : ae) + { + if(!seek(e, idx, std::nothrow)) + continue; + + if(!closure(idx, e)) + return false; + } + + return true; +} + void IRCD_MODULE_EXPORT ircd::m::event::refs::rebuild()