use actix_web::{ cookie::Cookie, get, http::StatusCode, post, web::Data, HttpRequest, HttpResponse, HttpResponseBuilder, }; use askama::Template; use pwhash::bcrypt::verify; use serde::Deserialize; use crate::{ auth::Claims, ctx::Ctx, db::models::Account, error::NekrochanError, qsform::QsForm, web::{tcx::TemplateCtx, template_response}, }; #[derive(Template)] #[template(path = "login.html")] struct LogInTemplate { tcx: TemplateCtx, } #[get("/login")] pub async fn login_get(ctx: Data, req: HttpRequest) -> Result { let tcx = TemplateCtx::new(&ctx, &req).await?; let template = LogInTemplate { tcx }; template_response(&template) } #[derive(Deserialize)] pub struct LogInForm { username: String, password: String, } #[post("/login")] pub async fn login_post( ctx: Data, QsForm(form): QsForm, ) -> Result { let account = Account::read(&ctx, form.username.clone()) .await? .ok_or(NekrochanError::IncorrectCredentialError)?; if !verify(form.password, &account.password) { return Err(NekrochanError::IncorrectCredentialError); } let auth = Claims::new(account.username).encode(&ctx)?; let res = HttpResponseBuilder::new(StatusCode::SEE_OTHER) .append_header(("Location", "/staff/account")) .cookie(Cookie::new("auth", auth)) .finish(); Ok(res) }