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

The user gets a message on screen, if he changes (or not changes) his profile data and password

parent db438a15
......@@ -58,7 +58,7 @@ impl MedalConnection for Connection {
// fn get_session<T: ToSql>(&self, key: T, keyname: &str) -> Option<SessionUser> {
fn get_session(&self, key: &str) -> Option<SessionUser> {
let res = self.query_row("SELECT id, csrf_token, last_login, last_activity, permanent_login, username, password, logincode, email, email_unconfirmed, email_confirmationcode, firstname, lastname, street, zip, city, nation, grade, is_teacher, managed_by, pms_id, pms_school_id FROM session_user WHERE session_token = ?1", &[&key], |row| {
let res = self.query_row("SELECT id, csrf_token, last_login, last_activity, permanent_login, username, password, logincode, email, email_unconfirmed, email_confirmationcode, firstname, lastname, street, zip, city, nation, grade, is_teacher, managed_by, pms_id, pms_school_id, salt FROM session_user WHERE session_token = ?1", &[&key], |row| {
SessionUser {
id: row.get(0),
session_token: Some(key.to_string()),
......@@ -69,7 +69,7 @@ impl MedalConnection for Connection {
username: row.get(5),
password: row.get(6),
salt: None,//"".to_string(),
salt: row.get(22),
logincode: row.get(7),
email: row.get(8),
email_unconfirmed: row.get(9),
......@@ -204,7 +204,7 @@ impl MedalConnection for Connection {
}) {
Ok((id, password_hash, salt)) => { //password_hash ist das, was in der Datenbank steht
//println!("{}, {}", password, password_hash.unwrap());
if verify_password(&password, &salt.unwrap(), &password_hash.unwrap()) == true { // TODO: fail more pleasantly
if verify_password(&password, &salt.expect("salt from database empty"), &password_hash.expect("password from database empty")) == true { // TODO: fail more pleasantly
// Login okay, update session now!
let session_token: String = thread_rng().sample_iter(&Alphanumeric).take(10).collect();
......
......@@ -78,6 +78,7 @@ pub enum MedalError {
SessionTimeout,
DatabaseError,
NoneError,
UnmatchedPasswords,
}
// TODO: Add CsrfCheckFailed, DatabaseError
......@@ -463,7 +464,7 @@ pub fn show_groups_results<T: MedalConnection>(conn: &T, contest_id: u32, sessio
Ok(("groupresults".into(), data))
}
pub fn show_profile<T: MedalConnection>(conn: &T, session_token: String, user_id: Option<u32>) -> MedalValueResult {
pub fn show_profile<T: MedalConnection>(conn: &T, session_token: String, user_id: Option<u32>, query_string: Option<String>) -> MedalValueResult {
let session = conn.get_session_or_new(&session_token).ensure_alive().ok_or(MedalError::AccessDenied)?; // TODO SessionTimeout
let mut data = json_val::Map::new();
......@@ -481,6 +482,20 @@ pub fn show_profile<T: MedalConnection>(conn: &T, session_token: String, user_id
data.insert("ownprofile".into(), to_json(&true));
data.insert("csrftoken".to_string(), to_json(&session.csrf_token));
let status = query_string.unwrap();
if status == "status=password_not_matched" {
data.insert("password_not_matched".to_string(), to_json(&true));
}
else if status == "status=password_changed" {
data.insert("password_changed".to_string(), to_json(&true));
}
else if status == "status=personal_data_changed" {
data.insert("personal_data_changed".to_string(), to_json(&true));
}
else if status == "status=nothing_changed" {
data.insert("nothing_changed".to_string(), to_json(&true));
}
},
Some(user_id) => {
// TODO: Add test to check if this access restriction works
......@@ -502,6 +517,8 @@ pub fn show_profile<T: MedalConnection>(conn: &T, session_token: String, user_id
data.insert("ownprofile".into(), to_json(&false));
data.insert("csrftoken".to_string(), to_json(&session.csrf_token));
// data.insert("query_string".to_string(), to_json(&query_string.unwrap()));
}
}
......@@ -516,25 +533,43 @@ fn hash_password(password: &str, salt: &str) -> Result<String, BcryptError> {
}
}
pub fn edit_profile<T: MedalConnection>(conn: &T, session_token: String, user_id: Option<u32>, csrf_token: String, firstname: String, lastname: String, new_password_1: String, new_password_2: String, grade: u8) -> MedalResult<()> {
pub enum ChangeData {
data_changed,
pw_changed_success,
pw_changed_failed,
nothing_changed,
}
pub fn edit_profile<T: MedalConnection>(conn: &T, session_token: String, user_id: Option<u32>, csrf_token: String, firstname: String, lastname: String, new_password_1: String, new_password_2: String, grade: u8) -> MedalResult<ChangeData> {
let mut session = conn.get_session(&session_token).ok_or(MedalError::AccessDenied)?.ensure_alive().ok_or(MedalError::AccessDenied)?; // TODO SessionTimeout
if session.csrf_token != csrf_token {
return Err(MedalError::AccessDenied); // CsrfError
}
let mut result = ChangeData::data_changed;
match user_id {
None => {
let firstname_for_check: String = firstname.to_owned();
let lastname_for_check: String = lastname.to_owned();
if session.firstname == Some(firstname_for_check) && session.lastname == Some(lastname_for_check) && session.grade == grade && new_password_1 == "" && new_password_2 == "" {
result = ChangeData::nothing_changed;
}
session.firstname = Some(firstname);
session.lastname = Some(lastname);
session.grade = grade;
if new_password_1 == new_password_2 {
if new_password_1 != "" && new_password_2 != "" && 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()?;
session.password = Some(hash);
session.salt = Some(salt.into());
result = ChangeData::pw_changed_success;
}
else if (new_password_1 != "" && new_password_2 != "" && new_password_1 != new_password_2) || ((new_password_1 != "" || new_password_2 != "") && new_password_1 != new_password_2) {
result = ChangeData::pw_changed_failed;
}
conn.save_session(session);
......@@ -563,7 +598,7 @@ pub fn edit_profile<T: MedalConnection>(conn: &T, session_token: String, user_id
}
}
Ok(())
Ok(result)
}
#[derive(PartialEq)]
......
......@@ -206,6 +206,9 @@ impl<'c, 'a, 'b> From<AugMedalError<'c, 'a, 'b>> for IronError {
functions::MedalError::NoneError => IronError {
error: Box::new(SessionError { message: "None Error".to_string() }),
response: Response::with(status::Forbidden) },
functions::MedalError::UnmatchedPasswords => IronError {
error: Box::new(SessionError { message: "The two passwords did not match.".to_string() }),
response: Response::with(status::Forbidden) },
}
}
}
......@@ -587,13 +590,18 @@ fn new_group(req: &mut Request) -> IronResult<Response> {
fn profile(req: &mut Request) -> IronResult<Response> {
let session_token = req.require_session_token()?;
let query_string :String = match req.url.query() {
Some(t) => t,
None => "",
}.to_string();
let (template, data) = {
// hier ggf. Daten aus dem Request holen
let mutex = req.get::<Write<SharedDatabaseConnection>>().unwrap();
let conn = mutex.lock().unwrap_or_else(|e| e.into_inner());
// Antwort erstellen und zurücksenden
functions::show_profile(&*conn, session_token, None).aug(req)?
functions::show_profile(&*conn, session_token, None, Some(query_string)).aug(req)?
};
let mut resp = Response::new();
......@@ -616,16 +624,19 @@ fn profile_post(req: &mut Request) -> IronResult<Response> {
};
let profilechangeresult = {
// hier ggf. Daten aus dem Request holen
let mutex = req.get::<Write<SharedDatabaseConnection>>().unwrap();
let conn = mutex.lock().unwrap_or_else(|e| e.into_inner());
// Antwort erstellen und zurücksenden
functions::edit_profile(&*conn, session_token, None, csrf_token, firstname, lastname, new_password_1, new_password_2, grade).aug(req)?
};
// hier ggf. Daten aus dem Request holen
let mutex = req.get::<Write<SharedDatabaseConnection>>().unwrap();
let conn = mutex.lock().unwrap_or_else(|e| e.into_inner());
Ok(Response::with((status::Found, Redirect(url_for!(req, "profile")))))
// Antwort erstellen und zurücksenden
let ans ={ functions::edit_profile(&*conn, session_token, None, csrf_token, firstname, lastname, new_password_1, new_password_2, grade)};
match ans {
Ok(functions::ChangeData::pw_changed_failed) => Ok(Response::with((status::Found, Redirect(iron::Url::parse(&format!("{}{}", &url_for!(req, "profile"),"?status=password_not_matched")).unwrap())))),
Ok(functions::ChangeData::pw_changed_success) => Ok(Response::with((status::Found, Redirect(iron::Url::parse(&format!("{}{}", &url_for!(req, "profile"),"?status=password_changed")).unwrap())))),
Ok(functions::ChangeData::data_changed) => Ok(Response::with((status::Found, Redirect(iron::Url::parse(&format!("{}{}", &url_for!(req, "profile"),"?status=personal_data_changed")).unwrap())))),
Ok(functions::ChangeData::nothing_changed) => Ok(Response::with((status::Found, Redirect(iron::Url::parse(&format!("{}{}", &url_for!(req, "profile"),"?status=nothing_changed")).unwrap())))),
Err(_) => Ok(Response::with((status::Found, Redirect(url_for!(req, "profile"))))),
}
}
fn user(req: &mut Request) -> IronResult<Response> {
......@@ -638,7 +649,7 @@ fn user(req: &mut Request) -> IronResult<Response> {
let conn = mutex.lock().unwrap_or_else(|e| e.into_inner());
// Antwort erstellen und zurücksenden
functions::show_profile(&*conn, session_token, Some(user_id)).aug(req)?
functions::show_profile(&*conn, session_token, Some(user_id), None).aug(req)?
};
let mut resp = Response::new();
......
......@@ -56,6 +56,22 @@
</table>
</form>
{{#if password_not_matched}}
<p>Die eingegebenen Paswörter stimmen nicht überein. Bitte versuche es nochmal.</p>
{{/if}}
{{#if password_changed}}
<p>Dein Passwort wurde erfolgreich geändert.</p>
{{/if}}
{{#if personal_data_changed}}
<p>Deine Daten wurden erfolgreich geändert.</p>
{{/if}}
{{#if nothing_changed}}
<p>Bitte ändere deine Daten, bevor du auf "Speichern" klickst.</p>
{{/if}}
<a href="/">Zur Startseite</a>
<!--a href="javascript:window.history.back();">Zurück</a-->
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