Cap and freeze-gate GroupServ registration
This commit is contained in:
parent
0c85c5b569
commit
fa9eaece45
4 changed files with 22 additions and 0 deletions
|
|
@ -2079,6 +2079,7 @@ pub trait Store {
|
|||
fn group(&self, name: &str) -> Option<GroupView>;
|
||||
fn groups(&self) -> Vec<String>;
|
||||
fn groups_of(&self, account: &str) -> Vec<String>;
|
||||
fn groups_founded(&self, account: &str) -> usize;
|
||||
// A user's effective channel capabilities (direct access unioned with groups).
|
||||
fn channel_caps(&self, channel: &str, account: &str) -> Caps;
|
||||
// Runtime operator grants (OperServ OPER), merged with config opers. `expires`
|
||||
|
|
|
|||
|
|
@ -11,6 +11,12 @@ pub fn handle(me: &str, from: &Sender, name: Option<&str>, ctx: &mut ServiceCtx,
|
|||
ctx.notice(me, from.uid, "A group name starts with \x02!\x02, e.g. \x02!staff\x02.");
|
||||
return;
|
||||
}
|
||||
// Honour the registration freeze staff raise during a spam wave, like
|
||||
// NickServ/ChanServ REGISTER — otherwise the group namespace stays open.
|
||||
if db.registrations_frozen() {
|
||||
ctx.notice(me, from.uid, "Group registration is temporarily disabled. Please try again later.");
|
||||
return;
|
||||
}
|
||||
// Guard the group namespace like NickServ/ChanServ REGISTER: a look-alike group
|
||||
// name (!аdmin) could impersonate a real one that opers grant channel access to.
|
||||
if db.confusable_check_enabled() {
|
||||
|
|
@ -19,6 +25,13 @@ pub fn handle(me: &str, from: &Sender, name: Option<&str>, ctx: &mut ServiceCtx,
|
|||
return;
|
||||
}
|
||||
}
|
||||
// Cap groups per founder so the append-only log can't be grown without bound
|
||||
// (mirrors NickServ's grouped-nick and AJOIN caps).
|
||||
const MAX_GROUPS: usize = 25;
|
||||
if db.groups_founded(acc) >= MAX_GROUPS {
|
||||
ctx.notice(me, from.uid, format!("You've reached the maximum of {MAX_GROUPS} registered groups."));
|
||||
return;
|
||||
}
|
||||
let acc = acc.to_string();
|
||||
match db.group_register(name, &acc) {
|
||||
Ok(()) => ctx.notice(me, from.uid, format!("Group \x02{name}\x02 registered — you're the founder.")),
|
||||
|
|
|
|||
|
|
@ -657,6 +657,11 @@ impl Db {
|
|||
names
|
||||
}
|
||||
|
||||
/// How many groups `account` is the founder of (bounds group registration).
|
||||
pub fn groups_founded(&self, account: &str) -> usize {
|
||||
self.net.groups.iter().filter(|g| g.founder.eq_ignore_ascii_case(account)).count()
|
||||
}
|
||||
|
||||
/// The groups an account belongs to (founder or member).
|
||||
pub fn groups_of(&self, account: &str) -> Vec<String> {
|
||||
self.net
|
||||
|
|
|
|||
|
|
@ -401,6 +401,9 @@ impl Store for Db {
|
|||
fn groups_of(&self, account: &str) -> Vec<String> {
|
||||
Db::groups_of(self, account)
|
||||
}
|
||||
fn groups_founded(&self, account: &str) -> usize {
|
||||
Db::groups_founded(self, account)
|
||||
}
|
||||
fn channel_caps(&self, channel: &str, account: &str) -> Caps {
|
||||
Db::channel_caps(self, channel, account)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue