use actix_session::Session; use actix_web::http::header::LOCATION; use actix_web::{get, post, web, HttpResponse}; use serde::Deserialize; use crate::error::PinussyError; use crate::notification::{Kind, Notification}; use crate::templates; use crate::Pinussy; use crate::Result; #[get("/login")] async fn get() -> HttpResponse { HttpResponse::Ok().body(render!(templates::login_html, None).unwrap()) } #[derive(Deserialize)] struct LoginForm { username: String, password: String, rememberme: Option, } #[post("/login")] async fn post( state: web::Data, session: Session, form: web::Form, ) -> Result { match state.db.users().read_username(&form.username).await { Ok(user) => { if user.verify_password(&form.password)? { let user_id = state.db.users().get_id(&form.username).await?; session.insert("user_id", user_id)?; return Ok(HttpResponse::SeeOther() .insert_header((LOCATION, "/")) .finish()); } else { return Ok(HttpResponse::Unauthorized().body( render!( templates::login_html, Some(Notification { kind: Kind::Error, message: "that password is incorrect".to_owned() }) ) .unwrap(), )); } } Err(PinussyError::Database(sqlx::Error::RowNotFound)) => { return Ok(HttpResponse::NotFound().body( render!( templates::login_html, Some(Notification { kind: Kind::Error, message: format!("the user \"{}\" does not exist", &form.username) }) ) .unwrap(), )); } Err(_) => { return Ok(HttpResponse::InternalServerError().body( render!( templates::login_html, Some(Notification { kind: Kind::Error, message: "internal server error. please try again later".to_owned() }) ) .unwrap(), )); } } }