use std::collections::HashSet;
use serde::Deserialize;
use typed_builder::TypedBuilder;
#[derive(Debug, PartialEq, Clone, Deserialize, TypedBuilder)]
pub(crate) struct TokenEntityMetadata {
#[serde(default = "default_trusted")]
#[builder(default = true)]
pub(crate) trusted: bool,
pub(crate) entity_type_name: String,
#[serde(default = "default_token_id")]
#[builder(default = default_token_id())]
pub(crate) token_id: String,
#[serde(default)]
#[builder(default)]
pub(crate) required_claims: HashSet<String>,
}
fn default_trusted() -> bool {
true
}
pub(crate) const DEFAULT_TKN_ID: &str = "jti";
fn default_token_id() -> String {
DEFAULT_TKN_ID.to_string()
}
#[cfg(test)]
impl TokenEntityMetadata {
pub(crate) fn access_token() -> Self {
Self {
trusted: true,
token_id: default_token_id(),
required_claims: HashSet::from(["iss".into(), "exp".into(), "jti".into()]),
entity_type_name: "Jans::Access_token".into(),
}
}
pub(crate) fn id_token() -> Self {
Self {
trusted: true,
token_id: default_token_id(),
required_claims: HashSet::from([
"iss".into(),
"sub".into(),
"aud".into(),
"exp".into(),
]),
entity_type_name: "Jans::Id_token".into(),
}
}
pub(crate) fn userinfo_token() -> Self {
Self {
trusted: true,
token_id: default_token_id(),
required_claims: HashSet::from([
"iss".into(),
"sub".into(),
"aud".into(),
"exp".into(),
]),
entity_type_name: "Jans::Userinfo_token".into(),
}
}
}
#[cfg(test)]
mod test {
use super::TokenEntityMetadata;
use serde_json::json;
#[test]
fn can_parse_from_json() {
let json = json!({
"entity_type_name": "Jans::Access_token",
});
let parsed = serde_json::from_value::<TokenEntityMetadata>(json)
.expect("Failed to parse an empty JSON object into TokenEntityMetadata");
assert_eq!(
parsed,
TokenEntityMetadata::builder()
.entity_type_name("Jans::Access_token".into())
.build(),
"Expected empty JSON to be parsed into default TokenEntityMetadata"
);
let json = json!({
"entity_type_name": "Jans::Access_token",
"user_id": "sub",
"role_mapping": "",
});
let parsed = serde_json::from_value::<TokenEntityMetadata>(json).expect(
"Failed to parse JSON object with user_id and role_mapping into TokenEntityMetadata",
);
assert_eq!(
parsed,
TokenEntityMetadata::builder()
.entity_type_name("Jans::Access_token".into())
.build(),
"Expected JSON with user_id and empty role_mapping to be parsed into \
TokenEntityMetadata"
);
}
#[test]
fn can_parse_from_yaml() {
let yaml = "
entity_type_name: Jans::Access_token
";
let parsed = serde_yaml_ng::from_str::<TokenEntityMetadata>(yaml)
.expect("Failed to parse an empty YAML object into TokenEntityMetadata");
assert_eq!(
parsed,
TokenEntityMetadata::builder()
.entity_type_name("Jans::Access_token".into())
.build(),
"Expected empty YAML to be parsed into default TokenEntityMetadata"
);
let yaml = "
user_id: 'sub'
role_mapping: ''
entity_type_name: Jans::Access_token
";
let parsed = serde_yaml_ng::from_str::<TokenEntityMetadata>(yaml).expect(
"Failed to parse YAML object with user_id and role_mapping into TokenEntityMetadata",
);
assert_eq!(
parsed,
TokenEntityMetadata::builder()
.entity_type_name("Jans::Access_token".into())
.build(),
"Expected YAML with user_id and empty role_mapping to be parsed into \
TokenEntityMetadata"
);
}
}