Commit 7a5f4d84 authored by Robert Czechowski's avatar Robert Czechowski
Browse files

Add request for secret if contest has secret set. Does not work in the case of...

Add request for secret if contest has secret set. Does not work in the case of not-logged-in users yet.
parent 7004e101
...@@ -328,7 +328,7 @@ fn check_contest_constraints(session: &SessionUser, contest: &Contest) -> Contes ...@@ -328,7 +328,7 @@ fn check_contest_constraints(session: &SessionUser, contest: &Contest) -> Contes
} }
pub fn show_contest<T: MedalConnection>(conn: &T, contest_id: i32, session_token: &str, pub fn show_contest<T: MedalConnection>(conn: &T, contest_id: i32, session_token: &str,
query_string: Option<String>, login_info: LoginInfo) query_string: Option<String>, login_info: LoginInfo, secret: Option<String>)
-> MedalValueResult -> MedalValueResult
{ {
let session = conn.get_session_or_new(&session_token).unwrap(); let session = conn.get_session_or_new(&session_token).unwrap();
...@@ -355,6 +355,21 @@ pub fn show_contest<T: MedalConnection>(conn: &T, contest_id: i32, session_token ...@@ -355,6 +355,21 @@ pub fn show_contest<T: MedalConnection>(conn: &T, contest_id: i32, session_token
data.insert("message".to_string(), to_json(&contest.message)); data.insert("message".to_string(), to_json(&contest.message));
fill_oauth_data(login_info, &mut data); fill_oauth_data(login_info, &mut data);
if secret.is_some() && secret != contest.secret {
return Err(MedalError::AccessDenied);
}
let mut require_secret = false;
if contest.secret.is_some() {
data.insert("secret_field".to_string(), to_json(&true));
if secret.is_some() {
data.insert("secret_field_prefill".to_string(), to_json(&secret));
} else {
require_secret = true;
}
}
let constraints = check_contest_constraints(&session, &contest); let constraints = check_contest_constraints(&session, &contest);
let is_qualified = check_contest_qualification(conn, &session, &contest).unwrap_or(true); let is_qualified = check_contest_qualification(conn, &session, &contest).unwrap_or(true);
...@@ -378,6 +393,7 @@ pub fn show_contest<T: MedalConnection>(conn: &T, contest_id: i32, session_token ...@@ -378,6 +393,7 @@ pub fn show_contest<T: MedalConnection>(conn: &T, contest_id: i32, session_token
&& contest.duration == 0 && contest.duration == 0
&& constraints.contest_running && constraints.contest_running
&& constraints.grade_matching && constraints.grade_matching
&& !require_secret
&& contest.requires_login != Some(true) && contest.requires_login != Some(true)
{ {
conn.new_participation(&session_token, contest_id).map_err(|_| MedalError::AccessDenied)?; conn.new_participation(&session_token, contest_id).map_err(|_| MedalError::AccessDenied)?;
...@@ -518,7 +534,7 @@ pub fn show_contest_results<T: MedalConnection>(conn: &T, contest_id: i32, sessi ...@@ -518,7 +534,7 @@ pub fn show_contest_results<T: MedalConnection>(conn: &T, contest_id: i32, sessi
Ok(("contestresults".to_owned(), data)) Ok(("contestresults".to_owned(), data))
} }
pub fn start_contest<T: MedalConnection>(conn: &T, contest_id: i32, session_token: &str, csrf_token: &str) pub fn start_contest<T: MedalConnection>(conn: &T, contest_id: i32, session_token: &str, csrf_token: &str, secret: Option<String>)
-> MedalResult<()> { -> MedalResult<()> {
// TODO: Is _or_new the right semantic? We need a CSRF token anyway … // TODO: Is _or_new the right semantic? We need a CSRF token anyway …
let session = conn.get_session_or_new(&session_token).unwrap(); let session = conn.get_session_or_new(&session_token).unwrap();
...@@ -547,6 +563,10 @@ pub fn start_contest<T: MedalConnection>(conn: &T, contest_id: i32, session_toke ...@@ -547,6 +563,10 @@ pub fn start_contest<T: MedalConnection>(conn: &T, contest_id: i32, session_toke
return Err(MedalError::AccessDenied); return Err(MedalError::AccessDenied);
} }
if contest.secret != secret {
return Err(MedalError::AccessDenied);
}
// Start contest // Start contest
match conn.new_participation(&session_token, contest_id) { match conn.new_participation(&session_token, contest_id) {
Ok(_) => Ok(()), Ok(_) => Ok(()),
......
...@@ -441,12 +441,13 @@ fn contests<C>(req: &mut Request) -> IronResult<Response> ...@@ -441,12 +441,13 @@ fn contests<C>(req: &mut Request) -> IronResult<Response>
fn contest<C>(req: &mut Request) -> IronResult<Response> fn contest<C>(req: &mut Request) -> IronResult<Response>
where C: MedalConnection + std::marker::Send + 'static { where C: MedalConnection + std::marker::Send + 'static {
let contest_id = req.expect_int::<i32>("contestid")?; let contest_id = req.expect_int::<i32>("contestid")?;
let secret = req.get_str("secret");
let session_token = req.require_session_token()?; let session_token = req.require_session_token()?;
let query_string = req.url.query().map(|s| s.to_string()); let query_string = req.url.query().map(|s| s.to_string());
let config = req.get::<Read<SharedConfiguration>>().unwrap(); let config = req.get::<Read<SharedConfiguration>>().unwrap();
let (template, data) = let (template, data) =
with_conn![core::show_contest, C, req, contest_id, &session_token, query_string, login_info(&config)].aug(req)?; with_conn![core::show_contest, C, req, contest_id, &session_token, query_string, login_info(&config), secret].aug(req)?;
let mut resp = Response::new(); let mut resp = Response::new();
resp.set_mut(Template::new(&template, data)).set_mut(status::Ok); resp.set_mut(Template::new(&template, data)).set_mut(status::Ok);
...@@ -514,13 +515,14 @@ fn contest_post<C>(req: &mut Request) -> IronResult<Response> ...@@ -514,13 +515,14 @@ fn contest_post<C>(req: &mut Request) -> IronResult<Response>
let contest_id = req.expect_int::<i32>("contestid")?; let contest_id = req.expect_int::<i32>("contestid")?;
let session_token = req.expect_session_token()?; let session_token = req.expect_session_token()?;
let csrf_token = { let (csrf_token, secret) = {
let formdata = itry!(req.get_ref::<UrlEncodedBody>()); let formdata = itry!(req.get_ref::<UrlEncodedBody>());
iexpect!(formdata.get("csrf_token"))[0].to_owned() (iexpect!(formdata.get("csrf_token"))[0].to_owned(),
formdata.get("secret").map(|x| x[0].to_owned()))
}; };
// TODO: Was mit dem Result? // TODO: Was mit dem Result?
with_conn![core::start_contest, C, req, contest_id, &session_token, &csrf_token].aug(req)?; with_conn![core::start_contest, C, req, contest_id, &session_token, &csrf_token, secret].aug(req)?;
Ok(Response::with((status::Found, Redirect(url_for!(req, "contest", "contestid" => format!("{}",contest_id)))))) Ok(Response::with((status::Found, Redirect(url_for!(req, "contest", "contestid" => format!("{}",contest_id))))))
} }
...@@ -1426,6 +1428,7 @@ pub fn start_server<C>(conn: C, config: Config) -> iron::error::HttpResult<iron: ...@@ -1426,6 +1428,7 @@ pub fn start_server<C>(conn: C, config: Config) -> iron::error::HttpResult<iron:
greet: get "/" => greet_personal::<C>, greet: get "/" => greet_personal::<C>,
contests: get "/contest/" => contests::<C>, contests: get "/contest/" => contests::<C>,
contest: get "/contest/:contestid" => contest::<C>, contest: get "/contest/:contestid" => contest::<C>,
contest_secret: get "/contest/:contestid/:secret" => contest::<C>,
contestresults: get "/contest/:contestid/result/" => contestresults::<C>, contestresults: get "/contest/:contestid/result/" => contestresults::<C>,
contestresults_download: get "/contest/:contestid/result/download" => contestresults_download::<C>, contestresults_download: get "/contest/:contestid/result/download" => contestresults_download::<C>,
contest_post: post "/contest/:contestid" => contest_post::<C>, contest_post: post "/contest/:contestid" => contest_post::<C>,
......
...@@ -108,6 +108,8 @@ ...@@ -108,6 +108,8 @@
<p> <p>
<form action="" method="post"> <form action="" method="post">
<input type="hidden" name="csrf_token" value="{{csrf_token}}"> <input type="hidden" name="csrf_token" value="{{csrf_token}}">
{{#if secret_field}}<input {{#if secret_field_prefill}}type="hidden"{{/if}} name="secret" value="{{secret_field_prefill}}" placeholder="Wettbewerbspasswort">{{/if}}
{{#if secret_wrong}}Das eingegeben Passwort ist nicht korrekt.{{/if}}
<input class="button is-warning is-medium" type="submit" value="{{#if contest.duration}}⏱ &nbsp; {{/if}}Jetzt starten! {{#if contest.duration}}({{contest.duration}} min){{/if}}" style="font-weight:bold;"> <input class="button is-warning is-medium" type="submit" value="{{#if contest.duration}}⏱ &nbsp; {{/if}}Jetzt starten! {{#if contest.duration}}({{contest.duration}} min){{/if}}" style="font-weight:bold;">
</form> </form>
</p> </p>
......
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