oxide_auth/frontends/simple/endpoint.rs
1//! An ad-hoc endpoint.
2//!
3//! Provides a simple struct with public members – [`Generic`] – that implements the central
4//! [`Endpoint`] trait implementation. Tries to implement the least amount of policies and logic
5//! while providing the biggest possible customizability (priority in this order).
6//!
7//! [`Generic`]: ./struct.Generic.html
8//! [`Endpoint`]: ../../endpoint/trait.Endpoint.html
9
10use crate::primitives::authorizer::Authorizer;
11use crate::primitives::issuer::Issuer;
12use crate::primitives::registrar::Registrar;
13use crate::primitives::scope::Scope;
14
15use crate::endpoint::{AccessTokenFlow, AuthorizationFlow, ResourceFlow, RefreshFlow, ClientCredentialsFlow};
16use crate::endpoint::{Endpoint, Extension, OAuthError, PreGrant, Template, Scopes};
17use crate::endpoint::{OwnerConsent, OwnerSolicitor, Solicitation};
18use crate::endpoint::WebRequest;
19
20use std::marker::PhantomData;
21
22/// Errors either caused by the underlying web types or the library.
23#[derive(Debug)]
24pub enum Error<W: WebRequest> {
25 /// An operation on a request or response failed.
26 ///
27 /// Typically, this should be represented as a `500–Internal Server Error`.
28 Web(W::Error),
29
30 /// Some part of the library signaled failure.
31 ///
32 /// No response has been generated, and in some cases doing so should be done with care or
33 /// under the consideration of an attacker currently trying to abuse the system.
34 OAuth(OAuthError),
35}
36
37/// A rather basic [`Endpoint`] implementation.
38///
39/// Substitue all parts that are not provided with the marker struct [`Vacant`]. This will at least
40/// ensure that no security properties are violated. Some flows may be unavailable when some
41/// primitives are missing. See [`AuthorizationFlow`], [`AccessTokenFlow`], [`ResourceFlow`] for
42/// more details.
43///
44/// Included types are assumed to be implemented independently, with no major connections. All
45/// attributes are public, so there is no inner invariant.
46///
47/// ## Usage
48///
49/// You should prefer this implementation when there are special requirements for your [`Endpoint`]
50/// implementation, or it is created ad-hoc. It also does some static type checking on dedicated
51/// methods to ensure that the creation of specific flows succeeds. You should prefer
52/// `authorization_flow`, `access_token_flow`, and `resource_flow` over the erroring preparation
53/// methods in [`AuthorizationFlow`], [`AccessTokenFlow`], and [`ResourceFlow`] respectively.
54///
55/// This should not be used when you special interacting primitives are used, that originate from
56/// outside this library. For example if you intend for your [`Scopes`] to be dynamically generated
57/// from a list of registered clients, its likely cleaner to provide your own [`Endpoint`]
58/// implementation instead.
59///
60/// ## Example
61///
62/// Here is an example where a `Generic` is used to set up an endpoint that is filled with the
63/// minimal members to be useable for an [`AccessTokenFlow`].
64///
65/// ```
66/// # extern crate oxide_auth;
67/// # use oxide_auth::frontends::simple::endpoint::Vacant;
68/// # use oxide_auth::frontends::simple::endpoint::Generic;
69/// use oxide_auth::endpoint::{AccessTokenFlow, Endpoint, WebRequest};
70/// use oxide_auth::primitives::{
71/// authorizer::AuthMap,
72/// generator::RandomGenerator,
73/// issuer::TokenMap,
74/// registrar::ClientMap,
75/// };
76///
77/// fn access_token_endpoint<R: WebRequest>() -> AccessTokenFlow<impl Endpoint<R>, R>
78/// where R::Response: Default,
79/// {
80/// let endpoint = Generic {
81/// authorizer: AuthMap::new(RandomGenerator::new(16)),
82/// registrar: ClientMap::new(),
83/// issuer: TokenMap::new(RandomGenerator::new(16)),
84/// scopes: Vacant,
85/// solicitor: Vacant,
86/// response: Vacant,
87/// };
88/// endpoint.access_token_flow()
89/// }
90/// ```
91///
92/// [`Endpoint`]: ../../../endpoint/trait.Endpoint.html
93/// [`Vacant`]: struct.Vacant.html
94/// [`AuthorizationFlow`]: ../../../endpoint/struct.AuthorizationFlow.html
95/// [`AccessTokenFlow`]: ../../../endpoint/struct.AccessTokenFlow.html
96/// [`ResourceFlow`]: ../../../endpoint/struct.ResourceFlow.html
97/// [`ResourceFlow`]: ../../../endpoint/trait.Scopes.html
98pub struct Generic<R, A, I, S = Vacant, C = Vacant, L = Vacant> {
99 /// The registrar implementation, or `Vacant` if it is not necesary.
100 pub registrar: R,
101
102 /// The authorizer implementation, or `Vacant` if it is not necesary.
103 pub authorizer: A,
104
105 /// The issuer implementation, or `Vacant` if it is not necesary.
106 pub issuer: I,
107
108 /// A solicitor implementation fit for the request types, or `Vacant` if it is not necesary.
109 pub solicitor: S,
110
111 /// Determine scopes for the request types, or `Vacant` if this does not protect resources.
112 pub scopes: C,
113
114 /// Creates responses, or `Vacant` if `Default::default` is applicable.
115 pub response: L,
116}
117
118/// A simple wrapper around an Endpoint to change it's error type into anything `Into`-able.
119pub struct ErrorInto<E, Error>(E, PhantomData<Error>);
120
121impl<E, Error> ErrorInto<E, Error> {
122 /// Create a new ErrorInto wrapping the supplied endpoint.
123 pub fn new(endpoint: E) -> Self {
124 ErrorInto(endpoint, PhantomData)
125 }
126}
127
128/// Marker struct if some primitive is not provided.
129///
130/// Used in place of other primitives when those are not provided. The exact semantics depend on
131/// the primitive.
132///
133/// ## Registrar, Authorizer, Issuer
134///
135/// Statically ensures to the `Generic` endpoint that no such primitive has been provided. Using
136/// the endpoint for flows that need such primitives will fail during the preparation phase. This
137/// returns `Option::None` in the implementations for `OptRef<T>`, `OptRegistrar`, `OptAuthorizer`,
138/// `OptIssuer`.
139///
140/// ## OwnerSolicitor
141///
142/// A solicitor denying all requests. This is the 'safe' default solicitor, remember to configure
143/// your own solicitor when you actually need to use it.
144///
145/// In contrast to the other primitives, this can not be solved as something such as
146/// `OptSolicitor<W>` since there is no current stable way to deny other crates from implementing
147/// `OptSolicitor<WR>` for some `WR` from that other crate. Thus, the compiler must assume that
148/// `None` may in fact implement some solicitor and this makes it impossible to implement as an
149/// optional reference trait for all solicitors in one way but in a different way for the `None`
150/// solicitor.
151///
152/// ## Scopes
153///
154/// Returns an empty list of scopes, effictively denying all requests since at least one scope
155/// needs to be fulfilled by token to gain access.
156///
157/// See [OwnerSolicitor](#OwnerSolicitor) for discussion on why this differs from the other
158/// primitives.
159pub struct Vacant;
160
161/// A simple wrapper for functions and lambdas to be used as solicitors.
162pub struct FnSolicitor<F>(pub F);
163
164/// Use a predetermined grant and owner as solicitor.
165///
166/// Convenience wrapper when the owner and her/his consent to a grant can be identified without
167/// further inspecting the request executing the flow. This may be the case for `WebRequest`
168/// implementations extracted from an original http request. This solicitor is obviously mostly
169/// useful for one-shot endpoints.
170pub struct ApprovedGrant {
171 /// The owner that approves of the grant.
172 pub owner: String,
173
174 /// The exact approved grant.
175 pub grant: PreGrant,
176}
177
178/// Like `AsRef<Registrar +'_>` but in a way that is expressible.
179///
180/// You are not supposed to need to implement this.
181///
182/// The difference to `AsRef` is that the `std` trait implies the trait lifetime bound be
183/// independent of the lifetime of `&self`. This leads to some annoying implementation constraints,
184/// similar to how you can not implement an `Iterator<&'_ mut Item>` whose items (i.e. `next`
185/// method) borrow the iterator. Only in this case the lifetime trouble is hidden behind the
186/// automatically inferred lifetime, as `AsRef<Trait>` actually refers to
187/// `AsRef<(Trait + 'static)`. But `as_ref` should have unsugared signature:
188///
189/// > `fn opt_ref<'a>(&'a self) -> Option<&'a (Trait + 'a)>`
190///
191/// Unfortunately, the `+ 'a` combiner can only be applied to traits, so we need a separate `OptX`
192/// trait for each trait for which we want to make use of such a function, afaik. If you have
193/// better ideas, I'll be grateful for opening an item on the Issue tracker.
194pub trait OptRegistrar {
195 /// Reference this as a `Registrar` or `Option::None`.
196 fn opt_ref(&self) -> Option<&dyn Registrar>;
197}
198
199/// Like `AsMut<Authorizer +'_>` but in a way that is expressible.
200///
201/// You are not supposed to need to implement this.
202///
203/// The difference to `AsMut` is that the `std` trait implies the trait lifetime bound be
204/// independent of the lifetime of `&self`. This leads to some annoying implementation constraints,
205/// similar to how you can not implement an `Iterator<&'_ mut Item>` whose items (i.e. `next`
206/// method) borrow the iterator. Only in this case the lifetime trouble is hidden behind the
207/// automatically inferred lifetime, as `AsMut<Trait>` actually refers to
208/// `AsMut<(Trait + 'static)`. But `opt_mut` should have unsugared signature:
209///
210/// > `fn opt_mut<'a>(&'a mut self) -> Option<&'a mut (Trait + 'a)>`
211///
212/// Unfortunately, the `+ 'a` combiner can only be applied to traits, so we need a separate `OptX`
213/// trait for each trait for which we want to make use of such a function, afaik. If you have
214/// better ideas, I'll be grateful for opening an item on the Issue tracker.
215pub trait OptAuthorizer {
216 /// Reference this mutably as an `Authorizer` or `Option::None`.
217 fn opt_mut(&mut self) -> Option<&mut dyn Authorizer>;
218}
219
220/// Like `AsMut<Issuer +'_>` but in a way that is expressible.
221///
222/// You are not supposed to need to implement this.
223///
224/// The difference to `AsMut` is that the `std` trait implies the trait lifetime bound be
225/// independent of the lifetime of `&self`. This leads to some annoying implementation constraints,
226/// similar to how you can not implement an `Iterator<&'_ mut Item>` whose items (i.e. `next`
227/// method) borrow the iterator. Only in this case the lifetime trouble is hidden behind the
228/// automatically inferred lifetime, as `AsMut<Trait>` actually refers to
229/// `AsMut<(Trait + 'static)`. But `opt_mut` should have unsugared signature:
230///
231/// > `fn opt_mut<'a>(&'a mut self) -> Option<&'a mut (Trait + 'a)>`
232///
233/// Unfortunately, the `+ 'a` combiner can only be applied to traits, so we need a separate `OptX`
234/// trait for each trait for which we want to make use of such a function, afaik. If you have
235/// better ideas, I'll be grateful for opening an item on the Issue tracker.
236pub trait OptIssuer {
237 /// Reference this mutably as an `Issuer` or `Option::None`.
238 fn opt_mut(&mut self) -> Option<&mut dyn Issuer>;
239}
240
241/// Independent component responsible for instantiating responses.
242pub trait ResponseCreator<W: WebRequest> {
243 /// Will only be called at most once per flow execution.
244 fn create(&mut self, request: &mut W, kind: Template) -> W::Response;
245}
246
247type Authorization<'a, W> = Generic<
248 &'a (dyn Registrar + 'a),
249 &'a mut (dyn Authorizer + 'a),
250 Vacant,
251 &'a mut (dyn OwnerSolicitor<W> + 'a),
252 Vacant,
253 Vacant,
254>;
255type AccessToken<'a> = Generic<
256 &'a (dyn Registrar + 'a),
257 &'a mut (dyn Authorizer + 'a),
258 &'a mut (dyn Issuer + 'a),
259 Vacant,
260 Vacant,
261 Vacant,
262>;
263type ClientCredentials<'a, W> = Generic<
264 &'a (dyn Registrar + 'a),
265 Vacant,
266 &'a mut (dyn Issuer + 'a),
267 &'a mut (dyn OwnerSolicitor<W> + 'a),
268 Vacant,
269 Vacant,
270>;
271type Refresh<'a> =
272 Generic<&'a (dyn Registrar + 'a), Vacant, &'a mut (dyn Issuer + 'a), Vacant, Vacant, Vacant>;
273type Resource<'a> = Generic<Vacant, Vacant, &'a mut (dyn Issuer + 'a), Vacant, &'a [Scope], Vacant>;
274
275/// Create an ad-hoc authorization flow.
276///
277/// Since all necessary primitives are expected in the function syntax, this is guaranteed to never
278/// fail or panic, compared to preparing one with `AuthorizationFlow`.
279///
280/// But this is not as versatile and extensible, so it should be used with care. The fact that it
281/// only takes references is a conscious choice to maintain forwards portability while encouraging
282/// the transition to custom `Endpoint` implementations instead.
283pub fn authorization_flow<'a, W>(
284 registrar: &'a dyn Registrar, authorizer: &'a mut dyn Authorizer,
285 solicitor: &'a mut dyn OwnerSolicitor<W>,
286) -> AuthorizationFlow<Authorization<'a, W>, W>
287where
288 W: WebRequest,
289 W::Response: Default,
290{
291 let flow = AuthorizationFlow::prepare(Generic {
292 registrar,
293 authorizer,
294 issuer: Vacant,
295 solicitor,
296 scopes: Vacant,
297 response: Vacant,
298 });
299
300 match flow {
301 Err(_) => unreachable!(),
302 Ok(flow) => flow,
303 }
304}
305
306/// Create an ad-hoc access token flow.
307///
308/// Since all necessary primitives are expected in the function syntax, this is guaranteed to never
309/// fail or panic, compared to preparing one with `AccessTokenFlow`.
310///
311/// But this is not as versatile and extensible, so it should be used with care. The fact that it
312/// only takes references is a conscious choice to maintain forwards portability while encouraging
313/// the transition to custom `Endpoint` implementations instead.
314pub fn access_token_flow<'a, W>(
315 registrar: &'a dyn Registrar, authorizer: &'a mut dyn Authorizer, issuer: &'a mut dyn Issuer,
316) -> AccessTokenFlow<AccessToken<'a>, W>
317where
318 W: WebRequest,
319 W::Response: Default,
320{
321 let flow = AccessTokenFlow::prepare(Generic {
322 registrar,
323 authorizer,
324 issuer,
325 solicitor: Vacant,
326 scopes: Vacant,
327 response: Vacant,
328 });
329
330 match flow {
331 Err(_) => unreachable!(),
332 Ok(flow) => flow,
333 }
334}
335
336/// Create an ad-hoc client credentials flow.
337///
338/// Since all necessary primitives are expected in the function syntax, this is guaranteed to never
339/// fail or panic, compared to preparing one with `ClientCredentialsFlow`.
340///
341/// But this is not as versatile and extensible, so it should be used with care. The fact that it
342/// only takes references is a conscious choice to maintain forwards portability while encouraging
343/// the transition to custom `Endpoint` implementations instead.
344pub fn client_credentials_flow<'a, W>(
345 registrar: &'a dyn Registrar, issuer: &'a mut dyn Issuer, solicitor: &'a mut dyn OwnerSolicitor<W>,
346) -> ClientCredentialsFlow<ClientCredentials<'a, W>, W>
347where
348 W: WebRequest,
349 W::Response: Default,
350{
351 let flow = ClientCredentialsFlow::prepare(Generic {
352 registrar,
353 authorizer: Vacant,
354 issuer,
355 solicitor,
356 scopes: Vacant,
357 response: Vacant,
358 });
359
360 match flow {
361 Err(_) => unreachable!(),
362 Ok(flow) => flow,
363 }
364}
365
366/// Create an ad-hoc resource flow.
367///
368/// Since all necessary primitives are expected in the function syntax, this is guaranteed to never
369/// fail or panic, compared to preparing one with `ResourceFlow`.
370///
371/// But this is not as versatile and extensible, so it should be used with care. The fact that it
372/// only takes references is a conscious choice to maintain forwards portability while encouraging
373/// the transition to custom `Endpoint` implementations instead.
374pub fn resource_flow<'a, W>(
375 issuer: &'a mut dyn Issuer, scopes: &'a [Scope],
376) -> ResourceFlow<Resource<'a>, W>
377where
378 W: WebRequest,
379 W::Response: Default,
380{
381 let flow = ResourceFlow::prepare(Generic {
382 registrar: Vacant,
383 authorizer: Vacant,
384 issuer,
385 solicitor: Vacant,
386 scopes,
387 response: Vacant,
388 });
389
390 match flow {
391 Err(_) => unreachable!(),
392 Ok(flow) => flow,
393 }
394}
395
396/// Create an ad-hoc refresh flow.
397///
398/// Since all necessary primitives are expected in the function syntax, this is guaranteed to never
399/// fail or panic, compared to preparing one with `ResourceFlow`.
400///
401/// But this is not as versatile and extensible, so it should be used with care. The fact that it
402/// only takes references is a conscious choice to maintain forwards portability while encouraging
403/// the transition to custom `Endpoint` implementations instead.
404pub fn refresh_flow<'a, W>(
405 registrar: &'a dyn Registrar, issuer: &'a mut dyn Issuer,
406) -> RefreshFlow<Refresh<'a>, W>
407where
408 W: WebRequest,
409 W::Response: Default,
410{
411 let flow = RefreshFlow::prepare(Generic {
412 registrar,
413 authorizer: Vacant,
414 issuer,
415 solicitor: Vacant,
416 scopes: Vacant,
417 response: Vacant,
418 });
419
420 match flow {
421 Err(_) => unreachable!(),
422 Ok(flow) => flow,
423 }
424}
425
426impl<R, A, I, O, C, L> Generic<R, A, I, O, C, L> {
427 /// Change the used solicitor.
428 pub fn with_solicitor<N>(self, new_solicitor: N) -> Generic<R, A, I, N, C, L> {
429 Generic {
430 registrar: self.registrar,
431 authorizer: self.authorizer,
432 issuer: self.issuer,
433 solicitor: new_solicitor,
434 scopes: self.scopes,
435 response: self.response,
436 }
437 }
438
439 /// Change the used scopes.
440 pub fn with_scopes<S>(self, new_scopes: S) -> Generic<R, A, I, O, S, L> {
441 Generic {
442 registrar: self.registrar,
443 authorizer: self.authorizer,
444 issuer: self.issuer,
445 solicitor: self.solicitor,
446 scopes: new_scopes,
447 response: self.response,
448 }
449 }
450
451 /// Create an authorization flow.
452 ///
453 /// Opposed to `AuthorizationFlow::prepare` this statically ensures that the construction
454 /// succeeds.
455 pub fn authorization_flow<W: WebRequest>(self) -> AuthorizationFlow<Self, W>
456 where
457 Self: Endpoint<W>,
458 R: Registrar,
459 A: Authorizer,
460 {
461 match AuthorizationFlow::prepare(self) {
462 Ok(flow) => flow,
463 Err(_) => unreachable!(),
464 }
465 }
466
467 /// Create an access token flow.
468 ///
469 /// Opposed to `AccessTokenFlow::prepare` this statically ensures that the construction
470 /// succeeds.
471 pub fn access_token_flow<W: WebRequest>(self) -> AccessTokenFlow<Self, W>
472 where
473 Self: Endpoint<W>,
474 R: Registrar,
475 A: Authorizer,
476 I: Issuer,
477 {
478 match AccessTokenFlow::prepare(self) {
479 Ok(flow) => flow,
480 Err(_) => unreachable!(),
481 }
482 }
483
484 /// Create a token refresh flow.
485 ///
486 /// Opposed to `RefreshFlow::prepare` this statically ensures that the construction succeeds.
487 pub fn refresh_flow<W: WebRequest>(self) -> RefreshFlow<Self, W>
488 where
489 Self: Endpoint<W>,
490 R: Registrar,
491 I: Issuer,
492 {
493 match RefreshFlow::prepare(self) {
494 Ok(flow) => flow,
495 Err(_) => unreachable!(),
496 }
497 }
498
499 /// Create a resource access flow.
500 ///
501 /// Opposed to `ResourceFlow::prepare` this statically ensures that the construction succeeds.
502 pub fn resource_flow<W: WebRequest>(self) -> ResourceFlow<Self, W>
503 where
504 Self: Endpoint<W>,
505 I: Issuer,
506 {
507 match ResourceFlow::prepare(self) {
508 Ok(flow) => flow,
509 Err(_) => unreachable!(),
510 }
511 }
512
513 /// Check, statically, that this is an endpoint for some request.
514 ///
515 /// This is mainly a utility method intended for compilation and integration tests.
516 pub fn assert<W: WebRequest>(self) -> Self
517 where
518 Self: Endpoint<W>,
519 {
520 self
521 }
522}
523
524impl<W: WebRequest> Error<W> {
525 /// Convert into a single error type.
526 ///
527 /// Note that the additional information whether the error occurred in the web components or
528 /// during the flow needs to be implicitely contained in the types. Otherwise, this information
529 /// is lost and you should use or provide a `From<Error<W>>` implementation instead. This
530 /// method is still useful for frontends providing a standard error type that interacts with
531 /// their web server library.
532 pub fn pack<P>(self) -> P
533 where
534 OAuthError: Into<P>,
535 W::Error: Into<P>,
536 {
537 match self {
538 Error::Web(err) => err.into(),
539 Error::OAuth(oauth) => oauth.into(),
540 }
541 }
542}
543
544impl<E, Error, W> Endpoint<W> for ErrorInto<E, Error>
545where
546 E: Endpoint<W>,
547 E::Error: Into<Error>,
548 W: WebRequest,
549{
550 type Error = Error;
551
552 fn registrar(&self) -> Option<&dyn Registrar> {
553 self.0.registrar()
554 }
555
556 fn authorizer_mut(&mut self) -> Option<&mut dyn Authorizer> {
557 self.0.authorizer_mut()
558 }
559
560 fn issuer_mut(&mut self) -> Option<&mut dyn Issuer> {
561 self.0.issuer_mut()
562 }
563
564 fn owner_solicitor(&mut self) -> Option<&mut dyn OwnerSolicitor<W>> {
565 self.0.owner_solicitor()
566 }
567
568 fn scopes(&mut self) -> Option<&mut dyn Scopes<W>> {
569 self.0.scopes()
570 }
571
572 fn response(&mut self, request: &mut W, kind: Template) -> Result<W::Response, Self::Error> {
573 self.0.response(request, kind).map_err(Into::into)
574 }
575
576 fn error(&mut self, err: OAuthError) -> Self::Error {
577 self.0.error(err).into()
578 }
579
580 fn web_error(&mut self, err: W::Error) -> Self::Error {
581 self.0.web_error(err).into()
582 }
583
584 fn extension(&mut self) -> Option<&mut dyn Extension> {
585 self.0.extension()
586 }
587}
588
589impl<W, R, A, I, O, C, L> Endpoint<W> for Generic<R, A, I, O, C, L>
590where
591 W: WebRequest,
592 R: OptRegistrar,
593 A: OptAuthorizer,
594 I: OptIssuer,
595 O: OwnerSolicitor<W>,
596 C: Scopes<W>,
597 L: ResponseCreator<W>,
598{
599 type Error = Error<W>;
600
601 fn registrar(&self) -> Option<&dyn Registrar> {
602 self.registrar.opt_ref()
603 }
604
605 fn authorizer_mut(&mut self) -> Option<&mut dyn Authorizer> {
606 self.authorizer.opt_mut()
607 }
608
609 fn issuer_mut(&mut self) -> Option<&mut dyn Issuer> {
610 self.issuer.opt_mut()
611 }
612
613 fn owner_solicitor(&mut self) -> Option<&mut dyn OwnerSolicitor<W>> {
614 Some(&mut self.solicitor)
615 }
616
617 fn scopes(&mut self) -> Option<&mut dyn Scopes<W>> {
618 Some(&mut self.scopes)
619 }
620
621 fn response(&mut self, request: &mut W, kind: Template) -> Result<W::Response, Self::Error> {
622 Ok(self.response.create(request, kind))
623 }
624
625 fn error(&mut self, err: OAuthError) -> Error<W> {
626 Error::OAuth(err)
627 }
628
629 fn web_error(&mut self, err: W::Error) -> Error<W> {
630 Error::Web(err)
631 }
632}
633
634impl<T: Registrar> OptRegistrar for T {
635 fn opt_ref(&self) -> Option<&dyn Registrar> {
636 Some(self)
637 }
638}
639
640impl<T: Authorizer> OptAuthorizer for T {
641 fn opt_mut(&mut self) -> Option<&mut dyn Authorizer> {
642 Some(self)
643 }
644}
645
646impl<T: Issuer> OptIssuer for T {
647 fn opt_mut(&mut self) -> Option<&mut dyn Issuer> {
648 Some(self)
649 }
650}
651
652impl OptRegistrar for Vacant {
653 fn opt_ref(&self) -> Option<&dyn Registrar> {
654 Option::None
655 }
656}
657
658impl OptAuthorizer for Vacant {
659 fn opt_mut(&mut self) -> Option<&mut dyn Authorizer> {
660 Option::None
661 }
662}
663
664impl OptIssuer for Vacant {
665 fn opt_mut(&mut self) -> Option<&mut dyn Issuer> {
666 Option::None
667 }
668}
669
670impl<W: WebRequest> OwnerSolicitor<W> for Vacant {
671 fn check_consent(&mut self, _: &mut W, _: Solicitation) -> OwnerConsent<W::Response> {
672 OwnerConsent::Denied
673 }
674}
675
676impl<W: WebRequest> Scopes<W> for Vacant {
677 fn scopes(&mut self, _: &mut W) -> &[Scope] {
678 const NO_SCOPES: [Scope; 0] = [];
679 &NO_SCOPES
680 }
681}
682
683impl<W, F> OwnerSolicitor<W> for FnSolicitor<F>
684where
685 W: WebRequest,
686 F: FnMut(&mut W, Solicitation) -> OwnerConsent<W::Response>,
687{
688 fn check_consent(
689 &mut self, request: &mut W, solicitation: Solicitation,
690 ) -> OwnerConsent<W::Response> {
691 (self.0)(request, solicitation)
692 }
693}
694
695impl<W: WebRequest> OwnerSolicitor<W> for ApprovedGrant {
696 /// Approve if the grant matches *exactly*.
697 ///
698 /// That is, `client_id`, `redirect_uri`, and `scope` of the pre-grant are all equivalent. In
699 /// particular, the requested scope must match exactly not only be a subset of the approved
700 /// scope.
701 fn check_consent(&mut self, _: &mut W, solicitation: Solicitation) -> OwnerConsent<W::Response> {
702 if &self.grant == solicitation.pre_grant() {
703 OwnerConsent::Authorized(self.owner.clone())
704 } else {
705 OwnerConsent::Denied
706 }
707 }
708}
709
710impl<W: WebRequest> ResponseCreator<W> for Vacant
711where
712 W::Response: Default,
713{
714 fn create(&mut self, _: &mut W, _: Template) -> W::Response {
715 Default::default()
716 }
717}
718
719impl<W: WebRequest, F> ResponseCreator<W> for F
720where
721 F: FnMut() -> W::Response,
722{
723 fn create(&mut self, _: &mut W, _: Template) -> W::Response {
724 self()
725 }
726}