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 group(&self, name: &str) -> Option<GroupView>;
|
||||||
fn groups(&self) -> Vec<String>;
|
fn groups(&self) -> Vec<String>;
|
||||||
fn groups_of(&self, account: &str) -> 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).
|
// A user's effective channel capabilities (direct access unioned with groups).
|
||||||
fn channel_caps(&self, channel: &str, account: &str) -> Caps;
|
fn channel_caps(&self, channel: &str, account: &str) -> Caps;
|
||||||
// Runtime operator grants (OperServ OPER), merged with config opers. `expires`
|
// 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.");
|
ctx.notice(me, from.uid, "A group name starts with \x02!\x02, e.g. \x02!staff\x02.");
|
||||||
return;
|
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
|
// 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.
|
// name (!аdmin) could impersonate a real one that opers grant channel access to.
|
||||||
if db.confusable_check_enabled() {
|
if db.confusable_check_enabled() {
|
||||||
|
|
@ -19,6 +25,13 @@ pub fn handle(me: &str, from: &Sender, name: Option<&str>, ctx: &mut ServiceCtx,
|
||||||
return;
|
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();
|
let acc = acc.to_string();
|
||||||
match db.group_register(name, &acc) {
|
match db.group_register(name, &acc) {
|
||||||
Ok(()) => ctx.notice(me, from.uid, format!("Group \x02{name}\x02 registered — you're the founder.")),
|
Ok(()) => ctx.notice(me, from.uid, format!("Group \x02{name}\x02 registered — you're the founder.")),
|
||||||
|
|
|
||||||
|
|
@ -657,6 +657,11 @@ impl Db {
|
||||||
names
|
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).
|
/// The groups an account belongs to (founder or member).
|
||||||
pub fn groups_of(&self, account: &str) -> Vec<String> {
|
pub fn groups_of(&self, account: &str) -> Vec<String> {
|
||||||
self.net
|
self.net
|
||||||
|
|
|
||||||
|
|
@ -401,6 +401,9 @@ impl Store for Db {
|
||||||
fn groups_of(&self, account: &str) -> Vec<String> {
|
fn groups_of(&self, account: &str) -> Vec<String> {
|
||||||
Db::groups_of(self, account)
|
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 {
|
fn channel_caps(&self, channel: &str, account: &str) -> Caps {
|
||||||
Db::channel_caps(self, channel, account)
|
Db::channel_caps(self, channel, account)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue