Commit 07b956d0 authored by Robert Czechowski's avatar Robert Czechowski
Browse files

Add more options for config.json: Socket-Addr, Url, Oauth url

parent 6f7cc456
......@@ -18,7 +18,7 @@ pub fn blaa() -> (String, json_val::Map<String, json_val::Value>) {
("greeting".to_owned(), data)
}
pub fn index<T: MedalConnection>(conn: &T, session_token: Option<String>) -> (String, json_val::Map<String, json_val::Value>) {
pub fn index<T: MedalConnection>(conn: &T, session_token: Option<String>, (self_url, oauth_url): (String, String)) -> (String, json_val::Map<String, json_val::Value>) {
let mut data = json_val::Map::new();
//let mut contests = Vec::new();
......@@ -32,8 +32,9 @@ pub fn index<T: MedalConnection>(conn: &T, session_token: Option<String>) -> (St
data.insert("teacher".to_string(), to_json(&session.is_teacher));
}
}
data.insert("self_url".to_string(), to_json(&self_url));
data.insert("oauth_url".to_string(), to_json(&oauth_url));
/*contests.push("blaa".to_string());
data.insert("contest".to_string(), to_json(&contests));*/
......@@ -42,7 +43,6 @@ pub fn index<T: MedalConnection>(conn: &T, session_token: Option<String>) -> (St
#[derive(Serialize, Deserialize)]
pub struct SubTaskInfo {
pub id: u32,
......
......@@ -48,8 +48,12 @@ use std::fs;
use std::path::{Path,PathBuf};
use structopt::StructOpt;
#[derive(Serialize, Deserialize)]
#[derive(Serialize, Deserialize, Clone)]
pub struct Config {
host: Option<String>,
port: Option<u16>,
self_url: Option<String>,
oauth_url: Option<String>,
oauth_client_id: Option<String>,
oauth_client_secret: Option<String>,
oauth_access_token_url: Option<String>,
......@@ -60,20 +64,30 @@ pub struct Config {
fn read_config_from_file(file: &Path) -> Config {
use std::io::Read;
if let Ok(mut file) = fs::File::open(file) {
let mut config = if let Ok(mut file) = fs::File::open(file) {
let mut contents = String::new();
file.read_to_string(&mut contents).unwrap();
serde_json::from_str(&contents).unwrap()
} else {
println!("Configuration file '{}' not found.", file.to_str().unwrap_or("<Encoding error>"));
Config {
host: None,
port: None,
self_url: None,
oauth_url: None,
oauth_client_id: None,
oauth_client_secret: None,
oauth_access_token_url: None,
oauth_user_data_url: None,
database_file: None,
}
}
};
if config.host.is_none() {config.host = Some("[::]".to_string())}
if config.port.is_none() {config.port = Some(8080)}
if config.self_url.is_none() {config.self_url = Some("https://localhost:8080".to_string())}
config
}
#[derive(StructOpt, Debug)]
......@@ -165,8 +179,8 @@ fn main() {
//if config.database_file.is_none() { config.database_file = Some(.to_path_buf()); }
let mut conn = match config.database_file {
Some(ref path) => Connection::create(path),
None => Connection::create(&Path::new("medal.db")),
Some(ref path) => {print!("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"))},
};
db_apply_migrations::test(&mut conn);
......
......@@ -215,13 +215,23 @@ fn greet_personal(req: &mut Request) -> IronResult<Response> {
let session_token = req.get_session_token();
// hier ggf. Daten aus dem Request holen
let (self_url, oauth_url) = {
let mutex = req.get::<Write<SharedConfiguration>>().unwrap();
let config = mutex.lock().unwrap_or_else(|e| e.into_inner());
if let (Some(su), Some(ou)) = (&config.self_url, &config.oauth_url) {
(su.clone(), ou.clone())
} else {
return Ok(Response::with(iron::status::NotFound)) // TODO: Remove OAuth Link if OAuth not available
}
};
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::index(&*conn, session_token)
functions::index(&*conn, session_token, (self_url, oauth_url))
};
// Daten verarbeiten
......@@ -286,9 +296,23 @@ fn contest_post(req: &mut Request) -> IronResult<Response> {
Ok(Response::with((status::Found, Redirect(url_for!(req, "contest", "contestid" => format!("{}",contest_id))))))
}
fn login(_: &mut Request) -> IronResult<Response> {
fn login(req: &mut Request) -> IronResult<Response> {
let (self_url, oauth_url) = {
let mutex = req.get::<Write<SharedConfiguration>>().unwrap();
let config = mutex.lock().unwrap_or_else(|e| e.into_inner());
if let (Some(su), Some(ou)) = (&config.self_url, &config.oauth_url) {
(su.clone(), ou.clone())
} else {
return Ok(Response::with(iron::status::NotFound)) // TODO: Remove OAuth Link if OAuth not available
}
};
let mut data = json_val::Map::new();
data.insert("self_url".to_string(), to_json(&self_url));
data.insert("oauth_url".to_string(), to_json(&oauth_url));
let mut resp = Response::new();
resp.set_mut(Template::new("login", "".to_owned())).set_mut(status::Ok);
resp.set_mut(Template::new("login", data)).set_mut(status::Ok);
Ok(resp)
}
......@@ -626,75 +650,74 @@ fn oauth(req: &mut Request) -> IronResult<Response> {
_ => return Ok(Response::with(iron::status::NotFound)),
}
};
let client = reqwest::Client::new().unwrap();
let params = [("code", code), ("grant_type", "authorization_code".to_string())];
let res = client.post(&access_token_url)
.header(header::Authorization(header::Basic {
username: client_id,
password: Some(client_secret)}))
.form(&params)
.send();
let access: OAuthAccess = res.expect("network error").json().expect("malformed json");
let res = client.post(&user_data_url)
.header(header::Authorization(header::Bearer{token: access.access_token}))
.form(&params)
.send();
let mut user_data: OAuthUserData = res.expect("network error").json().expect("malformed json");
if let Some(ref id) = user_data.userID {
user_data.userId_int = Some(id.parse::<u32>().unwrap());
}
if let Some(ref id) = user_data.userId {
user_data.userId_int = Some(id.parse::<u32>().unwrap());
}
use functions::{UserType, UserGender};
let user_data = functions::ForeignUserData {
foreign_id: user_data.userId_int.unwrap(),
foreign_type: match user_data.userType.as_ref() {
"a" | "A" => UserType::Admin,
"t" | "T" => UserType::Teacher,
"s" | "S" | _ => UserType::User,
},
gender: match user_data.gender.as_ref() {
"m" | "M" => UserGender::Male,
"f" | "F" | "w" | "W" => UserGender::Female,
"?" | _ => UserGender::Unknown,
},
firstname: user_data.firstName,
lastname: user_data.lastName,
};
let oauthloginresult = {
// 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::login_oauth(&*conn, user_data)
/*let mut data = json_val::Map::new();
data.insert("reason".to_string(), to_json(&"Not implemented".to_string()));
("profile", data)*/
};
match oauthloginresult {
// Login successful
Ok(sessionkey) => {
req.session().set(SessionToken { token: sessionkey }).unwrap();
Ok(Response::with((status::Found, Redirect(url_for!(req, "greet")))))
},
// Login failed
Err((template, data)) => {
let mut resp = Response::new();
resp.set_mut(Template::new(&template, data)).set_mut(status::Ok);
Ok(resp)
}
}
let client = reqwest::Client::new().unwrap();
let params = [("code", code), ("grant_type", "authorization_code".to_string())];
let res = client.post(&access_token_url)
.header(header::Authorization(header::Basic {
username: client_id,
password: Some(client_secret)}))
.form(&params)
.send();
let access: OAuthAccess = res.expect("network error").json().expect("malformed json");
let res = client.post(&user_data_url)
.header(header::Authorization(header::Bearer{token: access.access_token}))
.form(&params)
.send();
let mut user_data: OAuthUserData = res.expect("network error").json().expect("malformed json");
if let Some(ref id) = user_data.userID {
user_data.userId_int = Some(id.parse::<u32>().unwrap());
}
if let Some(ref id) = user_data.userId {
user_data.userId_int = Some(id.parse::<u32>().unwrap());
}
use functions::{UserType, UserGender};
let user_data = functions::ForeignUserData {
foreign_id: user_data.userId_int.unwrap(),
foreign_type: match user_data.userType.as_ref() {
"a" | "A" => UserType::Admin,
"t" | "T" => UserType::Teacher,
"s" | "S" | _ => UserType::User,
},
gender: match user_data.gender.as_ref() {
"m" | "M" => UserGender::Male,
"f" | "F" | "w" | "W" => UserGender::Female,
"?" | _ => UserGender::Unknown,
},
firstname: user_data.firstName,
lastname: user_data.lastName,
};
let oauthloginresult = {
// 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::login_oauth(&*conn, user_data)
/*let mut data = json_val::Map::new();
data.insert("reason".to_string(), to_json(&"Not implemented".to_string()));
("profile", data)*/
};
match oauthloginresult {
// Login successful
Ok(sessionkey) => {
req.session().set(SessionToken { token: sessionkey }).unwrap();
Ok(Response::with((status::Found, Redirect(url_for!(req, "greet")))))
},
// Login failed
Err((template, data)) => {
let mut resp = Response::new();
resp.set_mut(Template::new(&template, data)).set_mut(status::Ok);
Ok(resp)
}
}
}
......@@ -800,14 +823,16 @@ pub fn start_server(conn: Connection, config: ::Config) {
let mut ch = Chain::new(mount);
ch.link(Write::<SharedDatabaseConnection>::both(conn));
ch.link(Write::<SharedConfiguration>::both(config));
ch.link(Write::<SharedConfiguration>::both(config.clone()));
ch.link_around(SessionStorage::new(SignedCookieBackend::new(my_secret)));
ch.link_after(get_handlebars_engine());
ch.link_after(ErrorReporter);
let _res = Iron::new(ch).http("[::]:8080");
println!("Listening on 8080.");
let socket_addr = format!("{}:{}", config.host.unwrap(), config.port.unwrap());
let _res = Iron::new(ch).http(&socket_addr);
println!("Listening on {}.", &socket_addr);
}
......@@ -27,7 +27,7 @@ Eingeloggt als <em>{{ username }}</em>
<input type="submit" value="log in">
</form>
<a href="https://testpms.bwinf.de/app/PMS/wa/OAuth2/authorize?client_id=bwinf-junior-league&scope=authenticate&response_type=code&state=42&redirect_uri=http://localhost:8080/oauth">PMS-Login für Lehrer</a>
<a href="{{ oauth_url }}{{ self_url }}/oauth">PMS-Login für Lehrer</a>
{{/if}}
</div>
......
......@@ -24,4 +24,4 @@
<p>
<a href="https://testpms.bwinf.de/app/PMS/wa/OAuth2/authorize?client_id=bwinf-junior-league&scope=authenticate&response_type=code&state=42&redirect_uri=http://localhost:8080/oauth">PMS-Login</a>
<a href="{{ oauth_url }}{{ self_url }}/oauth">PMS-Login</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