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
}
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
{
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
data.insert("message".to_string(), to_json(&contest.message));
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 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
&& contest.duration == 0
&& constraints.contest_running
&& constraints.grade_matching
&& !require_secret
&& contest.requires_login != Some(true)
{
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
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<()> {
// TODO: Is _or_new the right semantic? We need a CSRF token anyway …
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
return Err(MedalError::AccessDenied);
}
if contest.secret != secret {
return Err(MedalError::AccessDenied);
}
// Start contest
match conn.new_participation(&session_token, contest_id) {
Ok(_) => Ok(()),
......
......@@ -441,12 +441,13 @@ fn contests<C>(req: &mut Request) -> IronResult<Response>
fn contest<C>(req: &mut Request) -> IronResult<Response>
where C: MedalConnection + std::marker::Send + 'static {
let contest_id = req.expect_int::<i32>("contestid")?;
let secret = req.get_str("secret");
let session_token = req.require_session_token()?;
let query_string = req.url.query().map(|s| s.to_string());
let config = req.get::<Read<SharedConfiguration>>().unwrap();
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();
resp.set_mut(Template::new(&template, data)).set_mut(status::Ok);
......@@ -514,13 +515,14 @@ fn contest_post<C>(req: &mut Request) -> IronResult<Response>
let contest_id = req.expect_int::<i32>("contestid")?;
let session_token = req.expect_session_token()?;
let csrf_token = {
let (csrf_token, secret) = {
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?
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))))))
}
......@@ -1426,6 +1428,7 @@ pub fn start_server<C>(conn: C, config: Config) -> iron::error::HttpResult<iron:
greet: get "/" => greet_personal::<C>,
contests: get "/contest/" => contests::<C>,
contest: get "/contest/:contestid" => contest::<C>,
contest_secret: get "/contest/:contestid/:secret" => contest::<C>,
contestresults: get "/contest/:contestid/result/" => contestresults::<C>,
contestresults_download: get "/contest/:contestid/result/download" => contestresults_download::<C>,
contest_post: post "/contest/:contestid" => contest_post::<C>,
......
......@@ -108,6 +108,8 @@
<p>
<form action="" method="post">
<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;">
</form>
</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