opers: add users/ignore-privdeaf — reach +D deaf users
A holder's channel messages reach +D (deaf) members: gate the deaf-skip in to_channel_tagged and the TAGMSG fanout on the sender's users/ignore-privdeaf (relayed/service messages, which have no local sender, are unaffected). Granted by the auspex class; verified live (netadmin reaches a deaf user, a restricted oper does not).
This commit is contained in:
parent
5dfedb5091
commit
2d42fbd2ca
4 changed files with 17 additions and 5 deletions
|
|
@ -91,6 +91,7 @@ command. Assign them via `privs=` on a class or type (`*` = all, `-x` removes on
|
||||||
| `users/flood` | exemption from the message- and join-flood limits |
|
| `users/flood` | exemption from the message- and join-flood limits |
|
||||||
| `users/ignore-commonchans` | message a `+c` user without sharing a common channel |
|
| `users/ignore-commonchans` | message a `+c` user without sharing a common channel |
|
||||||
| `users/ignore-callerid` | message a `+g` (caller-ID) user without being on their accept list |
|
| `users/ignore-callerid` | message a `+g` (caller-ID) user without being on their accept list |
|
||||||
|
| `users/ignore-privdeaf` | reach a `+D` (deaf) user with your channel messages despite their deafness |
|
||||||
| `users/ignore-restrictmsg` | private-message anyone while `restrictmsg` is on |
|
| `users/ignore-restrictmsg` | private-message anyone while `restrictmsg` is on |
|
||||||
| `users/secret-whois` | `/WHOIS` a `+W` (showwhois) user without notifying them |
|
| `users/secret-whois` | `/WHOIS` a `+W` (showwhois) user without notifying them |
|
||||||
| `servers/use-disabled-commands` | use a command turned off by `disabled_commands` |
|
| `servers/use-disabled-commands` | use a command turned off by `disabled_commands` |
|
||||||
|
|
@ -100,8 +101,9 @@ command. Assign them via `privs=` on a class or type (`*` = all, `-x` removes on
|
||||||
The built-in `override` class carries the channel/message/anti-spam bypasses
|
The built-in `override` class carries the channel/message/anti-spam bypasses
|
||||||
(`channels/restricted-create`, `channels/ignore-nonicks`, `users/ignore-restrictmsg`,
|
(`channels/restricted-create`, `channels/ignore-nonicks`, `users/ignore-restrictmsg`,
|
||||||
`servers/ignore-securelist`, `servers/ignore-blockamsg`), `auspex` carries the
|
`servers/ignore-securelist`, `servers/ignore-blockamsg`), `auspex` carries the
|
||||||
see-through-privacy set (the three `*/auspex` plus `users/secret-whois` and
|
see-through-privacy set (the three `*/auspex` plus `users/secret-whois`,
|
||||||
`users/ignore-callerid`), and `servers/use-disabled-commands` sits on the `server` class.
|
`users/ignore-callerid` and `users/ignore-privdeaf`), and `servers/use-disabled-commands`
|
||||||
|
sits on the `server` class.
|
||||||
|
|
||||||
## Snomasks
|
## Snomasks
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -755,8 +755,12 @@ impl Command for TagMsg {
|
||||||
.get(&key)
|
.get(&key)
|
||||||
.map(|c| c.members.keys().copied().collect())
|
.map(|c| c.members.keys().copied().collect())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
let reach_deaf =
|
||||||
|
crate::modules::opertypes::has_priv(s, uid, crate::modules::opertypes::privs::USERS_IGNORE_PRIVDEAF);
|
||||||
for m in members {
|
for m in members {
|
||||||
if (m == uid && !echo) || s.users.get(&m).map(|u| u.flags.deaf).unwrap_or(false) {
|
if (m == uid && !echo)
|
||||||
|
|| (s.users.get(&m).map(|u| u.flags.deaf).unwrap_or(false) && !reach_deaf)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// only message-tags clients receive a TAGMSG
|
// only message-tags clients receive a TAGMSG
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,8 @@ pub mod privs {
|
||||||
pub const CHANNELS_IGNORE_NONICKS: &str = "channels/ignore-nonicks";
|
pub const CHANNELS_IGNORE_NONICKS: &str = "channels/ignore-nonicks";
|
||||||
/// message a +g (caller-id) user without being on their ACCEPT list
|
/// message a +g (caller-id) user without being on their ACCEPT list
|
||||||
pub const USERS_IGNORE_CALLERID: &str = "users/ignore-callerid";
|
pub const USERS_IGNORE_CALLERID: &str = "users/ignore-callerid";
|
||||||
|
/// reach a +D (deaf) user with your channel messages despite their deafness
|
||||||
|
pub const USERS_IGNORE_PRIVDEAF: &str = "users/ignore-privdeaf";
|
||||||
/// `/WHOIS` a +W (showwhois) user without notifying them
|
/// `/WHOIS` a +W (showwhois) user without notifying them
|
||||||
pub const USERS_SECRET_WHOIS: &str = "users/secret-whois";
|
pub const USERS_SECRET_WHOIS: &str = "users/secret-whois";
|
||||||
/// private-message anyone while `restrictmsg` is on
|
/// private-message anyone while `restrictmsg` is on
|
||||||
|
|
@ -367,7 +369,7 @@ fn builtin() -> (HashMap<String, ClassDef>, HashMap<String, TypeDef>) {
|
||||||
classes.insert("services".into(), cdef(&["SVSNICK", "SVSJOIN", "SVSPART", "SVSMODE", "SVSLOGIN", "SVSLOGOUT"], &[], ""));
|
classes.insert("services".into(), cdef(&["SVSNICK", "SVSJOIN", "SVSPART", "SVSMODE", "SVSLOGIN", "SVSLOGOUT"], &[], ""));
|
||||||
classes.insert("server".into(), cdef(&["CONNECT", "SQUIT", "DIE", "RESTART"], &["servers/use-disabled-commands"], "lr"));
|
classes.insert("server".into(), cdef(&["CONNECT", "SQUIT", "DIE", "RESTART"], &["servers/use-disabled-commands"], "lr"));
|
||||||
// auspex: see through user/channel privacy (real host+IP, geo, secret channels)
|
// auspex: see through user/channel privacy (real host+IP, geo, secret channels)
|
||||||
classes.insert("auspex".into(), cdef(&[], &["users/auspex", "channels/auspex", "servers/auspex", "users/secret-whois", "users/ignore-callerid"], ""));
|
classes.insert("auspex".into(), cdef(&[], &["users/auspex", "channels/auspex", "servers/auspex", "users/secret-whois", "users/ignore-callerid", "users/ignore-privdeaf"], ""));
|
||||||
|
|
||||||
let mut types: HashMap<String, TypeDef> = HashMap::default();
|
let mut types: HashMap<String, TypeDef> = HashMap::default();
|
||||||
// The WHOIS title line is bold + colour 4 (red) by default; override per type
|
// The WHOIS title line is bold + colour 4 (red) by default; override per type
|
||||||
|
|
@ -685,6 +687,7 @@ mod tests {
|
||||||
assert!(has("override", "users/ignore-restrictmsg"));
|
assert!(has("override", "users/ignore-restrictmsg"));
|
||||||
assert!(has("override", "servers/ignore-securelist") && has("override", "servers/ignore-blockamsg"));
|
assert!(has("override", "servers/ignore-securelist") && has("override", "servers/ignore-blockamsg"));
|
||||||
assert!(has("auspex", "users/secret-whois") && has("auspex", "users/ignore-callerid"));
|
assert!(has("auspex", "users/secret-whois") && has("auspex", "users/ignore-callerid"));
|
||||||
|
assert!(has("auspex", "users/ignore-privdeaf"));
|
||||||
assert!(has("server", "servers/use-disabled-commands"));
|
assert!(has("server", "servers/use-disabled-commands"));
|
||||||
// netadmin holds every class ⇒ every one of the new privileges resolves in
|
// netadmin holds every class ⇒ every one of the new privileges resolves in
|
||||||
assert!(resolved("netadmin").all_privs);
|
assert!(resolved("netadmin").all_privs);
|
||||||
|
|
|
||||||
|
|
@ -1354,6 +1354,9 @@ impl Server {
|
||||||
let src_mask = self.users.get(&src).map(|su| su.prefix()).unwrap_or_default();
|
let src_mask = self.users.get(&src).map(|su| su.prefix()).unwrap_or_default();
|
||||||
let src_signore: Vec<String> =
|
let src_signore: Vec<String> =
|
||||||
self.users.get(&src).map(|su| su.signore.clone()).unwrap_or_default();
|
self.users.get(&src).map(|su| su.signore.clone()).unwrap_or_default();
|
||||||
|
// users/ignore-privdeaf: this sender's channel messages reach +D deaf members
|
||||||
|
let src_reaches_deaf =
|
||||||
|
crate::modules::opertypes::has_priv(self, src, crate::modules::opertypes::privs::USERS_IGNORE_PRIVDEAF);
|
||||||
// one cached line per (server_time, account_tag, message_tags) combination
|
// one cached line per (server_time, account_tag, message_tags) combination
|
||||||
let mut cache: [Option<std::sync::Arc<str>>; 8] = std::array::from_fn(|_| None);
|
let mut cache: [Option<std::sync::Arc<str>>; 8] = std::array::from_fn(|_| None);
|
||||||
for m in members {
|
for m in members {
|
||||||
|
|
@ -1363,7 +1366,7 @@ impl Server {
|
||||||
let Some(u) = self.users.get(&m) else {
|
let Some(u) = self.users.get(&m) else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
if u.flags.deaf {
|
if u.flags.deaf && !src_reaches_deaf {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// SIGNORE: skip a member mutually server-ignored with the sender
|
// SIGNORE: skip a member mutually server-ignored with the sender
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue