nekrochan/src/web/login.rs

60 řádky
1.4 KiB
Rust
Spustitelný soubor

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<Ctx>, req: HttpRequest) -> Result<HttpResponse, NekrochanError> {
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<Ctx>,
QsForm(form): QsForm<LogInForm>,
) -> Result<HttpResponse, NekrochanError> {
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)
}