#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::string::String;
#[cfg(feature = "std")]
use std::string::String;
#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::vec::Vec;
#[cfg(feature = "std")]
use std::vec::Vec;
use crate::{time::DurationSinceEpoch, TeamId};
use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
pub struct KeyId<'a>(pub &'a str);
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[non_exhaustive]
pub enum Algorithm {
Es256,
Rs256,
}
impl Algorithm {
fn as_str(&self) -> &str {
match self {
Algorithm::Es256 => "ES256",
Algorithm::Rs256 => "RS256",
}
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
#[non_exhaustive]
pub enum KeyData<'a> {
Pkcs8(&'a [u8]),
Jwk(&'a Jwk),
}
pub struct Key<'a> {
id: &'a KeyId<'a>,
alg: Algorithm,
data: &'a KeyData<'a>,
}
impl<'a> Key<'a> {
pub fn new(id: &'a KeyId<'a>, alg: Algorithm, data: &'a KeyData<'a>) -> Self {
Key { id, alg, data }
}
pub fn id(&self) -> &KeyId {
self.id
}
pub fn alg(&self) -> Algorithm {
self.alg
}
pub fn data(&self) -> &KeyData {
self.data
}
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct Header<'a> {
alg: &'a str,
kid: &'a str,
}
impl<'a> Header<'a> {
pub fn new(key: &'a Key<'a>) -> Self {
Header {
alg: key.alg.as_str(),
kid: key.id.0,
}
}
pub fn alg(&self) -> &str {
self.alg
}
pub fn kid(&self) -> &str {
self.kid
}
}
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize)]
pub struct Claims<'a> {
pub iss: &'a str,
pub iat: u64,
#[serde(skip_serializing_if = "Option::is_none")]
pub exp: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub aud: Option<&'a str>,
#[serde(skip_serializing_if = "Option::is_none")]
pub sub: Option<&'a str>,
}
impl<'a> Claims<'a> {
pub fn new<T>(team_id: &'a TeamId, duration_since_epoch: T) -> Self
where
T: DurationSinceEpoch,
{
Claims {
iss: team_id.0,
iat: duration_since_epoch.as_secs(),
exp: None,
aud: None,
sub: None,
}
}
pub fn iss(&self) -> &str {
self.iss
}
pub fn iat(&self) -> u64 {
self.iat
}
pub fn exp(&self) -> Option<u64> {
self.exp
}
pub fn aud(&self) -> Option<&str> {
self.aud
}
pub fn sub(&self) -> Option<&str> {
self.sub
}
}
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
#[cfg(any(feature = "alloc", feature = "std"))]
pub struct Jwk {
pub kty: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub r#use: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub alg: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub kid: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub crv: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub x: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub y: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub e: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub n: Option<String>,
}
#[derive(Clone, Debug, Eq, Hash, PartialEq, Serialize, Deserialize)]
#[cfg(any(feature = "alloc", feature = "std"))]
pub struct JwkSet {
pub keys: Vec<Jwk>,
}