Advertisement
Guest User

Untitled

a guest
Sep 21st, 2022
143
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.35 KB | None | 0 0
  1. use std::future::{ready, Ready};
  2.  
  3. const IGNORE_ROUTES: [&str; 1] = ["/api/user/signin"];
  4.  
  5. use actix_web::dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform};
  6. use actix_web::http::{header::HeaderName, header::HeaderValue, Method};
  7. use actix_web::middleware::{ErrorHandlerResponse, ErrorHandlers};
  8. use actix_web::{Error, HttpResponse};
  9. use futures::future::LocalBoxFuture;
  10. use serde::{Deserialize, Serialize};
  11.  
  12. #[derive(Debug, Serialize, Deserialize)]
  13. pub struct ResponseBody<T> {
  14. pub message: String,
  15. pub data: T,
  16. }
  17.  
  18. impl<T> ResponseBody<T> {
  19. pub fn new(message: &str, data: T) -> ResponseBody<T> {
  20. ResponseBody {
  21. message: message.to_string(),
  22. data,
  23. }
  24. }
  25. }
  26.  
  27. // There are two steps in middleware processing.
  28. // 1. Middleware initialization, middleware factory gets called with
  29. // next service in chain as parameter.
  30. // 2. Middleware's call method gets called with normal request.
  31. pub struct Authentication;
  32.  
  33. // Middleware factory is `Transform` trait
  34. // `S` - type of the next service
  35. // `B` - type of response's body
  36. impl<S, B> Transform<S, ServiceRequest> for Authentication
  37. where
  38. S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
  39. S::Future: 'static,
  40. B: 'static,
  41. {
  42. type Response = ServiceResponse<B>;
  43. type Error = Error;
  44. type InitError = ();
  45. type Transform = AuthenticationMiddleware<S>;
  46. type Future = Ready<Result<Self::Transform, Self::InitError>>;
  47.  
  48. fn new_transform(&self, service: S) -> Self::Future {
  49. ready(Ok(AuthenticationMiddleware { service }))
  50. }
  51. }
  52.  
  53. pub struct AuthenticationMiddleware<S> {
  54. service: S,
  55. }
  56.  
  57. impl<S, B> Service<ServiceRequest> for AuthenticationMiddleware<S>
  58. where
  59. S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
  60. S::Future: 'static,
  61. B: 'static,
  62. {
  63. type Response = ServiceResponse<B>;
  64. type Error = Error;
  65. type Future = LocalBoxFuture<'static, Result<Self::Response, Self::Error>>;
  66.  
  67. forward_ready!(service);
  68.  
  69. fn call(&self, mut req: ServiceRequest) -> Self::Future {
  70. let mut authenticate_pass: bool = false;
  71.  
  72. // get headers
  73. let headers = req.headers_mut();
  74.  
  75. // append header
  76. headers.append(
  77. HeaderName::from_static("content-length"),
  78. HeaderValue::from_static("true"),
  79. );
  80.  
  81. // if method was OPTIONS then automatically passes
  82. if Method::OPTIONS == *req.method() {
  83. authenticate_pass = true;
  84. }
  85.  
  86. // if the path is in IGNORE_ROUTES then automatically passes
  87. for ignore_route in IGNORE_ROUTES.iter() {
  88. if req.path().starts_with(ignore_route) {
  89. authenticate_pass = true;
  90. }
  91. }
  92.  
  93. println!("authenticate_pass {}", authenticate_pass);
  94.  
  95. if authenticate_pass {
  96. let fut = self.service.call(req);
  97. Box::pin(async move {
  98. let res = fut.await?;
  99. Ok(res)
  100. })
  101. } else {
  102. Box::pin(async move {
  103. Ok(req.into_response(
  104. HttpResponse::Unauthorized()
  105. .json(ResponseBody::new("INVALID TOKEN", ""))
  106. .into_body(),
  107. ))
  108. })
  109. }
  110. }
  111. }
  112.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement