Implement admin command
Diff
src/client.rs | 22 ++++++++++++++++------
src/messages.rs | 7 +++++++
src/server.rs | 18 +++++++++++++++---
src/server/response.rs | 36 ++++++++++++++++++++++++++++++++++++
4 files changed, 74 insertions(+), 9 deletions(-)
@@ -23,8 +23,9 @@ use crate::{
messages::{
Broadcast, ChannelFetchTopic, ChannelInvite, ChannelJoin, ChannelKickUser, ChannelList,
ChannelMemberList, ChannelMessage, ChannelPart, ChannelSetMode, ChannelUpdateTopic,
FetchClientDetails, MessageKind, PrivateMessage, ServerDisconnect, ServerFetchMotd,
ServerListUsers, UserKickedFromChannel, UserNickChange, UserNickChangeInternal,
FetchClientDetails, MessageKind, PrivateMessage, ServerAdminInfo, ServerDisconnect,
ServerFetchMotd, ServerListUsers, UserKickedFromChannel, UserNickChange,
UserNickChangeInternal,
},
persistence::{
events::{
@@ -487,9 +488,7 @@ impl StreamHandler<Result<irc_proto::Message, ProtocolError>> for Client {
span: Span::current(),
});
}
Command::OPER(_, _) => {}
Command::UserMODE(_, _) => {}
Command::SERVICE(_, _, _, _, _, _) => {}
Command::QUIT(message) => {
@@ -497,7 +496,6 @@ impl StreamHandler<Result<irc_proto::Message, ProtocolError>> for Client {
self.server_leave_reason = message;
ctx.stop();
}
Command::SQUIT(_, _) => {}
Command::JOIN(channel_names, _passwords, _real_name) => {
let channels = parse_channel_name_list(&channel_names);
@@ -706,7 +704,19 @@ impl StreamHandler<Result<irc_proto::Message, ProtocolError>> for Client {
),
});
}
Command::ADMIN(_) => {}
Command::ADMIN(_) => {
let span = Span::current();
let fut = self
.server
.send(ServerAdminInfo { span })
.into_actor(self)
.map(|result, this, _ctx| {
for message in result.unwrap().into_messages(&this.connection.nick) {
this.writer.write(message);
}
});
ctx.spawn(fut);
}
Command::INFO(_) => {}
Command::SERVLIST(_, _) => {}
Command::SQUERY(_, _) => {}
@@ -122,6 +122,13 @@ pub struct ServerListUsers {
pub span: Span,
}
#[derive(Message)]
#[rtype(result = "super::server::response::AdminInfo")]
pub struct ServerAdminInfo {
pub span: Span,
}
#[derive(Message)]
#[rtype(result = "()")]
@@ -21,11 +21,11 @@ use crate::{
connection::InitiatedConnection,
messages::{
Broadcast, ChannelFetchTopic, ChannelJoin, ChannelList, ChannelMemberList,
FetchClientByNick, MessageKind, PrivateMessage, ServerDisconnect, ServerFetchMotd,
ServerListUsers, UserConnected, UserNickChange, UserNickChangeInternal,
FetchClientByNick, MessageKind, PrivateMessage, ServerAdminInfo, ServerDisconnect,
ServerFetchMotd, ServerListUsers, UserConnected, UserNickChange, UserNickChangeInternal,
},
persistence::Persistence,
server::response::{ListUsers, Motd},
server::response::{AdminInfo, ListUsers, Motd},
SERVER_NAME,
};
@@ -276,6 +276,18 @@ impl Handler<ServerListUsers> for Server {
}
}
impl Handler<ServerAdminInfo> for Server {
type Result = MessageResult<ServerAdminInfo>;
fn handle(&mut self, _msg: ServerAdminInfo, _ctx: &mut Self::Context) -> Self::Result {
MessageResult(AdminInfo {
line1: "Name: example name".to_string(),
line2: "Nickname: examplenick".to_string(),
email: "Email: me@example.com".to_string(),
})
}
}
impl Handler<PrivateMessage> for Server {
type Result = ();
@@ -2,6 +2,42 @@ use irc_proto::{Command, Message, Prefix, Response};
use crate::{server::Server, SERVER_NAME};
pub struct AdminInfo {
pub line1: String,
pub line2: String,
pub email: String,
}
impl AdminInfo {
#[must_use]
pub fn into_messages(self, for_user: &str) -> Vec<Message> {
macro_rules! msg {
($response:ident, $($payload:expr),*) => {
Message {
tags: None,
prefix: Some(Prefix::ServerName(SERVER_NAME.to_string())),
command: Command::Response(
Response::$response,
vec![for_user.to_string(), $($payload),*],
),
}
};
}
vec![
msg!(
RPL_ADMINME,
SERVER_NAME.to_string(),
"Administrative info".to_string()
),
msg!(RPL_ADMINLOC1, self.line1),
msg!(RPL_ADMINLOC2, self.line2),
msg!(RPL_ADMINEMAIL, self.email),
]
}
}
pub struct ListUsers {
pub current_clients: usize,
pub max_clients: usize,