use actix_session::Session; use actix_web::http::header::LOCATION; use actix_web::{get, post, web, HttpResponse}; use serde::Deserialize; use uuid::Uuid; use crate::error::PinussyError; use crate::notification::{Kind, Notification}; use crate::templates; use crate::Pinussy; use crate::Result; #[get("/login")] async fn get(session: Session, state: web::Data) -> Result { if let Some(user_id) = session.get::("user_id")? { if state.db.users().read(user_id).await.is_ok() { return Ok(HttpResponse::SeeOther() .insert_header((LOCATION, "/")) .finish()); } else { session.purge() } } Ok(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)? { 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(), )); } } }