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:
@@ -796,6 +796,14 @@ impl AccessToken {
|
||||
}
|
||||
|
||||
impl AccessTokenInner {
|
||||
/// inbuxa: SCIM-27: the account's own effective permission, from its
|
||||
/// roles, its own settings and its tenant, before a credential narrows it
|
||||
pub fn account_has_permission(&self, permission: Permission) -> bool {
|
||||
self.scopes
|
||||
.first()
|
||||
.is_some_and(|scope| scope.permissions.get(permission as usize))
|
||||
}
|
||||
|
||||
pub fn from_id(account_id: u32) -> Self {
|
||||
Self {
|
||||
account_id,
|
||||
|
||||
@@ -69,7 +69,8 @@ pub struct DomainCache {
|
||||
|
||||
pub const DOMAIN_FLAG_RELAY: u8 = 1;
|
||||
pub const DOMAIN_FLAG_SUB_ADDRESSING: u8 = 1 << 1;
|
||||
|
||||
// inbuxa: SCIM-15, SCIM-58
|
||||
pub const DOMAIN_FLAG_SCIM: u8 = 1 << 2;
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct AccountCache {
|
||||
@@ -329,4 +330,8 @@ impl DomainCache {
|
||||
self.names.first().map(|s| s.as_ref()).unwrap_or_default()
|
||||
}
|
||||
|
||||
// inbuxa: SCIM-15, SCIM-58
|
||||
pub fn allows_scim(&self) -> bool {
|
||||
self.flags & DOMAIN_FLAG_SCIM != 0
|
||||
}
|
||||
}
|
||||
|
||||
+5
-1
@@ -158,7 +158,11 @@ impl Server {
|
||||
if domain.allow_relaying {
|
||||
flags |= DOMAIN_FLAG_RELAY;
|
||||
}
|
||||
|
||||
// inbuxa: SCIM-15, SCIM-58: the domain is open to SCIM, and SCIM is
|
||||
// authoritative for its accounts
|
||||
if domain.allow_scim_provisioning {
|
||||
flags |= crate::auth::DOMAIN_FLAG_SCIM;
|
||||
}
|
||||
|
||||
let sub_addressing_custom = match domain.sub_addressing {
|
||||
SubAddressing::Enabled => {
|
||||
|
||||
Reference in New Issue
Block a user