auth: deferred login is authoritative in the account map, not just ircd metadata
All checks were successful
CI / check (push) Successful in 3m46s
All checks were successful
CI / check (push) Successful in 3m46s
This commit is contained in:
parent
75c6537532
commit
e112b8737c
2 changed files with 27 additions and 2 deletions
|
|
@ -275,7 +275,7 @@ impl Engine {
|
|||
/// ctx helpers the inline path did, so its login side-effects (login, notice,
|
||||
/// AJOIN, vhost, memo notice) stay identical.
|
||||
pub fn complete_authenticate(&mut self, ok: bool, then: AuthThen) -> Vec<NetAction> {
|
||||
match then {
|
||||
let actions = match then {
|
||||
AuthThen::Identify { uid, agent, name, account } => {
|
||||
self.db.note_auth(&name, ok);
|
||||
let mut ctx = ServiceCtx::default();
|
||||
|
|
@ -320,6 +320,14 @@ impl Engine {
|
|||
self.sasl_deny("SASL PLAIN", &agent, &client, Some(&account), "bad password")
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
// This runs in the link layer, off the handle() path, so the login's
|
||||
// accountname metadata never reaches track_accounts in handle(). Apply it
|
||||
// here so echo's own account map is authoritative and doesn't depend on the
|
||||
// ircd reflecting the metadata back — which is a no-op when re-authenticating
|
||||
// an already-logged-in user after a services relink, leaving the user unable
|
||||
// to use their access despite a successful login.
|
||||
self.track_accounts(&actions);
|
||||
actions
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -673,6 +673,23 @@
|
|||
assert_eq!(e.network.account_of("000AAAAAB"), None, "empty account is a logout");
|
||||
}
|
||||
|
||||
// A login that finishes off the handle() path (the link layer's deferred
|
||||
// password/keycard verify) must still make echo's OWN account map authoritative.
|
||||
// Otherwise re-identifying an already-logged-in user after a services relink —
|
||||
// a no-op accountname on the ircd, so nothing is reflected back — leaves them
|
||||
// unable to use their access despite a successful login.
|
||||
#[test]
|
||||
fn deferred_login_makes_account_authoritative() {
|
||||
let mut e = engine_with("deferlogin", "foo", "sesame");
|
||||
e.handle(NetEvent::UserConnect { uid: "000AAAAAB".into(), nick: "foo".into(), host: "h".into(), ip: "0.0.0.0".into() });
|
||||
assert_eq!(e.network.account_of("000AAAAAB"), None);
|
||||
// Exactly what the link layer does after the off-thread verify — not via handle().
|
||||
let then = echo_api::AuthThen::Identify { uid: "000AAAAAB".into(), agent: "42SAAAAAA".into(), name: "foo".into(), account: "foo".into() };
|
||||
let out = e.complete_authenticate(true, then);
|
||||
assert!(out.iter().any(|a| matches!(a, NetAction::Metadata { key, value, .. } if key == "accountname" && value == "foo")), "emits accountname metadata for the ircd");
|
||||
assert_eq!(e.network.account_of("000AAAAAB"), Some("foo"), "and is authoritative in echo's own map");
|
||||
}
|
||||
|
||||
// A suspension that arrives by gossip must end local sessions on that account,
|
||||
// just as a local SUSPEND does — the account and its channels stay put.
|
||||
#[test]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue