Class BowireScimStore
- Namespace
- Kuestenlogik.Bowire.Scim
- Assembly
- Kuestenlogik.Bowire.Scim.dll
The provisioned user and group list, on disk (#96).
public sealed class BowireScimStore
- Inheritance
-
BowireScimStore
- Inherited Members
Remarks
One file per resource under <storage root>/scim/, with the
lookups an IdP needs held in memory. A single document holding every
record would have to be rewritten on each of the ten thousand writes a
first sync makes; a file per record makes a write cost one file and
leaves the read path — which is what the round-trip latency is actually
about — served from the index.
Every mutation also appends to scim/events.jsonl. Provisioning is
the one surface where "who removed this person, and when" gets asked
months later, and the resource files only ever show the current answer.
Constructors
BowireScimStore(string, TimeProvider?)
A store rooted at storageRoot.
public BowireScimStore(string storageRoot, TimeProvider? clock = null)
Parameters
storageRootstringThe data root — the same directory the identity slots live under, so deprovisioning can reach them.
clockTimeProviderInjected in tests so a purge window can be crossed without waiting.
Fields
DirectoryName
The directory under the storage root that holds provisioning state.
public const string DirectoryName = "scim"
Field Value
Properties
EventLog
The append-only record of every provisioning decision.
public string EventLog { get; }
Property Value
Root
Where the provisioning state is kept.
public string Root { get; }
Property Value
StorageRoot
The data root this store's identities live under.
public string StorageRoot { get; }
Property Value
Methods
BindSubject(string, string)
Remember which token subject this record turned out to belong to.
public void BindSubject(string id, string subject)
Parameters
CreateGroup(ScimGroup)
Provision a new group.
public ScimGroup CreateGroup(ScimGroup group)
Parameters
groupScimGroup
Returns
Exceptions
- ScimConflictException
The display name is already taken.
CreateUser(ScimUser)
Provision a new identity.
public ScimUserRecord CreateUser(ScimUser resource)
Parameters
resourceScimUser
Returns
Exceptions
- ScimConflictException
The login name is already taken.
DeleteGroup(string)
Remove a group. Groups carry no state of their own, so this is a hard delete.
public bool DeleteGroup(string id)
Parameters
idstring
Returns
DeleteUser(string)
Deprovision an identity: deactivate it and start the purge window.
public bool DeleteUser(string id)
Parameters
idstring
Returns
- bool
Whether there was anything to deprovision.
Remarks
A soft delete, because deprovisioning is routinely undone — a team change, a misfiring sync, an extended contract. Deleting on the DELETE makes those recoverable only from a backup, if one exists.
FindBySubject(string)
The record for a token subject, or null when the identity was
never provisioned.
public ScimUserRecord? FindBySubject(string subject)
Parameters
subjectstring
Returns
Remarks
Matched in the order the identifiers are trustworthy: the subject
already bound to this record, then the IdP's own immutable id, then the
login name. The last is the weakest — a person who changes their
e-mail address changes their userName — which is exactly why the
subject gets bound the first time it is seen.
FindByUserName(string)
The record with this login name, or null.
public ScimUserRecord? FindByUserName(string userName)
Parameters
userNamestring
Returns
GetGroup(string)
The group with this SCIM id, or null.
public ScimGroup? GetGroup(string id)
Parameters
idstring
Returns
GetUser(string)
The record with this SCIM id, or null.
public ScimUserRecord? GetUser(string id)
Parameters
idstring
Returns
Groups()
Every provisioned group.
public IReadOnlyList<ScimGroup> Groups()
Returns
IsMemberOf(string, string)
Whether the identity with this SCIM id is a member of
adminGroup.
public bool IsMemberOf(string userId, string adminGroup)
Parameters
Returns
Purge(TimeSpan)
Delete every identity whose purge window has run out, and their state.
public int Purge(TimeSpan after)
Parameters
afterTimeSpan
Returns
- int
How many were purged.
ReplaceGroup(string, ScimGroup)
Replace a group, keeping its id and creation time.
public ScimGroup? ReplaceGroup(string id, ScimGroup group)
Parameters
Returns
ReplaceUser(string, ScimUser)
Replace an identity's attributes, keeping its id and creation time.
public ScimUserRecord? ReplaceUser(string id, ScimUser resource)
Parameters
Returns
Exceptions
- ScimConflictException
The new login name belongs to somebody else.
UpdateGroup(string, Action<ScimGroup>)
Apply a change to a group in place.
public ScimGroup? UpdateGroup(string id, Action<ScimGroup> change)
Parameters
Returns
UpdateUser(string, Action<ScimUser>)
Record the outcome of a partial update the caller has already applied.
public ScimUserRecord? UpdateUser(string id, Action<ScimUser> change)
Parameters
Returns
Users()
Every provisioned identity, newest last.
public IReadOnlyList<ScimUserRecord> Users()