use serde::{Deserialize, Serialize};
use activitystreams_vocabulary::{field_access, impl_default};
use crate::app::oauth::{NormalizedParameter, OAuthGrantType, Scope, ScopeList};
use crate::db::Iri;
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct TokenRequest {
grant_type: OAuthGrantType,
#[serde(skip_serializing_if = "Option::is_none")]
client_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
client_secret: Option<String>,
code: String,
redirect_uri: Iri,
#[serde(skip_serializing_if = "Option::is_none")]
code_verifier: Option<String>,
}
impl TokenRequest {
pub const fn new() -> Self {
Self {
grant_type: OAuthGrantType::new(),
client_id: None,
client_secret: None,
code: String::new(),
redirect_uri: Iri::new(),
code_verifier: None,
}
}
pub fn encode_url(&self) -> String {
NormalizedParameter::from(self).to_string()
}
}
impl From<TokenRequest> for NormalizedParameter {
fn from(val: TokenRequest) -> Self {
(&val).into()
}
}
impl From<&TokenRequest> for NormalizedParameter {
fn from(val: &TokenRequest) -> Self {
let mut params = NormalizedParameter::new();
params.insert("grant_type", val.grant_type().as_str());
params.insert("code", val.code());
params.insert("redirect_uri", val.redirect_uri().as_str());
if let Some(v) = val.client_id() {
params.insert("client_id", v);
}
if let Some(v) = val.client_secret() {
params.insert("client_secret", v);
}
if let Some(v) = val.code_verifier() {
params.insert("code_verifier", v);
}
params
}
}
field_access! {
TokenRequest {
grant_type: OAuthGrantType,
}
}
field_access! {
TokenRequest {
code: as_ref { &str, String },
}
}
field_access! {
TokenRequest {
redirect_uri: as_ref { Iri },
}
}
field_access! {
TokenRequest {
client_id: option_deref { &str, String },
client_secret: option_deref { &str, String },
code_verifier: option_deref { &str, String },
}
}
impl_default!(TokenRequest);
impl std::fmt::Display for TokenRequest {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.encode_url())
}
}
#[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)]
pub struct RefreshTokenRequest {
grant_type: OAuthGrantType,
refresh_token: String,
#[serde(skip_serializing_if = "Option::is_none")]
scope: Option<ScopeList>,
}
impl RefreshTokenRequest {
pub const fn new() -> Self {
Self {
grant_type: OAuthGrantType::RefreshToken,
refresh_token: String::new(),
scope: None,
}
}
pub fn encode_url(&self) -> String {
NormalizedParameter::from(self).to_string()
}
}
impl From<RefreshTokenRequest> for NormalizedParameter {
fn from(val: RefreshTokenRequest) -> Self {
(&val).into()
}
}
impl From<&RefreshTokenRequest> for NormalizedParameter {
fn from(val: &RefreshTokenRequest) -> Self {
let mut params = NormalizedParameter::new();
params.insert("grant_type", val.grant_type().as_str());
params.insert("refresh_token", val.refresh_token());
if let Some(v) = val.scope.as_ref().map(|s| s.encode_url()) {
params.insert("scope", v);
}
params
}
}
field_access! {
RefreshTokenRequest {
grant_type: OAuthGrantType,
}
}
field_access! {
RefreshTokenRequest {
refresh_token: as_ref { &str, String },
}
}
field_access! {
RefreshTokenRequest {
scope: option_deref { &[Scope], ScopeList },
}
}
impl_default!(RefreshTokenRequest);
impl std::fmt::Display for RefreshTokenRequest {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.encode_url())
}
}