oauth2_client/device_authorization_grant/
provider_ext.rs1pub 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
20pub 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#[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 }
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 }