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.

92 lines
2.8 KiB

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