tower_oauth2_resource_server/
builder.rs1use std::{marker::PhantomData, sync::Arc};
2
3use serde::de::DeserializeOwned;
4
5use crate::{
6 auth_resolver::{AuthorizerResolver, IssuerAuthorizerResolver, SingleAuthorizerResolver},
7 error::StartupError,
8 server::OAuth2ResourceServer,
9 tenant::TenantConfiguration,
10};
11
12#[derive(Debug)]
13pub struct OAuth2ResourceServerBuilder<Claims> {
14 tenant_configurations: Vec<TenantConfiguration>,
15 auth_resolver: Option<Arc<dyn AuthorizerResolver<Claims>>>,
16 phantom: PhantomData<Claims>,
17}
18
19impl<Claims> OAuth2ResourceServer<Claims>
20where
21 Claims: Clone + DeserializeOwned + Send + Sync + 'static,
22{
23 pub fn builder() -> OAuth2ResourceServerBuilder<Claims> {
24 OAuth2ResourceServerBuilder::new()
25 }
26}
27
28impl<Claims> OAuth2ResourceServerBuilder<Claims> {
29 fn new() -> Self {
30 OAuth2ResourceServerBuilder::<Claims> {
31 tenant_configurations: Vec::new(),
32 auth_resolver: None,
33 phantom: PhantomData,
34 }
35 }
36}
37
38impl<Claims> OAuth2ResourceServerBuilder<Claims>
39where
40 Claims: Clone + DeserializeOwned + Send + Sync + 'static,
41{
42 pub fn add_tenant(mut self, tenant_configuration: TenantConfiguration) -> Self {
44 self.tenant_configurations.push(tenant_configuration);
45 self
46 }
47
48 pub fn add_tenants(mut self, tenant_configurations: Vec<TenantConfiguration>) -> Self {
50 self.tenant_configurations.extend(tenant_configurations);
51 self
52 }
53
54 pub fn auth_resolver(mut self, auth_resolver: Arc<dyn AuthorizerResolver<Claims>>) -> Self {
60 self.auth_resolver = Some(auth_resolver);
61 self
62 }
63
64 pub async fn build(self) -> Result<OAuth2ResourceServer<Claims>, StartupError> {
70 if self.tenant_configurations.is_empty() {
71 return Err(StartupError::InvalidParameter(
72 "At least one TenantConfiguration is required".to_owned(),
73 ));
74 }
75 let num_tenants = self.tenant_configurations.len();
76 let auth_resolver = self.auth_resolver.unwrap_or_else(|| {
77 if num_tenants == 1 {
78 Arc::new(SingleAuthorizerResolver {})
79 } else {
80 Arc::new(IssuerAuthorizerResolver {})
81 }
82 });
83 OAuth2ResourceServer::new(self.tenant_configurations, auth_resolver).await
84 }
85}
86
87impl<Claims> Default for OAuth2ResourceServerBuilder<Claims> {
88 fn default() -> Self {
89 Self::new()
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use serde::Deserialize;
96
97 use super::*;
98
99 #[derive(Clone, Debug, Deserialize)]
100 struct Claims {}
101
102 #[tokio::test]
103 async fn should_require_tenant_configurations() {
104 let result = OAuth2ResourceServerBuilder::<Claims>::new().build().await;
105 assert!(result.is_err());
106 assert_eq!(
107 result.unwrap_err(),
108 StartupError::InvalidParameter(
109 "At least one TenantConfiguration is required".to_owned()
110 )
111 )
112 }
113}