Implemented channel keys for autojoined channels (fixes #51).
This commit is contained in:
parent
ee7f963893
commit
5b8f320050
3 changed files with 39 additions and 1 deletions
|
@ -36,6 +36,8 @@ pub struct Config {
|
||||||
pub encoding: Option<String>,
|
pub encoding: Option<String>,
|
||||||
/// A list of channels to join on connection.
|
/// A list of channels to join on connection.
|
||||||
pub channels: Option<Vec<String>>,
|
pub channels: Option<Vec<String>>,
|
||||||
|
/// A mapping of channel names to keys for join-on-connect.
|
||||||
|
pub channel_keys: Option<HashMap<String, String>>,
|
||||||
/// User modes to set on connect. Example: "+RB-x"
|
/// User modes to set on connect. Example: "+RB-x"
|
||||||
pub umodes: Option<String>,
|
pub umodes: Option<String>,
|
||||||
/// The text that'll be sent in response to CTCP USERINFO requests.
|
/// The text that'll be sent in response to CTCP USERINFO requests.
|
||||||
|
@ -149,6 +151,12 @@ impl Config {
|
||||||
self.channels.as_ref().map_or(vec![], |v| v.iter().map(|s| &s[..]).collect())
|
self.channels.as_ref().map_or(vec![], |v| v.iter().map(|s| &s[..]).collect())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Gets the key for the specified channel if it exists in the configuration.
|
||||||
|
pub fn channel_key(&self, chan: &str) -> Option<&str> {
|
||||||
|
self.channel_keys.as_ref().and_then(|m| m.get(&chan.to_owned()).map(|s| &s[..]))
|
||||||
|
}
|
||||||
|
|
||||||
/// Gets the user modes to set on connect specified in the configuration.
|
/// Gets the user modes to set on connect specified in the configuration.
|
||||||
/// This defaults to an empty string when not specified.
|
/// This defaults to an empty string when not specified.
|
||||||
pub fn umodes(&self) -> &str {
|
pub fn umodes(&self) -> &str {
|
||||||
|
@ -217,6 +225,7 @@ mod test {
|
||||||
use_ssl: Some(false),
|
use_ssl: Some(false),
|
||||||
encoding: Some(format!("UTF-8")),
|
encoding: Some(format!("UTF-8")),
|
||||||
channels: Some(vec![format!("#test"), format!("#test2")]),
|
channels: Some(vec![format!("#test"), format!("#test2")]),
|
||||||
|
channel_keys: None,
|
||||||
user_info: None,
|
user_info: None,
|
||||||
ping_time: None,
|
ping_time: None,
|
||||||
ping_timeout: None,
|
ping_timeout: None,
|
||||||
|
@ -243,6 +252,7 @@ mod test {
|
||||||
use_ssl: Some(false),
|
use_ssl: Some(false),
|
||||||
encoding: Some(format!("UTF-8")),
|
encoding: Some(format!("UTF-8")),
|
||||||
channels: Some(vec![format!("#test"), format!("#test2")]),
|
channels: Some(vec![format!("#test"), format!("#test2")]),
|
||||||
|
channel_keys: None,
|
||||||
user_info: None,
|
user_info: None,
|
||||||
ping_time: None,
|
ping_time: None,
|
||||||
ping_timeout: None,
|
ping_timeout: None,
|
||||||
|
|
|
@ -346,7 +346,10 @@ impl IrcServer {
|
||||||
try!(self.send_nick_password());
|
try!(self.send_nick_password());
|
||||||
try!(self.send_umodes());
|
try!(self.send_umodes());
|
||||||
for chan in self.config().channels().into_iter() {
|
for chan in self.config().channels().into_iter() {
|
||||||
try!(self.send_join(chan))
|
match self.config().channel_key(chan) {
|
||||||
|
Some(key) => try!(self.send_join_with_keys(chan, key)),
|
||||||
|
None => try!(self.send_join(chan))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Command::Response(Response::ERR_NICKNAMEINUSE, _, _) |
|
Command::Response(Response::ERR_NICKNAMEINUSE, _, _) |
|
||||||
|
@ -538,6 +541,7 @@ impl<'a> Iterator for ServerIterator<'a> {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::{IrcServer, Server};
|
use super::{IrcServer, Server};
|
||||||
|
use std::collections::HashMap;
|
||||||
use std::default::Default;
|
use std::default::Default;
|
||||||
use client::conn::MockConnection;
|
use client::conn::MockConnection;
|
||||||
use client::data::Config;
|
use client::data::Config;
|
||||||
|
@ -604,6 +608,25 @@ mod test {
|
||||||
JOIN #test2\r\n");
|
JOIN #test2\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn handle_end_motd_with_chan_keys() {
|
||||||
|
let value = ":irc.test.net 376 test :End of /MOTD command\r\n";
|
||||||
|
let server = IrcServer::from_connection(Config {
|
||||||
|
nickname: Some(format!("test")),
|
||||||
|
channels: Some(vec![format!("#test"), format!("#test2")]),
|
||||||
|
channel_keys: {
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
map.insert(format!("#test2"), format!("password"));
|
||||||
|
Some(map)
|
||||||
|
},
|
||||||
|
.. Default::default()
|
||||||
|
}, MockConnection::new(value));
|
||||||
|
for message in server.iter() {
|
||||||
|
println!("{:?}", message);
|
||||||
|
}
|
||||||
|
assert_eq!(&get_server_value(server)[..], "JOIN #test\r\nJOIN #test2 password\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn handle_end_motd_with_ghost() {
|
fn handle_end_motd_with_ghost() {
|
||||||
let value = ":irc.pdgn.co 433 * test :Nickname is already in use.\r\n\
|
let value = ":irc.pdgn.co 433 * test :Nickname is already in use.\r\n\
|
||||||
|
|
|
@ -71,6 +71,11 @@ pub trait ServerExt: Server {
|
||||||
self.send(JOIN(chanlist.to_owned(), None, None))
|
self.send(JOIN(chanlist.to_owned(), None, None))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Joins the specified channel or chanlist using the specified key or keylist.
|
||||||
|
fn send_join_with_keys(&self, chanlist: &str, keylist: &str) -> Result<()> where Self: Sized {
|
||||||
|
self.send(JOIN(chanlist.to_owned(), Some(keylist.to_owned()), None))
|
||||||
|
}
|
||||||
|
|
||||||
/// Attempts to oper up using the specified username and password.
|
/// Attempts to oper up using the specified username and password.
|
||||||
fn send_oper(&self, username: &str, password: &str) -> Result<()> where Self: Sized {
|
fn send_oper(&self, username: &str, password: &str) -> Result<()> where Self: Sized {
|
||||||
self.send(OPER(username.to_owned(), password.to_owned()))
|
self.send(OPER(username.to_owned(), password.to_owned()))
|
||||||
|
|
Loading…
Reference in a new issue