0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-11-17 07:20:55 +01:00

ircd:Ⓜ️:room::auth: Reorg check() stack interface related.

This commit is contained in:
Jason Volk 2019-08-21 02:30:17 -07:00
parent 065c0bd426
commit 061b85de5b
5 changed files with 214 additions and 87 deletions

View file

@ -30,5 +30,5 @@ namespace ircd::m
// Informational pretty for state // Informational pretty for state
// io=true will run db queries to enhance w/ more information. // io=true will run db queries to enhance w/ more information.
std::ostream &pretty_stateline(std::ostream &, const event &, const event::id &rel = {}, const event::idx & = 0); std::ostream &pretty_stateline(std::ostream &, const event &, const event::idx & = 0);
} }

View file

@ -26,8 +26,12 @@ struct ircd::m::room::auth
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(const event &, hookdata &);
static passfail check(std::nothrow_t, const event &); static passfail check(const event &, const vector_view<event::idx> &);
static passfail check(const event &, const room &);
static passfail check_static(const event &);
static passfail check_present(const event &);
static passfail check_relative(const event &);
static void check(const event &); static void check(const event &);
static bool generate(json::stack::array &, const m::room &, const m::event &); static bool generate(json::stack::array &, const m::room &, const m::event &);

View file

@ -6732,11 +6732,28 @@ console_cmd__event(opt &out, const string_view &line)
<< "HASH MISMATCH :" << b64encode_unpadded(hash(event)) << "HASH MISMATCH :" << b64encode_unpadded(hash(event))
<< std::endl; << std::endl;
const auto &[authed, failmsg](m::room::auth::check(std::nothrow, event)); {
if(!authed) const auto &[authed, failmsg](m::room::auth::check_static(event));
out << std::setw(9) << std::left << "!!! ERROR" << " " if(!authed)
<< "UNAUTHORIZED :" << what(failmsg) out << std::setw(9) << std::left << "!!! ERROR" << " "
<< std::endl; << "UNAUTHORIZED STATIC :" << what(failmsg)
<< std::endl;
}
{
const auto &[authed, failmsg](m::room::auth::check_present(event));
if(!authed)
out << std::setw(9) << std::left << "!!! ERROR" << " "
<< "PRESENTLY UNAUTHORIZED :" << what(failmsg)
<< std::endl;
}
{
const auto &[authed, failmsg](m::room::auth::check_relative(event));
if(!authed)
out << std::setw(9) << std::left << "!!! ERROR" << " "
<< "RELATIVELY UNAUTHORIZED :" << what(failmsg)
<< std::endl;
}
try try
{ {
@ -7716,7 +7733,7 @@ console_cmd__room__top(opt &out, const string_view &line)
out << "top auth:" << std::endl; out << "top auth:" << std::endl;
ssize_t adi(auth.depth()); ssize_t adi(auth.depth());
auth.for_each([&room, &out, &adi] auth.for_each([&out, &adi]
(const m::event::idx &event_idx) (const m::event::idx &event_idx)
{ {
if(adi-- > 8) if(adi-- > 8)
@ -7728,7 +7745,7 @@ console_cmd__room__top(opt &out, const string_view &line)
}; };
if(event.valid) if(event.valid)
m::pretty_stateline(out, event, room.event_id, event_idx); m::pretty_stateline(out, event, event_idx);
return true; return true;
}); });
@ -8811,7 +8828,7 @@ console_cmd__room__state(opt &out, const string_view &line)
string_view{} string_view{}
}; };
state.for_each(type, [&out, &state] state.for_each(type, [&out]
(const string_view &type, const string_view &state_key, const m::event::idx &event_idx) (const string_view &type, const string_view &state_key, const m::event::idx &event_idx)
{ {
const m::event::fetch event const m::event::fetch event
@ -8822,7 +8839,7 @@ console_cmd__room__state(opt &out, const string_view &line)
if(!event.valid) if(!event.valid)
return true; return true;
m::pretty_stateline(out, event, state.event_id, event_idx); m::pretty_stateline(out, event, event_idx);
/* /*
size_t i(0); size_t i(0);
@ -9071,7 +9088,7 @@ console_cmd__room__state__history(opt &out, const string_view &line)
room, bound room, bound
}; };
history.for_each(type, state_key, [&out, &room] history.for_each(type, state_key, [&out]
(const auto &type, const auto &state_key, const auto &depth, const auto &event_idx) (const auto &type, const auto &state_key, const auto &depth, const auto &event_idx)
{ {
const m::event::fetch event const m::event::fetch event
@ -9082,7 +9099,7 @@ console_cmd__room__state__history(opt &out, const string_view &line)
if(!event.valid) if(!event.valid)
return true; return true;
m::pretty_stateline(out, event, room.event_id, event_idx); m::pretty_stateline(out, event, event_idx);
return true; return true;
}); });
@ -9129,7 +9146,7 @@ console_cmd__room__state__space(opt &out, const string_view &line)
room_id room_id
}; };
space.for_each(type, state_key, depth, [&out, &state] space.for_each(type, state_key, depth, [&out]
(const auto &type, const auto &state_key, const auto &depth, const auto &event_idx) (const auto &type, const auto &state_key, const auto &depth, const auto &event_idx)
{ {
const m::event::fetch event const m::event::fetch event
@ -9140,7 +9157,7 @@ console_cmd__room__state__space(opt &out, const string_view &line)
if(!event.valid) if(!event.valid)
return true; return true;
m::pretty_stateline(out, event, {}, event_idx); m::pretty_stateline(out, event, event_idx);
return true; return true;
}); });

View file

@ -23,12 +23,11 @@ std::ostream &
IRCD_MODULE_EXPORT IRCD_MODULE_EXPORT
ircd::m::pretty_stateline(std::ostream &out, ircd::m::pretty_stateline(std::ostream &out,
const event &event, const event &event,
const event::id &rel,
const event::idx &event_idx) const event::idx &event_idx)
{ {
const room room const room room
{ {
json::get<"room_id"_>(event), rel?: event::id{} json::get<"room_id"_>(event)
}; };
const room::state &state const room::state &state
@ -55,23 +54,40 @@ ircd::m::pretty_stateline(std::ostream &out,
m::room::auth::is_power_event(event) m::room::auth::is_power_event(event)
}; };
const auto auth const room::auth::passfail auth[]
{ {
event_idx? event_idx?
room::auth::check(std::nothrow, event): room::auth::check_static(event):
room::auth::passfail{true, {}} room::auth::passfail{false, {}},
event_idx && m::exists(event.event_id)?
room::auth::check_relative(event):
room::auth::passfail{false, {}},
event_idx?
room::auth::check_present(event):
room::auth::passfail{false, {}},
}; };
char buf[16]; char buf[32];
const string_view flags const string_view flags
{ {
fmt::sprintf fmt::sprintf
{ {
buf, "%c%c%c%c", buf, "%c%c%c|%c%c%c",
active? 'A' : ' ',
!std::get<bool>(auth)? 'F' : ' ', active? 'A' : '-',
power? 'P' : ' ', redacted? 'R' : '-',
redacted? 'R' : ' ', power? 'P' : '-',
std::get<bool>(auth[0]) && !std::get<std::exception_ptr>(auth[0])? ' ':
!std::get<bool>(auth[0]) && std::get<std::exception_ptr>(auth[0])? 'X': '?',
std::get<bool>(auth[1]) && !std::get<std::exception_ptr>(auth[1])? ' ':
!std::get<bool>(auth[1]) && std::get<std::exception_ptr>(auth[1])? 'X': '?',
std::get<bool>(auth[2]) && !std::get<std::exception_ptr>(auth[2])? ' ':
!std::get<bool>(auth[2]) && std::get<std::exception_ptr>(auth[2])? 'X': '?',
} }
}; };
@ -125,8 +141,8 @@ ircd::m::pretty_stateline(std::ostream &out,
; ;
} }
if(std::get<1>(auth)) if(std::get<1>(auth[0]))
out << ":" << trunc(what(std::get<1>(auth)), 72); out << ":" << trunc(what(std::get<1>(auth[0])), 72);
out << std::endl; out << std::endl;
return out; return out;

View file

@ -144,23 +144,95 @@ void
IRCD_MODULE_EXPORT IRCD_MODULE_EXPORT
ircd::m::room::auth::check(const event &event) ircd::m::room::auth::check(const event &event)
{ {
const auto &[pass, fail] passfail pf;
{ auto &[pass, fail] {pf};
check(std::nothrow, event)
};
if(!pass) pf = check_static(event);
if(!pass) try
{ {
assert(bool(fail)); assert(bool(fail));
std::rethrow_exception(fail); std::rethrow_exception(fail);
__builtin_unreachable(); __builtin_unreachable();
} }
catch(const FAIL &e)
{
throw FAIL
{
"Fails against provided auth_events :%s", e.what()
};
}
if(!m::exists(room(at<"room_id"_>(event))))
if(at<"type"_>(event) == "m.room.create")
return;
pf = check_present(event);
if(!pass) try
{
assert(bool(fail));
std::rethrow_exception(fail);
__builtin_unreachable();
}
catch(const FAIL &e)
{
throw FAIL
{
"Fails against present state of %s :%s",
json::get<"room_id"_>(event),
e.what()
};
}
if(!m::exists(event.event_id))
return;
pf = check_relative(event);
if(!pass) try
{
assert(bool(fail));
std::rethrow_exception(fail);
__builtin_unreachable();
}
catch(const FAIL &e)
{
throw FAIL
{
"Fails against state of %s relative to %s :%s",
json::get<"room_id"_>(event),
string_view{event.event_id},
e.what()
};
}
} }
ircd::m::room::auth::passfail ircd::m::room::auth::passfail
IRCD_MODULE_EXPORT IRCD_MODULE_EXPORT
ircd::m::room::auth::check(std::nothrow_t, ircd::m::room::auth::check_relative(const event &event)
const event &event) try
{
using json::at;
const m::room room
{
at<"room_id"_>(event), event.event_id
};
return check(event, room);
}
catch(const std::exception &)
{
return
{
false, std::current_exception()
};
}
ircd::m::room::auth::passfail
IRCD_MODULE_EXPORT
ircd::m::room::auth::check_present(const event &event)
try try
{ {
using json::at; using json::at;
@ -170,7 +242,28 @@ try
at<"room_id"_>(event) at<"room_id"_>(event)
}; };
const m::event::prev refs{event}; return check(event, room);
}
catch(const std::exception &)
{
return
{
false, std::current_exception()
};
}
ircd::m::room::auth::passfail
IRCD_MODULE_EXPORT
ircd::m::room::auth::check_static(const event &event)
try
{
using json::at;
const m::event::prev refs
{
event
};
const auto count const auto count
{ {
refs.auth_events_count() refs.auth_events_count()
@ -184,14 +277,33 @@ try
count, count,
}; };
// Vector of contingent event idxs from the event and the present state m::event::idx idx[4]
m::event::idx idxs[9]
{ {
count > 0? m::index(refs.auth_event(0)): 0UL, count > 0? m::index(refs.auth_event(0)): 0UL,
count > 1? m::index(refs.auth_event(1)): 0UL, count > 1? m::index(refs.auth_event(1)): 0UL,
count > 2? m::index(refs.auth_event(2)): 0UL, count > 2? m::index(refs.auth_event(2)): 0UL,
count > 3? m::index(refs.auth_event(3)): 0UL, count > 3? m::index(refs.auth_event(3)): 0UL,
};
return check(event, vector_view<event::idx>{idx, count});
}
catch(const std::exception &)
{
return
{
false, std::current_exception()
};
}
ircd::m::room::auth::passfail
IRCD_MODULE_EXPORT
ircd::m::room::auth::check(const event &event,
const room &room)
{
using json::at;
m::event::idx idx[5]
{
room.get(std::nothrow, "m.room.create", ""), room.get(std::nothrow, "m.room.create", ""),
room.get(std::nothrow, "m.room.power_levels", ""), room.get(std::nothrow, "m.room.power_levels", ""),
room.get(std::nothrow, "m.room.member", at<"sender"_>(event)), room.get(std::nothrow, "m.room.member", at<"sender"_>(event)),
@ -205,58 +317,36 @@ try
room.get(std::nothrow, "m.room.member", at<"state_key"_>(event)): 0UL, room.get(std::nothrow, "m.room.member", at<"state_key"_>(event)): 0UL,
}; };
m::event::fetch auth[9]; return check(event, vector_view<event::idx>{idx, 5});
for(size_t i(0); i < 9; ++i)
if(idxs[i])
seek(auth[i], idxs[i], std::nothrow);
size_t i, j;
const m::event *authv[4];
for(i = 0, j = 0; i < 4 && j < 4; ++i)
if(auth[i].valid)
authv[j++] = &auth[i];
hookdata data
{
event, {authv, j}
};
auto ret
{
check(std::nothrow, event, data)
};
if(!std::get<bool>(ret) || std::get<std::exception_ptr>(ret))
return ret;
for(i = 4, j = 0; i < 9 && j < 4; ++i)
if(auth[i].valid)
authv[j++] = &auth[i];
data =
{
event, {authv, j}
};
ret =
{
check(std::nothrow, event, data)
};
return ret;
}
catch(const std::exception &)
{
return
{
false, std::current_exception()
};
} }
ircd::m::room::auth::passfail ircd::m::room::auth::passfail
IRCD_MODULE_EXPORT IRCD_MODULE_EXPORT
ircd::m::room::auth::check(std::nothrow_t, ircd::m::room::auth::check(const event &event,
const event &event, const vector_view<event::idx> &idx)
{
std::array<m::event::fetch, 5> auth;
for(size_t i(0), j(0); i < idx.size(); ++i)
if(idx.at(i))
m::seek(auth.at(j++), idx.at(i), std::nothrow);
size_t j(0);
std::array<const m::event *, 5> authv;
for(size_t i(0); i < auth.size(); ++i)
if(auth.at(i).valid)
authv.at(j++) = &auth.at(i);
hookdata data
{
event, {authv.data(), j}
};
return check(event, data);
}
ircd::m::room::auth::passfail
IRCD_MODULE_EXPORT
ircd::m::room::auth::check(const event &event,
hookdata &data) hookdata &data)
try try
{ {