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}