diff --git a/Dockerfile b/Dockerfile index 1c5934b..4787d46 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,6 +23,5 @@ WORKDIR /opt COPY --from=build /simply-shorten/target/release/simply-shorten /opt/simply-shorten COPY --from=build /simply-shorten/resources /opt/resources -COPY ./urls.sqlite /opt/urls.sqlite CMD ["./simply-shorten"] diff --git a/actix/src/auth.rs b/actix/src/auth.rs index 0bf495d..0e501cb 100644 --- a/actix/src/auth.rs +++ b/actix/src/auth.rs @@ -1,7 +1,8 @@ use actix_session::Session; +use std::time::SystemTime; pub fn validate(session: Session) -> bool { - let token = session.get::("session-token"); + let token = session.get::("session-token"); if token.is_err() { false } else if !check(token.unwrap()) { @@ -11,12 +12,37 @@ pub fn validate(session: Session) -> bool { } } -fn check(token: Option) -> bool { +fn check(token: Option) -> bool { if token.is_none() { false - } else if token.unwrap() != 123 { - false } else { - true + let token_body = token.unwrap(); + let token_parts: Vec<&str> = token_body.split(";").collect(); + if token_parts.len() < 2 { + false + } else { + let token_text = token_parts[0]; + let token_time = token_parts[1].parse::().unwrap_or(0); + let time_now = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .expect("Time went backwards!") + .as_secs(); + println!("{:#?}", token_parts); + if token_text == "valid-session-token" && time_now < token_time + 1209600 { + // There are 1209600 seconds in 14 days + true + } else { + false + } + } } } + +pub fn gen_token() -> String { + let token_text = "valid-session-token".to_string(); + let time = SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .expect("Time went backwards!") + .as_secs(); + format!("{token_text};{time}") +} diff --git a/actix/src/database.rs b/actix/src/database.rs index 7935290..3239217 100644 --- a/actix/src/database.rs +++ b/actix/src/database.rs @@ -58,6 +58,7 @@ pub fn delete_link(shortlink: String, db: &Connection) -> () { pub fn open_db(path: String) -> Connection { let db = Connection::open(path).expect("Unable to open database!"); + // Create table if it doesn't exist db.execute( "CREATE TABLE IF NOT EXISTS urls ( id INTEGER PRIMARY KEY AUTOINCREMENT, diff --git a/actix/src/main.rs b/actix/src/main.rs index 085ba9d..7c6fc5d 100644 --- a/actix/src/main.rs +++ b/actix/src/main.rs @@ -78,8 +78,9 @@ async fn link_handler(shortlink: web::Path, data: web::Data) - // Handle login #[post("/api/login")] async fn login(req: String, session: Session) -> HttpResponse { - if req == "ssssss".to_string() { - session.insert("session-token", 123).unwrap(); + if req == env::var("password").unwrap_or(req.clone()) { + // If no password was provided, match any password + session.insert("session-token", auth::gen_token()).unwrap(); HttpResponse::Ok().body("Correct password!") } else { eprintln!("Failed login attempt!"); @@ -104,15 +105,20 @@ async fn delete_link( #[actix_web::main] async fn main() -> std::io::Result<()> { + // Generate session key in runtime so that restarts invalidates older logins let secret_key = Key::generate(); + let db_location = env::var("db_url").unwrap_or("/opt/urls.sqlite".to_string()); + + // Actually start the server HttpServer::new(move || { App::new() .wrap(SessionMiddleware::new( CookieSessionStore::default(), secret_key.clone(), )) + // Maintain a single instance of database throughout .app_data(web::Data::new(AppState { - db: database::open_db(env::var("db_url").unwrap_or("./urls.sqlite".to_string())), + db: database::open_db(env::var("db_url").unwrap_or(db_location.clone())), })) .wrap(middleware::Compress::default()) .service(link_handler)