use super::*;
use std::{future::Future, pin::Pin, sync::Arc};
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
#[serde(untagged)]
pub enum JwtAudience {
Single(String),
Multiple(Vec<String>),
}
impl From<String> for JwtAudience {
fn from(value: String) -> Self {
Self::Single(value)
}
}
impl From<&str> for JwtAudience {
fn from(value: &str) -> Self {
Self::Single(value.into())
}
}
impl From<Vec<String>> for JwtAudience {
fn from(value: Vec<String>) -> Self {
Self::Multiple(value)
}
}
impl JwtAudience {
pub(super) fn recipients(&self) -> Vec<&str> {
match self {
Self::Single(value) => vec![value],
Self::Multiple(values) => values.iter().map(String::as_str).collect(),
}
}
}
#[derive(Clone, Debug)]
pub enum JwtExpiration {
After(Duration),
At(serde_json::Number),
}
impl From<Duration> for JwtExpiration {
fn from(value: Duration) -> Self {
Self::After(value)
}
}
impl From<chrono::DateTime<Utc>> for JwtExpiration {
fn from(value: chrono::DateTime<Utc>) -> Self {
Self::At(value.timestamp().into())
}
}
impl From<i64> for JwtExpiration {
fn from(value: i64) -> Self {
Self::At(value.into())
}
}
impl JwtExpiration {
pub(super) fn claim(&self, issued: f64) -> Value {
match self {
Self::At(value) => Value::Number(value.clone()),
Self::After(duration) => {
let seconds =
duration.num_seconds() as f64 + f64::from(duration.subsec_nanos()) / 1e9;
let expires = issued + (seconds + 0.5).floor();
if expires.fract() == 0.0
&& (i64::MIN as f64..-(i64::MIN as f64)).contains(&expires)
{
Value::from(expires as i64)
} else {
Value::from(expires)
}
}
}
}
}
pub type JwtCallbackFuture<T> = Pin<Box<dyn Future<Output = AuthResult<T>> + Send>>;
pub type JwtDefinePayload =
Arc<dyn Fn(Value) -> JwtCallbackFuture<Map<String, Value>> + Send + Sync>;
pub type JwtGetSubject = Arc<dyn Fn(Value) -> JwtCallbackFuture<String> + Send + Sync>;
pub type JwtCustomSign =
Arc<dyn Fn(Map<String, Value>, JwtSigningOptions) -> JwtCallbackFuture<String> + Send + Sync>;
#[derive(Clone, Debug, Default)]
pub struct JwtSigningOptions {
pub key_id: Option<String>,
pub algorithm: Option<JwtAlgorithm>,
pub header: Map<String, Value>,
}
#[derive(Clone, Copy, Debug, serde::Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct JwtKeyPairConfig {
#[serde(rename = "alg")]
pub algorithm: JwtAlgorithm,
#[serde(default = "default_modulus_length")]
pub modulus_length: u32,
}
impl JwtKeyPairConfig {
pub fn new(algorithm: JwtAlgorithm) -> Self {
Self {
algorithm,
modulus_length: 2048,
}
}
}
fn default_modulus_length() -> u32 {
2048
}