use primitives::authorizer::Authorizer;
use primitives::issuer::Issuer;
use primitives::registrar::Registrar;
use primitives::scope::Scope;
use endpoint::{AccessTokenFlow, AuthorizationFlow, ResourceFlow, RefreshFlow};
use endpoint::{Endpoint, OAuthError, PreGrant, Template, Scopes};
use endpoint::{OwnerConsent, OwnerSolicitor};
use endpoint::WebRequest;
#[derive(Debug)]
pub enum Error<W: WebRequest> {
Web(W::Error),
OAuth(OAuthError),
}
pub struct Generic<R, A, I, S=Vacant, C=Vacant, L=Vacant> {
pub registrar: R,
pub authorizer: A,
pub issuer: I,
pub solicitor: S,
pub scopes: C,
pub response: L,
}
pub struct Vacant;
pub struct FnSolicitor<F>(pub F);
pub struct ApprovedGrant {
pub owner: String,
pub grant: PreGrant,
}
pub trait OptRegistrar {
fn opt_ref(&self) -> Option<&dyn Registrar>;
}
pub trait OptAuthorizer {
fn opt_mut(&mut self) -> Option<&mut dyn Authorizer>;
}
pub trait OptIssuer {
fn opt_mut(&mut self) -> Option<&mut dyn Issuer>;
}
pub trait ResponseCreator<W: WebRequest> {
fn create(&mut self, request: &mut W, kind: Template) -> W::Response;
}
type Authorization<'a, W> = Generic<&'a (dyn Registrar + 'a), &'a mut(dyn Authorizer + 'a), Vacant, &'a mut(dyn OwnerSolicitor<W> + 'a), Vacant, Vacant>;
type AccessToken<'a> = Generic<&'a (dyn Registrar + 'a), &'a mut(dyn Authorizer + 'a), &'a mut(dyn Issuer + 'a), Vacant, Vacant, Vacant>;
type Refresh<'a> = Generic<&'a (dyn Registrar + 'a), Vacant, &'a mut(dyn Issuer + 'a), Vacant, Vacant, Vacant>;
type Resource<'a> = Generic<Vacant, Vacant, &'a mut (dyn Issuer + 'a), Vacant, &'a [Scope], Vacant>;
pub fn authorization_flow<'a, W>(registrar: &'a dyn Registrar, authorizer: &'a mut dyn Authorizer, solicitor: &'a mut dyn OwnerSolicitor<W>)
-> AuthorizationFlow<Authorization<'a, W>, W>
where W: WebRequest, W::Response: Default
{
let flow = AuthorizationFlow::prepare(Generic {
registrar,
authorizer,
issuer: Vacant,
solicitor,
scopes: Vacant,
response: Vacant,
});
match flow {
Err(_) => unreachable!(),
Ok(flow) => flow,
}
}
pub fn access_token_flow<'a, W>(registrar: &'a dyn Registrar, authorizer: &'a mut dyn Authorizer, issuer: &'a mut dyn Issuer)
-> AccessTokenFlow<AccessToken<'a>, W>
where W: WebRequest, W::Response: Default
{
let flow = AccessTokenFlow::prepare(Generic {
registrar,
authorizer,
issuer,
solicitor: Vacant,
scopes: Vacant,
response: Vacant,
});
match flow {
Err(_) => unreachable!(),
Ok(flow) => flow,
}
}
pub fn resource_flow<'a, W>(issuer: &'a mut dyn Issuer, scopes: &'a [Scope])
-> ResourceFlow<Resource<'a>, W>
where W: WebRequest, W::Response: Default
{
let flow = ResourceFlow::prepare(Generic {
registrar: Vacant,
authorizer: Vacant,
issuer,
solicitor: Vacant,
scopes,
response: Vacant,
});
match flow {
Err(_) => unreachable!(),
Ok(flow) => flow,
}
}
pub fn refresh_flow<'a, W>(registrar: &'a dyn Registrar, issuer: &'a mut dyn Issuer)
-> RefreshFlow<Refresh<'a>, W> where W: WebRequest, W::Response: Default
{
let flow = RefreshFlow::prepare(Generic {
registrar,
authorizer: Vacant,
issuer,
solicitor: Vacant,
scopes: Vacant,
response: Vacant,
});
match flow {
Err(_) => unreachable!(),
Ok(flow) => flow,
}
}
impl<R, A, I, O, C, L> Generic<R, A, I, O, C, L> {
pub fn with_solicitor<N>(self, new_solicitor: N) -> Generic<R, A, I, N, C, L> {
Generic {
registrar: self.registrar,
authorizer: self.authorizer,
issuer: self.issuer,
solicitor: new_solicitor,
scopes: self.scopes,
response: self.response,
}
}
pub fn with_scopes<S>(self, new_scopes: S) -> Generic<R, A, I, O, S, L> {
Generic {
registrar: self.registrar,
authorizer: self.authorizer,
issuer: self.issuer,
solicitor: self.solicitor,
scopes: new_scopes,
response: self.response,
}
}
pub fn to_authorization<W: WebRequest>(self) -> AuthorizationFlow<Self, W>
where
Self: Endpoint<W>,
R: Registrar,
A: Authorizer,
{
match AuthorizationFlow::prepare(self) {
Ok(flow) => flow,
Err(_) => unreachable!(),
}
}
pub fn to_access_token<W: WebRequest>(self) -> AccessTokenFlow<Self, W>
where
Self: Endpoint<W>,
R: Registrar,
A: Authorizer,
I: Issuer,
{
match AccessTokenFlow::prepare(self) {
Ok(flow) => flow,
Err(_) => unreachable!(),
}
}
pub fn to_refresh<W: WebRequest>(self) -> RefreshFlow<Self, W>
where
Self: Endpoint<W>,
R: Registrar,
I: Issuer,
{
match RefreshFlow::prepare(self) {
Ok(flow) => flow,
Err(_) => unreachable!(),
}
}
pub fn to_resource<W: WebRequest>(self) -> ResourceFlow<Self, W>
where
Self: Endpoint<W>,
I: Issuer,
{
match ResourceFlow::prepare(self) {
Ok(flow) => flow,
Err(_) => unreachable!(),
}
}
pub fn assert<W: WebRequest>(self) -> Self where Self: Endpoint<W> {
self
}
}
impl<W: WebRequest> Error<W> {
pub fn pack<P>(self) -> P
where OAuthError: Into<P>, W::Error: Into<P>,
{
match self {
Error::Web(err) => err.into(),
Error::OAuth(oauth) => oauth.into(),
}
}
}
impl<W, R, A, I, O, C, L> Endpoint<W> for Generic<R, A, I, O, C, L>
where
W: WebRequest,
R: OptRegistrar,
A: OptAuthorizer,
I: OptIssuer,
O: OwnerSolicitor<W>,
C: Scopes<W>,
L: ResponseCreator<W>,
{
type Error = Error<W>;
fn registrar(&self) -> Option<&dyn Registrar> {
self.registrar.opt_ref()
}
fn authorizer_mut(&mut self) -> Option<&mut dyn Authorizer> {
self.authorizer.opt_mut()
}
fn issuer_mut(&mut self) -> Option<&mut dyn Issuer> {
self.issuer.opt_mut()
}
fn owner_solicitor(&mut self) -> Option<&mut dyn OwnerSolicitor<W>> {
Some(&mut self.solicitor)
}
fn scopes(&mut self) -> Option<&mut dyn Scopes<W>> {
Some(&mut self.scopes)
}
fn response(&mut self, request: &mut W, kind: Template) -> Result<W::Response, Self::Error> {
Ok(self.response.create(request, kind))
}
fn error(&mut self, err: OAuthError) -> Error<W> {
Error::OAuth(err)
}
fn web_error(&mut self, err: W::Error) -> Error<W> {
Error::Web(err)
}
}
impl<T: Registrar> OptRegistrar for T {
fn opt_ref(&self) -> Option<&dyn Registrar> {
Some(self)
}
}
impl<T: Authorizer> OptAuthorizer for T {
fn opt_mut(&mut self) -> Option<&mut dyn Authorizer> {
Some(self)
}
}
impl<T: Issuer> OptIssuer for T {
fn opt_mut(&mut self) -> Option<&mut dyn Issuer> {
Some(self)
}
}
impl OptRegistrar for Vacant {
fn opt_ref(&self) -> Option<&dyn Registrar> {
Option::None
}
}
impl OptAuthorizer for Vacant {
fn opt_mut(&mut self) -> Option<&mut dyn Authorizer> {
Option::None
}
}
impl OptIssuer for Vacant {
fn opt_mut(&mut self) -> Option<&mut dyn Issuer> {
Option::None
}
}
impl<W: WebRequest> OwnerSolicitor<W> for Vacant {
fn check_consent(&mut self, _: &mut W, _: &PreGrant) -> OwnerConsent<W::Response> {
OwnerConsent::Denied
}
}
impl<W: WebRequest> Scopes<W> for Vacant {
fn scopes(&mut self, _: &mut W) -> &[Scope] {
const NO_SCOPES: [Scope; 0] = [];
&NO_SCOPES
}
}
impl<W, F> OwnerSolicitor<W> for FnSolicitor<F>
where
W: WebRequest,
F: FnMut(&mut W, &PreGrant) -> OwnerConsent<W::Response>
{
fn check_consent(&mut self, request: &mut W, grant: &PreGrant)
-> OwnerConsent<W::Response>
{
(self.0)(request, grant)
}
}
impl<W: WebRequest> OwnerSolicitor<W> for ApprovedGrant {
fn check_consent(&mut self, _: &mut W, grant: &PreGrant) -> OwnerConsent<W::Response> {
if &self.grant == grant {
OwnerConsent::Authorized(self.owner.clone())
} else {
OwnerConsent::Denied
}
}
}
impl<W: WebRequest> ResponseCreator<W> for Vacant where W::Response: Default {
fn create(&mut self, _: &mut W, _: Template) -> W::Response {
Default::default()
}
}
impl<W: WebRequest, F> ResponseCreator<W> for F where F: FnMut() -> W::Response {
fn create(&mut self, _: &mut W, _: Template) -> W::Response {
self()
}
}