Skip to main content

saml_rs/model/
subject.rs

1use crate::config::NameIdFormat;
2
3/// NameID value and optional format.
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub struct NameId {
6    value: String,
7    format: Option<NameIdFormat>,
8}
9
10impl NameId {
11    /// Create a NameID value.
12    pub fn new(value: impl Into<String>, format: Option<NameIdFormat>) -> Self {
13        Self {
14            value: value.into(),
15            format,
16        }
17    }
18
19    /// Borrow the NameID text.
20    pub fn value(&self) -> &str {
21        &self.value
22    }
23
24    /// NameID format, when extracted.
25    pub fn format(&self) -> Option<&NameIdFormat> {
26        self.format.as_ref()
27    }
28}
29
30/// AuthnRequest NameIDPolicy.
31#[derive(Debug, Clone, PartialEq, Eq)]
32pub struct NameIdPolicy {
33    format: Option<NameIdFormat>,
34    creation_request: NameIdCreationRequest,
35}
36
37/// AuthnRequest NameID creation request.
38#[derive(Debug, Clone, Copy, PartialEq, Eq)]
39pub enum NameIdCreationRequest {
40    /// The request did not specify whether the IdP may create a new identifier.
41    Unspecified,
42    /// The IdP may create a new identifier.
43    AllowCreate,
44    /// The IdP must not create a new identifier.
45    DoNotAllowCreate,
46}
47
48impl NameIdPolicy {
49    /// Create a NameIDPolicy model.
50    pub fn new(format: Option<NameIdFormat>, creation_request: NameIdCreationRequest) -> Self {
51        Self {
52            format,
53            creation_request,
54        }
55    }
56
57    /// Create a NameIDPolicy without an AllowCreate preference.
58    pub fn unspecified(format: Option<NameIdFormat>) -> Self {
59        Self::new(format, NameIdCreationRequest::Unspecified)
60    }
61
62    /// Create a NameIDPolicy allowing the IdP to create a new identifier.
63    pub fn allow_creation(format: Option<NameIdFormat>) -> Self {
64        Self::new(format, NameIdCreationRequest::AllowCreate)
65    }
66
67    /// Create a NameIDPolicy forbidding the IdP from creating a new identifier.
68    pub fn disallow_creation(format: Option<NameIdFormat>) -> Self {
69        Self::new(format, NameIdCreationRequest::DoNotAllowCreate)
70    }
71
72    pub(crate) fn from_parsed(
73        format: Option<NameIdFormat>,
74        allow_create: Option<bool>,
75    ) -> Option<Self> {
76        if format.is_none() && allow_create.is_none() {
77            return None;
78        }
79        Some(match allow_create {
80            Some(true) => Self::allow_creation(format),
81            Some(false) => Self::disallow_creation(format),
82            None => Self::unspecified(format),
83        })
84    }
85
86    /// Requested NameID format.
87    pub fn format(&self) -> Option<&NameIdFormat> {
88        self.format.as_ref()
89    }
90
91    /// NameID creation request.
92    pub fn creation_request(&self) -> NameIdCreationRequest {
93        self.creation_request
94    }
95
96    /// Whether the IdP may create a new identifier.
97    pub fn allow_create(&self) -> Option<bool> {
98        match self.creation_request {
99            NameIdCreationRequest::Unspecified => None,
100            NameIdCreationRequest::AllowCreate => Some(true),
101            NameIdCreationRequest::DoNotAllowCreate => Some(false),
102        }
103    }
104}
105
106/// SubjectConfirmation captured from the validated flow result.
107#[derive(Debug, Clone, PartialEq, Eq)]
108pub struct SubjectConfirmation {
109    raw_xml: String,
110}
111
112impl SubjectConfirmation {
113    /// Create a subject confirmation from extractor context XML.
114    pub fn from_raw_xml(raw_xml: impl Into<String>) -> Self {
115        Self {
116            raw_xml: raw_xml.into(),
117        }
118    }
119
120    /// Borrow the raw confirmation XML captured by the extractor.
121    pub fn raw_xml(&self) -> &str {
122        &self.raw_xml
123    }
124}
125
126/// SAML subject.
127#[derive(Debug, Clone, PartialEq, Eq)]
128pub struct Subject {
129    name_id: NameId,
130    confirmations: Vec<SubjectConfirmation>,
131}
132
133impl Subject {
134    /// Create a subject.
135    pub fn new(name_id: NameId, confirmations: Vec<SubjectConfirmation>) -> Self {
136        Self {
137            name_id,
138            confirmations,
139        }
140    }
141
142    /// Subject NameID.
143    pub fn name_id(&self) -> &NameId {
144        &self.name_id
145    }
146
147    /// Subject confirmations.
148    pub fn confirmations(&self) -> &[SubjectConfirmation] {
149        &self.confirmations
150    }
151}