1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
use crate::endpoint::{Endpoint, Extension, OAuthError, OwnerSolicitor, Scopes, Template, WebRequest};
use crate::primitives::authorizer::Authorizer;
use crate::primitives::issuer::Issuer;
use crate::primitives::registrar::Registrar;

use super::AddonList;

/// An inner endpoint with simple extensions.
///
/// If the inner endpoint had any extension, it will simply never be provided to any flow and
/// overwritten. Therefore, this is mainly useful for other endpoints that did not implement
/// extensions by themselves such as `frontends::simple::endpoint::Generic`.
pub struct Extended<Inner, Extension> {
    /// Endpoint being extended. This field is `pub` for `oxide-auth-async` be able to implement
    /// async version of some traits.
    pub inner: Inner,

    /// Extensions of the endpoint. This field is `pub` for `oxide-auth-async` be able to implement
    /// async version of some traits.
    pub addons: Extension,
}

impl<Inner> Extended<Inner, AddonList> {
    /// Wrap an endpoint with a standard extension system.
    pub fn new(inner: Inner) -> Self {
        Extended {
            inner,
            addons: AddonList::default(),
        }
    }
}

impl<Inner, E> Extended<Inner, E> {
    /// Wrap an inner endpoint with a preconstructed extension instance.
    pub fn extend_with(inner: Inner, extension: E) -> Self {
        Extended {
            inner,
            addons: extension,
        }
    }

    /// A reference to the extension.
    pub fn extension(&self) -> &E {
        &self.addons
    }

    /// A mutable reference to the extension.
    pub fn extension_mut(&mut self) -> &mut E {
        &mut self.addons
    }
}

impl<Request, Inner, Ext> Endpoint<Request> for Extended<Inner, Ext>
where
    Request: WebRequest,
    Inner: Endpoint<Request>,
    Ext: Extension,
{
    type Error = Inner::Error;

    fn registrar(&self) -> Option<&dyn Registrar> {
        self.inner.registrar()
    }

    fn authorizer_mut(&mut self) -> Option<&mut dyn Authorizer> {
        self.inner.authorizer_mut()
    }

    fn issuer_mut(&mut self) -> Option<&mut dyn Issuer> {
        self.inner.issuer_mut()
    }

    fn owner_solicitor(&mut self) -> Option<&mut dyn OwnerSolicitor<Request>> {
        self.inner.owner_solicitor()
    }

    fn scopes(&mut self) -> Option<&mut dyn Scopes<Request>> {
        self.inner.scopes()
    }

    fn response(
        &mut self, request: &mut Request, kind: Template,
    ) -> Result<Request::Response, Self::Error> {
        self.inner.response(request, kind)
    }

    fn error(&mut self, err: OAuthError) -> Self::Error {
        self.inner.error(err)
    }

    fn web_error(&mut self, err: Request::Error) -> Self::Error {
        self.inner.web_error(err)
    }

    fn extension(&mut self) -> Option<&mut dyn Extension> {
        Some(&mut self.addons)
    }
}