use crate::website::{Page, WebSite}; use crate::AppState; use actix_web::{ get, post, web::{Data, Form, Json}, HttpRequest, HttpResponse, }; use std::sync::RwLock; #[get("/workspace")] async fn admin_workspace() -> HttpResponse { // TODO return admin static web view with js application 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<RwLock<AppState>>, req: HttpRequest, ) -> HttpResponse { let (admin_username, admin_pwd, cookie_name) = { let app_state = app_state .read() .expect("Couldn't read to RwLock<AppState>."); ( 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 mut app_state = app_state .write() .expect("Couldn't acquire write lock for RwLock<AppState>"); app_state.admin_auth_token.update_value(); let cookie = app_state.admin_auth_token.generate_cookie(); 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() -> HttpResponse { // TODO create a module with built-in admin static views HttpResponse::Ok().body( " <html lang='en' prefix='og: https://ogp.me/ns#'> <head> <meta charset='UTF-8'> <meta http-equiv='X-UA-Compatible' content='IE=edge'> <meta name='viewport' content='width=device-width, initial-scale=1.0'> <title>Krutacea - Admin Login</title> <link rel='stylesheet' href='/assets/default/admin.css'> </head> <body> <form id='admin-login-form'> <div> <label for='username'>Admin Id</label> <input type='text' name='username'/> </div> <div> <label for='password'>Password</label> <input type='password' name='password' /> </div> <input type='submit' /> </form> </body> <script src='/assets/default/admin.js'></script> </html> ", ) } #[derive(serde::Deserialize, Clone)] pub struct AddPageData { parent_page_id: usize, new_page: Page, } #[post("/add-page")] pub async fn add_page( website: Data<RwLock<WebSite>>, add_page_data: Json<AddPageData>, ) -> HttpResponse { match website .write() .expect("Couldn't acquire website write lock") .add_page(add_page_data.parent_page_id, add_page_data.new_page.clone()) { Ok(()) => HttpResponse::Ok().finish(), Err(msg) => { HttpResponse::BadRequest().body(format!("Error adding new page to website - {}", msg)) } } } #[get("/page-data/{id}")] pub async fn get_page_data( website: Data<RwLock<WebSite>>, id: actix_web::web::Path<usize>, ) -> HttpResponse { let id = id.into_inner(); match website .read() .expect("Couldn't acquire website read lock") .get_page(id) { Some(page) => HttpResponse::Ok().json(page), None => HttpResponse::NotFound().body(format!("Page with id {} was not found", id)), } }