@@ -6,7 +6,8 @@ use x509_cert::name::{Name, RelativeDistinguishedName};
66use crate :: certs:: SessionId ;
77use crate :: types:: { DomainName , FederationId } ;
88use crate :: {
9- OID_RDN_COMMON_NAME , OID_RDN_DOMAIN_COMPONENT , OID_RDN_UID , OID_RDN_UNIQUE_IDENTIFIER ,
9+ Constrained , OID_RDN_COMMON_NAME , OID_RDN_DOMAIN_COMPONENT , OID_RDN_UID ,
10+ OID_RDN_UNIQUE_IDENTIFIER ,
1011} ;
1112
1213/// Higher-level abstraction of X.509 [distinguished names](https://ldap.com/ldap-dns-and-rdns/),
@@ -65,21 +66,57 @@ impl TryFrom<Name> for ActorDN {
6566 type Error = crate :: errors:: InvalidInput ;
6667
6768 fn try_from ( x509_distinguished_name : Name ) -> Result < Self , Self :: Error > {
68- let federation_id: AttributeTypeAndValue ;
69- let domain_name: AttributeTypeAndValue ;
70- let session_id: AttributeTypeAndValue ;
71- let additional_fields: AttributeTypeAndValue ;
69+ x509_distinguished_name
70+ . validate ( Some ( crate :: certs:: Target :: Actor ) )
71+ . map_err ( |e| crate :: errors:: InvalidInput :: Malformed ( e. to_string ( ) ) ) ?;
72+ let mut maybe_federation_id: Option < AttributeTypeAndValue > = None ;
73+ let mut maybe_local_name: Option < AttributeTypeAndValue > = None ;
74+ let mut maybe_domain_names: Vec < AttributeTypeAndValue > = Vec :: new ( ) ;
75+ let mut maybe_session_id: Option < AttributeTypeAndValue > = None ;
76+ let mut maybe_additional_fields: Vec < AttributeTypeAndValue > = Vec :: new ( ) ;
7277 for relative_distinguished_name in x509_distinguished_name. 0 . into_iter ( ) {
7378 for attribute_value_and_item in relative_distinguished_name. 0 . iter ( ) {
7479 match attribute_value_and_item. oid {
75- OID_RDN_COMMON_NAME => ( ) ,
76- OID_RDN_UID => ( ) ,
77- OID_RDN_UNIQUE_IDENTIFIER => ( ) ,
78- OID_RDN_DOMAIN_COMPONENT => ( ) ,
79- other => ( ) ,
80+ OID_RDN_COMMON_NAME => {
81+ make_some_or_error ( attribute_value_and_item, & mut maybe_local_name) ?
82+ }
83+ OID_RDN_UID => {
84+ make_some_or_error ( attribute_value_and_item, & mut maybe_federation_id) ?
85+ }
86+ OID_RDN_UNIQUE_IDENTIFIER => {
87+ make_some_or_error ( attribute_value_and_item, & mut maybe_session_id) ?
88+ }
89+ OID_RDN_DOMAIN_COMPONENT => {
90+ maybe_domain_names. push ( attribute_value_and_item. clone ( ) )
91+ }
92+ _other => maybe_additional_fields. push ( attribute_value_and_item. clone ( ) ) ,
8093 }
8194 }
8295 }
96+ // TODO: Ok now we have it all (hopefully); lets confirm that fact, turn the individual fields into their strongly typed counterparts and then return a full ActorDN!
97+ if let Some ( some_federation_id) = maybe_federation_id {
98+ todo ! ( )
99+ }
100+
83101 todo ! ( )
84102 }
85103}
104+
105+ /// Helper function. Takes an exclusive reference `Option<AttributeTypeAndValue>`, inspects if it
106+ /// holds a value, and
107+ ///
108+ /// - Errors appropriately, if it already holds a value
109+ /// - Else, updates the `None` value with the passed `attribute_value_and_item`, then returns `Ok(())`
110+ fn make_some_or_error (
111+ attribute_value_and_item : & AttributeTypeAndValue ,
112+ value_to_update : & mut Option < AttributeTypeAndValue > ,
113+ ) -> Result < ( ) , crate :: errors:: InvalidInput > {
114+ if value_to_update. is_none ( ) {
115+ * value_to_update = Some ( attribute_value_and_item. clone ( ) ) ;
116+ Ok ( ( ) )
117+ } else {
118+ Err ( crate :: errors:: InvalidInput :: Malformed (
119+ "Found multiple entries for same OID, where only one OID is allowed" . to_owned ( ) ,
120+ ) )
121+ }
122+ }
0 commit comments