Skip to content

Commit

Permalink
Implement SAQUIT
Browse files Browse the repository at this point in the history
  • Loading branch information
w4 committed Jan 30, 2024
1 parent 1923415 commit 85756a6
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 10 deletions.
42 changes: 35 additions & 7 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ use crate::{
Broadcast, ChannelFetchTopic, ChannelFetchWhoList, ChannelInvite, ChannelJoin,
ChannelKickUser, ChannelList, ChannelMemberList, ChannelMessage, ChannelPart,
ChannelSetMode, ChannelUpdateTopic, ClientAway, ConnectedChannels, FetchClientDetails,
FetchUserPermission, FetchWhoList, FetchWhois, KillUser, MessageKind, PrivateMessage,
ServerAdminInfo, ServerDisconnect, ServerFetchMotd, ServerListUsers, UserKickedFromChannel,
UserNickChange, UserNickChangeInternal, Wallops,
FetchUserPermission, FetchWhoList, FetchWhois, ForceDisconnect, KillUser, MessageKind,
PrivateMessage, ServerAdminInfo, ServerDisconnect, ServerFetchMotd, ServerListUsers,
UserKickedFromChannel, UserNickChange, UserNickChangeInternal, Wallops,
},
persistence::{
events::{
Expand All @@ -35,7 +35,10 @@ use crate::{
},
Persistence,
},
server::{response::WhoList, Server},
server::{
response::{NoSuchNick, WhoList},
Server,
},
SERVER_NAME,
};

Expand Down Expand Up @@ -296,6 +299,15 @@ impl Handler<ConnectedChannels> for Client {
}
}

impl Handler<ForceDisconnect> for Client {
type Result = MessageResult<ForceDisconnect>;

fn handle(&mut self, _msg: ForceDisconnect, ctx: &mut Self::Context) -> Self::Result {
ctx.stop();
MessageResult(true)
}
}

/// Retrieves the entire WHO list for the user.
impl Handler<FetchWhoList> for Client {
type Result = ResponseFuture<<FetchWhoList as actix::Message>::Result>;
Expand Down Expand Up @@ -380,7 +392,7 @@ impl Handler<SetAway> for Client {
impl Handler<KillUser> for Client {
type Result = ();

#[instrument(parent = & msg.span, skip_all)]
#[instrument(parent = &msg.span, skip_all)]
fn handle(&mut self, msg: KillUser, ctx: &mut Self::Context) -> Self::Result {
self.server_leave_reason = Some(format!("Killed ({} ({}))", msg.killer, msg.comment));
ctx.stop();
Expand Down Expand Up @@ -900,7 +912,6 @@ impl StreamHandler<Result<irc_proto::Message, ProtocolError>> for Client {
Command::REHASH => {}
Command::DIE => {}
Command::RESTART => {}
Command::USERS(_) => {}
Command::WALLOPS(message) if self.connection.mode.contains(UserMode::OPER) => {
self.server.do_send(Wallops {
span: Span::current(),
Expand All @@ -919,7 +930,24 @@ impl StreamHandler<Result<irc_proto::Message, ProtocolError>> for Client {
});
}
Command::SAPART(_, _) => {}
Command::SAQUIT(_, _) => {}
Command::SAQUIT(user, comment) if self.connection.mode.contains(UserMode::OPER) => {
let span = Span::current();
self.server_send_map_write(
ctx,
ForceDisconnect {
span,
user: user.to_string(),
comment,
},
move |res, this| {
if res {
vec![]
} else {
NoSuchNick { nick: user }.into_messages(&this.connection.nick)
}
},
);
}
Command::AUTHENTICATE(_) => {
self.writer.write(
SaslAlreadyAuthenticated(self.connection.nick.to_string()).into_message(),
Expand Down
8 changes: 8 additions & 0 deletions src/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ pub struct KillUser {
pub killed: String,
}

#[derive(Message, Clone)]
#[rtype(result = "bool")]
pub struct ForceDisconnect {
pub span: Span,
pub user: String,
pub comment: String,
}

/// Internal event to update a user's nick.
#[derive(Message, Clone)]
#[rtype(result = "()")]
Expand Down
20 changes: 17 additions & 3 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ use crate::{
messages::{
Broadcast, ChannelFetchTopic, ChannelFetchWhoList, ChannelJoin, ChannelList,
ChannelMemberList, ClientAway, ConnectedChannels, FetchClientByNick, FetchWhoList,
FetchWhois, KillUser, MessageKind, PrivateMessage, ServerAdminInfo, ServerDisconnect,
ServerFetchMotd, ServerListUsers, UserConnected, UserNickChange, UserNickChangeInternal,
Wallops,
FetchWhois, ForceDisconnect, KillUser, MessageKind, PrivateMessage, ServerAdminInfo,
ServerDisconnect, ServerFetchMotd, ServerListUsers, UserConnected, UserNickChange,
UserNickChangeInternal, Wallops,
},
persistence::Persistence,
server::response::{AdminInfo, ListUsers, Motd, WhoList, Whois},
Expand Down Expand Up @@ -306,6 +306,20 @@ impl Handler<FetchWhois> for Server {
}
}

impl Handler<ForceDisconnect> for Server {
type Result = MessageResult<ForceDisconnect>;

#[instrument(parent = &msg.span, skip_all)]
fn handle(&mut self, msg: ForceDisconnect, _ctx: &mut Self::Context) -> Self::Result {
if let Some((handle, _)) = self.clients.iter().find(|(_, v)| v.nick == msg.user) {
handle.do_send(msg);
MessageResult(true)
} else {
MessageResult(false)
}
}
}

impl Handler<FetchWhoList> for Server {
type Result = ResponseFuture<<FetchWhoList as actix::Message>::Result>;

Expand Down
18 changes: 18 additions & 0 deletions src/server/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,24 @@ impl Whois {
}
}

pub struct NoSuchNick {
pub nick: String,
}

impl NoSuchNick {
#[must_use]
pub fn into_messages(self, for_user: &str) -> Vec<Message> {
vec![Message {
tags: None,
prefix: Some(Prefix::ServerName(SERVER_NAME.to_string())),
command: Command::Response(
Response::ERR_NOSUCHNICK,
vec![for_user.to_string(), self.nick, "No such nick".to_string()],
),
}]
}
}

#[derive(Default)]
pub struct WhoList {
pub list: Vec<crate::channel::response::ChannelWhoList>,
Expand Down

0 comments on commit 85756a6

Please sign in to comment.