Commit 26effac5 authored by Robert Czechowski's avatar Robert Czechowski
Browse files

Rustfmt ALL the code!

parent 598119ab
Pipeline #70 failed with stage
in 1 minute and 29 seconds
use db_objects::{Contest, Taskgroup, Task};
use db_objects::{Contest, Task, Taskgroup};
use serde_yaml;
......@@ -9,19 +9,22 @@ struct ContestYaml {
participation_end: Option<String>,
duration_minutes: Option<u32>,
public_listing: Option<bool>,
tasks: Option<serde_yaml::Mapping>,
}
// The task path is stored relatively to the contest.yaml for easier identificationy
// Concatenation happens in functions::show_task
pub fn parse_yaml(content: &str, filename: &str, directory: &str) -> Option<Contest> {
let config: ContestYaml = serde_yaml::from_str(&content).unwrap();
let mut contest = Contest::new(directory.to_string(), filename.to_string(), config.name?, config.duration_minutes?, config.public_listing.unwrap_or(false), None, None);
let mut contest = Contest::new(directory.to_string(),
filename.to_string(),
config.name?,
config.duration_minutes?,
config.public_listing.unwrap_or(false),
None,
None);
for (name, info) in config.tasks? {
if let serde_yaml::Value::String(name) = name {
......@@ -30,46 +33,46 @@ pub fn parse_yaml(content: &str, filename: &str, directory: &str) -> Option<Cont
serde_yaml::Value::String(taskdir) => {
let mut task = Task::new(taskdir, 3);
taskgroup.tasks.push(task);
},
}
serde_yaml::Value::Sequence(taskdirs) => {
let mut stars = 2;
for taskdir in taskdirs {
if let serde_yaml::Value::String(taskdir) = taskdir {
let mut task = Task::new(taskdir, stars);
taskgroup.tasks.push(task);
}
else {
} else {
panic!("Invalid contest YAML: {}{} (a)", directory, filename)
}
stars += 1;
}
}
serde_yaml::Value::Mapping(taskdirs) => {
let mut stars = 2;
for (taskdir, taskinfo) in taskdirs {
if let (serde_yaml::Value::String(taskdir), serde_yaml::Value::Mapping(taskinfo)) = (taskdir, taskinfo) {
if let Some(serde_yaml::Value::Number(cstars)) = taskinfo.get(&serde_yaml::Value::String("stars".to_string())) {
if let (serde_yaml::Value::String(taskdir), serde_yaml::Value::Mapping(taskinfo)) =
(taskdir, taskinfo)
{
if let Some(serde_yaml::Value::Number(cstars)) =
taskinfo.get(&serde_yaml::Value::String("stars".to_string()))
{
stars = cstars.as_u64().unwrap() as u8;
}
let mut task = Task::new(taskdir, stars);
taskgroup.tasks.push(task);
stars += 1;
}
else {
} else {
panic!("Invalid contest YAML: {}{} (b)", directory, filename)
}
}
}
_ => panic!("Invalid contest YAML: {}{} (c)", directory, filename)
_ => panic!("Invalid contest YAML: {}{} (c)", directory, filename),
}
contest.taskgroups.push(taskgroup);
}
else {
} else {
panic!("Invalid contest YAML: {}{} (d)", directory, filename)
}
}
Some(contest)
}
......@@ -3,22 +3,19 @@ use std::io::Read;
use db_conn::MedalConnection;
pub fn test<C: MedalConnection>(conn: &mut C) {
let mut paths: Vec<_> =
fs::read_dir(format!("migrations/{}", conn.dbtype()))
.unwrap()
.map(|r| r.unwrap())
.filter(|r| r.path()
.display()
.to_string()
.ends_with(".sql"))
.collect();
fs::read_dir(format!("migrations/{}", conn.dbtype())).unwrap()
.map(|r| r.unwrap())
.filter(|r| {
r.path().display().to_string().ends_with(".sql")
})
.collect();
paths.sort_by_key(|dir| dir.path());
for path in paths {
for path in paths {
let filename = path.file_name().into_string().unwrap();
if ! conn.migration_already_applied(&filename) {
if !conn.migration_already_applied(&filename) {
let mut file = fs::File::open(path.path()).unwrap();
let mut contents = String::new();
file.read_to_string(&mut contents).unwrap();
......@@ -28,8 +25,5 @@ pub fn test<C: MedalConnection>(conn: &mut C) {
/*else { // TODO: Show in high debug level only
println!("Found: {}. Already applied", path.path().display());
}*/
}
}
use db_objects::*;
use ::functions;
use std::path::{Path};
use functions;
use std::path::Path;
pub trait MedalConnection {
fn create(file: &Path) -> Self;
......@@ -19,21 +19,24 @@ pub trait MedalConnection {
//fn login(&self, session: &SessionUser, username: String, password: String) -> Result<String,()>;
fn login(&self, session: Option<&str>, username: &str, password: &str) -> Result<String,()>;
fn login_with_code(&self, session: Option<&str>, logincode: &str) -> Result<String,()>;
fn login_foreign(&self, session: Option<&str>, foreign_id: u32, foreign_type: functions::UserType, firstname: &str, lastname:&str) -> Result<String,()>;
fn create_user_with_groupcode(&self, session: Option<&str>, groupcode: &str) -> Result<String,()>;
fn login(&self, session: Option<&str>, username: &str, password: &str) -> Result<String, ()>;
fn login_with_code(&self, session: Option<&str>, logincode: &str) -> Result<String, ()>;
fn login_foreign(&self, session: Option<&str>, foreign_id: u32, foreign_type: functions::UserType,
firstname: &str, lastname: &str)
-> Result<String, ()>;
fn create_user_with_groupcode(&self, session: Option<&str>, groupcode: &str) -> Result<String, ()>;
fn logout(&self, session: &str);
fn load_submission(&self, session: &SessionUser, task: u32, subtask: Option<&str>) -> Option<Submission>;
fn submit_submission(&self, submission: Submission);
fn get_grade_by_submission(&self, submission_id: u32) -> Grade;
fn get_contest_groups_grades(&self, session_id: u32, contest_id: u32) -> (Vec<String>, Vec<(Group, Vec<(UserInfo, Vec<Grade>)>)>);
fn get_contest_groups_grades(&self, session_id: u32, contest_id: u32)
-> (Vec<String>, Vec<(Group, Vec<(UserInfo, Vec<Grade>)>)>);
fn get_contest_user_grades(&self, session: String, contest_id: u32) -> Vec<Grade>;
fn get_contest_list(&self) -> Vec<Contest>;
fn get_contest_by_id(&self, contest_id: u32) -> Contest;
fn get_contest_by_id_complete(&self, contest_id :u32) -> Contest;
fn get_contest_by_id_complete(&self, contest_id: u32) -> Contest;
fn get_participation(&self, session: &str, contest_id: u32) -> Option<Participation>;
fn new_participation(&self, session: &str, contest_id: u32) -> Result<Participation, ()>;
fn get_task_by_id(&self, task_id: u32) -> Task;
......@@ -48,7 +51,6 @@ pub trait MedalConnection {
fn get_group_complete(&self, group_id: u32) -> Option<Group>;
}
pub trait MedalObject<T: MedalConnection> {
fn save(&mut self, conn: &T);
}
extern crate rusqlite;
extern crate bcrypt;
extern crate rusqlite;
use self::rusqlite::Connection;
use db_conn::{MedalConnection, MedalObject};
use db_objects::*;
use rand::{thread_rng, Rng, distributions::Alphanumeric};
use rand::{distributions::Alphanumeric, thread_rng, Rng};
use time;
use self::time::Duration;
use time;
use std::path::{Path};
use std::path::Path;
use self::bcrypt::{verify};
use self::bcrypt::verify;
use ::functions; // todo: remove (usertype in db)
use functions; // todo: remove (usertype in db)
fn verify_password(password: &str, salt: &str, password_hash: &str) -> bool {
let password_and_salt = [password, salt].concat().to_string();
match verify(password_and_salt, password_hash) {
Ok(result) => result,
_ => false
}
let password_and_salt = [password, salt].concat().to_string();
match verify(password_and_salt, password_hash) {
Ok(result) => result,
_ => false,
}
}
impl MedalConnection for Connection {
fn create(file: &Path) -> Connection {
Connection::open(file).unwrap()
}
fn create(file: &Path) -> Connection { Connection::open(file).unwrap() }
fn dbtype(&self) -> &'static str {
"sqlite"
}
fn dbtype(&self) -> &'static str { "sqlite" }
fn migration_already_applied(&self, name: &str) -> bool {
let create_string = "CREATE TABLE IF NOT EXISTS migrations (name TEXT PRIMARY KEY);";
......@@ -94,16 +89,16 @@ impl MedalConnection for Connection {
let duration = if session.permanent_login { Duration::days(90) } else { Duration::minutes(90) };
let now = time::get_time();
if now - session.last_activity? < duration {
self.execute("UPDATE session_user SET last_activity = ?1 WHERE id = ?2", &[&now, &session.id]).unwrap();
self.execute("UPDATE session_user SET last_activity = ?1 WHERE id = ?2", &[&now, &session.id])
.unwrap();
Some(session)
}
else {
} else {
// Session timed out
// Should remove session token from session_user
None
}
},
_ => None // no session found, should create new session in get_session_or_new()
}
_ => None, // no session found, should create new session in get_session_or_new()
}
}
fn save_session(&self, session: SessionUser) {
......@@ -114,7 +109,16 @@ impl MedalConnection for Connection {
logincode = ?4,
firstname = ?5,
lastname = ?6,
grade = ?7 WHERE id = ?", &[&session.username, &session.password, &session.salt, &session.logincode, &session.firstname, &session.lastname, &session.grade, &session.id]).unwrap();
grade = ?7 WHERE id = ?",
&[&session.username,
&session.password,
&session.salt,
&session.logincode,
&session.firstname,
&session.lastname,
&session.grade,
&session.id])
.unwrap();
}
fn new_session(&self) -> SessionUser {
let session_token = "123".to_string();
......@@ -122,8 +126,9 @@ impl MedalConnection for Connection {
self.execute("INSERT INTO session_user (session_token, csrf_token, permanent_login, is_teacher)
VALUES (?1, ?2, 0, 0)",
&[&session_token, &csrf_token]).unwrap();
let id = self.query_row("SELECT last_insert_rowid()", &[], |row| {row.get(0)}).unwrap();
&[&session_token, &csrf_token])
.unwrap();
let id = self.query_row("SELECT last_insert_rowid()", &[], |row| row.get(0)).unwrap();
SessionUser::minimal(id, session_token, csrf_token)
}
......@@ -171,35 +176,36 @@ impl MedalConnection for Connection {
let group_id = match session.managed_by {
Some(id) => id,
None => return Some((session, None))
None => return Some((session, None)),
};
let res = self.query_row("SELECT name, groupcode, tag, admin FROM usergroup WHERE id = ?1", &[&group_id], |row| {
Group {
id: Some(group_id),
name: row.get(0),
groupcode: row.get(1),
tag: row.get(2),
admin: row.get(3),
members: Vec::new(),
}
});
let res = self.query_row("SELECT name, groupcode, tag, admin FROM usergroup WHERE id = ?1",
&[&group_id],
|row| Group { id: Some(group_id),
name: row.get(0),
groupcode: row.get(1),
tag: row.get(2),
admin: row.get(3),
members: Vec::new() });
match res {
Ok(group) => Some((session, Some(group))),
_ => Some((session, None))
_ => Some((session, None)),
}
}
//TODO: use session
fn login(&self, _session: Option<&str>, username: &str, password: &str) -> Result<String,()> {
match self.query_row(
"SELECT id, password, salt FROM session_user WHERE username = ?1",
&[&username],
|row| -> (u32, Option<String>, Option<String>) {
(row.get(0), row.get(1), row.get(2))
}) {
Ok((id, password_hash, salt)) => { //password_hash ist das, was in der Datenbank steht
if verify_password(&password, &salt.expect("salt from database empty"), &password_hash.expect("password from database empty")) { // TODO: fail more pleasantly
fn login(&self, _session: Option<&str>, username: &str, password: &str) -> Result<String, ()> {
match self.query_row("SELECT id, password, salt FROM session_user WHERE username = ?1",
&[&username],
|row| -> (u32, Option<String>, Option<String>) { (row.get(0), row.get(1), row.get(2)) })
{
Ok((id, password_hash, salt)) => {
//password_hash ist das, was in der Datenbank steht
if verify_password(&password,
&salt.expect("salt from database empty"),
&password_hash.expect("password from database empty"))
{
// TODO: fail more pleasantly
// Login okay, update session now!
let session_token: String = thread_rng().sample_iter(&Alphanumeric).take(10).collect();
......@@ -209,22 +215,19 @@ impl MedalConnection for Connection {
self.execute("UPDATE session_user SET session_token = ?1, csrf_token = ?2, last_login = ?3, last_activity = ?3 WHERE id = ?4", &[&session_token, &csrf_token, &now, &id]).unwrap();
Ok(session_token)
} else {
Err(())
}
else {Err(()) }
},
_ => {Err(()) }
}
_ => Err(()),
}
}
//TODO: use session
fn login_with_code(&self, _session: Option<&str>, logincode: &str) -> Result<String,()> {
match self.query_row(
"SELECT id FROM session_user WHERE logincode = ?1",
&[&logincode],
|row| -> u32 {
row.get(0)
}) {
fn login_with_code(&self, _session: Option<&str>, logincode: &str) -> Result<String, ()> {
match self.query_row("SELECT id FROM session_user WHERE logincode = ?1", &[&logincode], |row| -> u32 {
row.get(0)
}) {
Ok(id) => {
// Login okay, update session now!
......@@ -235,26 +238,28 @@ impl MedalConnection for Connection {
self.execute("UPDATE session_user SET session_token = ?1, csrf_token = ?2, last_login = ?3, last_activity = ?3 WHERE id = ?4", &[&session_token, &csrf_token, &now, &id]).unwrap();
Ok(session_token)
},
_ => {Err(()) }
}
_ => Err(()),
}
}
//TODO: use session
fn login_foreign(&self, _session: Option<&str>, foreign_id: u32, foreign_type: functions::UserType, firstname: &str, lastname: &str) -> Result<String,()> {
fn login_foreign(&self, _session: Option<&str>, foreign_id: u32, foreign_type: functions::UserType,
firstname: &str, lastname: &str)
-> Result<String, ()>
{
let session_token: String = thread_rng().sample_iter(&Alphanumeric).take(10).collect();
let csrf_token: String = thread_rng().sample_iter(&Alphanumeric).take(10).collect();
let now = time::get_time();
match self.query_row(
"SELECT id FROM session_user WHERE pms_id = ?1",
&[&foreign_id],
|row| -> u32 {row.get(0)}) {
match self.query_row("SELECT id FROM session_user WHERE pms_id = ?1", &[&foreign_id], |row| -> u32 {
row.get(0)
}) {
Ok(id) => {
self.execute("UPDATE session_user SET session_token = ?1, csrf_token = ?2, last_login = ?3, last_activity = ?3 WHERE id = ?4", &[&session_token, &csrf_token, &now, &id]).unwrap();
Ok(session_token)
},
}
// Add!
_ => {
self.execute("INSERT INTO session_user (session_token, csrf_token, last_login, last_activity, permanent_login, grade, is_teacher, pms_id, firstname, lastname) VALUES (?1, ?2, ?3, ?3, ?4, ?5, ?6, ?7, ?8, ?9)", &[&session_token, &csrf_token, &now, &false, &0, &(foreign_type != functions::UserType::User), &foreign_id, &firstname, &lastname]).unwrap();
......@@ -265,29 +270,32 @@ impl MedalConnection for Connection {
}
//TODO: use session
fn create_user_with_groupcode(&self, _session: Option<&str>, groupcode: &str) -> Result<String,()> {
match self.query_row(
"SELECT id FROM usergroup WHERE groupcode = ?1",
&[&groupcode],
|row| -> u32 {
row.get(0)
}) {
fn create_user_with_groupcode(&self, _session: Option<&str>, groupcode: &str) -> Result<String, ()> {
match self.query_row("SELECT id FROM usergroup WHERE groupcode = ?1", &[&groupcode], |row| -> u32 {
row.get(0)
}) {
Ok(group_id) => {
// Login okay, create session_user!
let session_token: String = thread_rng().sample_iter(&Alphanumeric).take(10).collect();
let csrf_token: String = thread_rng().sample_iter(&Alphanumeric).take(10).collect();
let login_code: String = Some('u').into_iter().chain(thread_rng().sample_iter(&Alphanumeric))
.filter(|x| {let x = *x; !(x == 'l' || x == 'I' || x == '1' || x == 'O' || x == 'o' || x == '0')})
.take(9).collect();
let login_code: String =
Some('u').into_iter()
.chain(thread_rng().sample_iter(&Alphanumeric))
.filter(|x| {
let x = *x;
!(x == 'l' || x == 'I' || x == '1' || x == 'O' || x == 'o' || x == '0')
})
.take(9)
.collect();
// todo: check for collisions
let now = time::get_time();
self.execute("INSERT INTO session_user (session_token, csrf_token, last_login, last_activity, permanent_login, logincode, grade, is_teacher, managed_by) VALUES (?1, ?2, ?3, ?3, ?4, ?5, ?6, ?7, ?8)", &[&session_token, &csrf_token, &now, &false, &login_code, &0, &false, &group_id]).unwrap();
Ok(session_token)
},
_ => {Err(()) }
}
_ => Err(()),
}
}
......@@ -295,7 +303,6 @@ impl MedalConnection for Connection {
self.execute("UPDATE session_user SET session_token = NULL WHERE session_token = ?1", &[&session]).unwrap();
}
fn load_submission(&self, session: &SessionUser, task: u32, subtask: Option<&str>) -> Option<Submission> {
match subtask {
None => self.query_row("SELECT id, grade, validated, nonvalidated_grade, value, date, needs_validation FROM submission WHERE task = ?1 AND session_user = ?2 ORDER BY id DESC LIMIT 1", &[&task, &session.id], |row| {
......@@ -337,7 +344,6 @@ impl MedalConnection for Connection {
grade.validated = false;
grade.save(self);
}
}
fn get_grade_by_submission(&self, submission_id: u32) -> Grade {
self.query_row("SELECT grade.taskgroup, grade.user, grade.grade, grade.validated FROM grade JOIN task ON grade.taskgroup = task.taskgroup JOIN submission ON task.id = submission.task AND grade.user = submission.session_user WHERE submission.id = ?1", &[&submission_id], |row| {
......@@ -359,14 +365,16 @@ impl MedalConnection for Connection {
})
}
fn get_contest_groups_grades(&self, session_id: u32, contest_id: u32) -> (Vec<String>, Vec<(Group, Vec<(UserInfo, Vec<Grade>)>)>) {
fn get_contest_groups_grades(&self, session_id: u32, contest_id: u32)
-> (Vec<String>, Vec<(Group, Vec<(UserInfo, Vec<Grade>)>)>) {
let mut stmt = self.prepare("SELECT id, name FROM taskgroup WHERE contest = ?1 ORDER BY id ASC").unwrap();
let tasknames_iter = stmt.query_map(&[&contest_id], |row| {
let x : (u32, String) = (row.get(0), row.get(1));
x
}).unwrap();
let x: (u32, String) = (row.get(0), row.get(1));
x
})
.unwrap();
let tasknames : Vec<(u32, String)> = tasknames_iter.map(|x| x.unwrap()).collect();
let tasknames: Vec<(u32, String)> = tasknames_iter.map(|x| x.unwrap()).collect();
let mut taskindex: ::std::collections::BTreeMap<u32, usize> = ::std::collections::BTreeMap::new();
let n_tasks = tasknames.len();
......@@ -381,29 +389,24 @@ impl MedalConnection for Connection {
JOIN usergroup ON student.managed_by = usergroup.id
WHERE usergroup.admin = ?1 AND taskgroup.contest = ?2
ORDER BY usergroup.id, student.id, taskgroup.id ASC").unwrap();
let mut gradeinfo_iter = stmt.query_map(&[&session_id, &contest_id], |row| {
(Grade {
taskgroup: row.get(0),
user: row.get(1),
grade: row.get(2),
validated: row.get(3),
},Group {
id: Some(row.get(4)),
name: row.get(5),
groupcode: row.get(6),
tag: row.get(7),
admin: session_id,
members: Vec::new()
},UserInfo {
id: row.get(8),
username: row.get(9),
logincode: row.get(10),
firstname: row.get(11),
lastname: row.get(12),
})
}).unwrap();
let mut gradeinfo_iter =
stmt.query_map(&[&session_id, &contest_id], |row| {
(Grade { taskgroup: row.get(0), user: row.get(1), grade: row.get(2), validated: row.get(3) },
Group { id: Some(row.get(4)),
name: row.get(5),
groupcode: row.get(6),
tag: row.get(7),
admin: session_id,
members: Vec::new() },
UserInfo { id: row.get(8),
username: row.get(9),
logincode: row.get(10),
firstname: row.get(11),
lastname: row.get(12) })
})
.unwrap();
if let Some(t/*Ok((grade, mut group, mut userinfo))*/) = gradeinfo_iter.next() {
if let Some(t /*Ok((grade, mut group, mut userinfo))*/) = gradeinfo_iter.next() {
let (grade, mut group, mut userinfo) = t.unwrap();
let mut grades: Vec<Grade> = vec![Default::default(); n_tasks];
......@@ -425,8 +428,7 @@ impl MedalConnection for Connection {
groups.push((group.clone(), users));
users = Vec::new();
}
else if ui.id != userinfo.id {
} else if ui.id != userinfo.id {
users.push((userinfo.clone(), grades));
grades = vec![Default::default(); n_tasks];
}
......@@ -438,19 +440,19 @@ impl MedalConnection for Connection {
groups.push((group, users));
(tasknames.iter().map(|(_, name)| name.clone()).collect(), groups)
}
else {
} else {
(Vec::new(), Vec::new()) // should those be default filled?
}
}
fn get_contest_user_grades(&self, session_token: String, contest_id: u32) -> Vec<Grade> {
let mut stmt = self.prepare("SELECT id, name FROM taskgroup WHERE contest = ?1 ORDER BY id ASC").unwrap();
let tasknames_iter = stmt.query_map(&[&contest_id], |row| {
let x : (u32, String) = (row.get(0), row.get(1));
x
}).unwrap();
let x: (u32, String) = (row.get(0), row.get(1));
x
})
.unwrap();
let tasknames : Vec<(u32, String)> = tasknames_iter.map(|x| x.unwrap()).collect();
let tasknames: Vec<(u32, String)> = tasknames_iter.map(|x| x.unwrap()).collect();
let mut taskindex: ::std::collections::BTreeMap<u32, usize> = ::std::collections::BTreeMap::new();
let n_tasks = tasknames.len();
......@@ -463,15 +465,13 @@ impl MedalConnection for Connection {
JOIN taskgroup ON grade.taskgroup = taskgroup.id
JOIN session_user ON session_user.id = grade.user
WHERE session_user.session_token = ?1 AND taskgroup.contest = ?2
ORDER BY taskgroup.id ASC").unwrap();
let gradeinfo_iter = stmt.query_map(&[&session_token, &contest_id], |row| {
Grade {
taskgroup: row.get(0),
user: row.get(1),
grade: row.get(2),
validated: row.get(3),
}
}).unwrap();
ORDER BY taskgroup.id ASC")
.unwrap();
let gradeinfo_iter = stmt.query_map(&[&session_token, &contest_id], |row| Grade { taskgroup: row.get(0),
user: row.get(1),
grade: row.get(2),
validated: row.get(3) })
.unwrap();
let mut grades: Vec<Grade> = vec![Default::default(); n_tasks];
......@@ -485,24 +485,25 @@ impl MedalConnection for Connection {
}