use crate::endpoint::*;
use crate::primitives::generator::TagGrant;
use crate::primitives::grant::Grant;
use std::borrow::Cow;
use std::collections::HashMap;
use url::Url;
#[derive(Clone, Debug, Default)]
struct CraftedRequest {
pub query: Option<HashMap<String, Vec<String>>>,
pub urlbody: Option<HashMap<String, Vec<String>>>,
pub auth: Option<String>,
}
#[derive(Debug, Default)]
struct CraftedResponse {
pub status: Status,
pub location: Option<Url>,
pub www_authenticate: Option<String>,
pub body: Option<Body>,
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
enum Status {
Ok,
Redirect,
BadRequest,
Unauthorized,
}
#[derive(Clone, Debug)]
enum Body {
Text(String),
Json(String),
}
#[derive(Debug)]
enum CraftedError {
Crafted,
}
impl WebRequest for CraftedRequest {
type Response = CraftedResponse;
type Error = CraftedError;
fn query(&mut self) -> Result<Cow<dyn QueryParameter + 'static>, Self::Error> {
self.query
.as_ref()
.map(|hm| Cow::Borrowed(hm as &dyn QueryParameter))
.ok_or(CraftedError::Crafted)
}
fn urlbody(&mut self) -> Result<Cow<dyn QueryParameter + 'static>, Self::Error> {
self.urlbody
.as_ref()
.map(|hm| Cow::Borrowed(hm as &dyn QueryParameter))
.ok_or(CraftedError::Crafted)
}
fn authheader(&mut self) -> Result<Option<Cow<str>>, Self::Error> {
Ok(self.auth.as_ref().map(|bearer| bearer.as_str().into()))
}
}
impl WebResponse for CraftedResponse {
type Error = CraftedError;
fn ok(&mut self) -> Result<(), Self::Error> {
self.status = Status::Ok;
self.location = None;
self.www_authenticate = None;
Ok(())
}
fn redirect(&mut self, url: Url) -> Result<(), Self::Error> {
self.status = Status::Redirect;
self.location = Some(url);
self.www_authenticate = None;
Ok(())
}
fn client_error(&mut self) -> Result<(), Self::Error> {
self.status = Status::BadRequest;
self.location = None;
self.www_authenticate = None;
Ok(())
}
fn unauthorized(&mut self, header_value: &str) -> Result<(), Self::Error> {
self.status = Status::Unauthorized;
self.location = None;
self.www_authenticate = Some(header_value.to_owned());
Ok(())
}
fn body_text(&mut self, text: &str) -> Result<(), Self::Error> {
self.body = Some(Body::Text(text.to_owned()));
Ok(())
}
fn body_json(&mut self, data: &str) -> Result<(), Self::Error> {
self.body = Some(Body::Json(data.to_owned()));
Ok(())
}
}
struct TestGenerator(String);
impl TagGrant for TestGenerator {
fn tag(&mut self, _: u64, _grant: &Grant) -> Result<String, ()> {
Ok(self.0.clone())
}
}
struct Allow(String);
struct Deny;
impl OwnerSolicitor<CraftedRequest> for Allow {
fn check_consent(
&mut self, _: &mut CraftedRequest, _: Solicitation,
) -> OwnerConsent<CraftedResponse> {
OwnerConsent::Authorized(self.0.clone())
}
}
impl OwnerSolicitor<CraftedRequest> for Deny {
fn check_consent(
&mut self, _: &mut CraftedRequest, _: Solicitation,
) -> OwnerConsent<CraftedResponse> {
OwnerConsent::Denied
}
}
impl<'l> OwnerSolicitor<CraftedRequest> for &'l Allow {
fn check_consent(
&mut self, _: &mut CraftedRequest, _: Solicitation,
) -> OwnerConsent<CraftedResponse> {
OwnerConsent::Authorized(self.0.clone())
}
}
impl<'l> OwnerSolicitor<CraftedRequest> for &'l Deny {
fn check_consent(
&mut self, _: &mut CraftedRequest, _: Solicitation,
) -> OwnerConsent<CraftedResponse> {
OwnerConsent::Denied
}
}
trait ToSingleValueQuery {
fn to_single_value_query(self) -> HashMap<String, Vec<String>>;
}
impl<'r, I, K, V> ToSingleValueQuery for I
where
I: Iterator<Item = &'r (K, V)>,
K: AsRef<str> + 'r,
V: AsRef<str> + 'r,
{
fn to_single_value_query(self) -> HashMap<String, Vec<String>> {
self.map(|&(ref k, ref v)| (k.as_ref().to_string(), vec![v.as_ref().to_string()]))
.collect()
}
}
impl Default for Status {
fn default() -> Self {
Status::Ok
}
}
pub mod defaults {
pub const EXAMPLE_CLIENT_ID: &str = "ClientId";
pub const EXAMPLE_OWNER_ID: &str = "Owner";
pub const EXAMPLE_PASSPHRASE: &str = "VGhpcyBpcyBhIHZlcnkgc2VjdXJlIHBhc3NwaHJhc2UK";
pub const EXAMPLE_REDIRECT_URI: &str = "https://client.example/endpoint";
pub const EXAMPLE_SCOPE: &str = "example default";
}
mod authorization;
mod access_token;
mod client_credentials;
mod resource;
mod refresh;
mod pkce;