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:
@@ -25,11 +25,13 @@ impl PatchPath {
|
||||
let text = text.trim();
|
||||
let (head, filter, after) = match text.find('[') {
|
||||
Some(open) => {
|
||||
let close = text.rfind(']').filter(|close| *close > open).ok_or_else(invalid)?;
|
||||
let close = text
|
||||
.rfind(']')
|
||||
.filter(|close| *close > open)
|
||||
.ok_or_else(invalid)?;
|
||||
let inner = &text[open + 1..close];
|
||||
let filter = Filter::parse(inner).map_err(|err| {
|
||||
ScimError::invalid_path(format!("'{text}': {}", err.detail))
|
||||
})?;
|
||||
let filter = Filter::parse(inner)
|
||||
.map_err(|err| ScimError::invalid_path(format!("'{text}': {}", err.detail)))?;
|
||||
let after = &text[close + 1..];
|
||||
let after = if after.is_empty() {
|
||||
None
|
||||
@@ -85,7 +87,14 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn refuses_bad_paths() {
|
||||
for text in ["", "members[", "members[value eq]", "a[b eq 1]x", "1a", "a.b[c eq 1]"] {
|
||||
for text in [
|
||||
"",
|
||||
"members[",
|
||||
"members[value eq]",
|
||||
"a[b eq 1]x",
|
||||
"1a",
|
||||
"a.b[c eq 1]",
|
||||
] {
|
||||
assert!(PatchPath::parse(text).is_err(), "{text}");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user