0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-09-29 12:18:54 +02: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
// 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 passfail check(std::nothrow_t, const event &, hookdata &);
static passfail check(std::nothrow_t, const event &);
static passfail check(const event &, hookdata &);
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 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))
<< std::endl;
const auto &[authed, failmsg](m::room::auth::check(std::nothrow, event));
if(!authed)
out << std::setw(9) << std::left << "!!! ERROR" << " "
<< "UNAUTHORIZED :" << what(failmsg)
<< std::endl;
{
const auto &[authed, failmsg](m::room::auth::check_static(event));
if(!authed)
out << std::setw(9) << std::left << "!!! ERROR" << " "
<< "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
{
@ -7716,7 +7733,7 @@ console_cmd__room__top(opt &out, const string_view &line)
out << "top auth:" << std::endl;
ssize_t adi(auth.depth());
auth.for_each([&room, &out, &adi]
auth.for_each([&out, &adi]
(const m::event::idx &event_idx)
{
if(adi-- > 8)
@ -7728,7 +7745,7 @@ console_cmd__room__top(opt &out, const string_view &line)
};
if(event.valid)
m::pretty_stateline(out, event, room.event_id, event_idx);
m::pretty_stateline(out, event, event_idx);
return true;
});
@ -8811,7 +8828,7 @@ console_cmd__room__state(opt &out, const string_view &line)
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 m::event::fetch event
@ -8822,7 +8839,7 @@ console_cmd__room__state(opt &out, const string_view &line)
if(!event.valid)
return true;
m::pretty_stateline(out, event, state.event_id, event_idx);
m::pretty_stateline(out, event, event_idx);
/*
size_t i(0);
@ -9071,7 +9088,7 @@ console_cmd__room__state__history(opt &out, const string_view &line)
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 m::event::fetch event
@ -9082,7 +9099,7 @@ console_cmd__room__state__history(opt &out, const string_view &line)
if(!event.valid)
return true;
m::pretty_stateline(out, event, room.event_id, event_idx);
m::pretty_stateline(out, event, event_idx);
return true;
});
@ -9129,7 +9146,7 @@ console_cmd__room__state__space(opt &out, const string_view &line)
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 m::event::fetch event
@ -9140,7 +9157,7 @@ console_cmd__room__state__space(opt &out, const string_view &line)
if(!event.valid)
return true;
m::pretty_stateline(out, event, {}, event_idx);
m::pretty_stateline(out, event, event_idx);
return true;
});

View file

@ -23,12 +23,11 @@ std::ostream &
IRCD_MODULE_EXPORT
ircd::m::pretty_stateline(std::ostream &out,
const event &event,
const event::id &rel,
const event::idx &event_idx)
{
const room room
{
json::get<"room_id"_>(event), rel?: event::id{}
json::get<"room_id"_>(event)
};
const room::state &state
@ -55,23 +54,40 @@ ircd::m::pretty_stateline(std::ostream &out,
m::room::auth::is_power_event(event)
};
const auto auth
const room::auth::passfail auth[]
{
event_idx?
room::auth::check(std::nothrow, event):
room::auth::passfail{true, {}}
room::auth::check_static(event):
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
{
fmt::sprintf
{
buf, "%c%c%c%c",
active? 'A' : ' ',
!std::get<bool>(auth)? 'F' : ' ',
power? 'P' : ' ',
redacted? 'R' : ' ',
buf, "%c%c%c|%c%c%c",
active? 'A' : '-',
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))
out << ":" << trunc(what(std::get<1>(auth)), 72);
if(std::get<1>(auth[0]))
out << ":" << trunc(what(std::get<1>(auth[0])), 72);
out << std::endl;
return out;

View file

@ -144,23 +144,95 @@ void
IRCD_MODULE_EXPORT
ircd::m::room::auth::check(const event &event)
{
const auto &[pass, fail]
{
check(std::nothrow, event)
};
passfail pf;
auto &[pass, fail] {pf};
if(!pass)
pf = check_static(event);
if(!pass) try
{
assert(bool(fail));
std::rethrow_exception(fail);
__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_MODULE_EXPORT
ircd::m::room::auth::check(std::nothrow_t,
const event &event)
ircd::m::room::auth::check_relative(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
{
using json::at;
@ -170,7 +242,28 @@ try
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
{
refs.auth_events_count()
@ -184,14 +277,33 @@ try
count,
};
// Vector of contingent event idxs from the event and the present state
m::event::idx idxs[9]
m::event::idx idx[4]
{
count > 0? m::index(refs.auth_event(0)): 0UL,
count > 1? m::index(refs.auth_event(1)): 0UL,
count > 2? m::index(refs.auth_event(2)): 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.power_levels", ""),
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,
};
m::event::fetch auth[9];
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()
};
return check(event, vector_view<event::idx>{idx, 5});
}
ircd::m::room::auth::passfail
IRCD_MODULE_EXPORT
ircd::m::room::auth::check(std::nothrow_t,
const event &event,
ircd::m::room::auth::check(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)
try
{