cts_common/auth/claims/
aud.rs1use crate::auth::claims::common::ArrayOrValue;
2use serde::{Deserialize, Serialize};
3
4#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
8#[serde(transparent)]
9pub struct Audience(ArrayOrValue<String>);
10
11impl From<ArrayOrValue<String>> for Audience {
12 fn from(audience: ArrayOrValue<String>) -> Self {
13 Self(audience)
14 }
15}
16
17impl Audience {
18 pub fn new(audience: impl Into<String>) -> Self {
20 Self(ArrayOrValue::single(audience.into()))
21 }
22
23 pub fn add_audience(self, audience: impl Into<String>) -> Self {
25 Self(self.0.add(audience.into()))
26 }
27
28 pub fn contains(&self, audience: &str) -> bool {
29 self.0.contains(audience)
30 }
31}
32
33impl From<String> for Audience {
34 fn from(audience: String) -> Self {
35 Self::new(audience)
36 }
37}
38
39impl From<Vec<String>> for Audience {
40 fn from(audiences: Vec<String>) -> Self {
41 Self(ArrayOrValue::from_iter(audiences))
42 }
43}
44
45#[cfg(feature = "test_utils")]
46impl<T> fake::Dummy<T> for Audience {
47 fn dummy_with_rng<R: rand::Rng + ?Sized>(_: &T, _rng: &mut R) -> Self {
48 Self::new("https://console-api.stashdata.net")
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use super::*;
55 use serde_json::json;
56
57 mod single {
58 use super::*;
59
60 #[test]
61 fn serializes_as_literal() {
62 let audience = Audience::new("http://example.com");
63 let serialized = serde_json::to_value(&audience).unwrap();
64 assert_eq!(serialized, json!("http://example.com"));
65 }
66
67 #[test]
68 fn deserializes_from_literal() {
69 let audience: Audience = serde_json::from_str(r#""http://example.com""#).unwrap();
70 assert_eq!(
71 audience.0,
72 ArrayOrValue::single("http://example.com".to_string())
73 );
74 }
75 }
76
77 mod multiple {
78 use super::*;
79
80 #[test]
81 fn serializes_as_array() {
82 let target_a = "http://example.com";
83 let target_b = "http://another-example.com";
84 let audience = Audience::new(target_a).add_audience(target_b);
85 let serialized = serde_json::to_value(&audience).unwrap();
86 assert!(
87 serialized == json!([target_a, target_b])
88 || serialized == json!([target_b, target_a]),
89 "Serialized audience should be an array of two URLs, got: {serialized}"
90 );
91 }
92
93 #[test]
94 fn deserializes_from_array() {
95 let audience: Audience =
96 serde_json::from_str(r#"["http://example.com","http://another-example.com"]"#)
97 .unwrap();
98 assert_eq!(
99 audience.0,
100 ArrayOrValue::from_iter(vec![
101 "http://example.com".to_string(),
102 "http://another-example.com".to_string(),
103 ])
104 );
105 }
106 }
107}