use http::Method;
use serde::{Deserialize, Serialize};
use crate::{api, auth::Unauthenticated, query::DefaultModel, BodyError, Endpoint};
#[derive(Clone, Eq, Ord, Hash, PartialEq, PartialOrd, Serialize)]
#[serde(tag = "grant_type", rename_all = "snake_case")]
pub enum Token {
Password {
#[serde(rename = "username")]
mail: String,
password: String,
},
ClientCredentials {
client_id: String,
client_secret: String,
},
}
impl Token {
pub fn password<U, P>(mail: U, password: P) -> Self
where
U: Into<String>,
P: Into<String>,
{
Self::Password {
mail: mail.into(),
password: password.into(),
}
}
pub fn client_credentials<U, P>(id: U, secret: P) -> Self
where
U: Into<String>,
P: Into<String>,
{
Self::ClientCredentials {
client_id: id.into(),
client_secret: secret.into(),
}
}
}
impl std::fmt::Debug for Token {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
Self::Password { mail, .. } => f
.debug_struct("Password")
.field("mail", mail)
.field("password", &"***")
.finish(),
Self::ClientCredentials { client_id, .. } => f
.debug_struct("ClientCredentials")
.field("cliend_id", client_id)
.field("client_secret", &"***")
.finish(),
}
}
}
impl Endpoint for Token {
fn method(&self) -> http::Method {
Method::POST
}
fn endpoint(&self) -> std::borrow::Cow<'static, str> {
"auth/token".into()
}
fn body(&self) -> Result<Option<(&'static str, Vec<u8>)>, BodyError> {
Ok(Some((
api::mime_types::JSON,
serde_json::to_string(self)?.into_bytes(),
)))
}
type AccessControl = Unauthenticated;
}
impl DefaultModel for Token {
type Model = AccessToken;
fn map(data: serde_json::Value) -> Result<Self::Model, serde_json::Error> {
serde_json::from_value(data)
}
}
#[derive(Clone, Debug, Deserialize, Hash, Eq, Ord, PartialEq, PartialOrd)]
pub struct AccessToken {
pub access_token: api::AccessToken,
pub expires_in: String,
pub token_type: String,
}