Check for name to be ascii characters only

This commit is contained in:
Phuntsok Drak-pa 2018-03-23 17:25:13 +01:00
parent 7dfbf7c081
commit 5a56afb709
2 changed files with 71 additions and 35 deletions

View File

@ -34,7 +34,6 @@ use self::chrono::Local;
*/ */
// TODO: Implement requests 0.1 and 1.2 // TODO: Implement requests 0.1 and 1.2
// TODO: Limit usernames to ascii
fn hash_name(name: &str) -> usize { fn hash_name(name: &str) -> usize {
let mut s = DefaultHasher::new(); let mut s = DefaultHasher::new();
@ -50,7 +49,7 @@ fn get_entry() -> String {
} }
fn get_name() -> String { fn get_name() -> String {
loop { 'mainloop: loop {
println!("{}", "Please enter your name:".yellow().dimmed()); println!("{}", "Please enter your name:".yellow().dimmed());
let mut name = &*get_entry(); let mut name = &*get_entry();
name = name.trim(); name = name.trim();
@ -61,6 +60,17 @@ fn get_name() -> String {
); );
continue; continue;
} }
for c in name.chars() {
if !c.is_ascii() {
println!(
"{}{}{}",
"Character ".red(),
&format!("{}", c).green(),
" is not an ASCII character.".red()
);
continue 'mainloop;
}
}
match name { match name {
"" => { "" => {
continue; continue;
@ -193,6 +203,9 @@ fn exchange_with_server(stream: TcpStream) {
let input: String = String::from(receive!()); let input: String = String::from(receive!());
let spliced_input: Vec<&str> = input.split(" ").collect(); let spliced_input: Vec<&str> = input.split(" ").collect();
match spliced_input[0] { match spliced_input[0] {
"BAD" => {
println!("{}", "Bad request from client".red());
}
"WELCOME" => { "WELCOME" => {
println!("{}", ">>> Login Successful <<<".green()); println!("{}", ">>> Login Successful <<<".green());
println!("Type /clients to get the list of users connected"); println!("Type /clients to get the list of users connected");
@ -217,10 +230,12 @@ fn exchange_with_server(stream: TcpStream) {
name.push_str(spliced_input[1]); name.push_str(spliced_input[1]);
name.push('>'); name.push('>');
// Display message with soft-wrap
if let Some((w, _)) = term_size::dimensions() { if let Some((w, _)) = term_size::dimensions() {
let mut msg = String::new(); let mut msg = String::new();
let w = w - 34; let w = w - 34;
// format message
for mut i in 3..spliced_input.len() { for mut i in 3..spliced_input.len() {
if w > msg.len() + spliced_input[i].len() + 1 { if w > msg.len() + spliced_input[i].len() + 1 {
msg.push(' '); msg.push(' ');
@ -228,9 +243,10 @@ fn exchange_with_server(stream: TcpStream) {
} else { } else {
if first_line == true { if first_line == true {
println!( println!(
"{} {}:{}", "{}{}{}{}",
date.format("[%H:%M:%S]").to_string().dimmed(), date.format("[%H:%M:%S]").to_string().dimmed(),
name.color(COLORS[name_hash]), name.color(COLORS[name_hash]),
" |".green(),
msg.yellow().dimmed() msg.yellow().dimmed()
); );
first_line = false; first_line = false;
@ -249,9 +265,10 @@ fn exchange_with_server(stream: TcpStream) {
if first_line == true { if first_line == true {
println!( println!(
"{} {}:{}", "{}{}{}{}",
date.format("[%H:%M:%S]").to_string().dimmed(), date.format("[%H:%M:%S]").to_string().dimmed(),
name.color(COLORS[name_hash]), name.color(COLORS[name_hash]),
" |".green(),
msg.yellow().dimmed() msg.yellow().dimmed()
); );
} else { } else {
@ -291,7 +308,7 @@ fn exchange_with_server(stream: TcpStream) {
println!( println!(
"{}{}{}{}", "{}{}{}{}",
date.format("[%H:%M:%S]").to_string().dimmed(), date.format("[%H:%M:%S]").to_string().dimmed(),
" ------> ".green(), " ------> ".green(),
spliced_input[1].color(COLORS[name_hash]), spliced_input[1].color(COLORS[name_hash]),
" has joined".green() " has joined".green()
) )
@ -303,7 +320,7 @@ fn exchange_with_server(stream: TcpStream) {
println!( println!(
"{}{}{}{}", "{}{}{}{}",
date.format("[%H:%M:%S]").to_string().dimmed(), date.format("[%H:%M:%S]").to_string().dimmed(),
" <------ ".red(), " <------ ".red(),
spliced_input[1].color(COLORS[name_hash]), spliced_input[1].color(COLORS[name_hash]),
" has left".red() " has left".red()
) )

View File

@ -179,36 +179,15 @@ fn handle_client(stream: TcpStream, clients: Arc<Mutex<UserMap>>) {
if spliced_input.len() == 5 { if spliced_input.len() == 5 {
if spliced_input[2] == "CONNECT" && spliced_input[3] == "USER" { if spliced_input[2] == "CONNECT" && spliced_input[3] == "USER" {
let username = String::from(spliced_input[4]); let username = String::from(spliced_input[4]);
let mut used = false; let mut ascii_nick = true;
{ for c in username.chars() {
let lock = clients.lock().unwrap(); if !c.is_ascii() {
for (_, entry) in (*lock).iter() { ascii_nick = false;
if username == entry.0 { send!("NAME FAILURE");
used = true; break;
break;
}
} }
} }
if used == false { if ascii_nick {
send!("NAME OK");
return Ok(username);
} else {
send!("NAME FAILURE");
}
} else {
return Err(Error::new(ErrorKind::Other, "BAD REQ"));
}
}
loop {
send!("NAME REQ");
match receive!() {
input => {
let spliced_input: Vec<&str> = input.split_whitespace().collect();
if spliced_input.len() != 2 || spliced_input[0] != "NAME" {
return Err(Error::new(ErrorKind::Other, "BAD REQ"));
}
let username = String::from(spliced_input[1]);
let mut used = false; let mut used = false;
{ {
let lock = clients.lock().unwrap(); let lock = clients.lock().unwrap();
@ -226,9 +205,49 @@ fn handle_client(stream: TcpStream, clients: Arc<Mutex<UserMap>>) {
send!("NAME FAILURE"); send!("NAME FAILURE");
} }
} }
} else {
return Err(Error::new(ErrorKind::Other, "BAD REQ"));
}
}
loop {
send!("NAME REQ");
match receive!() {
input => {
let spliced_input: Vec<&str> = input.split_whitespace().collect();
if spliced_input.len() != 2 || spliced_input[0] != "NAME" {
return Err(Error::new(ErrorKind::Other, "BAD REQ"));
}
let username = String::from(spliced_input[1]);
let mut ascii_nick = true;
for c in username.chars() {
if !c.is_ascii() {
ascii_nick = false;
send!("NAME FAILURE");
break;
}
}
if ascii_nick {
let mut used = false;
{
let lock = clients.lock().unwrap();
for (_, entry) in (*lock).iter() {
if username == entry.0 {
used = true;
break;
}
}
}
if used == false {
send!("NAME OK");
return Ok(username);
} else {
send!("NAME FAILURE");
}
}
}
} }
} }
// return Ok(String::new());
} }
} }
})() })()