Commit 629f04b9 authored by Robert Czechowski's avatar Robert Czechowski

Merge branch 'v1.5' into deploy

parents 6b575e1c 5103c709
Pipeline #833 passed with stages
in 17 minutes and 20 seconds
......@@ -1064,7 +1064,7 @@ checksum = "79c56d6a0b07f9e19282511c83fc5b086364cbae4ba8c7d5f190c3d9b0425a48"
[[package]]
name = "medal"
version = "1.5.0"
version = "1.5.1"
dependencies = [
"bcrypt",
"csv",
......
[package]
version = "1.5.0"
version = "1.5.1"
name = "medal"
authors = ["Robert Czechowski <czechowski@bwinf.de>", "Daniel Brüning <bruening@bwinf.de>"]
......
# The Medal Contest Platform
[![crates.io](https://img.shields.io/crates/v/medal?color=orange)](https://crates.io/crates/medal)
[![documentation](https://img.shields.io/crates/v/medal?label=docs)](https://jim.test.bwinf.de/doc/medal/)
[![pipeline](https://git.bwinf.de/bwinf/medal/badges/master/pipeline.svg)](https://git.bwinf.de/bwinf/medal/-/pipelines)
[![License: AGPL3](https://img.shields.io/crates/l/medal?color=green)](LICENSE)
Medal is a small platform for in-browser running contest written in rust.
It is designed for the German "Jugendwettbewerb Informatik", a computer science contest with tasks using Google Blockly as a programming language-replacement.
......
......@@ -308,7 +308,7 @@ pub fn show_contest<T: MedalConnection>(conn: &T, contest_id: i32, session_token
let contest = conn.get_contest_by_id_complete(contest_id);
let grades = conn.get_contest_user_grades(&session_token, contest_id);
let mut opt_part = conn.get_participation(&session_token, contest_id);
let mut opt_part = conn.get_participation(session.id, contest_id);
let ci = ContestInfo { id: contest.id.unwrap(),
name: contest.name.clone(),
......@@ -611,7 +611,7 @@ pub fn save_submission<T: MedalConnection>(conn: &T, task_id: i32, session_token
let (t, _, c) = conn.get_task_by_id_complete(task_id);
match conn.get_participation(&session_token, c.id.expect("Value from database")) {
match conn.get_participation(session.id, c.id.expect("Value from database")) {
None => return Err(MedalError::AccessDenied),
Some(participation) => {
let now = time::get_time();
......@@ -706,7 +706,7 @@ pub fn show_task<T: MedalConnection>(conn: &T, task_id: i32, session_token: &str
}
}
match conn.get_participation(&session_token, c.id.expect("Value from database")) {
match conn.get_own_participation(&session_token, c.id.expect("Value from database")) {
None => Err(MedalError::AccessDenied),
Some(participation) => {
let now = time::get_time();
......@@ -1392,7 +1392,7 @@ pub fn admin_show_participation<T: MedalConnection>(conn: &T, user_id: i32, cont
data.insert("userid".to_string(), to_json(&user.id));
let participation =
conn.get_participation(&user.session_token.unwrap(), contest_id).ok_or(MedalError::AccessDenied)?;
conn.get_participation(user.id, contest_id).ok_or(MedalError::AccessDenied)?;
data.insert("start_date".to_string(),
to_json(&self::time::strftime("%FT%T%z", &self::time::at(participation.start)).unwrap()));
......@@ -1414,7 +1414,7 @@ pub fn admin_delete_participation<T: MedalConnection>(conn: &T, user_id: i32, co
}
let user = conn.get_user_by_id(user_id).ok_or(MedalError::AccessDenied)?;
let _part = conn.get_participation(&user.session_token.unwrap(), contest_id).ok_or(MedalError::AccessDenied)?;
let _part = conn.get_participation(user.id, contest_id).ok_or(MedalError::AccessDenied)?;
let data = json_val::Map::new();
conn.delete_participation(user_id, contest_id);
......
......@@ -1105,7 +1105,18 @@ impl MedalConnection for Connection {
contest
}
fn get_participation(&self, session: &str, contest_id: i32) -> Option<Participation> {
fn get_participation(&self, session_id: i32, contest_id: i32) -> Option<Participation> {
let query = "SELECT start_date
FROM participation
WHERE session = $1
AND contest = $2";
self.query_map_one(query, &[&session_id, &contest_id], |row| Participation { contest: contest_id,
user: session_id,
start: row.get(0) })
.ok()?
}
fn get_own_participation(&self, session: &str, contest_id: i32) -> Option<Participation> {
let query = "SELECT session, start_date
FROM participation
JOIN session ON session.id = session
......@@ -1161,7 +1172,7 @@ impl MedalConnection for Connection {
)
.unwrap();
Ok(self.get_participation(session, contest_id).unwrap()) // TODO: This errors if not logged in …
Ok(self.get_own_participation(session, contest_id).unwrap()) // TODO: This errors if not logged in …
}
}
}
......
......@@ -101,10 +101,15 @@ pub trait MedalConnection {
/// taskgroups. Panics if the contest does not exist.
fn get_contest_by_id_complete(&self, contest_id: i32) -> Contest;
/// Try to get the participation associated to the session id `session_id` and the contest id `contest_id`.
///
/// Returns an `Option` that can contain the `Participation` if it exists or `None` otherwise.
fn get_participation(&self, session_id: i32, contest_id: i32) -> Option<Participation>;
/// Try to get the participation associated to the session token `session` and the contest id `contest_id`.
///
/// Returns an `Option` that can contain the `Participation` if it exists or `None` otherwise.
fn get_participation(&self, session: &str, contest_id: i32) -> Option<Participation>;
fn get_own_participation(&self, session: &str, contest_id: i32) -> Option<Participation>;
/// Collect all the participation associated to the session token `session`.
///
......
......@@ -1217,7 +1217,18 @@ impl MedalConnection for Connection {
contest
}
fn get_participation(&self, session: &str, contest_id: i32) -> Option<Participation> {
fn get_participation(&self, session_id: i32, contest_id: i32) -> Option<Participation> {
let query = "SELECT start_date
FROM participation
WHERE session = $1
AND contest = $2";
self.query_map_one(query, &[&session_id, &contest_id], |row| Participation { contest: contest_id,
user: session_id,
start: row.get(0) })
.ok()?
}
fn get_own_participation(&self, session: &str, contest_id: i32) -> Option<Participation> {
let query = "SELECT session, start_date
FROM participation
JOIN session ON session.id = session
......@@ -1273,7 +1284,7 @@ impl MedalConnection for Connection {
)
.unwrap();
Ok(self.get_participation(session, contest_id).unwrap()) // TODO: This errors if not logged in …
Ok(self.get_own_participation(session, contest_id).unwrap()) // TODO: This errors if not logged in …
}
}
}
......
......@@ -1217,7 +1217,18 @@ impl MedalConnection for Connection {
contest
}
fn get_participation(&self, session: &str, contest_id: i32) -> Option<Participation> {
fn get_participation(&self, session_id: i32, contest_id: i32) -> Option<Participation> {
let query = "SELECT start_date
FROM participation
WHERE session = ?1
AND contest = ?2";
self.query_map_one(query, &[&session_id, &contest_id], |row| Participation { contest: contest_id,
user: session_id,
start: row.get(0) })
.ok()?
}
fn get_own_participation(&self, session: &str, contest_id: i32) -> Option<Participation> {
let query = "SELECT session, start_date
FROM participation
JOIN session ON session.id = session
......@@ -1273,7 +1284,7 @@ impl MedalConnection for Connection {
)
.unwrap();
Ok(self.get_participation(session, contest_id).unwrap()) // TODO: This errors if not logged in …
Ok(self.get_own_participation(session, contest_id).unwrap()) // TODO: This errors if not logged in …
}
}
}
......
......@@ -2,6 +2,7 @@
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=600">
<style>
body{
margin: 0px;
......@@ -56,7 +57,7 @@ padding-right: 20px;
}
#bar>div.highlight {
background: #e7f1ae;
background: #f5fbe8;
color:#334900;
}
......
......@@ -2,7 +2,7 @@
<html lang="en" style="background-color: #fafafa;">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=450">
<meta name="viewport" content="width=300">
<title>Jugendwettbewerb Informatik: Programmieren – leichter, als du denkst!</title>
<link rel="stylesheet" href="/static/lib/bulma/medal-bulma-0.7.5.css">
<link rel="icon" href="/static/images/favicon.png" type="image/png">
......
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