Add OperServ with AKILL network bans
The first operator module. AKILL manages network bans as a typed, event-sourced list with lazy expiry, mirroring the patterns the other modules use: - AKILL ADD [+expiry] <user@host> <reason> stores the ban and drives an ircd G-line (applied to matching users already online and to future connections); AKILL DEL <mask|number> lifts it; AKILL LIST [pattern] shows the live list, numbered. Admin-only. - Bans are Global events, so every node holds the list and re-asserts each one at burst with its remaining duration. Expired bans are hidden lazily and dropped at compaction. - Masks are normalised to user@host (a nick! prefix is stripped, both sides lowercased) and an all-wildcard mask is refused. Email (send_email) is already reachable from the api via ServiceCtx, and adds AddLine/DelLine to the action vocabulary for any future X-line kinds.
This commit is contained in:
parent
253d4c2a2d
commit
d2c1d076fb
12 changed files with 430 additions and 12 deletions
|
|
@ -86,6 +86,12 @@ pub enum NetAction {
|
|||
Topic { from: String, channel: String, topic: String },
|
||||
// Invite a user to a channel, sourced from pseudoclient `from`.
|
||||
Invite { from: String, uid: String, channel: String },
|
||||
// Add a network ban (X-line — `kind` is the ircd's line type, e.g. "G" for a
|
||||
// G-line) covering `mask`, applied to matching users already online and to
|
||||
// future connections. `duration` in seconds, 0 = permanent.
|
||||
AddLine { kind: String, mask: String, setter: String, duration: u64, reason: String },
|
||||
// Lift a network ban previously set with AddLine.
|
||||
DelLine { kind: String, mask: String },
|
||||
Raw(String),
|
||||
// Internal only, never serialized to the wire: a registration whose password
|
||||
// still needs its (expensive) key derivation. The link layer runs the
|
||||
|
|
@ -324,6 +330,22 @@ impl ServiceCtx {
|
|||
channel: channel.to_string(),
|
||||
});
|
||||
}
|
||||
|
||||
// Set a network ban (X-line) at the ircd. `duration` seconds, 0 = permanent.
|
||||
pub fn add_line(&mut self, kind: &str, mask: &str, setter: &str, duration: u64, reason: &str) {
|
||||
self.actions.push(NetAction::AddLine {
|
||||
kind: kind.to_string(),
|
||||
mask: mask.to_string(),
|
||||
setter: setter.to_string(),
|
||||
duration,
|
||||
reason: reason.to_string(),
|
||||
});
|
||||
}
|
||||
|
||||
// Lift a network ban previously set with `add_line`.
|
||||
pub fn del_line(&mut self, kind: &str, mask: &str) {
|
||||
self.actions.push(NetAction::DelLine { kind: kind.to_string(), mask: mask.to_string() });
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
@ -386,6 +408,16 @@ pub struct VhostView {
|
|||
pub expires: Option<u64>,
|
||||
}
|
||||
|
||||
// A network ban (AKILL / G-line) held by OperServ.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct AkillView {
|
||||
pub mask: String,
|
||||
pub setter: String,
|
||||
pub reason: String,
|
||||
pub ts: u64,
|
||||
pub expires: Option<u64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct BotView {
|
||||
pub nick: String,
|
||||
|
|
@ -632,6 +664,12 @@ pub trait Store {
|
|||
// Inactivity-expiry pins (oper-only, gated on Priv::Admin at the command layer).
|
||||
fn set_account_noexpire(&mut self, account: &str, on: bool) -> Result<bool, RegError>;
|
||||
fn set_channel_noexpire(&mut self, channel: &str, on: bool) -> Result<bool, ChanError>;
|
||||
// Network bans (AKILL / G-lines, oper-only). `akill_add` returns whether the
|
||||
// mask was newly added (false = an existing entry was refreshed); `akills`
|
||||
// lists only entries that haven't lazily expired, oldest first.
|
||||
fn akill_add(&mut self, mask: &str, setter: &str, reason: &str, expires: Option<u64>) -> Result<bool, RegError>;
|
||||
fn akill_del(&mut self, mask: &str) -> Result<bool, RegError>;
|
||||
fn akills(&self) -> Vec<AkillView>;
|
||||
fn register_channel(&mut self, name: &str, founder: &str) -> Result<(), ChanError>;
|
||||
fn drop_channel(&mut self, name: &str) -> Result<(), ChanError>;
|
||||
fn set_mlock(&mut self, name: &str, on: &str, off: &str) -> Result<(), ChanError>;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue