Skip to content
This repository was archived by the owner on Aug 15, 2025. It is now read-only.

Commit 214989c

Browse files
committed
feat: impl Constrained for DomainName and PDN
1 parent 5e1d89c commit 214989c

File tree

3 files changed

+95
-0
lines changed

3 files changed

+95
-0
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// This Source Code Form is subject to the terms of the Mozilla Public
2+
// License, v. 2.0. If a copy of the MPL was not distributed with this
3+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4+
5+
use regex::Regex;
6+
7+
use crate::types::{DomainName, REGEX_DOMAIN_NAME};
8+
9+
use super::*;
10+
11+
impl Constrained for DomainName {
12+
fn validate(&self, _target: Option<Target>) -> Result<(), ConstraintError> {
13+
if self.value.trim().is_empty() {
14+
return Err(ConstraintError::Malformed(Some(
15+
"HomeServerDN must have a non-empty domain name".to_string(),
16+
)));
17+
}
18+
#[allow(clippy::unwrap_used)]
19+
let regex = Regex::new(REGEX_DOMAIN_NAME).unwrap();
20+
if regex.is_match(&self.value) {
21+
Ok(())
22+
} else {
23+
Err(ConstraintError::Malformed(Some(String::from(
24+
"Supplied domain name does not match regex",
25+
))))
26+
}
27+
}
28+
}

src/constraints/types/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
// License, v. 2.0. If a copy of the MPL was not distributed with this
33
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
44

5+
mod domain_name;
56
mod federation_id;
67
mod local_name;
8+
mod pdn;
79
mod rawr;
810
mod service;
911

src/constraints/types/pdn.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// This Source Code Form is subject to the terms of the Mozilla Public
2+
// License, v. 2.0. If a copy of the MPL was not distributed with this
3+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4+
5+
use crate::types::pdn::{ActorDN, HomeServerDN, PolyprotoDistinguishedName};
6+
7+
use super::*;
8+
9+
impl Constrained for PolyprotoDistinguishedName {
10+
fn validate(&self, target: Option<Target>) -> Result<(), ConstraintError> {
11+
match (self, target) {
12+
(PolyprotoDistinguishedName::ActorDn(actor_dn), Some(Target::Actor))
13+
| (PolyprotoDistinguishedName::ActorDn(actor_dn), None) => actor_dn.validate(target),
14+
(
15+
PolyprotoDistinguishedName::HomeServerDn(home_server_dn),
16+
Some(Target::HomeServer),
17+
)
18+
| (PolyprotoDistinguishedName::HomeServerDn(home_server_dn), None) => {
19+
home_server_dn.validate(target)
20+
}
21+
_ => Err(ConstraintError::Malformed(Some(format!(
22+
"Combination of target {target:?} and given PolyprotoDistinguishedName is invalid"
23+
)))),
24+
}
25+
}
26+
}
27+
28+
impl Constrained for ActorDN {
29+
fn validate(&self, target: Option<Target>) -> Result<(), ConstraintError> {
30+
// Validate all component fields
31+
self.federation_id.validate(target)?;
32+
self.local_name.validate(target)?;
33+
self.session_id.validate(target)?;
34+
self.domain_name.validate(target)?;
35+
36+
// Additional validation specific to ActorDN structure
37+
// Ensure the local name matches the federation ID's local part
38+
if self.local_name != self.federation_id.local_name {
39+
return Err(ConstraintError::Malformed(Some(format!(
40+
"LocalName '{}' does not match federation ID local part '{}'",
41+
self.local_name, self.federation_id.local_name
42+
))));
43+
}
44+
45+
// Ensure the domain name matches the federation ID's domain part
46+
if self.domain_name != self.federation_id.domain_name {
47+
return Err(ConstraintError::Malformed(Some(format!(
48+
"DomainName '{}' does not match federation ID domain part '{}'",
49+
self.domain_name, self.federation_id.domain_name
50+
))));
51+
}
52+
53+
Ok(())
54+
}
55+
}
56+
57+
impl Constrained for HomeServerDN {
58+
fn validate(&self, _target: Option<Target>) -> Result<(), ConstraintError> {
59+
// DomainName validation is done at construction time via DomainName::new()
60+
61+
// HomeServerDN should not have actor-specific fields
62+
// This is inherently satisfied by the structure, but we validate the domain
63+
self.domain_name.validate(None)
64+
}
65+
}

0 commit comments

Comments
 (0)