Commit db438a15 authored by Daniel Brüning's avatar Daniel Brüning
Browse files

new passwords are now hashed before they are saved

parent a8878f9b
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]] [[package]]
name = "adler32" name = "adler32"
version = "1.0.3" version = "1.0.3"
......
...@@ -165,10 +165,10 @@ impl MedalConnection for Connection { ...@@ -165,10 +165,10 @@ impl MedalConnection for Connection {
}); });
res.ok() res.ok()
} }
fn get_user_and_group_by_id(&self, user_id: u32) -> Option<(SessionUser, Option<Group>)> { fn get_user_and_group_by_id(&self, user_id: u32) -> Option<(SessionUser, Option<Group>)> {
let session = self.get_user_by_id(user_id)?; let session = self.get_user_by_id(user_id)?;
println!("A"); println!("A");
let group_id = match session.managed_by { let group_id = match session.managed_by {
Some(id) => id, Some(id) => id,
...@@ -853,18 +853,3 @@ impl MedalObject<Connection> for Group { ...@@ -853,18 +853,3 @@ impl MedalObject<Connection> for Group {
} }
} }
} }
pub trait SetPassword {
fn set_password(&mut self, &str) -> Option<()>;
}
impl SetPassword for SessionUser {
fn set_password(&mut self, password: &str) -> Option<()> {
let salt = "blub";
let hash = hash_password(password, salt);
self.password = Some(hash);
self.salt = Some(salt.into());
Some(())
}
}
...@@ -8,7 +8,7 @@ use rand::{thread_rng, Rng, distributions::Alphanumeric}; ...@@ -8,7 +8,7 @@ use rand::{thread_rng, Rng, distributions::Alphanumeric};
use db_conn::{MedalConnection}; use db_conn::{MedalConnection};
use db_objects::{Submission, Group}; use db_objects::{Submission, Group, SessionUser};
use self::bcrypt::{DEFAULT_COST, hash, verify, BcryptError}; use self::bcrypt::{DEFAULT_COST, hash, verify, BcryptError};
...@@ -77,9 +77,16 @@ pub enum MedalError { ...@@ -77,9 +77,16 @@ pub enum MedalError {
CsrfCheckFailed, CsrfCheckFailed,
SessionTimeout, SessionTimeout,
DatabaseError, DatabaseError,
NoneError,
} }
// TODO: Add CsrfCheckFailed, DatabaseError // TODO: Add CsrfCheckFailed, DatabaseError
impl std::convert::From<std::option::NoneError> for MedalError {
fn from(_: std::option::NoneError) -> Self {
MedalError::NoneError
}
}
type MedalValue = (String, json_val::Map<String, json_val::Value>); type MedalValue = (String, json_val::Map<String, json_val::Value>);
type MedalResult<T> = Result<T, MedalError>; type MedalResult<T> = Result<T, MedalError>;
type MedalValueResult = MedalResult<MedalValue>; type MedalValueResult = MedalResult<MedalValue>;
...@@ -523,7 +530,11 @@ pub fn edit_profile<T: MedalConnection>(conn: &T, session_token: String, user_id ...@@ -523,7 +530,11 @@ pub fn edit_profile<T: MedalConnection>(conn: &T, session_token: String, user_id
session.grade = grade; session.grade = grade;
if new_password_1 == new_password_2 { if new_password_1 == new_password_2 {
session.password = Some(new_password_1); let salt: String = thread_rng().sample_iter(&Alphanumeric).take(10).collect();
let hash = hash_password(&new_password_1, &salt).ok()?;
session.password = Some(hash);
session.salt = Some(salt.into());
} }
conn.save_session(session); conn.save_session(session);
...@@ -540,6 +551,14 @@ pub fn edit_profile<T: MedalConnection>(conn: &T, session_token: String, user_id ...@@ -540,6 +551,14 @@ pub fn edit_profile<T: MedalConnection>(conn: &T, session_token: String, user_id
user.lastname = Some(lastname); user.lastname = Some(lastname);
user.grade = grade; user.grade = grade;
if new_password_1 == new_password_2 {
let salt: String = thread_rng().sample_iter(&Alphanumeric).take(10).collect();
let hash = hash_password(&new_password_1, &salt).ok()?;
user.password = Some(hash);
user.salt = Some(salt.into());
}
conn.save_session(user); conn.save_session(user);
} }
} }
...@@ -582,3 +601,17 @@ pub fn login_oauth<T: MedalConnection>(conn: &T, user_data: ForeignUserData) -> ...@@ -582,3 +601,17 @@ pub fn login_oauth<T: MedalConnection>(conn: &T, user_data: ForeignUserData) ->
} }
} }
pub trait SetPassword {
fn set_password(&mut self, &str) -> Option<()>;
}
impl SetPassword for SessionUser {
fn set_password(&mut self, password: &str) -> Option<()> {
let salt: String = thread_rng().sample_iter(&Alphanumeric).take(10).collect();
let hash = hash_password(password, &salt).ok()?;
self.password = Some(hash);
self.salt = Some(salt.into());
Some(())
}
}
#![feature(try_trait)]
#[macro_use] #[macro_use]
extern crate iron; extern crate iron;
#[macro_use] #[macro_use]
...@@ -29,7 +31,7 @@ mod db_conn_sqlite; ...@@ -29,7 +31,7 @@ mod db_conn_sqlite;
mod db_conn; mod db_conn;
mod db_objects; mod db_objects;
use db_conn_sqlite::SetPassword; // TODO: Refactor, so we don't need to take this from there! use functions::SetPassword; // TODO: Refactor, so we don't need to take this from there!
use db_conn::{MedalConnection, MedalObject}; use db_conn::{MedalConnection, MedalObject};
use db_objects::*; use db_objects::*;
...@@ -64,7 +66,7 @@ fn read_config_from_file(file: &Path) -> Config { ...@@ -64,7 +66,7 @@ fn read_config_from_file(file: &Path) -> Config {
use std::io::Read; use std::io::Read;
println!("Reading Config file '{}'", file.to_str().unwrap_or("<Encoding error>")); println!("Reading Config file '{}'", file.to_str().unwrap_or("<Encoding error>"));
let mut config : Config = if let Ok(mut file) = fs::File::open(file) { let mut config : Config = if let Ok(mut file) = fs::File::open(file) {
let mut contents = String::new(); let mut contents = String::new();
file.read_to_string(&mut contents).unwrap(); file.read_to_string(&mut contents).unwrap();
...@@ -79,7 +81,7 @@ fn read_config_from_file(file: &Path) -> Config { ...@@ -79,7 +81,7 @@ fn read_config_from_file(file: &Path) -> Config {
if config.self_url.is_none() {config.self_url = Some("http://localhost:8080".to_string())} if config.self_url.is_none() {config.self_url = Some("http://localhost:8080".to_string())}
println!("I will ask OAuth-providers to redirect to {}", config.self_url.as_ref().unwrap()); println!("I will ask OAuth-providers to redirect to {}", config.self_url.as_ref().unwrap());
config config
} }
...@@ -109,8 +111,8 @@ fn read_contest(p: &path::PathBuf) -> Option<Contest> { ...@@ -109,8 +111,8 @@ fn read_contest(p: &path::PathBuf) -> Option<Contest> {
let mut file = File::open(p).unwrap(); let mut file = File::open(p).unwrap();
let mut contents = String::new(); let mut contents = String::new();
file.read_to_string(&mut contents).unwrap(); file.read_to_string(&mut contents).unwrap();
configreader_yaml::parse_yaml(&contents, p.file_name().to_owned()?.to_str()?, &format!("{}/", p.parent().unwrap().to_str()?)) configreader_yaml::parse_yaml(&contents, p.file_name().to_owned()?.to_str()?, &format!("{}/", p.parent().unwrap().to_str()?))
} }
fn get_all_contest_info(task_dir: &str) -> Vec<Contest> { fn get_all_contest_info(task_dir: &str) -> Vec<Contest> {
...@@ -122,16 +124,16 @@ fn get_all_contest_info(task_dir: &str) -> Vec<Contest> { ...@@ -122,16 +124,16 @@ fn get_all_contest_info(task_dir: &str) -> Vec<Contest> {
}, },
_ => (), _ => (),
} }
if p.file_name().unwrap().to_string_lossy().to_string().ends_with(".yaml") { if p.file_name().unwrap().to_string_lossy().to_string().ends_with(".yaml") {
match read_contest(p) { match read_contest(p) {
Some(contest) => contests.push(contest), Some(contest) => contests.push(contest),
_ => (), _ => (),
} }
}; };
}; };
let mut contests = Vec::new(); let mut contests = Vec::new();
match fs::read_dir(task_dir) { match fs::read_dir(task_dir) {
Err(why) => println!("Error opening tasks directory! {:?}", why.kind()), Err(why) => println!("Error opening tasks directory! {:?}", why.kind()),
...@@ -170,28 +172,28 @@ fn add_admin_user(conn: &mut Connection) { ...@@ -170,28 +172,28 @@ fn add_admin_user(conn: &mut Connection) {
fn main() { fn main() {
let opt = Opt::from_args(); let opt = Opt::from_args();
println!("{:?}", opt); println!("{:?}", opt);
let mut config = read_config_from_file(&opt.configfile); let mut config = read_config_from_file(&opt.configfile);
if opt.databasefile.is_some() { config.database_file = opt.databasefile; } if opt.databasefile.is_some() { config.database_file = opt.databasefile; }
if opt.port.is_some() { config.port = opt.port; } if opt.port.is_some() { config.port = opt.port; }
let mut conn = match config.database_file { let mut conn = match config.database_file {
Some(ref path) => {println!("Using database file {}", &path.to_str().unwrap_or("<unprintable filename>")); Connection::create(path)}, Some(ref path) => {println!("Using database file {}", &path.to_str().unwrap_or("<unprintable filename>")); Connection::create(path)},
None => {println!("Using default database file ./medal.db"); Connection::create(&Path::new("medal.db"))}, None => {println!("Using default database file ./medal.db"); Connection::create(&Path::new("medal.db"))},
}; };
db_apply_migrations::test(&mut conn); db_apply_migrations::test(&mut conn);
refresh_all_contests(&mut conn); refresh_all_contests(&mut conn);
println!("Hello, world!"); println!("Hello, world!");
let contest = conn.get_contest_by_id_complete(1); let contest = conn.get_contest_by_id_complete(1);
add_admin_user(&mut conn); add_admin_user(&mut conn);
println!("Contest {}", contest.name); println!("Contest {}", contest.name);
for taskgroup in contest.taskgroups { for taskgroup in contest.taskgroups {
print!(" Task {}: ", taskgroup.name); print!(" Task {}: ", taskgroup.name);
for task in taskgroup.tasks { for task in taskgroup.tasks {
...@@ -199,7 +201,7 @@ fn main() { ...@@ -199,7 +201,7 @@ fn main() {
} }
println!(""); println!("");
} }
start_server(conn, config); start_server(conn, config);
println!("Could not run server. Is the port already in use?"); println!("Could not run server. Is the port already in use?");
...@@ -215,7 +217,7 @@ mod tests { ...@@ -215,7 +217,7 @@ mod tests {
fn start_server_and_check_request() { fn start_server_and_check_request() {
use std::{thread, time}; use std::{thread, time};
let mut conn = Connection::open_in_memory().unwrap(); let mut conn = Connection::open_in_memory().unwrap();
db_apply_migrations::test(&mut conn); db_apply_migrations::test(&mut conn);
...@@ -226,7 +228,7 @@ mod tests { ...@@ -226,7 +228,7 @@ mod tests {
let pair_ = pair.clone(); let pair_ = pair.clone();
let mut config = read_config_from_file(Path::new("thisfileshoudnotexist")); let mut config = read_config_from_file(Path::new("thisfileshoudnotexist"));
let srvr = start_server(conn, config); let srvr = start_server(conn, config);
thread::spawn(move || { thread::spawn(move || {
...@@ -242,14 +244,14 @@ mod tests { ...@@ -242,14 +244,14 @@ mod tests {
resp.read_to_string(&mut content); resp.read_to_string(&mut content);
assert!(content.contains("<h1>Jugendwettbewerb Informatik</h1>")); assert!(content.contains("<h1>Jugendwettbewerb Informatik</h1>"));
assert!(!content.contains("Error")); assert!(!content.contains("Error"));
let &(ref lock, ref cvar) = &*pair_; let &(ref lock, ref cvar) = &*pair_;
let mut should_exit = lock.lock().unwrap(); let mut should_exit = lock.lock().unwrap();
*should_exit = true; *should_exit = true;
cvar.notify_one(); cvar.notify_one();
//fs::copy("foo.txt", "bar.txt").unwrap(); //fs::copy("foo.txt", "bar.txt").unwrap();
}); });
// Copied from docs // Copied from docs
let &(ref lock, ref cvar) = &*pair; let &(ref lock, ref cvar) = &*pair;
let mut should_exit = lock.lock().unwrap(); let mut should_exit = lock.lock().unwrap();
...@@ -258,7 +260,7 @@ mod tests { ...@@ -258,7 +260,7 @@ mod tests {
} }
srvr.unwrap().close().unwrap(); srvr.unwrap().close().unwrap();
assert!(true); assert!(true);
} }
} }
...@@ -203,6 +203,9 @@ impl<'c, 'a, 'b> From<AugMedalError<'c, 'a, 'b>> for IronError { ...@@ -203,6 +203,9 @@ impl<'c, 'a, 'b> From<AugMedalError<'c, 'a, 'b>> for IronError {
functions::MedalError::DatabaseError => IronError { functions::MedalError::DatabaseError => IronError {
error: Box::new(SessionError { message: "Database Error".to_string() }), error: Box::new(SessionError { message: "Database Error".to_string() }),
response: Response::with(status::Forbidden) }, response: Response::with(status::Forbidden) },
functions::MedalError::NoneError => IronError {
error: Box::new(SessionError { message: "None Error".to_string() }),
response: Response::with(status::Forbidden) },
} }
} }
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment