oauth2_client/device_authorization_grant/
provider_ext.rs

1pub use crate::device_authorization_grant::device_access_token_endpoint::DeviceAccessTokenEndpointRetryReason;
2use dyn_clone::{clone_trait_object, DynClone};
3pub use oauth2_core::{
4    access_token_request::BodyWithDeviceAuthorizationGrant,
5    device_authorization_grant::{
6        device_authorization_request::Body as DeviceAuthorizationRequestBody,
7        device_authorization_response::{
8            ErrorBody as DeviceAuthorizationResponseErrorBody,
9            SuccessfulBody as DeviceAuthorizationResponseSuccessfulBody,
10        },
11    },
12    re_exports::{AccessTokenResponseErrorBody, AccessTokenResponseSuccessfulBody},
13};
14
15use crate::{
16    re_exports::{Body, ClientId, ClientSecret, Map, Request, Response, Scope, Url, Value},
17    Provider,
18};
19
20//
21pub trait ProviderExtDeviceAuthorizationGrant: Provider + DynClone {
22    fn scopes_default(&self) -> Option<Vec<<Self as Provider>::Scope>> {
23        None
24    }
25
26    fn device_authorization_endpoint_url(&self) -> &Url;
27
28    fn device_authorization_request_body_extra(&self) -> Option<Map<String, Value>> {
29        None
30    }
31
32    fn device_authorization_request_rendering(
33        &self,
34        _body: &DeviceAuthorizationRequestBody<<Self as Provider>::Scope>,
35    ) -> Option<Result<Request<Body>, Box<dyn std::error::Error + Send + Sync + 'static>>> {
36        None
37    }
38
39    fn device_authorization_response_parsing(
40        &self,
41        _response: &Response<Body>,
42    ) -> Option<
43        Result<
44            Result<DeviceAuthorizationResponseSuccessfulBody, DeviceAuthorizationResponseErrorBody>,
45            Box<dyn std::error::Error + Send + Sync + 'static>,
46        >,
47    > {
48        None
49    }
50
51    fn device_access_token_request_body_extra(
52        &self,
53        _body: &BodyWithDeviceAuthorizationGrant,
54        _device_authorization_response_body: &DeviceAuthorizationResponseSuccessfulBody,
55    ) -> Option<Map<String, Value>> {
56        None
57    }
58
59    fn device_access_token_request_rendering(
60        &self,
61        _body: &BodyWithDeviceAuthorizationGrant,
62        _device_authorization_response_body: &DeviceAuthorizationResponseSuccessfulBody,
63    ) -> Option<Result<Request<Body>, Box<dyn std::error::Error + Send + Sync + 'static>>> {
64        None
65    }
66
67    #[allow(clippy::type_complexity)]
68    fn device_access_token_response_parsing(
69        &self,
70        _response: &Response<Body>,
71    ) -> Option<
72        Result<
73            Result<
74                Result<
75                    AccessTokenResponseSuccessfulBody<<Self as Provider>::Scope>,
76                    AccessTokenResponseErrorBody,
77                >,
78                DeviceAccessTokenEndpointRetryReason,
79            >,
80            Box<dyn std::error::Error + Send + Sync + 'static>,
81        >,
82    > {
83        None
84    }
85}
86
87clone_trait_object!(<SCOPE> ProviderExtDeviceAuthorizationGrant<Scope = SCOPE> where SCOPE: Scope + Clone);
88
89impl<SCOPE> core::fmt::Debug
90    for dyn ProviderExtDeviceAuthorizationGrant<Scope = SCOPE> + Send + Sync
91where
92    SCOPE: Scope,
93{
94    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
95        f.debug_struct("ProviderExtDeviceAuthorizationGrant")
96            .field("client_id", &self.client_id())
97            .field("token_endpoint_url", &self.token_endpoint_url().as_str())
98            .field("scopes_default", &self.scopes_default())
99            .field(
100                "device_authorization_endpoint_url",
101                &self.device_authorization_endpoint_url().as_str(),
102            )
103            .finish()
104    }
105}
106
107//
108//
109//
110#[derive(Debug, Clone)]
111pub struct ProviderExtDeviceAuthorizationGrantStringScopeWrapper<P>
112where
113    P: ProviderExtDeviceAuthorizationGrant,
114{
115    inner: P,
116}
117
118impl<P> ProviderExtDeviceAuthorizationGrantStringScopeWrapper<P>
119where
120    P: ProviderExtDeviceAuthorizationGrant,
121{
122    pub fn new(provider: P) -> Self {
123        Self { inner: provider }
124    }
125}
126
127impl<P> Provider for ProviderExtDeviceAuthorizationGrantStringScopeWrapper<P>
128where
129    P: ProviderExtDeviceAuthorizationGrant + Clone,
130{
131    type Scope = String;
132
133    fn client_id(&self) -> Option<&ClientId> {
134        self.inner.client_id()
135    }
136
137    fn client_secret(&self) -> Option<&ClientSecret> {
138        self.inner.client_secret()
139    }
140
141    fn token_endpoint_url(&self) -> &Url {
142        self.inner.token_endpoint_url()
143    }
144
145    fn extra(&self) -> Option<Map<String, Value>> {
146        self.inner.extra()
147    }
148
149    // Note
150}
151
152impl<P> ProviderExtDeviceAuthorizationGrant
153    for ProviderExtDeviceAuthorizationGrantStringScopeWrapper<P>
154where
155    P: ProviderExtDeviceAuthorizationGrant + Clone,
156{
157    fn scopes_default(&self) -> Option<Vec<<Self as Provider>::Scope>> {
158        self.inner
159            .scopes_default()
160            .map(|x| x.iter().map(|y| y.to_string()).collect())
161    }
162
163    fn device_authorization_endpoint_url(&self) -> &Url {
164        self.inner.device_authorization_endpoint_url()
165    }
166
167    fn device_authorization_request_body_extra(&self) -> Option<Map<String, Value>> {
168        self.inner.device_authorization_request_body_extra()
169    }
170
171    fn device_authorization_request_rendering(
172        &self,
173        body: &DeviceAuthorizationRequestBody<<Self as Provider>::Scope>,
174    ) -> Option<Result<Request<Body>, Box<dyn std::error::Error + Send + Sync + 'static>>> {
175        let body =
176            match DeviceAuthorizationRequestBody::<<P as Provider>::Scope>::try_from_t_with_string(
177                body,
178            ) {
179                Ok(x) => x,
180                Err(err) => return Some(Err(Box::new(err))),
181            };
182
183        self.inner.device_authorization_request_rendering(&body)
184    }
185
186    fn device_authorization_response_parsing(
187        &self,
188        response: &Response<Body>,
189    ) -> Option<
190        Result<
191            Result<DeviceAuthorizationResponseSuccessfulBody, DeviceAuthorizationResponseErrorBody>,
192            Box<dyn std::error::Error + Send + Sync + 'static>,
193        >,
194    > {
195        self.inner.device_authorization_response_parsing(response)
196    }
197
198    fn device_access_token_request_body_extra(
199        &self,
200        body: &BodyWithDeviceAuthorizationGrant,
201        device_authorization_response_body: &DeviceAuthorizationResponseSuccessfulBody,
202    ) -> Option<Map<String, Value>> {
203        self.inner
204            .device_access_token_request_body_extra(body, device_authorization_response_body)
205    }
206
207    fn device_access_token_request_rendering(
208        &self,
209        body: &BodyWithDeviceAuthorizationGrant,
210        device_authorization_response_body: &DeviceAuthorizationResponseSuccessfulBody,
211    ) -> Option<Result<Request<Body>, Box<dyn std::error::Error + Send + Sync + 'static>>> {
212        self.inner
213            .device_access_token_request_rendering(body, device_authorization_response_body)
214    }
215
216    #[allow(clippy::type_complexity)]
217    fn device_access_token_response_parsing(
218        &self,
219        response: &Response<Body>,
220    ) -> Option<
221        Result<
222            Result<
223                Result<
224                    AccessTokenResponseSuccessfulBody<<Self as Provider>::Scope>,
225                    AccessTokenResponseErrorBody,
226                >,
227                DeviceAccessTokenEndpointRetryReason,
228            >,
229            Box<dyn std::error::Error + Send + Sync + 'static>,
230        >,
231    > {
232        self.inner
233            .device_access_token_response_parsing(response)
234            .map(|x| {
235                x.map(|y| {
236                    y.map(|z| {
237                        z.map(|a| {
238                            AccessTokenResponseSuccessfulBody::<<Self as Provider>::Scope>::from(&a)
239                        })
240                    })
241                })
242            })
243    }
244
245    // Note
246}