oxide_auth_async/endpoint/
mod.rs

1use async_trait::async_trait;
2use oxide_auth::endpoint::{OAuthError, Template, WebRequest, OwnerConsent, Solicitation, Scopes};
3
4pub use crate::code_grant::access_token::{Extension as AccessTokenExtension};
5pub use crate::code_grant::authorization::Extension as AuthorizationExtension;
6pub use crate::code_grant::client_credentials::{Extension as ClientCredentialsExtension};
7use crate::primitives::{Authorizer, Registrar, Issuer};
8
9pub mod authorization;
10pub mod access_token;
11pub mod client_credentials;
12pub mod refresh;
13pub mod resource;
14
15pub trait Endpoint<Request>
16where
17    Request: WebRequest,
18{
19    /// The error typed used as the error representation of each flow.
20    type Error;
21
22    /// A registrar if this endpoint can access one.
23    ///
24    /// Returning `None` will implicate failing any flow that requires a registrar but does not
25    /// have any effect on flows that do not require one.
26    fn registrar(&self) -> Option<&(dyn Registrar + Sync)>;
27
28    /// An authorizer if this endpoint can access one.
29    ///
30    /// Returning `None` will implicate failing any flow that requires an authorizer but does not
31    /// have any effect on flows that do not require one.
32    fn authorizer_mut(&mut self) -> Option<&mut (dyn Authorizer + Send)>;
33
34    /// An issuer if this endpoint can access one.
35    ///
36    /// Returning `None` will implicate failing any flow that requires an issuer but does not have
37    /// any effect on flows that do not require one.
38    fn issuer_mut(&mut self) -> Option<&mut (dyn Issuer + Send)>;
39
40    /// Return the system that checks owner consent.
41    ///
42    /// Returning `None` will implicated failing the authorization code flow but does have any
43    /// effect on other flows.
44    fn owner_solicitor(&mut self) -> Option<&mut (dyn OwnerSolicitor<Request> + Send)>;
45
46    /// Determine the required scopes for a request.
47    ///
48    /// The client must fulfill any one scope, so returning an empty slice will always deny the
49    /// request.
50    fn scopes(&mut self) -> Option<&mut dyn Scopes<Request>>;
51
52    /// Generate a prototype response.
53    ///
54    /// The endpoint can rely on this being called at most once for each flow, if it wants
55    /// to preallocate the response or return a handle on an existing prototype.
56    fn response(
57        &mut self, request: &mut Request, kind: Template,
58    ) -> Result<Request::Response, Self::Error>;
59
60    /// Wrap an error.
61    fn error(&mut self, err: OAuthError) -> Self::Error;
62
63    /// Wrap an error in the request/response types.
64    fn web_error(&mut self, err: Request::Error) -> Self::Error;
65
66    /// Get the central extension instance this endpoint.
67    ///
68    /// Returning `None` is the default implementation and acts as simply providing any extensions.
69    fn extension(&mut self) -> Option<&mut (dyn Extension + Send)> {
70        None
71    }
72}
73
74pub trait Extension {
75    /// The handler for authorization code extensions.
76    fn authorization(&mut self) -> Option<&mut (dyn AuthorizationExtension + Send)> {
77        None
78    }
79
80    /// The handler for access token extensions.
81    fn access_token(&mut self) -> Option<&mut (dyn AccessTokenExtension + Send)> {
82        None
83    }
84
85    /// The handler for client credentials extensions.
86    fn client_credentials(&mut self) -> Option<&mut (dyn ClientCredentialsExtension + Send)> {
87        None
88    }
89}
90
91/// Checks consent with the owner of a resource, identified in a request.
92///
93/// See [`frontends::simple`] for an implementation that permits arbitrary functions.
94///
95/// [`frontends::simple`]: ../frontends/simple/endpoint/struct.FnSolicitor.html
96#[async_trait]
97pub trait OwnerSolicitor<Request: WebRequest> {
98    /// Ensure that a user (resource owner) is currently authenticated (for example via a session
99    /// cookie) and determine if he has agreed to the presented grants.
100    async fn check_consent(
101        &mut self, req: &mut Request, solicitation: Solicitation<'_>,
102    ) -> OwnerConsent<Request::Response>;
103}
104
105#[async_trait]
106impl<T, Request: WebRequest> OwnerSolicitor<Request> for T
107where
108    T: oxide_auth::endpoint::OwnerSolicitor<Request> + ?Sized + Send,
109    Request: Send,
110{
111    async fn check_consent(
112        &mut self, req: &mut Request, solicitation: Solicitation<'_>,
113    ) -> OwnerConsent<Request::Response> {
114        oxide_auth::endpoint::OwnerSolicitor::check_consent(self, req, solicitation)
115    }
116}