operserv: type the X-line kind as an enum at the command/store boundary, wire token in storage
This commit is contained in:
parent
2c8ba4460d
commit
ef34c04c8d
9 changed files with 96 additions and 45 deletions
|
|
@ -1,4 +1,4 @@
|
|||
use echo_api::{NetView, Priv, Sender, ServiceCtx, Store};
|
||||
use echo_api::{NetView, Priv, Sender, ServiceCtx, Store, XlineKind};
|
||||
use std::collections::HashSet;
|
||||
|
||||
// CHANKILL <#channel> [reason]: AKILL every user in a channel by host, clearing
|
||||
|
|
@ -29,8 +29,8 @@ pub fn handle(me: &str, from: &Sender, args: &[&str], ctx: &mut ServiceCtx, net:
|
|||
let Some(host) = net.host_of(uid) else { continue };
|
||||
if seen.insert(host.to_string()) {
|
||||
let mask = format!("*@{host}");
|
||||
let _ = db.akill_add("G", &mask, setter, &reason, None);
|
||||
ctx.add_line("G", &mask, from.nick, 0, &reason);
|
||||
let _ = db.akill_add(XlineKind::Gline, &mask, setter, &reason, None);
|
||||
ctx.add_line(XlineKind::Gline, &mask, from.nick, 0, &reason);
|
||||
banned += 1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
use echo_api::{Sender, ServiceCtx, Store};
|
||||
use echo_api::{Sender, ServiceCtx, Store, XlineKind};
|
||||
|
||||
// STATS: an at-a-glance summary of the enforcement state OperServ holds — how
|
||||
// many network bans of each kind and how many services ignores are live.
|
||||
// Read-only, so any operator may run it (the module is already oper-gated).
|
||||
pub fn handle(me: &str, from: &Sender, db: &mut dyn Store, ctx: &mut ServiceCtx) {
|
||||
let akills = db.akills();
|
||||
let glines = akills.iter().filter(|a| a.kind == "G").count();
|
||||
let qlines = akills.iter().filter(|a| a.kind == "Q").count();
|
||||
let rlines = akills.iter().filter(|a| a.kind == "R").count();
|
||||
let glines = akills.iter().filter(|a| a.kind == XlineKind::Gline).count();
|
||||
let qlines = akills.iter().filter(|a| a.kind == XlineKind::Qline).count();
|
||||
let rlines = akills.iter().filter(|a| a.kind == XlineKind::Rline).count();
|
||||
let ignores = db.ignores().len();
|
||||
ctx.notice(me, from.uid, format!("Live network bans: \x02{glines}\x02 AKILL, \x02{qlines}\x02 SQLINE, \x02{rlines}\x02 SNLINE. Services ignores: \x02{ignores}\x02."));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
use echo_api::{parse_duration, Sender, ServiceCtx, Store};
|
||||
use echo_api::{parse_duration, Sender, ServiceCtx, Store, XlineKind};
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
// A network-ban command family (AKILL, SQLINE, …): the ircd X-line `kind`, the
|
||||
// user-facing command `name`, and the mask shape it accepts. One implementation
|
||||
// drives ADD / DEL / LIST for every kind so they stay consistent.
|
||||
pub struct Xline {
|
||||
pub kind: &'static str,
|
||||
pub kind: XlineKind,
|
||||
pub name: &'static str,
|
||||
pub target: &'static str, // e.g. "user@host" or "nick" — shown in syntax
|
||||
pub normalize: fn(&str) -> Option<String>,
|
||||
|
|
@ -114,22 +114,22 @@ impl Xline {
|
|||
}
|
||||
|
||||
// AKILL: a user@host G-line. Strips any nick! prefix, lowercases both sides.
|
||||
pub const AKILL: Xline = Xline { kind: "G", name: "AKILL", target: "user@host", normalize: norm_userhost };
|
||||
pub const AKILL: Xline = Xline { kind: XlineKind::Gline, name: "AKILL", target: "user@host", normalize: norm_userhost };
|
||||
|
||||
// SQLINE: a nick Q-line. The mask is a nick glob (no '@'); wildcards allowed.
|
||||
pub const SQLINE: Xline = Xline { kind: "Q", name: "SQLINE", target: "nick", normalize: norm_nick };
|
||||
pub const SQLINE: Xline = Xline { kind: XlineKind::Qline, name: "SQLINE", target: "nick", normalize: norm_nick };
|
||||
|
||||
// SNLINE: a realname R-line. The mask is a regex the ircd matches against a
|
||||
// connecting user's realname (use `.` for spaces, e.g. `.*free.money.*`).
|
||||
pub const SNLINE: Xline = Xline { kind: "R", name: "SNLINE", target: "realname-regex", normalize: norm_realname };
|
||||
pub const SNLINE: Xline = Xline { kind: XlineKind::Rline, name: "SNLINE", target: "realname-regex", normalize: norm_realname };
|
||||
|
||||
// SHUN: a user@host shun. A matching user stays connected but the ircd silently
|
||||
// drops their commands — a quieter alternative to an AKILL.
|
||||
pub const SHUN: Xline = Xline { kind: "SHUN", name: "SHUN", target: "user@host", normalize: norm_userhost };
|
||||
pub const SHUN: Xline = Xline { kind: XlineKind::Shun, name: "SHUN", target: "user@host", normalize: norm_userhost };
|
||||
|
||||
// CBAN: a channel-name ban. Users can't join (or create) a channel matching the
|
||||
// mask, which is a channel glob like `#warez*`.
|
||||
pub const CBAN: Xline = Xline { kind: "CBAN", name: "CBAN", target: "#channel", normalize: norm_channel };
|
||||
pub const CBAN: Xline = Xline { kind: XlineKind::Cban, name: "CBAN", target: "#channel", normalize: norm_channel };
|
||||
|
||||
fn norm_userhost(input: &str) -> Option<String> {
|
||||
let body = input.rsplit('!').next().unwrap_or(input);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue