forbid: type the FORBID kind as an enum at the store boundary, string only in storage
All checks were successful
CI / check (push) Successful in 3m56s
All checks were successful
CI / check (push) Successful in 3m56s
This commit is contained in:
parent
1fb3615b7e
commit
2c8ba4460d
10 changed files with 91 additions and 49 deletions
|
|
@ -37,41 +37,48 @@ impl Db {
|
|||
|
||||
/// Add a registration ban of `kind` ("NICK"/"CHAN"/"EMAIL") for `mask`.
|
||||
/// Returns whether it was new.
|
||||
pub fn forbid_add(&mut self, kind: &str, mask: &str, setter: &str, reason: &str) -> Result<bool, RegError> {
|
||||
let same = |f: &Forbid| f.kind == kind && f.mask.eq_ignore_ascii_case(mask);
|
||||
pub fn forbid_add(&mut self, kind: ForbidKind, mask: &str, setter: &str, reason: &str) -> Result<bool, RegError> {
|
||||
// The store persists/gossips the wire token; the API is typed.
|
||||
let wire = kind.wire();
|
||||
let same = |f: &Forbid| f.kind == wire && f.mask.eq_ignore_ascii_case(mask);
|
||||
let fresh = !self.net.forbids.iter().any(same);
|
||||
self.log
|
||||
.append(Event::ForbidAdded { kind: kind.to_string(), mask: mask.to_string(), setter: setter.to_string(), reason: reason.to_string(), ts: now() })
|
||||
.append(Event::ForbidAdded { kind: wire.to_string(), mask: mask.to_string(), setter: setter.to_string(), reason: reason.to_string(), ts: now() })
|
||||
.map_err(|_| RegError::Internal)?;
|
||||
self.net.forbids.retain(|f| !same(f));
|
||||
self.net.forbids.push(Forbid { kind: kind.to_string(), mask: mask.to_string(), setter: setter.to_string(), reason: reason.to_string(), ts: now() });
|
||||
self.net.forbids.push(Forbid { kind: wire.to_string(), mask: mask.to_string(), setter: setter.to_string(), reason: reason.to_string(), ts: now() });
|
||||
Ok(fresh)
|
||||
}
|
||||
|
||||
/// Remove a registration ban of `kind` for `mask`. Returns whether one existed.
|
||||
pub fn forbid_del(&mut self, kind: &str, mask: &str) -> Result<bool, RegError> {
|
||||
let same = |f: &Forbid| f.kind == kind && f.mask.eq_ignore_ascii_case(mask);
|
||||
pub fn forbid_del(&mut self, kind: ForbidKind, mask: &str) -> Result<bool, RegError> {
|
||||
let wire = kind.wire();
|
||||
let same = |f: &Forbid| f.kind == wire && f.mask.eq_ignore_ascii_case(mask);
|
||||
if !self.net.forbids.iter().any(same) {
|
||||
return Ok(false);
|
||||
}
|
||||
self.log.append(Event::ForbidRemoved { kind: kind.to_string(), mask: mask.to_string() }).map_err(|_| RegError::Internal)?;
|
||||
self.log.append(Event::ForbidRemoved { kind: wire.to_string(), mask: mask.to_string() }).map_err(|_| RegError::Internal)?;
|
||||
self.net.forbids.retain(|f| !same(f));
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
/// All registration bans, oldest first.
|
||||
/// All registration bans, oldest first. A stored kind that no longer parses
|
||||
/// (corrupt/old log) is skipped rather than shown.
|
||||
pub fn forbids(&self) -> Vec<ForbidView> {
|
||||
self.net.forbids
|
||||
.iter()
|
||||
.map(|f| ForbidView { kind: f.kind.clone(), mask: f.mask.clone(), setter: f.setter.clone(), reason: f.reason.clone(), ts: f.ts })
|
||||
.filter_map(|f| {
|
||||
ForbidKind::from_name(&f.kind).map(|kind| ForbidView { kind, mask: f.mask.clone(), setter: f.setter.clone(), reason: f.reason.clone(), ts: f.ts })
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// The reason `name` is forbidden for `kind` registration (glob), if it is.
|
||||
pub fn is_forbidden(&self, kind: &str, name: &str) -> Option<String> {
|
||||
pub fn is_forbidden(&self, kind: ForbidKind, name: &str) -> Option<String> {
|
||||
let wire = kind.wire();
|
||||
self.net.forbids
|
||||
.iter()
|
||||
.find(|f| f.kind == kind && glob_match(&f.mask, name))
|
||||
.find(|f| f.kind == wire && glob_match(&f.mask, name))
|
||||
.map(|f| f.reason.clone())
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue