auth_middleware.rs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. use crate::service::user::{LoggedUser, AUTHORIZED_USERS};
  2. use actix_service::{Service, Transform};
  3. use actix_web::{
  4. dev::{ServiceRequest, ServiceResponse},
  5. Error,
  6. HttpResponse,
  7. ResponseError,
  8. };
  9. use crate::config::IGNORE_ROUTES;
  10. use actix_web::{body::AnyBody, dev::MessageBody};
  11. use flowy_net::{config::HEADER_TOKEN, errors::ServerError};
  12. use futures::future::{ok, LocalBoxFuture, Ready};
  13. use std::{
  14. convert::TryInto,
  15. error::Error as StdError,
  16. task::{Context, Poll},
  17. };
  18. pub struct AuthenticationService;
  19. impl<S, B> Transform<S, ServiceRequest> for AuthenticationService
  20. where
  21. S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
  22. S::Future: 'static,
  23. B: MessageBody + 'static,
  24. B::Error: StdError,
  25. {
  26. type Response = ServiceResponse;
  27. type Error = Error;
  28. type Transform = AuthenticationMiddleware<S>;
  29. type InitError = ();
  30. type Future = Ready<Result<Self::Transform, Self::InitError>>;
  31. fn new_transform(&self, service: S) -> Self::Future { ok(AuthenticationMiddleware { service }) }
  32. }
  33. pub struct AuthenticationMiddleware<S> {
  34. service: S,
  35. }
  36. impl<S, B> Service<ServiceRequest> for AuthenticationMiddleware<S>
  37. where
  38. S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error> + 'static,
  39. S::Future: 'static,
  40. B: MessageBody + 'static,
  41. B::Error: StdError,
  42. {
  43. type Response = ServiceResponse;
  44. type Error = Error;
  45. type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
  46. fn poll_ready(&self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { self.service.poll_ready(cx) }
  47. fn call(&self, req: ServiceRequest) -> Self::Future {
  48. let mut authenticate_pass: bool = false;
  49. for ignore_route in IGNORE_ROUTES.iter() {
  50. // log::info!("ignore: {}, path: {}", ignore_route, req.path());
  51. if req.path().starts_with(ignore_route) {
  52. authenticate_pass = true;
  53. break;
  54. }
  55. }
  56. if !authenticate_pass {
  57. if let Some(header) = req.headers().get(HEADER_TOKEN) {
  58. let result: Result<LoggedUser, ServerError> = header.try_into();
  59. match result {
  60. Ok(logged_user) => {
  61. if cfg!(feature = "ignore_auth") {
  62. authenticate_pass = true;
  63. AUTHORIZED_USERS.store_auth(logged_user, true);
  64. } else {
  65. authenticate_pass = AUTHORIZED_USERS.is_authorized(&logged_user);
  66. if authenticate_pass {
  67. AUTHORIZED_USERS.store_auth(logged_user, true);
  68. }
  69. }
  70. },
  71. Err(e) => log::error!("{:?}", e),
  72. }
  73. } else {
  74. log::debug!("Can't find any token from request: {:?}", req);
  75. }
  76. }
  77. if authenticate_pass {
  78. let fut = self.service.call(req);
  79. return Box::pin(async move {
  80. let res = fut.await?;
  81. Ok(res.map_body(|_, body| AnyBody::from_message(body)))
  82. });
  83. } else {
  84. Box::pin(async move { Ok(req.into_response(unauthorized_response())) })
  85. }
  86. }
  87. }
  88. fn unauthorized_response() -> HttpResponse {
  89. let error = ServerError::unauthorized();
  90. error.error_response()
  91. }