use crate::common::{issuer_utils::IssClaim, policy_store::TrustedIssuer};
use serde::Deserialize;
use serde_json::Value;
use std::{collections::HashMap, sync::Arc};
#[derive(Debug, PartialEq, Clone)]
pub(crate) struct Token {
pub name: String,
pub iss: Option<Arc<TrustedIssuer>>,
pub(crate) claims: TokenClaims,
}
impl Token {
pub(crate) fn new(name: &str, claims: TokenClaims, iss: Option<Arc<TrustedIssuer>>) -> Token {
Self {
name: name.to_string(),
iss,
claims,
}
}
pub(crate) fn get_claim(&self, name: &str) -> Option<TokenClaim<'_>> {
self.claims.get_claim(name)
}
pub(crate) fn get_claim_val(&self, name: &str) -> Option<&Value> {
self.claims.claims.get(name)
}
pub(crate) fn logging_info(&self, claim: &str) -> HashMap<String, serde_json::Value> {
self.claims.logging_info(claim)
}
pub(crate) fn claims_value(&self) -> &HashMap<String, Value> {
&self.claims.claims
}
pub(crate) fn extract_normalized_issuer(&self) -> Option<IssClaim> {
if let Some(trusted_issuer) = &self.iss {
return Some(trusted_issuer.iss_claim());
}
self.claims
.get_claim("iss")
.and_then(|claim| claim.value().as_str().map(IssClaim::new))
}
}
#[derive(Debug, PartialEq, Default, Deserialize, Clone)]
pub(crate) struct TokenClaims {
#[serde(flatten)]
claims: HashMap<String, Value>,
}
impl From<HashMap<String, Value>> for TokenClaims {
fn from(claims: HashMap<String, Value>) -> Self {
Self { claims }
}
}
impl TryFrom<Value> for TokenClaims {
type Error = &'static str;
fn try_from(claims: Value) -> Result<Self, Self::Error> {
match claims {
Value::Object(map) => Ok(Self {
claims: map.into_iter().collect(),
}),
_ => Err("expected a JSON object for TokenClaims"),
}
}
}
impl TokenClaims {
pub(crate) fn get_claim(&self, name: &str) -> Option<TokenClaim<'_>> {
self.claims.get(name).map(|value| TokenClaim { value })
}
pub(crate) fn logging_info(&self, claim: &str) -> HashMap<String, serde_json::Value> {
let claim = if claim.is_empty() { "jti" } else { claim };
self.claims
.get(claim)
.map(|value| HashMap::from([(claim.to_string(), value.clone())]))
.unwrap_or_default()
}
}
pub(crate) struct TokenClaim<'a> {
value: &'a serde_json::Value,
}
impl TokenClaim<'_> {
pub(crate) fn value(&self) -> &Value {
self.value
}
}