actix_jwt_auth_middleware/middleware/
transform.rs

1use crate::AuthenticationServiceInner;
2use crate::Authority;
3
4use std::future;
5use std::marker::PhantomData;
6use std::rc::Rc;
7use std::sync::Arc;
8
9use actix_web::body::MessageBody;
10use actix_web::dev::{Service, ServiceRequest, ServiceResponse, Transform};
11use actix_web::{Error as ActixWebError, FromRequest, Handler};
12use jwt_compact::Algorithm;
13use serde::de::DeserializeOwned;
14use serde::Serialize;
15
16/**
17   A wrapper around the [`Authority`] which can be passed to the `wrap` function of a [`App`](actix_web::App)/[`Scope`](actix_web::Scope) orĀ [`Resource`](actix_web::Resource).
18
19   ## Example
20   ```rust
21   use actix_jwt_auth_middleware::{TokenSigner, Authority, AuthenticationService};
22   use actix_web::{web, App};
23   use serde::{Serialize, Deserialize};
24   use ed25519_compact::KeyPair;
25   use jwt_compact::{alg::Ed25519};
26
27   #[derive(Serialize, Deserialize, Clone)]
28   struct User {
29       id: u32
30   }
31
32   let KeyPair {
33       pk: public_key,
34       sk: secret_key,
35   } = KeyPair::generate();
36
37   let authority = Authority::<User, _, _, _>::new()
38       .refresh_authorizer(|| async move { Ok(()) })
39       .token_signer(Some(
40           TokenSigner::new()
41               .signing_key(secret_key)
42               .algorithm(Ed25519)
43               .build()
44               .unwrap()
45       ))
46       .verifying_key(public_key)
47       .build()
48       .unwrap();
49
50   let app = App::new()
51       .service(
52           web::scope("/auth-only")
53               .wrap(
54                   AuthenticationService::new(authority.clone())
55               )
56        );
57   ```
58*/
59pub struct AuthenticationService<Claims, Algo, ReAuth, Args>
60where
61    Algo: Algorithm + Clone,
62    Algo::SigningKey: Clone,
63{
64    inner: Arc<Authority<Claims, Algo, ReAuth, Args>>,
65    claims_marker: PhantomData<Claims>,
66}
67
68impl<Claims, Algo, ReAuth, Args> AuthenticationService<Claims, Algo, ReAuth, Args>
69where
70    Claims: DeserializeOwned,
71    Algo: Algorithm + Clone,
72    Algo::SigningKey: Clone,
73{
74    /**
75        returns a new `AuthenticationService` wrapping the [`Authority`]
76    */
77    pub fn new(
78        authority: Authority<Claims, Algo, ReAuth, Args>,
79    ) -> AuthenticationService<Claims, Algo, ReAuth, Args> {
80        AuthenticationService {
81            inner: Arc::new(authority),
82            claims_marker: PhantomData,
83        }
84    }
85}
86
87impl<S, Body, Claims, Algo, ReAuth, Args> Transform<S, ServiceRequest>
88    for AuthenticationService<Claims, Algo, ReAuth, Args>
89where
90    S: Service<ServiceRequest, Response = ServiceResponse<Body>, Error = ActixWebError> + 'static,
91    Claims: Serialize + DeserializeOwned + 'static,
92    Algo: Algorithm + Clone + 'static,
93    Algo::SigningKey: Clone,
94    Body: MessageBody,
95    ReAuth: Handler<Args, Output = Result<(), ActixWebError>>,
96    Args: FromRequest + 'static,
97{
98    type Response = <AuthenticationServiceInner<S, Claims, Algo, ReAuth, Args> as Service<
99        ServiceRequest,
100    >>::Response;
101    type Error = ActixWebError;
102    type Transform = AuthenticationServiceInner<S, Claims, Algo, ReAuth, Args>;
103    type InitError = ();
104    type Future = future::Ready<Result<Self::Transform, Self::InitError>>;
105
106    fn new_transform(&self, service: S) -> Self::Future {
107        future::ready(Ok(AuthenticationServiceInner::new(
108            Rc::new(service),
109            Arc::clone(&self.inner),
110        )))
111    }
112}