SCIM: users, groups, queries, PATCH, Bulk and cursors at /scim/v2, over x:Account (SCIM-1 to SCIM-57)
Every SCIM operation becomes the x:Account get, query or set JMAP makes, as the service principal, so permissions, tenant scope and limits, address uniqueness and account destruction are enforced in one place. Discovery is anonymous; everything else takes an API key as a bearer token and nothing else. Domains open to SCIM carry a flag in the domain cache. Filters take eq and and, answered from the account indexes, with unindexed attributes checked on at most 200 candidates. Cursors are stateless, HMAC-sealed under the server key. PATCH applies to the resource in memory and saves it as a PUT, so it is all or nothing. Groups get an address from their display name on the principal's domain; membership is written on each user. Every write emits one of five new scim.* events (ids 637 to 641), also added to the packaged schema. The helpers the surviving SCIM suites import are rebuilt from the spec; scim_tests runs the new acceptance suite and the surviving tenant isolation suite, and both pass.
This commit is contained in:
@@ -6,7 +6,8 @@
|
||||
|
||||
// This file is auto-generated. Do not edit directly.
|
||||
|
||||
pub const TOTAL_EVENT_COUNT: usize = 637;
|
||||
// inbuxa: 637 to 641 are the fork's SCIM events (SCIM-54)
|
||||
pub const TOTAL_EVENT_COUNT: usize = 642;
|
||||
pub const TOTAL_METRIC_COUNT: usize = 369;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
@@ -42,6 +43,8 @@ pub enum EventType {
|
||||
Queue(QueueEvent),
|
||||
Registry(RegistryEvent),
|
||||
Resource(ResourceEvent),
|
||||
// inbuxa: SCIM-54
|
||||
Scim(ScimEvent),
|
||||
Security(SecurityEvent),
|
||||
Server(ServerEvent),
|
||||
Sieve(SieveEvent),
|
||||
@@ -624,6 +627,17 @@ pub enum ResourceEvent {
|
||||
ApplicationUnpacked = 602,
|
||||
}
|
||||
|
||||
// inbuxa: SCIM-54: every write an identity provider makes
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[repr(u16)]
|
||||
pub enum ScimEvent {
|
||||
ResourceCreated = 637,
|
||||
ResourceUpdated = 638,
|
||||
ResourceSuspended = 639,
|
||||
ResourceReactivated = 640,
|
||||
ResourceDeleted = 641,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[repr(u16)]
|
||||
pub enum SecurityEvent {
|
||||
|
||||
@@ -36,6 +36,12 @@ impl EventType {
|
||||
b"acme.error" => EventType::Acme(AcmeEvent::Error),
|
||||
b"ai.llm-response" => EventType::Ai(AiEvent::LlmResponse),
|
||||
b"ai.api-error" => EventType::Ai(AiEvent::ApiError),
|
||||
// inbuxa: SCIM-54
|
||||
b"scim.resource-created" => EventType::Scim(ScimEvent::ResourceCreated),
|
||||
b"scim.resource-updated" => EventType::Scim(ScimEvent::ResourceUpdated),
|
||||
b"scim.resource-suspended" => EventType::Scim(ScimEvent::ResourceSuspended),
|
||||
b"scim.resource-reactivated" => EventType::Scim(ScimEvent::ResourceReactivated),
|
||||
b"scim.resource-deleted" => EventType::Scim(ScimEvent::ResourceDeleted),
|
||||
b"arc.chain-too-long" => EventType::Arc(ArcEvent::ChainTooLong),
|
||||
b"arc.invalid-instance" => EventType::Arc(ArcEvent::InvalidInstance),
|
||||
b"arc.invalid-cv" => EventType::Arc(ArcEvent::InvalidCv),
|
||||
@@ -679,6 +685,12 @@ impl EventType {
|
||||
EventType::Acme(AcmeEvent::Error) => "acme.error",
|
||||
EventType::Ai(AiEvent::LlmResponse) => "ai.llm-response",
|
||||
EventType::Ai(AiEvent::ApiError) => "ai.api-error",
|
||||
// inbuxa: SCIM-54
|
||||
EventType::Scim(ScimEvent::ResourceCreated) => "scim.resource-created",
|
||||
EventType::Scim(ScimEvent::ResourceUpdated) => "scim.resource-updated",
|
||||
EventType::Scim(ScimEvent::ResourceSuspended) => "scim.resource-suspended",
|
||||
EventType::Scim(ScimEvent::ResourceReactivated) => "scim.resource-reactivated",
|
||||
EventType::Scim(ScimEvent::ResourceDeleted) => "scim.resource-deleted",
|
||||
EventType::Arc(ArcEvent::ChainTooLong) => "arc.chain-too-long",
|
||||
EventType::Arc(ArcEvent::InvalidInstance) => "arc.invalid-instance",
|
||||
EventType::Arc(ArcEvent::InvalidCv) => "arc.invalid-cv",
|
||||
@@ -1457,6 +1469,12 @@ impl EventType {
|
||||
EventType::Acme(AcmeEvent::Error) => 15,
|
||||
EventType::Ai(AiEvent::LlmResponse) => 556,
|
||||
EventType::Ai(AiEvent::ApiError) => 557,
|
||||
// inbuxa: SCIM-54
|
||||
EventType::Scim(ScimEvent::ResourceCreated) => 637,
|
||||
EventType::Scim(ScimEvent::ResourceUpdated) => 638,
|
||||
EventType::Scim(ScimEvent::ResourceSuspended) => 639,
|
||||
EventType::Scim(ScimEvent::ResourceReactivated) => 640,
|
||||
EventType::Scim(ScimEvent::ResourceDeleted) => 641,
|
||||
EventType::Arc(ArcEvent::ChainTooLong) => 28,
|
||||
EventType::Arc(ArcEvent::InvalidInstance) => 31,
|
||||
EventType::Arc(ArcEvent::InvalidCv) => 30,
|
||||
@@ -2099,6 +2117,12 @@ impl EventType {
|
||||
15 => Some(EventType::Acme(AcmeEvent::Error)),
|
||||
556 => Some(EventType::Ai(AiEvent::LlmResponse)),
|
||||
557 => Some(EventType::Ai(AiEvent::ApiError)),
|
||||
// inbuxa: SCIM-54
|
||||
637 => Some(EventType::Scim(ScimEvent::ResourceCreated)),
|
||||
638 => Some(EventType::Scim(ScimEvent::ResourceUpdated)),
|
||||
639 => Some(EventType::Scim(ScimEvent::ResourceSuspended)),
|
||||
640 => Some(EventType::Scim(ScimEvent::ResourceReactivated)),
|
||||
641 => Some(EventType::Scim(ScimEvent::ResourceDeleted)),
|
||||
28 => Some(EventType::Arc(ArcEvent::ChainTooLong)),
|
||||
31 => Some(EventType::Arc(ArcEvent::InvalidInstance)),
|
||||
30 => Some(EventType::Arc(ArcEvent::InvalidCv)),
|
||||
@@ -3056,6 +3080,12 @@ impl EventType {
|
||||
EventType::Acme(AcmeEvent::TlsAlpnError) => Level::Warn,
|
||||
EventType::Acme(AcmeEvent::TokenNotFound) => Level::Warn,
|
||||
EventType::Ai(AiEvent::ApiError) => Level::Warn,
|
||||
// inbuxa: SCIM-54
|
||||
EventType::Scim(ScimEvent::ResourceCreated) => Level::Info,
|
||||
EventType::Scim(ScimEvent::ResourceUpdated) => Level::Info,
|
||||
EventType::Scim(ScimEvent::ResourceSuspended) => Level::Info,
|
||||
EventType::Scim(ScimEvent::ResourceReactivated) => Level::Info,
|
||||
EventType::Scim(ScimEvent::ResourceDeleted) => Level::Info,
|
||||
EventType::Arc(ArcEvent::SealerNotFound) => Level::Warn,
|
||||
EventType::Auth(AuthEvent::TooManyAttempts) => Level::Warn,
|
||||
EventType::Calendar(CalendarEvent::AlarmFailed) => Level::Warn,
|
||||
@@ -3137,6 +3167,12 @@ impl EventType {
|
||||
EventType::Acme(AcmeEvent::Error) => "ACME error",
|
||||
EventType::Ai(AiEvent::LlmResponse) => "LLM response",
|
||||
EventType::Ai(AiEvent::ApiError) => "AI API error",
|
||||
// inbuxa: SCIM-54
|
||||
EventType::Scim(ScimEvent::ResourceCreated) => "SCIM resource created",
|
||||
EventType::Scim(ScimEvent::ResourceUpdated) => "SCIM resource updated",
|
||||
EventType::Scim(ScimEvent::ResourceSuspended) => "SCIM user suspended",
|
||||
EventType::Scim(ScimEvent::ResourceReactivated) => "SCIM user reactivated",
|
||||
EventType::Scim(ScimEvent::ResourceDeleted) => "SCIM resource deleted",
|
||||
EventType::Arc(ArcEvent::ChainTooLong) => "ARC chain too long",
|
||||
EventType::Arc(ArcEvent::InvalidInstance) => "Invalid ARC instance",
|
||||
EventType::Arc(ArcEvent::InvalidCv) => "Invalid ARC CV",
|
||||
@@ -4203,6 +4239,12 @@ impl EventType {
|
||||
EventType::Acme(AcmeEvent::Error),
|
||||
EventType::Ai(AiEvent::LlmResponse),
|
||||
EventType::Ai(AiEvent::ApiError),
|
||||
// inbuxa: SCIM-54
|
||||
EventType::Scim(ScimEvent::ResourceCreated),
|
||||
EventType::Scim(ScimEvent::ResourceUpdated),
|
||||
EventType::Scim(ScimEvent::ResourceSuspended),
|
||||
EventType::Scim(ScimEvent::ResourceReactivated),
|
||||
EventType::Scim(ScimEvent::ResourceDeleted),
|
||||
EventType::Arc(ArcEvent::ChainTooLong),
|
||||
EventType::Arc(ArcEvent::InvalidInstance),
|
||||
EventType::Arc(ArcEvent::InvalidCv),
|
||||
|
||||
Reference in New Issue
Block a user