0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-30 17:34:04 +01:00

ircd:Ⓜ️:event::auth: Add hookdata::find() to improve initialization.

This commit is contained in:
Jason Volk 2019-07-20 16:29:58 -07:00
parent 9e2e20f3e8
commit e1356fb50d
2 changed files with 85 additions and 62 deletions

View file

@ -13,33 +13,20 @@
struct ircd::m::event::auth struct ircd::m::event::auth
{ {
struct hookdata;
struct refs; struct refs;
struct chain; struct chain;
struct hookdata;
using passfail = std::tuple<bool, std::exception_ptr>; using passfail = std::tuple<bool, std::exception_ptr>;
using events_view = vector_view<const event *>;
IRCD_M_EXCEPTION(error, FAIL, http::UNAUTHORIZED) IRCD_M_EXCEPTION(error, FAIL, http::UNAUTHORIZED)
static bool is_power_event(const event &); static bool is_power_event(const event &);
static passfail check(std::nothrow_t, const event &, hookdata &);
static passfail check(std::nothrow_t, const event &); static passfail check(std::nothrow_t, const event &);
static void check(const event &); static void check(const event &);
}; };
struct ircd::m::event::auth::hookdata
{
event::prev prev;
vector_view<const event *> auth_events;
const event *auth_create {nullptr};
const event *auth_power {nullptr};
const event *auth_join_rules {nullptr};
const event *auth_member_target {nullptr};
const event *auth_member_sender {nullptr};
bool allow {false};
std::exception_ptr fail;
hookdata(const event &, const vector_view<const event *> &auth_events);
};
/// 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
@ -86,3 +73,22 @@ struct ircd::m::event::auth::chain
:idx{idx} :idx{idx}
{} {}
}; };
class ircd::m::event::auth::hookdata
{
const event *find(const event::closure_bool &) const;
public:
event::prev prev;
vector_view<const event *> auth_events;
const event *auth_create {nullptr};
const event *auth_power {nullptr};
const event *auth_join_rules {nullptr};
const event *auth_member_target {nullptr};
const event *auth_member_sender {nullptr};
bool allow {false};
std::exception_ptr fail;
hookdata(const event &, const events_view &auth_events);
};

View file

@ -1845,20 +1845,23 @@ ircd::m::event::auth::check(std::nothrow_t,
event, {authv, j} event, {authv, j}
}; };
return check(std::nothrow, event, data);
}
ircd::m::event::auth::passfail
ircd::m::event::auth::check(std::nothrow_t,
const event &event,
hookdata &data)
try try
{ {
event_auth_hook(event, data); event_auth_hook(event, data);
return {data.allow, data.fail};
} }
catch(const FAIL &e) catch(const FAIL &e)
{ {
data.allow = false; data.allow = false;
data.fail = std::current_exception(); data.fail = std::current_exception();
} return {data.allow, data.fail};
return
{
data.allow, data.fail
};
} }
ircd::m::event::auth::hookdata::hookdata(const m::event &event, ircd::m::event::auth::hookdata::hookdata(const m::event &event,
@ -1871,41 +1874,55 @@ ircd::m::event::auth::hookdata::hookdata(const m::event &event,
{ {
auth_events auth_events
} }
,auth_create
{ {
for(size_t i(0); i < auth_events.size(); ++i) find([](const auto &event)
{ {
const m::event &a(*auth_events.at(i)); return json::get<"type"_>(event) == "m.room.create";
const auto &type(json::get<"type"_>(a)); })
if(type == "m.room.create")
{
assert(!auth_create);
auth_create = &a;
} }
else if(type == "m.room.power_levels") ,auth_power
{ {
assert(!auth_power); find([](const auto &event)
auth_power = &a; {
return json::get<"type"_>(event) == "m.room.power_levels";
})
} }
else if(type == "m.room.join_rules") ,auth_join_rules
{ {
assert(!auth_join_rules); find([](const auto &event)
auth_join_rules = &a; {
return json::get<"type"_>(event) == "m.room.join_rules";
})
} }
else if(type == "m.room.member") ,auth_member_target
{ {
if(json::get<"sender"_>(event) == json::get<"state_key"_>(a)) find([&event](const auto &auth_event)
{
return json::get<"type"_>(auth_event) == "m.room.member" &&
json::get<"state_key"_>(auth_event) == json::get<"state_key"_>(event);
})
}
,auth_member_sender
{
find([&event](const auto &auth_event)
{
return json::get<"type"_>(auth_event) == "m.room.member" &&
json::get<"state_key"_>(auth_event) == json::get<"sender"_>(event);
})
}
{ {
assert(!auth_member_sender);
auth_member_sender = &a;
} }
if(json::get<"state_key"_>(event) == json::get<"state_key"_>(a)) const ircd::m::event *
ircd::m::event::auth::hookdata::find(const event::closure_bool &closure)
const
{ {
assert(!auth_member_target); for(const auto *const &event : auth_events)
auth_member_target = &a; if(likely(event) && closure(*event))
} return event;
}
} return nullptr;
} }
/* /*