1use std::sync::Arc;
2
3use serde::de::DeserializeOwned;
4
5use crate::{
6 authorizer::{ClaimsCheckerFn, KeySourceType},
7 error::InitError,
8 layer::{AuthorizationLayer, JwtSource},
9 Authorizer, Refresh, RefreshStrategy, RegisteredClaims, Validation,
10};
11
12use reqwest::Client;
13
14pub struct AuthorizerBuilder<C = RegisteredClaims>
19where
20 C: Clone + DeserializeOwned,
21{
22 key_source_type: KeySourceType,
23 refresh: Option<Refresh>,
24 claims_checker: Option<ClaimsCheckerFn<C>>,
25 validation: Option<Validation>,
26 jwt_source: JwtSource,
27 http_client: Option<Client>,
28}
29
30pub type JwtAuthorizer<C = RegisteredClaims> = AuthorizerBuilder<C>;
32
33impl<C> AuthorizerBuilder<C>
35where
36 C: Clone + DeserializeOwned + Send + Sync,
37{
38 pub fn from_oidc(issuer: &str) -> AuthorizerBuilder<C> {
40 AuthorizerBuilder {
41 key_source_type: KeySourceType::Discovery(issuer.to_string()),
42 refresh: Default::default(),
43 claims_checker: None,
44 validation: None,
45 jwt_source: JwtSource::AuthorizationHeader,
46 http_client: None,
47 }
48 }
49
50 pub fn from_jwks_url(url: &str) -> AuthorizerBuilder<C> {
52 AuthorizerBuilder {
53 key_source_type: KeySourceType::Jwks(url.to_owned()),
54 refresh: Default::default(),
55 claims_checker: None,
56 validation: None,
57 jwt_source: JwtSource::AuthorizationHeader,
58 http_client: None,
59 }
60 }
61
62 pub fn from_jwks(path: &str) -> AuthorizerBuilder<C> {
63 AuthorizerBuilder {
64 key_source_type: KeySourceType::JwksPath(path.to_owned()),
65 refresh: Default::default(),
66 claims_checker: None,
67 validation: None,
68 jwt_source: JwtSource::AuthorizationHeader,
69 http_client: None,
70 }
71 }
72
73 pub fn from_jwks_text(text: &str) -> AuthorizerBuilder<C> {
74 AuthorizerBuilder {
75 key_source_type: KeySourceType::JwksString(text.to_owned()),
76 refresh: Default::default(),
77 claims_checker: None,
78 validation: None,
79 jwt_source: JwtSource::AuthorizationHeader,
80 http_client: None,
81 }
82 }
83
84 pub fn from_rsa_pem(path: &str) -> AuthorizerBuilder<C> {
86 AuthorizerBuilder {
87 key_source_type: KeySourceType::RSA(path.to_owned()),
88 refresh: Default::default(),
89 claims_checker: None,
90 validation: None,
91 jwt_source: JwtSource::AuthorizationHeader,
92 http_client: None,
93 }
94 }
95
96 pub fn from_rsa_pem_text(text: &str) -> AuthorizerBuilder<C> {
98 AuthorizerBuilder {
99 key_source_type: KeySourceType::RSAString(text.to_owned()),
100 refresh: Default::default(),
101 claims_checker: None,
102 validation: None,
103 jwt_source: JwtSource::AuthorizationHeader,
104 http_client: None,
105 }
106 }
107
108 pub fn from_ec_pem(path: &str) -> AuthorizerBuilder<C> {
110 AuthorizerBuilder {
111 key_source_type: KeySourceType::EC(path.to_owned()),
112 refresh: Default::default(),
113 claims_checker: None,
114 validation: None,
115 jwt_source: JwtSource::AuthorizationHeader,
116 http_client: None,
117 }
118 }
119
120 pub fn from_ec_pem_text(text: &str) -> AuthorizerBuilder<C> {
122 AuthorizerBuilder {
123 key_source_type: KeySourceType::ECString(text.to_owned()),
124 refresh: Default::default(),
125 claims_checker: None,
126 validation: None,
127 jwt_source: JwtSource::AuthorizationHeader,
128 http_client: None,
129 }
130 }
131
132 pub fn from_ed_pem(path: &str) -> AuthorizerBuilder<C> {
134 AuthorizerBuilder {
135 key_source_type: KeySourceType::ED(path.to_owned()),
136 refresh: Default::default(),
137 claims_checker: None,
138 validation: None,
139 jwt_source: JwtSource::AuthorizationHeader,
140 http_client: None,
141 }
142 }
143
144 pub fn from_ed_pem_text(text: &str) -> AuthorizerBuilder<C> {
146 AuthorizerBuilder {
147 key_source_type: KeySourceType::EDString(text.to_owned()),
148 refresh: Default::default(),
149 claims_checker: None,
150 validation: None,
151 jwt_source: JwtSource::AuthorizationHeader,
152 http_client: None,
153 }
154 }
155
156 pub fn from_secret(secret: &str) -> AuthorizerBuilder<C> {
158 AuthorizerBuilder {
159 key_source_type: KeySourceType::Secret(secret.to_owned()),
160 refresh: Default::default(),
161 claims_checker: None,
162 validation: None,
163 jwt_source: JwtSource::AuthorizationHeader,
164 http_client: None,
165 }
166 }
167
168 pub fn refresh(mut self, refresh: Refresh) -> AuthorizerBuilder<C> {
170 if self.refresh.is_some() {
171 tracing::warn!("More than one refresh configuration found!");
172 }
173 self.refresh = Some(refresh);
174 self
175 }
176
177 pub fn no_refresh(mut self) -> AuthorizerBuilder<C> {
179 if self.refresh.is_some() {
180 tracing::warn!("More than one refresh configuration found!");
181 }
182 self.refresh = Some(Refresh {
183 strategy: RefreshStrategy::NoRefresh,
184 ..Default::default()
185 });
186 self
187 }
188
189 pub fn check<F>(mut self, checker_fn: F) -> AuthorizerBuilder<C>
192 where
193 F: Fn(&C) -> bool + Send + Sync + 'static,
194 {
195 self.claims_checker = Some(Arc::new(Box::new(checker_fn)));
196
197 self
198 }
199
200 pub fn validation(mut self, validation: Validation) -> AuthorizerBuilder<C> {
201 self.validation = Some(validation);
202
203 self
204 }
205
206 pub fn jwt_source(mut self, src: JwtSource) -> AuthorizerBuilder<C> {
210 self.jwt_source = src;
211
212 self
213 }
214
215 pub fn http_client(mut self, http_client: Client) -> AuthorizerBuilder<C> {
220 self.http_client = Some(http_client);
221
222 self
223 }
224
225 #[deprecated(since = "0.10.0", note = "please use `IntoLayer::into_layer()` instead")]
227 pub async fn layer(self) -> Result<AuthorizationLayer<C>, InitError> {
228 let val = self.validation.unwrap_or_default();
229 let auth = Arc::new(
230 Authorizer::build(
231 self.key_source_type,
232 self.claims_checker,
233 self.refresh,
234 val,
235 self.jwt_source,
236 None,
237 )
238 .await?,
239 );
240 Ok(AuthorizationLayer::new(vec![auth]))
241 }
242
243 pub async fn build(self) -> Result<Authorizer<C>, InitError> {
244 let val = self.validation.unwrap_or_default();
245
246 Authorizer::build(
247 self.key_source_type,
248 self.claims_checker,
249 self.refresh,
250 val,
251 self.jwt_source,
252 self.http_client,
253 )
254 .await
255 }
256}