0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2025-02-18 09:40:12 +01:00

ircd:Ⓜ️:event::auth: Restructure / rename interfaces; move is_power_event() to module.

This commit is contained in:
Jason Volk 2019-02-12 17:50:44 -08:00
parent aaf80932fe
commit 674373be90
5 changed files with 200 additions and 49 deletions

View file

@ -11,20 +11,25 @@
#pragma once #pragma once
#define HAVE_IRCD_M_EVENT_AUTH_H #define HAVE_IRCD_M_EVENT_AUTH_H
namespace ircd::m struct ircd::m::event::auth
{ {
bool is_power_event(const event &); struct refs;
} struct chain;
static bool is_power_event(const event &);
static string_view failed(const event &, const vector_view<const event> &auth_events);
static string_view failed(const event &);
static bool check(std::nothrow_t, const event &);
static void check(const event &);
};
/// Interface to the references made by other power events to this power /// Interface to the references made by other power events to this power
/// event in the `auth_events`. This interface only deals with power events, /// event in the `auth_events`. This interface only deals with power events,
/// it doesn't care if a non-power event referenced a power event. This does /// it doesn't care if a non-power event referenced a power event. This does
/// not contain the auth-chain or state resolution algorithm here, those are /// not contain the auth-chain or state resolution algorithm here, those are
/// later constructed out of this data. /// later constructed out of this data.
struct ircd::m::event::auth struct ircd::m::event::auth::refs
{ {
struct chain;
event::idx idx; event::idx idx;
public: public:
@ -39,7 +44,7 @@ struct ircd::m::event::auth
size_t count(const string_view &type) const noexcept; size_t count(const string_view &type) const noexcept;
size_t count() const noexcept; size_t count() const noexcept;
auth(const event::idx &idx) refs(const event::idx &idx)
:idx{idx} :idx{idx}
{ {
assert(idx); assert(idx);
@ -47,3 +52,21 @@ struct ircd::m::event::auth
static void rebuild(); static void rebuild();
}; };
struct ircd::m::event::auth::chain
{
event::idx idx;
public:
using closure_bool = std::function<bool (const vector_view<const event::id> &)>;
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);
}
};

View file

@ -136,9 +136,9 @@ ircd::m::dbs::init::init(std::string dbopts)
// Construct global convenience references for the event property columns. // Construct global convenience references for the event property columns.
for(size_t i(0); i < keys.size(); ++i) for(size_t i(0); i < keys.size(); ++i)
event_column[i] = db::column event_column.at(i) = db::column
{ {
*events, keys[i], std::nothrow *events, keys.at(i), std::nothrow
}; };
// Construct global convenience references for the metadata columns // Construct global convenience references for the metadata columns
@ -318,7 +318,7 @@ ircd::m::dbs::_index_event(db::txn &txn,
if(opts.event_id) if(opts.event_id)
_index_event_id(txn, event, opts); _index_event_id(txn, event, opts);
if(opts.event_auth) if(opts.event_auth && event::auth::is_power_event(event))
_index_event_auth(txn, event, opts); _index_event_auth(txn, event, opts);
if(opts.event_refs) if(opts.event_refs)
@ -380,8 +380,7 @@ ircd::m::dbs::_index_event_auth(db::txn &txn,
const event &event, const event &event,
const write_opts &opts) const write_opts &opts)
{ {
if(!is_power_event(event)) assert(event::auth::is_power_event(event));
return;
const event::prev &prev{event}; const event::prev &prev{event};
for(size_t i(0); i < prev.auth_events_count(); ++i) for(size_t i(0); i < prev.auth_events_count(); ++i)

View file

@ -1259,59 +1259,100 @@ ircd::m::index(const event::id &event_id,
// event/auth.h // event/auth.h
// //
bool
ircd::m::is_power_event(const m::event &event)
{
if(json::get<"type"_>(event) == "m.room.create")
return true;
if(json::get<"type"_>(event) == "m.room.power_levels")
return true;
if(json::get<"type"_>(event) == "m.room.join_rules")
return true;
if(json::get<"type"_>(event) != "m.room.member")
return false;
if(at<"sender"_>(event) == at<"state_key"_>(event))
return false;
if(membership(event) == "leave" || membership(event) == "ban")
return true;
return false;
}
// //
// event::auth // event::auth
// //
void void
ircd::m::event::auth::rebuild() ircd::m::event::auth::check(const event &event)
{
const auto reason
{
failed(event)
};
if(reason)
throw m::ACCESS_DENIED
{
"Authorization of %s failed against its auth_events :%s",
json::get<"event_id"_>(event),
reason
};
}
bool
ircd::m::event::auth::check(std::nothrow_t,
const event &event)
{
return !failed(event);
}
ircd::string_view
ircd::m::event::auth::failed(const event &event)
{
using prototype = string_view (const m::event &);
static mods::import<prototype> call
{
"m_event", "ircd::m::event::auth::failed"
};
return call(event);
}
ircd::string_view
ircd::m::event::auth::failed(const event &event,
const vector_view<const m::event> &auth_events)
{
using prototype = string_view (const m::event &, const vector_view<const m::event> &);
static mods::import<prototype> call
{
"m_event", "ircd::m::event::auth::failed"
};
return call(event, auth_events);
}
bool
ircd::m::event::auth::is_power_event(const m::event &event)
{
static mods::import<decltype(auth::is_power_event)> call
{
"m_event", "ircd::m::event::auth::is_power_event"
};
return call(event);
}
//
// event::auth::refs
//
void
ircd::m::event::auth::refs::rebuild()
{ {
using prototype = void (); using prototype = void ();
static mods::import<prototype> rebuild static mods::import<prototype> rebuild
{ {
"m_event", "ircd::m::event::auth::rebuild" "m_event", "ircd::m::event::auth::refs::rebuild"
}; };
rebuild(); rebuild();
} }
size_t size_t
ircd::m::event::auth::count() ircd::m::event::auth::refs::count()
const noexcept const noexcept
{ {
return count(string_view{}); return count(string_view{});
} }
size_t size_t
ircd::m::event::auth::count(const string_view &type) ircd::m::event::auth::refs::count(const string_view &type)
const noexcept const noexcept
{ {
assert(idx);
size_t ret(0); size_t ret(0);
for_each(type, [&ret](const auto &) for_each(type, [&ret](const auto &)
{ {
@ -1323,7 +1364,7 @@ const noexcept
} }
bool bool
ircd::m::event::auth::has(const event::idx &idx) ircd::m::event::auth::refs::has(const event::idx &idx)
const noexcept const noexcept
{ {
return !for_each([&idx](const event::idx &ref) return !for_each([&idx](const event::idx &ref)
@ -1333,7 +1374,7 @@ const noexcept
} }
bool bool
ircd::m::event::auth::has(const string_view &type) ircd::m::event::auth::refs::has(const string_view &type)
const noexcept const noexcept
{ {
bool ret{false}; bool ret{false};
@ -1347,17 +1388,18 @@ const noexcept
} }
bool bool
ircd::m::event::auth::for_each(const closure_bool &closure) ircd::m::event::auth::refs::for_each(const closure_bool &closure)
const const
{ {
return for_each(string_view{}, closure); return for_each(string_view{}, closure);
} }
bool bool
ircd::m::event::auth::for_each(const string_view &type, ircd::m::event::auth::refs::for_each(const string_view &type,
const closure_bool &closure) const closure_bool &closure)
const const
{ {
assert(idx);
auto &column auto &column
{ {
dbs::event_auth dbs::event_auth
@ -1411,6 +1453,53 @@ const
return true; return true;
} }
//
// event::auth::chain
//
size_t
ircd::m::event::auth::chain::depth()
const noexcept
{
size_t ret(0);
for_each([&ret](const auto &)
{
++ret;
return true;
});
return ret;
}
bool
ircd::m::event::auth::chain::has(const string_view &type)
const noexcept
{
bool ret(false);
for_each([&type, &ret]
(const vector_view<const event::id> &v)
{
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;
});
return !ret;
});
return ret;
}
bool
ircd::m::event::auth::chain::for_each(const closure_bool &closure)
const
{
assert(idx);
return true;
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// //
// event/refs.h // event/refs.h

View file

@ -5964,7 +5964,7 @@ console_cmd__event__refs__rebuild(opt &out, const string_view &line)
} }
bool bool
console_cmd__event__auth(opt &out, const string_view &line) console_cmd__event__auth__refs(opt &out, const string_view &line)
{ {
const params param{line, " ", const params param{line, " ",
{ {
@ -5981,7 +5981,7 @@ console_cmd__event__auth(opt &out, const string_view &line)
param.at("type", ""_sv) param.at("type", ""_sv)
}; };
const m::event::auth auth const m::event::auth::refs auth
{ {
index(event_id) index(event_id)
}; };

View file

@ -626,7 +626,7 @@ ircd::m::event::refs::rebuild()
void void
IRCD_MODULE_EXPORT IRCD_MODULE_EXPORT
ircd::m::event::auth::rebuild() ircd::m::event::auth::refs::rebuild()
{ {
static const size_t pool_size{96}; static const size_t pool_size{96};
static const size_t log_interval{8192}; static const size_t log_interval{8192};
@ -689,3 +689,43 @@ ircd::m::event::auth::rebuild()
txn(); txn();
} }
ircd::string_view
IRCD_MODULE_EXPORT
ircd::m::event::auth::failed(const m::event &event)
{
return {};
}
ircd::string_view
IRCD_MODULE_EXPORT
ircd::m::event::auth::failed(const m::event &event,
const vector_view<const m::event> &auth_events)
{
return {};
}
bool
IRCD_MODULE_EXPORT
ircd::m::event::auth::is_power_event(const m::event &event)
{
if(json::get<"type"_>(event) == "m.room.create")
return true;
if(json::get<"type"_>(event) == "m.room.power_levels")
return true;
if(json::get<"type"_>(event) == "m.room.join_rules")
return true;
if(json::get<"type"_>(event) != "m.room.member")
return false;
if(at<"sender"_>(event) == at<"state_key"_>(event))
return false;
if(membership(event) == "leave" || membership(event) == "ban")
return true;
return false;
}