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:
parent
065c0bd426
commit
061b85de5b
5 changed files with 214 additions and 87 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 &);
|
||||||
|
|
|
@ -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;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue