raos/
builder.rs

1use crate::{
2    authorize::AuthorizationProvider,
3    common::model::ClientProvider,
4    manager::{CodeChallengeRequirement, OAuthConfig, OAuthManager},
5    token::TokenProvider,
6};
7
8/// The OAuthManagerBuilder is used to build an [OAuthManager].
9/// This builder is used to configure the OAuthManager with the necessary providers,
10/// and to set the configuration options.
11pub struct OAuthManagerBuilder<C, A, T> {
12    client_provider: Option<C>,
13    authorization_provider: Option<A>,
14    token_provider: Option<T>,
15    config: OAuthConfig,
16}
17
18impl OAuthManagerBuilder<NeedsClientProvider, NeedsAuthorizationProvider, NeedsTokenProvider> {
19    pub(crate) fn new() -> Self {
20        Self {
21            client_provider: None,
22            authorization_provider: None,
23            token_provider: None,
24            config: OAuthConfig::default(),
25        }
26    }
27}
28
29impl<A, T> OAuthManagerBuilder<NeedsClientProvider, A, T> {
30    /// Set the client provider for the OAuthManager.
31    /// The client provider is used to get information about clients that are making requests.
32    /// See [ClientProvider] for more information.
33    pub fn client_provider<C>(self, client_provider: C) -> OAuthManagerBuilder<C, A, T>
34    where
35        C: ClientProvider,
36    {
37        OAuthManagerBuilder {
38            client_provider: Some(client_provider),
39            authorization_provider: self.authorization_provider,
40            token_provider: self.token_provider,
41            config: self.config,
42        }
43    }
44}
45
46impl<C, T> OAuthManagerBuilder<C, NeedsAuthorizationProvider, T> {
47    /// Set the authorization provider for the OAuthManager.
48    /// The authorization provider is used to authorize grants and exchange codes for grants.
49    /// See [AuthorizationProvider] for more information.
50    pub fn authorization_provider<A>(
51        self,
52        authorization_provider: A,
53    ) -> OAuthManagerBuilder<C, A, T>
54    where
55        A: AuthorizationProvider,
56    {
57        OAuthManagerBuilder {
58            authorization_provider: Some(authorization_provider),
59            client_provider: self.client_provider,
60            token_provider: self.token_provider,
61            config: self.config,
62        }
63    }
64}
65
66impl<C, A> OAuthManagerBuilder<C, A, NeedsTokenProvider> {
67    /// Set the token provider for the OAuthManager.
68    /// The token provider is used to generate and validate tokens and refresh tokens.
69    /// See [TokenProvider] for more information.
70    pub fn token_provider<T>(self, token_provider: T) -> OAuthManagerBuilder<C, A, T>
71    where
72        T: TokenProvider,
73    {
74        OAuthManagerBuilder {
75            token_provider: Some(token_provider),
76            client_provider: self.client_provider,
77            authorization_provider: self.authorization_provider,
78            config: self.config,
79        }
80    }
81}
82
83impl<C, A, T> OAuthManagerBuilder<C, A, T> {
84    /// Calling disallow_plain_code_challenge will disallow the use of plain code challenges.
85    /// If this function is called, the code challenge must be a S256 challenge.
86    /// This is a security measure to prevent code injection attacks.
87    pub fn disallow_plain_code_challenge(mut self) -> Self {
88        self.config.disallow_plain_code_challenge = true;
89        self
90    }
91
92    /// Set the authorization server identifier.
93    /// This is used to identify the authorization server in the authorization response.
94    /// This is an optional setting.
95    pub fn set_authorization_server_identifier(mut self, identifier: String) -> Self {
96        self.config.authorization_server_identifier = Some(identifier);
97        self
98    }
99
100    /// Set the code challenge requirement to always require a code challenge.
101    /// By default, it is only required for public clients.
102    pub fn code_challenge_always_required(mut self) -> Self {
103        self.config.require_code_challenge = CodeChallengeRequirement::Always;
104        self
105    }
106
107    /// Set the code challenge requirement to never require a code challenge.
108    /// This is intended for use-cases where the implementer takes responsibility for client authentication, like with a secured network or trusted source.
109    /// By default, it is only required for public clients.
110    pub fn code_challenge_never_required(mut self) -> Self {
111        self.config.require_code_challenge = CodeChallengeRequirement::Never;
112        self
113    }
114}
115
116impl<C, A, T, O, E, Ex> OAuthManagerBuilder<C, A, T>
117where
118    C: ClientProvider<Error = E>,
119    A: AuthorizationProvider<OwnerId = O, Error = E, Extras = Ex>,
120    T: TokenProvider<OwnerId = O, Error = E>,
121{
122    /// Build the OAuthManager with the configured providers.
123    /// This function will consume the builder and return an OAuthManager.
124    pub fn build(self) -> OAuthManager<O, E, Ex> {
125        OAuthManager {
126            client_provider: Box::new(self.client_provider.unwrap()),
127            authorization_provider: Box::new(self.authorization_provider.unwrap()),
128            token_provider: Box::new(self.token_provider.unwrap()),
129            config: self.config,
130        }
131    }
132}
133
134/// Marker type for the [OAuthManagerBuilder] to indicate that the client provider is needed,
135/// it does not fulfill the trait requirements causing it to prevent the manager from being built.
136pub struct NeedsClientProvider;
137/// Marker type for the [OAuthManagerBuilder] to indicate that the authorization provider is needed,
138/// it does not fulfill the trait requirements causing it to prevent the manager from being built.
139pub struct NeedsAuthorizationProvider;
140/// Marker type for the [OAuthManagerBuilder] to indicate that the token provider is needed,
141/// it does not fulfill the trait requirements causing it to prevent the manager from being built.
142pub struct NeedsTokenProvider;