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;
......@@ -13,15 +13,18 @@ struct ContestYaml {
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,15 +33,14 @@ 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)
}
......@@ -48,28 +50,29 @@ pub fn parse_yaml(content: &str, filename: &str, directory: &str) -> Option<Cont
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()
fs::read_dir(format!("migrations/{}", conn.dbtype())).unwrap()
.map(|r| r.unwrap())
.filter(|r| r.path()
.display()
.to_string()
.ends_with(".sql"))
.filter(|r| {
r.path().display().to_string().ends_with(".sql")
})
.collect();
paths.sort_by_key(|dir| dir.path());
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);
}
This diff is collapsed.
extern crate time;
use self::time::{Timespec, Duration};
use self::time::{Duration, Timespec};
#[derive(Clone)]
pub struct SessionUser {
......@@ -51,7 +50,7 @@ pub struct Group {
pub groupcode: String,
pub tag: String,
pub admin: u32,
pub members: Vec<SessionUser>
pub members: Vec<SessionUser>,
}
pub struct Contest {
......@@ -66,7 +65,6 @@ pub struct Contest {
pub taskgroups: Vec<Taskgroup>,
}
pub struct Taskgroup {
pub id: Option<u32>,
pub contest: u32,
......@@ -81,7 +79,6 @@ pub struct Task {
pub stars: u8,
}
pub struct Submission {
pub id: Option<u32>,
pub session_user: u32,
......@@ -109,18 +106,37 @@ pub struct Participation {
pub start: Timespec,
}
pub trait HasId { fn get_id(&self) -> Option<u32>; fn set_id(&mut self, id: u32); }
impl HasId for Submission { fn get_id(&self) -> Option<u32> { self.id } fn set_id(&mut self, id: u32) { self.id = Some(id);} }
impl HasId for Task { fn get_id(&self) -> Option<u32> { self.id } fn set_id(&mut self, id: u32) { self.id = Some(id);} }
impl HasId for Taskgroup { fn get_id(&self) -> Option<u32> { self.id } fn set_id(&mut self, id: u32) { self.id = Some(id);} }
impl HasId for Contest { fn get_id(&self) -> Option<u32> { self.id } fn set_id(&mut self, id: u32) { self.id = Some(id);} }
impl HasId for Group { fn get_id(&self) -> Option<u32> { self.id } fn set_id(&mut self, id: u32) { self.id = Some(id);} }
pub trait HasId {
fn get_id(&self) -> Option<u32>;
fn set_id(&mut self, id: u32);
}
impl HasId for Submission {
fn get_id(&self) -> Option<u32> { self.id }
fn set_id(&mut self, id: u32) { self.id = Some(id); }
}
impl HasId for Task {
fn get_id(&self) -> Option<u32> { self.id }
fn set_id(&mut self, id: u32) { self.id = Some(id); }
}
impl HasId for Taskgroup {
fn get_id(&self) -> Option<u32> { self.id }
fn set_id(&mut self, id: u32) { self.id = Some(id); }
}
impl HasId for Contest {
fn get_id(&self) -> Option<u32> { self.id }
fn set_id(&mut self, id: u32) { self.id = Some(id); }
}
impl HasId for Group {
fn get_id(&self) -> Option<u32> { self.id }
fn set_id(&mut self, id: u32) { self.id = Some(id); }
}
impl Contest {
pub fn new(location: String, filename: String, name: String, duration: u32, public: bool, start: Option<Timespec>, end: Option<Timespec>) -> Self {
Contest {
id: None,
pub fn new(location: String, filename: String, name: String, duration: u32, public: bool,
start: Option<Timespec>, end: Option<Timespec>)
-> Self
{
Contest { id: None,
location: location,
filename: filename,
name: name,
......@@ -128,16 +144,13 @@ impl Contest {
public: public,
start: start,
end: end,
taskgroups: Vec::new(),
}
taskgroups: Vec::new() }
}
}
impl SessionUser {
pub fn minimal(id: u32, session_token: String, csrf_token: String) -> Self {
SessionUser {
id: id,
SessionUser { id: id,
session_token: Some(session_token),
csrf_token: csrf_token,
last_login: None,
......@@ -164,8 +177,7 @@ impl SessionUser {
is_teacher: false,
managed_by: None,
pms_id: None,
pms_school_id: None,
}
pms_school_id: None }
}
pub fn ensure_alive(self) -> Option<Self> {
......@@ -173,8 +185,7 @@ impl SessionUser {
let now = time::get_time();
if now - self.last_activity? < duration {
Some(self)
}
else {
} else {
None
}
}
......@@ -182,32 +193,18 @@ impl SessionUser {
pub fn ensure_logged_in(self) -> Option<Self> {
if self.password.is_some() || self.logincode.is_some() || self.pms_id.is_some() {
self.ensure_alive()
}
else {
} else {
None
}
}
}
impl Taskgroup {
pub fn new(name: String) -> Self {
Taskgroup {
id: None,
contest: 0,
name: name,
tasks: Vec::new(),
}
}
pub fn new(name: String) -> Self { Taskgroup { id: None, contest: 0, name: name, tasks: Vec::new() } }
}
impl Task {
pub fn new(location: String, stars: u8) -> Self {
Task {
id: None,
taskgroup: 0,
location: location,
stars: stars,
}
Task { id: None, taskgroup: 0, location: location, stars: stars }
}
}
This diff is collapsed.
......@@ -7,44 +7,44 @@ extern crate router;
#[macro_use]
extern crate serde_derive;
extern crate structopt;
extern crate rusqlite;
extern crate handlebars_iron;
extern crate iron_sessionstorage;
extern crate urlencoded;
extern crate time;
extern crate persistent;
extern crate rand;
extern crate mount;
extern crate staticfile;
extern crate handlebars_iron;
extern crate serde_json;
extern crate params;
extern crate persistent;
extern crate rand;
extern crate reqwest;
extern crate rusqlite;
extern crate serde_json;
extern crate serde_yaml;
extern crate staticfile;
extern crate structopt;
extern crate time;
extern crate urlencoded;
use rusqlite::Connection;
mod db_apply_migrations;
mod db_conn_sqlite;
mod db_conn;
mod db_conn_sqlite;
mod db_objects;
use functions::SetPassword; // TODO: Refactor, so we don't need to take this from there!
use db_conn::{MedalConnection, MedalObject};
use functions::SetPassword; // TODO: Refactor, so we don't need to take this from there!
use db_objects::*;
mod webfw_iron;
mod configreader_yaml;
mod webfw_iron;
use webfw_iron::start_server;
mod functions;
use std::path;
use std::fs;
use std::path;
use std::path::{Path,PathBuf};
use std::path::{Path, PathBuf};
use structopt::StructOpt;
#[derive(Serialize, Deserialize, Clone, Default)]
......@@ -65,7 +65,7 @@ fn read_config_from_file(file: &Path) -> Config {
println!("Reading configuration file '{}'", file.to_str().unwrap_or("<Encoding error>"));
let mut config : Config = if let Ok(mut file) = fs::File::open(file) {
let mut config: 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()
......@@ -74,9 +74,15 @@ fn read_config_from_file(file: &Path) -> Config {
Default::default()
};
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("http://localhost:8080".to_string())}
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("http://localhost:8080".to_string())
}
println!("OAuth providers will be told to redirect to {}", config.self_url.as_ref().unwrap());
......@@ -103,8 +109,6 @@ struct Opt {
resetadminpw: bool,
}
fn read_contest(p: &path::PathBuf) -> Option<Contest> {
use std::fs::File;
use std::io::Read;
......@@ -113,7 +117,9 @@ fn read_contest(p: &path::PathBuf) -> Option<Contest> {
let mut contents = String::new();
file.read_to_string(&mut contents).unwrap();
configreader_yaml::parse_yaml(&contents, p.file_name().to_owned()?.to_str()?, &format!("{}/", p.parent().unwrap().to_str()?))
configreader_yaml::parse_yaml(&contents,
p.file_name().to_owned()?.to_str()?,
&format!("{}/", p.parent().unwrap().to_str()?))
}
fn get_all_contest_info(task_dir: &str) -> Vec<Contest> {
......@@ -130,19 +136,20 @@ fn get_all_contest_info(task_dir: &str) -> Vec<Contest> {
};
};
let mut contests = Vec::new();
match fs::read_dir(task_dir) {
Err(why) => println!("Error opening tasks directory! {:?}", why.kind()),
Ok(paths) => for path in paths {
Ok(paths) => {
for path in paths {
walk_me_recursively(&path.unwrap().path(), &mut contests);
},
}
}
};
contests
}
fn refresh_all_contests(conn : &mut Connection) {
fn refresh_all_contests(conn: &mut Connection) {
let v = get_all_contest_info("tasks/");
for mut contest_info in v {
......@@ -155,22 +162,25 @@ fn add_admin_user(conn: &mut Connection, resetpw: bool) {
None => {
print!("New Database. Creating new admin user with credentials 'admin':");
conn.new_session()
},
}
Some(user) => {
if !resetpw {
return
return;
}
print!("Request to reset admin password. Set credentials 'admin':");
user
}
};
use rand::{thread_rng, Rng, distributions::Alphanumeric};
use rand::{distributions::Alphanumeric, thread_rng, Rng};
let password: String = thread_rng().sample_iter(&Alphanumeric)
.filter(|x| {let x = *x; !(x == 'l' || x == 'I' || x == '1' || x == 'O' || x == 'o' || x == '0')})
.take(8).collect();
.filter(|x| {
let x = *x;
!(x == 'l' || x == 'I' || x == '1' || x == 'O' || x == 'o' || x == '0')
})
.take(8)
.collect();
print!("'{}' …", &password);
admin.username = Some("admin".into());
......@@ -189,12 +199,22 @@ fn main() {
let mut config = read_config_from_file(&opt.configfile);
if opt.databasefile.is_some() { config.database_file = opt.databasefile; }
if opt.port.is_some() { config.port = opt.port; }
if opt.databasefile.is_some() {
config.database_file = opt.databasefile;
}
if opt.port.is_some() {
config.port = opt.port;
}
let mut conn = match config.database_file {
Some(ref path) => {println!("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"))},
Some(ref path) => {
println!("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);
......@@ -205,22 +225,21 @@ fn main() {
match start_server(conn, config) {
Ok(_) => println!("Server started"),
Err(_) => println!("Error on server start …")
Err(_) => println!("Error on server start …"),
};
println!("Could not run server. Is the port already in use?");
}
#[cfg(test)]
mod tests {
use super::*;
use std::io::Read;
fn start_server_and_fn<F>(port: u16, set_user: Option<(String, String)>, f: F) where F: FnOnce() {
use std::{thread, time};
fn start_server_and_fn<F>(port: u16, set_user: Option<(String, String)>, f: F)
where F: FnOnce() {
use std::sync::mpsc::channel;
use std::{thread, time};
let (start_tx, start_rx) = channel();
let (stop_tx, stop_rx) = channel();
......@@ -257,8 +276,7 @@ mod tests {
fn login_for_tests(port: u16, client: &reqwest::Client, username: &str, password: &str) -> reqwest::Response {
let params = [("username", username), ("password", password)];
let resp = client.post(&format!("http://localhost:{}/login", port))
.form(&params).send().unwrap();
let resp = client.post(&format!("http://localhost:{}/login", port)).form(&params).send().unwrap();
return resp;
}
......@@ -271,7 +289,7 @@ mod tests {
#[test]
fn start_server_and_check_request() {
start_server_and_fn(8080, None, ||{
start_server_and_fn(8080, None, || {
let mut resp = reqwest::get("http://localhost:8080").unwrap();
check_status(&resp, reqwest::StatusCode::Ok);
let mut content = String::new();
......@@ -279,7 +297,6 @@ mod tests {
assert!(content.contains("<h1>Jugendwettbewerb Informatik</h1>"));
assert!(!content.contains("Error"));
let mut resp = reqwest::get("http://localhost:8080/contest").unwrap();
check_status(&resp, reqwest::StatusCode::Ok);
let mut content = String::new();
......@@ -291,7 +308,7 @@ mod tests {
#[test]
fn check_login_wrong_credentials() {
start_server_and_fn(8081, None, ||{
start_server_and_fn(8081, None, || {
let client = reqwest::Client::new().unwrap();
let mut resp = login_for_tests(8081, &client, "nonexistingusername", "wrongpassword");
check_status(&resp, reqwest::StatusCode::Ok);
......@@ -305,9 +322,9 @@ mod tests {
#[test]
fn start_server_and_check_login() {
start_server_and_fn(8082, Some(("testusr".to_string(), "testpw".to_string())), ||{
start_server_and_fn(8082, Some(("testusr".to_string(), "testpw".to_string())), || {
let mut client = reqwest::Client::new().unwrap();
client.redirect(reqwest::RedirectPolicy::custom(|attempt| {attempt.stop()}));
client.redirect(reqwest::RedirectPolicy::custom(|attempt| attempt.stop()));
let mut resp = login_for_tests(8082, &client, "testusr", "testpw");
check_status(&resp, reqwest::StatusCode::Found);
......@@ -319,10 +336,10 @@ mod tests {
let set_cookie = header.get::<reqwest::header::SetCookie>();
match set_cookie {
None => panic!("No setCookie."),
Some(cookie) => if cookie.len() == 1 {
Some(cookie) => {
if cookie.len() == 1 {
let new_cookie = reqwest::header::Cookie(cookie.to_vec());
let mut new_resp = client.get("http://localhost:8082")
.header(new_cookie).send().unwrap();
let mut new_resp = client.get("http://localhost:8082").header(new_cookie).send().unwrap();
check_status(&new_resp, reqwest::StatusCode::Ok);
let mut new_content = String::new();
......@@ -332,16 +349,17 @@ mod tests {
assert!(new_content.contains("<h1>Jugendwettbewerb Informatik</h1>"));
} else {
panic!("More than one setCookie.");
},
}
}
};
})
}
#[test]
fn start_server_and_check_logout() {
start_server_and_fn(8083, Some(("testusr".to_string(), "testpw".to_string())), ||{