From 722a11bb811eebaec230a95e200baa3aa236eafe Mon Sep 17 00:00:00 2001 From: William Brown <william@blackhats.net.au> Date: Sat, 29 Mar 2025 12:22:26 +1000 Subject: [PATCH] Uhoh --- proto/src/internal/error.rs | 2 ++ server/core/src/actors/v1_scim.rs | 2 +- server/lib/src/entry.rs | 5 +++++ server/lib/src/server/scim.rs | 27 +++++++++++++++++++++++---- 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/proto/src/internal/error.rs b/proto/src/internal/error.rs index 09f6cb144..0bdd890b1 100644 --- a/proto/src/internal/error.rs +++ b/proto/src/internal/error.rs @@ -213,6 +213,7 @@ pub enum OperationError { SC0024SshPublicKeySyntaxInvalid, SC0025UiHintSyntaxInvalid, SC0026Utf8SyntaxInvalid, + SC0027ClassSetInvalid, // Migration MG0001InvalidReMigrationLevel, MG0002RaiseDomainLevelExceedsMaximum, @@ -492,6 +493,7 @@ impl OperationError { Self::SC0024SshPublicKeySyntaxInvalid => Some("A SCIM Ssh Public Key contained invalid syntax".into()), Self::SC0025UiHintSyntaxInvalid => Some("A SCIM UiHint contained invalid syntax".into()), Self::SC0026Utf8SyntaxInvalid => Some("A SCIM Utf8 String Scope Map contained invalid syntax".into()), + Self::SC0027ClassSetInvalid => Some("The internal set of class templates used in this create operation was invalid. THIS IS A BUG.".into()), Self::UI0001ChallengeSerialisation => Some("The WebAuthn challenge was unable to be serialised.".into()), Self::UI0002InvalidState => Some("The credential update process returned an invalid state transition.".into()), diff --git a/server/core/src/actors/v1_scim.rs b/server/core/src/actors/v1_scim.rs index e8326f317..6761ba1f2 100644 --- a/server/core/src/actors/v1_scim.rs +++ b/server/core/src/actors/v1_scim.rs @@ -202,7 +202,7 @@ impl QueryServerWriteV1 { e })?; - let scim_create_event = ScimCreateEvent::try_from(ident, classes, entry, idms_prox_write)?; + let scim_create_event = ScimCreateEvent::try_from(ident, classes, entry, &mut idms_prox_write.qs_write)?; idms_prox_write .qs_write diff --git a/server/lib/src/entry.rs b/server/lib/src/entry.rs index 6ac88d3e0..4563fe5fd 100644 --- a/server/lib/src/entry.rs +++ b/server/lib/src/entry.rs @@ -488,6 +488,11 @@ impl Entry<EntryInit, EntryNew> { self.attrs.remove(attr); } + /// Set the content of this ava with this valueset, ignoring the previous data. + pub fn set_ava_set(&mut self, attr: &Attribute, vs: ValueSet) { + self.attrs.insert(attr.clone(), vs); + } + /// Replace the existing content of an attribute set of this Entry, with a new set of Values. pub fn set_ava<T>(&mut self, attr: Attribute, iter: T) where diff --git a/server/lib/src/server/scim.rs b/server/lib/src/server/scim.rs index 4d3e48122..5f785777b 100644 --- a/server/lib/src/server/scim.rs +++ b/server/lib/src/server/scim.rs @@ -65,14 +65,24 @@ impl ScimCreateEvent { entry: ScimEntryPostGeneric, qs: &mut QueryServerWriteTransaction, ) -> Result<Self, OperationError> { - let entry = entry + let mut entry = entry .attrs .into_iter() .map(|(attr, json_value)| { qs.resolve_scim_json_post(&attr, json_value) .map(|kani_value| (attr, kani_value)) }) - .collect::<Result<_, _>>()?; + .collect::<Result<EntryInitNew, _>>()?; + + + let classes = + ValueSetIutf8::from_iter( + classes.iter() + .map(|cls| cls.as_ref()) + ) + .ok_or(OperationError::SC0027ClassSetInvalid)?; + + entry.set_ava_set(&Attribute::Class, classes); Ok(ScimCreateEvent { ident, entry }) } @@ -169,8 +179,17 @@ impl QueryServerWriteTransaction<'_> { } } - pub fn scim_create(&mut self, _scim_create: ScimCreateEvent) -> Result<(), OperationError> { - todo!(); + pub fn scim_create(&mut self, scim_create: ScimCreateEvent) -> Result<(), OperationError> { + let ScimCreateEvent { + ident, entry + } = scim_create; + + let create_event = CreateEvent { + ident, + entries: vec![entry], + }; + + self.create(&create_event) } pub fn scim_delete(&mut self, scim_delete: ScimDeleteEvent) -> Result<(), OperationError> {