engine: log out local sessions on a gossiped account suspension
All checks were successful
CI / check (push) Successful in 3m43s
All checks were successful
CI / check (push) Successful in 3m43s
A local SUSPEND logs out the account's active sessions, but a suspension arriving by gossip only set the flag — a session already identified on a remote node stayed logged in despite the network-wide suspension. ingest now signals AccountChange::Suspended, and gossip_ingest ends those sessions (the account and its channels are kept). Factors the per-session logout into a shared logout_uid helper.
This commit is contained in:
parent
58af1187fc
commit
886fe65e4d
3 changed files with 84 additions and 10 deletions
|
|
@ -469,6 +469,12 @@ impl Engine {
|
|||
self.handle_account_gone(&a, "was dropped");
|
||||
true
|
||||
}
|
||||
Some(db::AccountChange::Suspended(a)) => {
|
||||
// A gossiped suspension keeps the account and its channels, but its
|
||||
// live sessions here must end (a local SUSPEND logs them out too).
|
||||
self.logout_account_sessions(&a, "was suspended");
|
||||
false
|
||||
}
|
||||
None => false,
|
||||
};
|
||||
// handle_account_gone may have released a channel that had a bot assigned.
|
||||
|
|
@ -504,15 +510,9 @@ impl Engine {
|
|||
}
|
||||
// Log out and inform each local session that held the name.
|
||||
for uid in victims {
|
||||
self.network.clear_account(&uid);
|
||||
self.emit_irc(NetAction::Metadata { target: uid.clone(), key: "accountname".to_string(), value: String::new() });
|
||||
if let Some(ns) = &ns {
|
||||
self.emit_irc(NetAction::Notice {
|
||||
from: ns.clone(),
|
||||
to: uid.clone(),
|
||||
text: format!("Your account \x02{account}\x02 {reason}. You have been logged out."),
|
||||
});
|
||||
if !orphaned.is_empty() {
|
||||
self.logout_uid(&uid, account, reason);
|
||||
if !orphaned.is_empty() {
|
||||
if let Some(ns) = &ns {
|
||||
self.emit_irc(NetAction::Notice {
|
||||
from: ns.clone(),
|
||||
to: uid,
|
||||
|
|
@ -523,6 +523,28 @@ impl Engine {
|
|||
}
|
||||
}
|
||||
|
||||
// Log a single session out of `account`, telling them why (services-sourced).
|
||||
fn logout_uid(&mut self, uid: &str, account: &str, reason: &str) {
|
||||
self.network.clear_account(uid);
|
||||
self.emit_irc(NetAction::Metadata { target: uid.to_string(), key: "accountname".to_string(), value: String::new() });
|
||||
if let Some(ns) = self.nick_service.clone() {
|
||||
self.emit_irc(NetAction::Notice {
|
||||
from: ns,
|
||||
to: uid.to_string(),
|
||||
text: format!("Your account \x02{account}\x02 {reason}. You have been logged out."),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Log out every local session identified to `account` — e.g. after a gossiped
|
||||
// suspension. Unlike `handle_account_gone` the account and its channels stay
|
||||
// put; only the live sessions end.
|
||||
fn logout_account_sessions(&mut self, account: &str, reason: &str) {
|
||||
for uid in self.network.uids_logged_into(account) {
|
||||
self.logout_uid(&uid, account, reason);
|
||||
}
|
||||
}
|
||||
|
||||
// Compact the log if it has grown past the live account count. Returns
|
||||
// whether it rewrote anything.
|
||||
pub fn maybe_compact(&mut self) -> std::io::Result<bool> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue