Class UserManagementService
Default IUserManagementService implementation. Directory operations require a registered IUserDirectoryService; deletion composes the storage seams — remove from all teams, then delete the user record — and only then attempts the (opt-in) directory delete, so a directory failure never leaves the local store half-deleted. Authorization and audit are applied by decorators.
public class UserManagementService : IUserManagementService
- Inheritance
-
UserManagementService
- Implements
- Inherited Members
Constructors
UserManagementService(IUserService, ITeamService, IUserDirectoryService, bool)
public UserManagementService(IUserService userService, ITeamService teamService, IUserDirectoryService directoryService = null, bool writeNameToDirectory = false)
Parameters
userServiceIUserServiceThe user store.
teamServiceITeamServiceThe team store, used to remove memberships and to find owned teams.
directoryServiceIUserDirectoryServiceThe external directory, when one is registered.
writeNameToDirectoryboolWhether an administrative rename also writes the name back to the directory. Default off: which side owns display names is a per-host decision, and a host federating from a corporate directory wants the directory authoritative.
Methods
DeleteUserAsync(string, bool, CancellationToken)
Delete a user: removes the user from every team and deletes the user record (audited).
With deleteFromDirectory the user is also deleted from the external directory;
a directory failure does not roll back the local delete — it is reported on the result.
public Task<UserDeleteResult> DeleteUserAsync(string userKey, bool deleteFromDirectory = false, CancellationToken cancellationToken = default)
Parameters
userKeystringdeleteFromDirectoryboolcancellationTokenCancellationToken
Returns
GetDirectoryOnlyUsersAsync(CancellationToken)
List directory users that have no matching local user (matched by directory id, falling back to email), streamed as directory pages arrive.
public IAsyncEnumerable<DirectoryUser> GetDirectoryOnlyUsersAsync(CancellationToken cancellationToken = default)
Parameters
cancellationTokenCancellationToken
Returns
GetOwnedTeamsAsync(string, CancellationToken)
The teams this user owns — the teams that deleting them would leave with no owner.
public Task<IReadOnlyList<ITeam>> GetOwnedTeamsAsync(string userKey, CancellationToken cancellationToken = default)
Parameters
userKeystringcancellationTokenCancellationToken
Returns
Remarks
Meant to be asked before confirming a delete, so the operator can transfer ownership
instead of learning afterwards that a team is unrecoverable: TransferOwnershipAsync
requires the caller to be the owner, so once the owner is gone only a holder of
SetOwner can repair it.
On IUserManagementService rather than ITeamService deliberately. The question
is "what will deleting this user break", which is user administration; and it keeps the delete
dialog off the internal team contract, which no component should inject.
SetUserDisabledAsync(string, bool, CancellationToken)
public Task SetUserDisabledAsync(string userKey, bool disabled, CancellationToken cancellationToken = default)
Parameters
userKeystringdisabledboolcancellationTokenCancellationToken
Returns
Remarks
The self-disable refusal lives here, not only in UserAdminGate. A host can inject its own
entry through ActionItems and dispatch straight to this method, so a UI-only guard is one
the server never applies — the same lesson the delete guard learned.
SetUserNameAsync(string, string, CancellationToken)
Set a user's display name, and — when o.Blazor.WriteNameToDirectory is enabled and the user
is linked to a directory account — write it back to the external directory too.
public Task<UserNameChangeResult> SetUserNameAsync(string userKey, string name, CancellationToken cancellationToken = default)
Parameters
userKeystringnamestringcancellationTokenCancellationToken
Returns
Remarks
The local write always happens; a failure there throws. The directory write is best-effort and its outcome is reported on the result rather than rolled back into the local one: they fail independently, and coupling them would let a directory outage block renaming a user here.
Administrative rename only. The self-service path (IUserService.SetUserNameAsync) stays
local deliberately — a user editing their own display name in this application should not silently
rewrite the organization's directory.
VerifyAllAsync(CancellationToken)
Verify all local users against the external directory, streamed as results arrive.
public IAsyncEnumerable<UserVerificationResult> VerifyAllAsync(CancellationToken cancellationToken = default)
Parameters
cancellationTokenCancellationToken
Returns
VerifyUserAsync(string, CancellationToken)
Verify a local user against the external directory. When the user resolves via email fallback, the found directory id is persisted on the user (relink).
public Task<DirectoryVerificationResult> VerifyUserAsync(string userKey, CancellationToken cancellationToken = default)
Parameters
userKeystringcancellationTokenCancellationToken