use crate::AppState; use actix_web::{ cookie::{time::Duration, Cookie, SameSite}, get, post, web::{Data, Form}, HttpRequest, HttpResponse, Responder, }; #[get("/workspace")] async fn admin_workspace() -> impl Responder { actix_web::HttpResponse::Ok().body("Welcome Admin") } #[derive(serde::Deserialize)] struct Credentials { username: String, password: String, } #[post("/login")] async fn admin_authenticate( credentials: Form<Credentials>, app_state: Data<std::sync::Mutex<AppState>>, req: HttpRequest, ) -> impl Responder { let (admin_username, admin_pwd, cookie_name) = { let app_state = app_state.lock().unwrap(); ( app_state.config.admin_username.to_owned(), app_state.config.admin_pwd.to_owned(), app_state.config.admin_cookie_name.to_owned(), ) }; if admin_username.eq(&credentials.username) && admin_pwd.eq(&credentials.password) { let cookie_value = { let mut app_state = app_state.lock().unwrap(); app_state.admin_auth_token.generate(); app_state .admin_auth_token .value .as_ref() .unwrap() .to_owned() }; let cookie = Cookie::build(cookie_name, cookie_value) .path("/") .http_only(true) .max_age(Duration::days(7)) .same_site(SameSite::Strict) .secure(true) .finish(); return HttpResponse::Accepted().cookie(cookie).finish(); } else { let mut res = HttpResponse::Unauthorized().finish(); match req.cookie(&cookie_name) { Some(_) => { res.del_cookie(&cookie_name); return res; } None => return res, } } } #[get("/login")] pub async fn admin_login() -> impl Responder { // TODO real HTML doc - create a module with admin views and a js file to load. HttpResponse::Ok().body( " <form id='admin-login-form'> <input type='text' name='username'/> <input type='password' name='password' /> <input type='submit' /> </form> <script> document.getElementById('admin-login-form').onsubmit = function (e) { e.preventDefault(); fetch('/admin/login', { method: 'POST', body: new URLSearchParams(new FormData(e.target)) }).then(res => { if (res.status >= 200 && res.status < 400) { console.log(res) window.location = '/admin/auth/workspace'; } }).catch(err => console.log(err)) } </script> ", ) }