use std::fmt;
use serde::Serialize;
use serde::de::{self, Deserialize, Deserializer, Visitor};
#[derive(Debug, Clone, PartialEq, Eq, Hash, derive_more::Display)]
pub(crate) struct IssClaim(String);
impl IssClaim {
pub(crate) fn new(issuer: &str) -> Self {
Self(normalize_issuer(issuer))
}
pub(crate) fn as_str(&self) -> &str {
&self.0
}
}
impl<'de> Deserialize<'de> for IssClaim {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct IssClaimVisitor;
impl Visitor<'_> for IssClaimVisitor {
type Value = IssClaim;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string representing an issuer claim")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(IssClaim::new(value))
}
fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
where
E: de::Error,
{
Ok(IssClaim::new(&value))
}
}
deserializer.deserialize_string(IssClaimVisitor)
}
}
impl Serialize for IssClaim {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_str(&self.0)
}
}
fn normalize_issuer(issuer: &str) -> String {
if let Ok(url) = url::Url::parse(issuer) {
url.to_string().trim_end_matches('/').to_string()
} else {
issuer.trim_end_matches('/').to_string()
}
}
#[cfg(test)]
mod tests {
use super::*;
use test_utils::assert_eq;
#[test]
fn test_normalize_issuer() {
assert_eq!(
normalize_issuer("https://DEV-1e737fn2gji0j3fe.us.auth0.com/"),
"https://dev-1e737fn2gji0j3fe.us.auth0.com"
);
assert_eq!(
normalize_issuer("https://dev-1e737fn2gji0j3fe.us.auth0.com/"),
"https://dev-1e737fn2gji0j3fe.us.auth0.com"
);
assert_eq!(
normalize_issuer("https://dev-1e737fn2gji0j3fe.us.auth0.com"),
"https://dev-1e737fn2gji0j3fe.us.auth0.com"
);
assert_eq!(
normalize_issuer("https://example.com///"),
"https://example.com"
);
assert_eq!(normalize_issuer("test///"), "test");
assert_eq!(normalize_issuer("test"), "test");
assert_eq!(normalize_issuer(""), "");
assert_eq!(normalize_issuer("/"), "");
assert_eq!(normalize_issuer("///"), "");
assert_eq!(
normalize_issuer("https://example.com"),
"https://example.com"
);
assert_eq!(
normalize_issuer("https://example.com/"),
"https://example.com"
);
assert_eq!(
normalize_issuer("https://example.com/path"),
"https://example.com/path"
);
assert_eq!(
normalize_issuer("https://example.com/path/"),
"https://example.com/path"
);
}
}