NICKLOCK / NICKUNLOCK (services hold a user's nick)
This commit is contained in:
parent
4d6525cac2
commit
e2a4a3e248
3 changed files with 95 additions and 0 deletions
|
|
@ -50,6 +50,8 @@ pub fn commands() -> Vec<Box<dyn Command>> {
|
|||
Box::new(AllTime),
|
||||
Box::new(SwhoisCmd),
|
||||
Box::new(SetIdle),
|
||||
Box::new(NickLock),
|
||||
Box::new(NickUnlock),
|
||||
]
|
||||
}
|
||||
|
||||
|
|
@ -699,6 +701,84 @@ impl Command for Cban {
|
|||
}
|
||||
}
|
||||
|
||||
/// NICKLOCK — force a user's nick and lock it so they can't change it (InspIRCd
|
||||
/// `m_nicklock`). `NICKLOCK <nick> <newnick>`; opers/services still can.
|
||||
struct NickLock;
|
||||
impl Command for NickLock {
|
||||
fn name(&self) -> &'static str {
|
||||
"NICKLOCK"
|
||||
}
|
||||
fn min_params(&self) -> usize {
|
||||
2
|
||||
}
|
||||
fn handle(&self, s: &mut Server, uid: Uid, params: &[String]) -> CmdResult {
|
||||
if !require_oper(s, uid) {
|
||||
return CmdResult::Fail;
|
||||
}
|
||||
let Some(tuid) = oper_target(s, uid, ¶ms[0]) else {
|
||||
return CmdResult::Fail;
|
||||
};
|
||||
let newnick = ¶ms[1];
|
||||
if !valid_nick(newnick) {
|
||||
s.numeric(
|
||||
uid,
|
||||
ERR_ERRONEUSNICKNAME,
|
||||
&format!("{newnick} :Erroneous nickname"),
|
||||
);
|
||||
return CmdResult::Fail;
|
||||
}
|
||||
let cur = s
|
||||
.users
|
||||
.get(&tuid)
|
||||
.map(|u| u.nick.clone())
|
||||
.unwrap_or_default();
|
||||
if !newnick.eq_ignore_ascii_case(&cur) {
|
||||
if s.find_nick(newnick).is_some()
|
||||
|| s.remote_nick.contains_key(&newnick.to_ascii_lowercase())
|
||||
{
|
||||
s.numeric(
|
||||
uid,
|
||||
ERR_NICKNAMEINUSE,
|
||||
&format!("{newnick} :Nickname is already in use"),
|
||||
);
|
||||
return CmdResult::Fail;
|
||||
}
|
||||
s.set_nick(tuid, newnick);
|
||||
}
|
||||
if let Some(u) = s.users.get_mut(&tuid) {
|
||||
u.flags.nick_locked = true;
|
||||
}
|
||||
let by = oper_nick(s, uid);
|
||||
s.snotice(&format!("{by} used NICKLOCK on {newnick}"));
|
||||
CmdResult::Ok
|
||||
}
|
||||
}
|
||||
|
||||
/// NICKUNLOCK — release a NICKLOCK so the user may change nick again.
|
||||
struct NickUnlock;
|
||||
impl Command for NickUnlock {
|
||||
fn name(&self) -> &'static str {
|
||||
"NICKUNLOCK"
|
||||
}
|
||||
fn min_params(&self) -> usize {
|
||||
1
|
||||
}
|
||||
fn handle(&self, s: &mut Server, uid: Uid, params: &[String]) -> CmdResult {
|
||||
if !require_oper(s, uid) {
|
||||
return CmdResult::Fail;
|
||||
}
|
||||
let Some(tuid) = oper_target(s, uid, ¶ms[0]) else {
|
||||
return CmdResult::Fail;
|
||||
};
|
||||
if let Some(u) = s.users.get_mut(&tuid) {
|
||||
u.flags.nick_locked = false;
|
||||
}
|
||||
let by = oper_nick(s, uid);
|
||||
s.snotice(&format!("{by} used NICKUNLOCK on {}", params[0]));
|
||||
CmdResult::Ok
|
||||
}
|
||||
}
|
||||
|
||||
/// CONNECT — dial a configured server link on demand. `CONNECT <servername>`.
|
||||
struct Connect;
|
||||
impl Command for Connect {
|
||||
|
|
|
|||
|
|
@ -353,6 +353,20 @@ impl Command for Nick {
|
|||
);
|
||||
return CmdResult::Fail;
|
||||
}
|
||||
// NICKLOCK: a services-held nick can't be changed by the user (opers bypass)
|
||||
if s.users
|
||||
.get(&uid)
|
||||
.map(|u| u.flags.nick_locked)
|
||||
.unwrap_or(false)
|
||||
&& !s.is_oper(uid)
|
||||
{
|
||||
s.numeric(
|
||||
uid,
|
||||
ERR_CANTCHANGENICK,
|
||||
":Your nickname is locked and cannot be changed",
|
||||
);
|
||||
return CmdResult::Fail;
|
||||
}
|
||||
// Q-line: a reserved nick is refused (opers and services bypass)
|
||||
if !s.is_oper(uid) {
|
||||
if let Some(reason) = s.matched_qline(newnick) {
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ pub struct UserFlags {
|
|||
pub callerid: bool, // +g (only accept PMs from users on the ACCEPT list)
|
||||
pub showwhois: bool, // +W (get a notice when someone WHOISes you)
|
||||
pub deny_uncommon: bool, // +c (only users sharing a channel may PM you)
|
||||
pub nick_locked: bool, // NICKLOCK: services/oper holds this nick (no self-change)
|
||||
pub away: Option<String>, // AWAY message, if set
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue