From a18e209015c3dad092d11b8fbea8761e822e2bdd Mon Sep 17 00:00:00 2001 From: John Coffey Date: Sat, 19 Sep 2026 09:52:11 -0700 Subject: [PATCH] SCIM: publish meta in /Schemas, and run the conformance container on the host network (SCIM-6, SCIM-30) scim2-client builds its models from /Schemas, so meta is described there as the mapping tables give it, without lastModified. The tester container now shares the host's network, so a host firewall that drops the Docker bridge doesn't block the test server. With SCIM_CONFORMANCE=1, the scim2-client lifecycle (12 steps), the eight replayed Okta, Keycloak and Entra payloads, and scim2-tester (errors only for its generated non-address userName) all pass. --- crates/scim/src/discovery.rs | 14 ++++++++++++++ tests/src/utils/containers.rs | 3 +++ 2 files changed, 17 insertions(+) diff --git a/crates/scim/src/discovery.rs b/crates/scim/src/discovery.rs index 369e05a..bd3bc71 100644 --- a/crates/scim/src/discovery.rs +++ b/crates/scim/src/discovery.rs @@ -239,6 +239,18 @@ fn schema(base: &str, id: &str, name: &str, description: &str, attributes: Vec Attr { + Attr::new("meta", "complex").read_only().with(vec![ + Attr::new("resourceType", "string").read_only().case_exact(), + Attr::new("created", "dateTime").read_only(), + Attr::new("location", "reference") + .read_only() + .refs(&["uri"]), + Attr::new("version", "string").read_only().case_exact(), + ]) +} + /// The User attributes of the mapping table (SCIM-6); `password` isn't /// published. pub fn user_schema(base: &str) -> Value { @@ -269,6 +281,7 @@ pub fn user_schema(base: &str) -> Value { Attr::new("display", "string").read_only(), Attr::new("$ref", "reference").read_only().refs(&["Group"]), ]), + meta(), ], ) } @@ -289,6 +302,7 @@ pub fn group_schema(base: &str) -> Value { Attr::new("type", "string").immutable().canonical(&["User"]), Attr::new("$ref", "reference").immutable().refs(&["User"]), ]), + meta(), ], ) } diff --git a/tests/src/utils/containers.rs b/tests/src/utils/containers.rs index 57a2e43..3ddce4d 100644 --- a/tests/src/utils/containers.rs +++ b/tests/src/utils/containers.rs @@ -312,6 +312,9 @@ pub async fn ensure_scim_tester() -> &'static ContainerAsync { .expect("Failed to build the SCIM tester image"); image .with_host("host.docker.internal", Host::HostGateway) + // inbuxa: on the host's network, so a host firewall that + // drops the Docker bridge doesn't block the test server + .with_network("host") .with_startup_timeout(READY_TIMEOUT) .with_container_name("stalwart-test-scim-tester") .with_reuse(ReuseDirective::Always)