Commit fd5f188d authored by Robert Czechowski's avatar Robert Czechowski
Browse files

Strictly check that PMS OAuth school data is valid for teachers and students

parent 5b860211
...@@ -1175,7 +1175,7 @@ struct OAuthAccess { ...@@ -1175,7 +1175,7 @@ struct OAuthAccess {
#[allow(non_snake_case)] #[allow(non_snake_case)]
#[serde(untagged)] #[serde(untagged)]
pub enum SchoolIdOrSchoolIds { pub enum SchoolIdOrSchoolIds {
None(i32), None(i32), // PMS sends -1 here if user has no schools associated (admin, jury)
SchoolId(String), SchoolId(String),
SchoolIds(Vec<String>), SchoolIds(Vec<String>),
} }
...@@ -1213,7 +1213,7 @@ fn pms_hash_school(school_id: &str, secret: &str) -> String { ...@@ -1213,7 +1213,7 @@ fn pms_hash_school(school_id: &str, secret: &str) -> String {
format!("{:02X?}", hashed_string).chars().filter(|c| c.is_ascii_alphanumeric()).collect() format!("{:02X?}", hashed_string).chars().filter(|c| c.is_ascii_alphanumeric()).collect()
} }
fn oauth_pms(req: &mut Request, oauth_provider: OauthProvider, school_id: Option<&String>) fn oauth_pms(req: &mut Request, oauth_provider: OauthProvider, selected_school_id: Option<&String>)
-> Result<Result<core::ForeignUserData, Response>, core::MedalError> { -> Result<Result<core::ForeignUserData, Response>, core::MedalError> {
use core::{UserSex, UserType}; use core::{UserSex, UserType};
use params::{Params, Value}; use params::{Params, Value};
...@@ -1250,18 +1250,44 @@ fn oauth_pms(req: &mut Request, oauth_provider: OauthProvider, school_id: Option ...@@ -1250,18 +1250,44 @@ fn oauth_pms(req: &mut Request, oauth_provider: OauthProvider, school_id: Option
// Unify ambiguous fields // Unify ambiguous fields
user_data.userId = user_data.userID.or(user_data.userId); user_data.userId = user_data.userID.or(user_data.userId);
let user_type = match user_data.userType.as_ref() {
"a" | "A" => UserType::Admin,
"t" | "T" => UserType::Teacher,
"s" | "S" => UserType::User,
_ => UserType::User,
};
let user_sex = match user_data.gender.as_ref() {
"m" | "M" => UserSex::Male,
"f" | "F" | "w" | "W" => UserSex::Female,
"?" => UserSex::Unknown,
_ => UserSex::Unknown,
};
match (&user_data.schoolId, user_type) {
// Students cannot have a list of schools
(Some(SchoolIdOrSchoolIds::SchoolIds(_)), UserType::User) => return e("#70"),
// If we need to make sure, a student has a school, we should add the case None(_) here
// Teachers must have a list of schools
(Some(SchoolIdOrSchoolIds::SchoolId(_)), UserType::Teacher) => return e("#71"),
(Some(SchoolIdOrSchoolIds::None(_)), UserType::Teacher) => return e("#72"),
// For other users, we currently don't care
_ => (),
}
// Does the user has an array of school (i.e. is he a teacher)? // Does the user has an array of school (i.e. is he a teacher)?
if let Some(SchoolIdOrSchoolIds::SchoolIds(school_ids)) = user_data.schoolId { if let Some(SchoolIdOrSchoolIds::SchoolIds(school_ids)) = user_data.schoolId {
// Has there been a school selected? // Has there been a school selected?
if let Some(school_id) = school_id { if let Some(selected_school_id) = selected_school_id {
if school_id == "none" && oauth_provider.allow_teacher_login_without_school == Some(true) { if selected_school_id == "none" && oauth_provider.allow_teacher_login_without_school == Some(true) {
// Nothing to do // Nothing to do
} }
// Is the school a valid school for the user? // Is the school a valid school for the user?
else if school_ids.contains(&school_id) { else if school_ids.contains(&selected_school_id) {
if let Some(mut user_id) = user_data.userId { if let Some(mut user_id) = user_data.userId {
user_id.push('/'); user_id.push('/');
user_id.push_str(&school_id); user_id.push_str(&selected_school_id);
user_data.userId = Some(user_id); user_data.userId = Some(user_id);
} }
} else { } else {
...@@ -1309,24 +1335,14 @@ fn oauth_pms(req: &mut Request, oauth_provider: OauthProvider, school_id: Option ...@@ -1309,24 +1335,14 @@ fn oauth_pms(req: &mut Request, oauth_provider: OauthProvider, school_id: Option
return Err(core::MedalError::ConfigurationError); return Err(core::MedalError::ConfigurationError);
} }
} }
} else if school_id.is_some() { } else if selected_school_id.is_some() {
// A school has apparently been selected but the user is actually not a teacher // A school has apparently been selected but the user is actually not a teacher
return e("#50"); return e("#50");
} }
Ok(Ok(core::ForeignUserData { foreign_id: user_data.userId.ok_or(er("#60"))?, Ok(Ok(core::ForeignUserData { foreign_id: user_data.userId.ok_or(er("#60"))?,
foreign_type: match user_data.userType.as_ref() { foreign_type: user_type,
"a" | "A" => UserType::Admin, sex: user_sex,
"t" | "T" => UserType::Teacher,
"s" | "S" => UserType::User,
_ => UserType::User,
},
sex: match user_data.gender.as_ref() {
"m" | "M" => UserSex::Male,
"f" | "F" | "w" | "W" => UserSex::Female,
"?" => UserSex::Unknown,
_ => UserSex::Unknown,
},
firstname: user_data.firstName, firstname: user_data.firstName,
lastname: user_data.lastName })) lastname: user_data.lastName }))
} }
......
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