0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-25 16:22:35 +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
#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
/// 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
/// not contain the auth-chain or state resolution algorithm here, those are
/// later constructed out of this data.
struct ircd::m::event::auth
struct ircd::m::event::auth::refs
{
struct chain;
event::idx idx;
public:
@ -39,7 +44,7 @@ struct ircd::m::event::auth
size_t count(const string_view &type) const noexcept;
size_t count() const noexcept;
auth(const event::idx &idx)
refs(const event::idx &idx)
:idx{idx}
{
assert(idx);
@ -47,3 +52,21 @@ struct ircd::m::event::auth
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.
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
@ -318,7 +318,7 @@ ircd::m::dbs::_index_event(db::txn &txn,
if(opts.event_id)
_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);
if(opts.event_refs)
@ -380,8 +380,7 @@ ircd::m::dbs::_index_event_auth(db::txn &txn,
const event &event,
const write_opts &opts)
{
if(!is_power_event(event))
return;
assert(event::auth::is_power_event(event));
const event::prev &prev{event};
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
//
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
//
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 ();
static mods::import<prototype> rebuild
{
"m_event", "ircd::m::event::auth::rebuild"
"m_event", "ircd::m::event::auth::refs::rebuild"
};
rebuild();
}
size_t
ircd::m::event::auth::count()
ircd::m::event::auth::refs::count()
const noexcept
{
return count(string_view{});
}
size_t
ircd::m::event::auth::count(const string_view &type)
ircd::m::event::auth::refs::count(const string_view &type)
const noexcept
{
assert(idx);
size_t ret(0);
for_each(type, [&ret](const auto &)
{
@ -1323,7 +1364,7 @@ const noexcept
}
bool
ircd::m::event::auth::has(const event::idx &idx)
ircd::m::event::auth::refs::has(const event::idx &idx)
const noexcept
{
return !for_each([&idx](const event::idx &ref)
@ -1333,7 +1374,7 @@ const noexcept
}
bool
ircd::m::event::auth::has(const string_view &type)
ircd::m::event::auth::refs::has(const string_view &type)
const noexcept
{
bool ret{false};
@ -1347,17 +1388,18 @@ const noexcept
}
bool
ircd::m::event::auth::for_each(const closure_bool &closure)
ircd::m::event::auth::refs::for_each(const closure_bool &closure)
const
{
return for_each(string_view{}, closure);
}
bool
ircd::m::event::auth::for_each(const string_view &type,
const closure_bool &closure)
ircd::m::event::auth::refs::for_each(const string_view &type,
const closure_bool &closure)
const
{
assert(idx);
auto &column
{
dbs::event_auth
@ -1411,6 +1453,53 @@ const
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

View file

@ -5964,7 +5964,7 @@ console_cmd__event__refs__rebuild(opt &out, const string_view &line)
}
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, " ",
{
@ -5981,7 +5981,7 @@ console_cmd__event__auth(opt &out, const string_view &line)
param.at("type", ""_sv)
};
const m::event::auth auth
const m::event::auth::refs auth
{
index(event_id)
};

View file

@ -626,7 +626,7 @@ ircd::m::event::refs::rebuild()
void
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 log_interval{8192};
@ -689,3 +689,43 @@ ircd::m::event::auth::rebuild()
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;
}