mod authorization;
mod accesstoken;
mod error;
mod refresh;
mod resource;
mod query;
#[cfg(test)]
mod tests;
use std::borrow::Cow;
use std::marker::PhantomData;
pub use primitives::authorizer::Authorizer;
pub use primitives::issuer::Issuer;
pub use primitives::registrar::Registrar;
pub use primitives::scope::Scope;
use code_grant::resource::{Error as ResourceError};
use code_grant::error::{AuthorizationError, AccessTokenError};
use url::Url;
pub use code_grant::authorization::Extension as AuthorizationExtension;
pub use code_grant::accesstoken::Extension as AccessTokenExtension;
pub use primitives::registrar::PreGrant;
pub use self::authorization::*;
pub use self::accesstoken::*;
pub use self::error::OAuthError;
pub use self::refresh::RefreshFlow;
pub use self::resource::*;
pub use self::query::*;
pub enum OwnerConsent<Response: WebResponse> {
Denied,
InProgress(Response),
Authorized(String),
Error(Response::Error),
}
#[derive(Debug)]
pub struct Template<'a> {
inner: InnerTemplate<'a>,
}
#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum ResponseStatus {
Unauthorized,
Redirect,
BadRequest,
Ok,
}
#[derive(Debug)]
enum InnerTemplate<'a> {
Unauthorized {
error: Option<ResourceError>,
access_token_error: Option<&'a mut AccessTokenError>,
},
Redirect {
authorization_error: Option<&'a mut AuthorizationError>,
},
BadRequest {
access_token_error: Option<&'a mut AccessTokenError>,
},
Ok,
}
pub trait OwnerSolicitor<Request: WebRequest> {
fn check_consent(&mut self, &mut Request, pre_grant: &PreGrant) -> OwnerConsent<Request::Response>;
}
pub trait Scopes<Request: WebRequest> {
fn scopes(&mut self, request: &mut Request) -> &[Scope];
}
pub trait WebRequest {
type Error;
type Response: WebResponse<Error=Self::Error>;
fn query(&mut self) -> Result<Cow<dyn QueryParameter + 'static>, Self::Error>;
fn urlbody(&mut self) -> Result<Cow<dyn QueryParameter + 'static>, Self::Error>;
fn authheader(&mut self) -> Result<Option<Cow<str>>, Self::Error>;
}
pub trait WebResponse {
type Error;
fn ok(&mut self) -> Result<(), Self::Error>;
fn redirect(&mut self, url: Url) -> Result<(), Self::Error>;
fn client_error(&mut self) -> Result<(), Self::Error>;
fn unauthorized(&mut self, header_value: &str) -> Result<(), Self::Error>;
fn body_text(&mut self, text: &str) -> Result<(), Self::Error>;
fn body_json(&mut self, data: &str) -> Result<(), Self::Error>;
}
pub trait Extension {
fn authorization(&mut self) -> Option<&mut dyn AuthorizationExtension> {
None
}
fn access_token(&mut self) -> Option<&mut dyn AccessTokenExtension> {
None
}
}
pub trait Endpoint<Request: WebRequest> {
type Error;
fn registrar(&self) -> Option<&dyn Registrar>;
fn authorizer_mut(&mut self) -> Option<&mut dyn Authorizer>;
fn issuer_mut(&mut self) -> Option<&mut dyn Issuer>;
fn owner_solicitor(&mut self) -> Option<&mut dyn OwnerSolicitor<Request>>;
fn scopes(&mut self) -> Option<&mut dyn Scopes<Request>>;
fn response(&mut self, request: &mut Request, kind: Template)
-> Result<Request::Response, Self::Error>;
fn error(&mut self, err: OAuthError) -> Self::Error;
fn web_error(&mut self, err: Request::Error) -> Self::Error;
fn extension(&mut self) -> Option<&mut dyn Extension> {
None
}
}
impl<'a> Template<'a> {
pub fn status(&self) -> ResponseStatus {
match self.inner {
InnerTemplate::Unauthorized { .. } => ResponseStatus::Unauthorized,
InnerTemplate::Redirect {.. } => ResponseStatus::Redirect,
InnerTemplate::BadRequest {.. } => ResponseStatus::BadRequest,
InnerTemplate::Ok => ResponseStatus::Ok,
}
}
pub fn authorization_error(&mut self) -> Option<&mut AuthorizationError> {
match &mut self.inner {
InnerTemplate::Redirect { authorization_error, .. } => reborrow(authorization_error),
_ => None,
}
}
pub fn access_token_error(&mut self) -> Option<&mut AccessTokenError> {
match &mut self.inner {
InnerTemplate::Unauthorized { access_token_error, .. } => reborrow(access_token_error),
InnerTemplate::BadRequest { access_token_error, .. } => reborrow(access_token_error),
_ => None,
}
}
}
fn reborrow<'a, T>(opt: &'a mut Option<&mut T>) -> Option<&'a mut T> {
match opt {
Some(inner) => Some(inner),
None => None,
}
}
impl<'a, W: WebRequest> WebRequest for &'a mut W {
type Error = W::Error;
type Response = W::Response;
fn query(&mut self) -> Result<Cow<dyn QueryParameter + 'static>, Self::Error> {
(**self).query()
}
fn urlbody(&mut self) -> Result<Cow<dyn QueryParameter + 'static>, Self::Error> {
(**self).urlbody()
}
fn authheader(&mut self) -> Result<Option<Cow<str>>, Self::Error> {
(**self).authheader()
}
}
impl<'a, R: WebRequest, E: Endpoint<R>> Endpoint<R> for &'a mut E {
type Error = E::Error;
fn registrar(&self) -> Option<&dyn Registrar> {
(**self).registrar()
}
fn authorizer_mut(&mut self) -> Option<&mut dyn Authorizer> {
(**self).authorizer_mut()
}
fn issuer_mut(&mut self) -> Option<&mut dyn Issuer> {
(**self).issuer_mut()
}
fn owner_solicitor(&mut self) -> Option<&mut dyn OwnerSolicitor<R>> {
(**self).owner_solicitor()
}
fn scopes(&mut self) -> Option<&mut dyn Scopes<R>> {
(**self).scopes()
}
fn response(&mut self, request: &mut R, kind: Template) -> Result<R::Response, Self::Error> {
(**self).response(request, kind)
}
fn error(&mut self, err: OAuthError) -> Self::Error {
(**self).error(err)
}
fn web_error(&mut self, err: R::Error) -> Self::Error {
(**self).web_error(err)
}
fn extension(&mut self) -> Option<&mut dyn Extension> {
(**self).extension()
}
}
impl<'a, R: WebRequest, E: Endpoint<R> + 'a> Endpoint<R> for Box<E> {
type Error = E::Error;
fn registrar(&self) -> Option<&dyn Registrar> {
(**self).registrar()
}
fn authorizer_mut(&mut self) -> Option<&mut dyn Authorizer> {
(**self).authorizer_mut()
}
fn issuer_mut(&mut self) -> Option<&mut dyn Issuer> {
(**self).issuer_mut()
}
fn owner_solicitor(&mut self) -> Option<&mut dyn OwnerSolicitor<R>> {
(**self).owner_solicitor()
}
fn scopes(&mut self) -> Option<&mut dyn Scopes<R>> {
(**self).scopes()
}
fn response(&mut self, request: &mut R, kind: Template) -> Result<R::Response, Self::Error> {
(**self).response(request, kind)
}
fn error(&mut self, err: OAuthError) -> Self::Error {
(**self).error(err)
}
fn web_error(&mut self, err: R::Error) -> Self::Error {
(**self).web_error(err)
}
fn extension(&mut self) -> Option<&mut dyn Extension> {
(**self).extension()
}
}
impl Extension for () { }
impl<'a, W: WebRequest, S: OwnerSolicitor<W> + 'a + ?Sized> OwnerSolicitor<W> for &'a mut S {
fn check_consent(&mut self, request: &mut W, pre: &PreGrant) -> OwnerConsent<W::Response> {
(**self).check_consent(request, pre)
}
}
impl<'a, W: WebRequest, S: OwnerSolicitor<W> + 'a + ?Sized> OwnerSolicitor<W> for Box<S> {
fn check_consent(&mut self, request: &mut W, pre: &PreGrant) -> OwnerConsent<W::Response> {
(**self).check_consent(request, pre)
}
}
impl<W: WebRequest> Scopes<W> for [Scope] {
fn scopes(&mut self, _: &mut W) -> &[Scope] {
self
}
}
impl<W: WebRequest> Scopes<W> for Vec<Scope> {
fn scopes(&mut self, _: &mut W) -> &[Scope] {
self.as_slice()
}
}
impl<'a, W: WebRequest> Scopes<W> for &'a [Scope] {
fn scopes(&mut self, _: &mut W) -> &[Scope] {
self
}
}
impl<'a, W: WebRequest, S: Scopes<W> + 'a + ?Sized> Scopes<W> for &'a mut S {
fn scopes(&mut self, request: &mut W) -> &[Scope] {
(**self).scopes(request)
}
}
impl<'a, W: WebRequest, S: Scopes<W> + 'a + ?Sized> Scopes<W> for Box<S> {
fn scopes(&mut self, request: &mut W) -> &[Scope] {
(**self).scopes(request)
}
}
impl<'a> From<InnerTemplate<'a>> for Template<'a> {
fn from(inner: InnerTemplate<'a>) -> Self {
Template { inner }
}
}