Commit e4391061 authored by Robert Czechowski's avatar Robert Czechowski
Browse files

Merge branch 'debug-display' into task-display

parents 1a91b49b 955d0a52
......@@ -2,7 +2,6 @@ image: 'rust:latest'
stages:
- test
- doc
- build
- deploy
......@@ -10,16 +9,7 @@ variables:
CARGO_HOME: $CI_PROJECT_DIR/cargo
APT_CACHE_DIR: $CI_PROJECT_DIR/apt
before_script:
- apt-get update -yq
- rustup component add clippy
- rustup component add rustfmt
# Setup SSH deploy keys
- 'which ssh-agent || ( apt-get install -qq openssh-client )'
- eval $(ssh-agent -s)
- ssh-add <(echo "$SSH_PRIVATE_KEY" | base64 -d)
- mkdir -p ~/.ssh
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
test:
stage: test
......@@ -27,10 +17,17 @@ test:
- rustc --version
- cargo --version
- cargo test --features "strict" --verbose
- cargo clippy --all-targets --all-features -- -D warnings -A clippy::redundant_field_names -A clippy::useless_format -A clippy::let_and_return -A clippy::type_complexity -A clippy::option_map_unit_fn -A clippy::too_many_arguments
pages:
stage: doc
clippy:
stage: test
script:
- rustup component add clippy
- make clippy
documentation:
stage: build
script:
- cargo doc --no-deps
- echo '<meta http-equiv="refresh" content="0; url=medal">' > target/doc/index.html
......@@ -43,10 +40,19 @@ build:
- cargo build --release
only:
- master
deploy:
stage: deploy
script:
script:
# Setup SSH deploy keys
- 'which ssh-agent || ( apt-get install -qq openssh-client )'
- eval $(ssh-agent -s)
- ssh-add <(echo "$SSH_PRIVATE_KEY" | base64 -d)
- mkdir -p ~/.ssh
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
# Stop server and upload
- ssh medald@jim.test.bwinf.de "sudo /bin/systemctl stop medal && exit"
- "scp target/release/medal medald@jim.test.bwinf.de:medal/"
- "scp -r migrations static templates medald@jim.test.bwinf.de:medal/"
......@@ -55,6 +61,8 @@ deploy:
only:
- master
cache:
paths:
- apt/
......
......@@ -11,6 +11,6 @@ format:
cargo +nightly fmt
clippy:
cargo clippy --all-targets --all-features -- -D warnings -A clippy::redundant_field_names -A clippy::useless_format -A clippy::let_and_return -A clippy::type_complexity -A clippy::option_map_unit_fn -A clippy::too_many_arguments
cargo clippy --all-targets --all-features -- -D warnings -A clippy::redundant_field_names -A clippy::useless_format -A clippy::let_and_return -A clippy::type_complexity -A clippy::option_map_unit_fn -A clippy::too_many_arguments -A clippy::redundant_closure -A clippy::identity_conversion
......@@ -10,7 +10,7 @@ pub trait MedalConnection {
fn apply_migration(&mut self, name: &str, contents: &str);
fn get_session(&self, key: &str) -> Option<SessionUser>;
fn new_session(&self) -> SessionUser;
fn new_session(&self, key: &str) -> SessionUser;
fn save_session(&self, session: SessionUser);
fn get_session_or_new(&self, key: &str) -> SessionUser;
......
......@@ -53,7 +53,9 @@ impl MedalConnection for Connection {
// fn get_session<T: ToSql>(&self, key: T, keyname: &str) -> Option<SessionUser> {
fn get_session(&self, key: &str) -> Option<SessionUser> {
println!("looking for session!");
let res = self.query_row("SELECT id, csrf_token, last_login, last_activity, permanent_login, username, password, logincode, email, email_unconfirmed, email_confirmationcode, firstname, lastname, street, zip, city, nation, grade, is_teacher, managed_by, pms_id, pms_school_id, salt FROM session_user WHERE session_token = ?1", &[&key], |row| {
println!("found some!");
SessionUser {
id: row.get(0),
session_token: Some(key.to_string()),
......@@ -86,15 +88,23 @@ impl MedalConnection for Connection {
});
match res {
Ok(session) => {
println!("is session");
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();
Some(session)
if let Some(last_activity) = session.last_activity {
if now - last_activity < duration {
self.execute("UPDATE session_user SET last_activity = ?1 WHERE id = ?2", &[&now, &session.id])
.unwrap();
println!("session is online!");
Some(session)
} else {
// Session timed out
// Should remove session token from session_user
None
}
} else {
// Session timed out
// Should remove session token from session_user
// last_activity undefined
// TODO: What should happen here?
None
}
}
......@@ -120,20 +130,22 @@ impl MedalConnection for Connection {
&session.id])
.unwrap();
}
fn new_session(&self) -> SessionUser {
let session_token = "123".to_string();
let csrf_token = "123".to_string();
fn new_session(&self, session_token: &str) -> SessionUser {
let csrf_token: String = thread_rng().sample_iter(&Alphanumeric).take(10).collect();
self.execute("INSERT INTO session_user (session_token, csrf_token, permanent_login, is_teacher)
VALUES (?1, ?2, 0, 0)",
&[&session_token, &csrf_token])
let now = time::get_time();
self.execute("INSERT INTO session_user (session_token, csrf_token, last_activity, permanent_login, grade, is_teacher)
VALUES (?1, ?2, ?3, 0, 0, 0)",
&[&session_token, &csrf_token, &now])
.unwrap();
let id = self.query_row("SELECT last_insert_rowid()", &[], |row| row.get(0)).unwrap();
SessionUser::minimal(id, session_token, csrf_token)
println!("Neue Session!");
SessionUser::minimal(id, session_token.to_owned(), csrf_token)
}
fn get_session_or_new(&self, key: &str) -> SessionUser {
self.get_session(&key).unwrap_or_else(|| self.new_session())
self.get_session(&key).unwrap_or_else(|| self.new_session(&key))
}
fn get_user_by_id(&self, user_id: u32) -> Option<SessionUser> {
......
......@@ -180,10 +180,22 @@ impl SessionUser {
pms_school_id: None }
}
pub fn ensure_alive(self) -> Option<Self> {
pub fn is_alive(&self) -> bool {
let duration = if self.permanent_login { Duration::days(90) } else { Duration::minutes(90) };
let now = time::get_time();
if now - self.last_activity? < duration {
if let Some(last_activity) = self.last_activity {
now - last_activity < duration
} else {
false
}
}
pub fn is_logged_in(&self) -> bool {
(self.password.is_some() || self.logincode.is_some() || self.pms_id.is_some()) && self.is_alive()
}
pub fn ensure_alive(self) -> Option<Self> {
if self.is_alive() {
Some(self)
} else {
None
......@@ -191,8 +203,8 @@ 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()
if self.is_logged_in() {
Some(self)
} else {
None
}
......
......@@ -61,11 +61,13 @@ pub fn index<T: MedalConnection>(conn: &T, session_token: Option<String>,
if let Some(token) = session_token {
if let Some(session) = conn.get_session(&token) {
data.insert("logged_in".to_string(), to_json(&true));
data.insert("username".to_string(), to_json(&session.username));
data.insert("firstname".to_string(), to_json(&session.firstname));
data.insert("lastname".to_string(), to_json(&session.lastname));
data.insert("teacher".to_string(), to_json(&session.is_teacher));
if session.is_logged_in() {
data.insert("logged_in".to_string(), to_json(&true));
data.insert("username".to_string(), to_json(&session.username));
data.insert("firstname".to_string(), to_json(&session.firstname));
data.insert("lastname".to_string(), to_json(&session.lastname));
data.insert("teacher".to_string(), to_json(&session.is_teacher));
}
}
}
......@@ -77,6 +79,45 @@ pub fn index<T: MedalConnection>(conn: &T, session_token: Option<String>,
("index".to_owned(), data)
}
pub fn debug<T: MedalConnection>(conn: &T, session_token: Option<String>)
-> (String, json_val::Map<String, json_val::Value>) {
let mut data = json_val::Map::new();
if let Some(token) = session_token {
if let Some(session) = conn.get_session(&token) {
data.insert("known_session".to_string(), to_json(&true));
data.insert("now_timestamp".to_string(), to_json(&time::get_time().sec));
if let Some(last_activity) = session.last_activity {
data.insert("session_timestamp".to_string(), to_json(&last_activity.sec));
data.insert("timediff".to_string(), to_json(&(time::get_time() - last_activity).num_seconds()));
}
if session.is_alive() {
data.insert("alive_session".to_string(), to_json(&true));
if session.is_logged_in() {
data.insert("logged_in".to_string(), to_json(&true));
data.insert("username".to_string(), to_json(&session.username));
data.insert("firstname".to_string(), to_json(&session.firstname));
data.insert("lastname".to_string(), to_json(&session.lastname));
data.insert("teacher".to_string(), to_json(&session.is_teacher));
}
}
}
data.insert("session".to_string(), to_json(&token));
println!("etwas session?!");
} else {
data.insert("session".to_string(), to_json(&"No session token given"));
println!("warum nix session?!");
}
("debug".to_owned(), data)
}
pub fn debug_create_session<T: MedalConnection>(conn: &T, session_token: Option<String>) {
if let Some(token) = session_token {
conn.get_session_or_new(&token);
}
}
pub fn show_contests<T: MedalConnection>(conn: &T) -> MedalValue {
let mut data = json_val::Map::new();
......
......@@ -161,7 +161,7 @@ fn add_admin_user(conn: &mut Connection, resetpw: bool) {
let mut admin = match conn.get_user_by_id(1) {
None => {
print!("New Database. Creating new admin user with credentials 'admin':");
conn.new_session()
conn.new_session("")
}
Some(user) => {
if !resetpw {
......@@ -248,7 +248,7 @@ mod tests {
db_apply_migrations::test(&mut conn);
if let Some(user) = set_user {
let mut test_user = conn.new_session();
let mut test_user = conn.new_session("");
test_user.username = Some(user.0);
match test_user.set_password(&user.1) {
None => panic!("Set Password did not work correctly.)"),
......
......@@ -82,7 +82,6 @@ impl iron_sessionstorage::Value for SessionToken {
}
use iron::middleware::{AroundMiddleware, Handler};
use rand::{distributions::Alphanumeric, thread_rng, Rng};
pub struct CookieDistributor {}
......@@ -92,6 +91,8 @@ impl CookieDistributor {
impl AroundMiddleware for CookieDistributor {
fn around(self, handler: Box<Handler>) -> Box<Handler> {
use rand::{distributions::Alphanumeric, thread_rng, Rng};
Box::new(move |req: &mut Request| -> IronResult<Response> {
if req.session().get::<SessionToken>().expect("blub...").is_none() {
let session_token: String = thread_rng().sample_iter(&Alphanumeric).take(10).collect();
......@@ -130,7 +131,7 @@ impl<'a, 'b> RequestSession for Request<'a, 'b> {
match self.session().get::<SessionToken>().unwrap() {
Some(SessionToken { token: session }) => Ok(session),
_ => {
use rand::{thread_rng, Rng};
use rand::{distributions::Alphanumeric, thread_rng, Rng};
let new_session_key: String = thread_rng().sample_iter(&Alphanumeric).take(28).collect();
self.session().set(SessionToken { token: new_session_key }).unwrap();
......@@ -252,6 +253,49 @@ fn greet_personal(req: &mut Request) -> IronResult<Response> {
Ok(resp)
}
fn debug(req: &mut Request) -> IronResult<Response> {
let session_token = req.get_session_token();
let (template, data) = {
let mutex = req.get::<Write<SharedDatabaseConnection>>().unwrap();
let conn = mutex.lock().unwrap_or_else(|e| e.into_inner());
functions::debug(&*conn, session_token)
};
let mut resp = Response::new();
resp.set_mut(Template::new(&template, data)).set_mut(status::Ok);
Ok(resp)
}
fn debug_new_token(req: &mut Request) -> IronResult<Response> {
let session_token = req.get_session_token();
println!("Loggin out session {:?}", session_token);
with_conn![functions::logout, req, session_token];
Ok(Response::with((status::Found, Redirect(url_for!(req, "debug")))))
}
fn debug_logout(req: &mut Request) -> IronResult<Response> {
let session_token = req.get_session_token();
println!("Loggin out session {:?}", session_token);
with_conn![functions::logout, req, session_token];
Ok(Response::with((status::Found, Redirect(url_for!(req, "debug")))))
}
fn debug_create_session(req: &mut Request) -> IronResult<Response> {
let session_token = req.get_session_token();
with_conn![functions::debug_create_session, req, session_token];
Ok(Response::with((status::Found, Redirect(url_for!(req, "debug")))))
}
fn contests(req: &mut Request) -> IronResult<Response> {
let (template, data) = with_conn![functions::show_contests, req,];
......@@ -766,6 +810,10 @@ pub fn start_server(conn: Connection, config: ::Config) -> iron::error::HttpResu
task: get "/task/:taskid" => task,
oauth: get "/oauth" => oauth,
check_cookie: get "/cookie" => cookie_warning,
debug: get "/debug" => debug,
debug_reset: get "/debug/reset" => debug_new_token,
debug_logout: get "/debug/logout" => debug_logout,
debug_create: get "/debug/create" => debug_create_session,
);
let my_secret = b"verysecret".to_vec();
......
{{#if known_session}}<p>Session in Datenbank vorhanden {{/if}}
{{#if alive_session}}<p>Session lebt {{/if}}
<p>Now: {{ now_timestamp }}
<p>Last: {{ session_timestamp }}
<p>Diff: {{ timediff }}
{{#if logged_in}}
<p> Eingeloggt als <em>{{ username }}</em>
{{#if firstname}}{{#if lastname}}
<p>({{firstname}} {{lastname}})
{{/if}}{{/if}}
{{#if teacher}}
<p>[Lehrer]
{{/if}}
{{#if admin}}
<p>[Admin]
{{/if}}
<p><a href="/debug/logout">Logout</a>
{{/if}}
<p>Session-Token: {{session}}
<p><a href="/debug/reset">Neues Token</a>
<p><a href="/debug/create">Erzeuge Session in DB</a>
Supports Markdown
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