chanserv: channel SUSPEND / UNSUSPEND (oper-gated)
Freezes a channel gated on Priv::Suspend: a typed Suspension on ChannelInfo (event-logged, snapshotted, lazy expiry — same shape as the account one, no Anope Extensible/Checker or expiry timer). While suspended, ChanServ refuses all management (guards in require_op/require_founder and the founder-inline SET/DROP/MLOCK), the engine skips Join enforcement (no auto-op/akick/entrymsg), and suspending kicks everyone out; INFO shows it. parse_duration moved into the SDK so both SUSPEND commands share it. Data + full-flow tests.
This commit is contained in:
parent
bbbe2c6cb8
commit
cb081a2e95
8 changed files with 241 additions and 18 deletions
|
|
@ -1,4 +1,4 @@
|
|||
use fedserv_api::{NetView, Priv, Sender, ServiceCtx, Store};
|
||||
use fedserv_api::{parse_duration, NetView, Priv, Sender, ServiceCtx, Store};
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
// SUSPEND <account> [+expiry] [reason] / UNSUSPEND <account>: freeze or unfreeze
|
||||
|
|
@ -49,19 +49,6 @@ pub fn handle(me: &str, from: &Sender, args: &[&str], ctx: &mut ServiceCtx, net:
|
|||
}
|
||||
}
|
||||
|
||||
// Parse a duration like "30d", "12h", "45m", "90s", or a bare number of seconds.
|
||||
fn parse_duration(s: &str) -> Option<u64> {
|
||||
let (num, mult) = match s.chars().last()? {
|
||||
'd' | 'D' => (&s[..s.len() - 1], 86_400),
|
||||
'h' | 'H' => (&s[..s.len() - 1], 3_600),
|
||||
'm' | 'M' => (&s[..s.len() - 1], 60),
|
||||
's' | 'S' => (&s[..s.len() - 1], 1),
|
||||
c if c.is_ascii_digit() => (s, 1),
|
||||
_ => return None,
|
||||
};
|
||||
num.parse::<u64>().ok().map(|n| n * mult)
|
||||
}
|
||||
|
||||
fn now_unix() -> u64 {
|
||||
SystemTime::now().duration_since(UNIX_EPOCH).map(|d| d.as_secs()).unwrap_or(0)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue