You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

89 lines
2.6 KiB

  1. use actix_web::web;
  2. use actix_web_httpauth::extractors::basic::BasicAuth;
  3. use crate::actions::users;
  4. use crate::{errors, AppConfig};
  5. use actix_identity::Identity;
  6. use actix_web::{get, Error, HttpResponse};
  7. #[get("/login")]
  8. pub async fn login(
  9. id: Identity,
  10. credentials: BasicAuth,
  11. config: web::Data<AppConfig>,
  12. ) -> Result<HttpResponse, Error> {
  13. let maybe_identity = id.identity();
  14. let response = if let Some(identity) = maybe_identity {
  15. Ok(HttpResponse::Found()
  16. .header("location", "/")
  17. .content_type("text/plain")
  18. .json(format!("Already logged in as {}", identity)))
  19. } else {
  20. let credentials2 = credentials.clone();
  21. let valid =
  22. web::block(move || validate_basic_auth(credentials2, &config))
  23. .await?;
  24. if valid {
  25. id.remember(credentials.user_id().to_string());
  26. Ok(HttpResponse::Found().header("location", "/").finish())
  27. } else {
  28. Ok(HttpResponse::BadRequest().json(
  29. crate::models::errors::ErrorModel::new(
  30. 20,
  31. "Wrong password or account does not exist",
  32. ),
  33. ))
  34. }
  35. };
  36. response
  37. }
  38. #[get("/logout")]
  39. pub async fn logout(
  40. id: Identity,
  41. _credentials: BasicAuth,
  42. ) -> Result<HttpResponse, Error> {
  43. let maybe_identity = id.identity();
  44. let response = if let Some(identity) = maybe_identity {
  45. info!("Logging out {user}", user = identity);
  46. id.forget();
  47. HttpResponse::Found().header("location", "/").finish()
  48. } else {
  49. HttpResponse::Found()
  50. .header("location", "/")
  51. .content_type("text/plain")
  52. .json("Not logged in")
  53. };
  54. Ok(response)
  55. }
  56. #[get("/")]
  57. pub async fn index(id: Identity) -> String {
  58. format!(
  59. "Hello {}",
  60. id.identity().unwrap_or_else(|| "Anonymous".to_owned())
  61. )
  62. }
  63. /// basic auth middleware function
  64. pub fn validate_basic_auth(
  65. credentials: BasicAuth,
  66. config: &web::Data<AppConfig>,
  67. ) -> Result<bool, errors::DomainError> {
  68. let result = if let Some(password_ref) = credentials.password() {
  69. let pool = &config.pool;
  70. let conn = pool.get()?;
  71. let password = password_ref.clone().into_owned();
  72. let valid = users::verify_password(
  73. &credentials.user_id().clone().into_owned(),
  74. &password,
  75. &conn,
  76. )?;
  77. Ok(valid)
  78. } else {
  79. Err(errors::DomainError::new_password_error(
  80. "No password given".to_owned(),
  81. ))
  82. };
  83. result
  84. }