Class AuditingUserManagementServiceDecorator
Decorator that wraps IUserManagementService and logs audit entries for user administration: per-user verification (with outcome), bulk verification (one summary entry), and deletion (with team count and directory result). The directory-only listing is a read with no side effect and is not audited, consistent with team enumeration.
public class AuditingUserManagementServiceDecorator : IUserManagementService
- Inheritance
-
AuditingUserManagementServiceDecorator
- Implements
- Inherited Members
Constructors
AuditingUserManagementServiceDecorator(IUserManagementService, CompositeAuditLogger, IHttpContextAccessor)
public AuditingUserManagementServiceDecorator(IUserManagementService inner, CompositeAuditLogger auditLogger, IHttpContextAccessor httpContextAccessor)
Parameters
innerIUserManagementServiceauditLoggerCompositeAuditLoggerhttpContextAccessorIHttpContextAccessor
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)
public Task<IReadOnlyList<ITeam>> GetOwnedTeamsAsync(string userKey, CancellationToken cancellationToken = default)
Parameters
userKeystringcancellationTokenCancellationToken
Returns
Remarks
A read that runs when a delete confirmation opens, so it is not audited — logging it would record an entry for looking at a dialog the operator may then cancel. The delete it precedes is audited.
GetSignInIdentitiesAsync(IEnumerable<string>, CancellationToken)
How each of the given users signs in, read from the directory in one batch. One entry per user that is linked to a directory account the directory still knows; unknown and unlinked users are left out.
public Task<UserSignInIdentities[]> GetSignInIdentitiesAsync(IEnumerable<string> userKeys, CancellationToken cancellationToken = default)
Parameters
userKeysIEnumerable<string>cancellationTokenCancellationToken
Returns
Remarks
Requires a registered IUserIdentityDirectory; without one the result is empty. Meant for a list surface reading the rows it shows, so pass a page of keys rather than every user.
The default implementation returns nothing, so a host's own implementation of this interface keeps compiling; such a host shows no sign-in methods until it implements this.
SetUserDisabledAsync(string, bool, CancellationToken)
public Task SetUserDisabledAsync(string userKey, bool disabled, CancellationToken cancellationToken = default)
Parameters
userKeystringdisabledboolcancellationTokenCancellationToken
Returns
Remarks
Both directions, under distinct actions — disable is a containment, enable is a
decision to let the person back in. One entry keyed on a boolean would make "who re-enabled this"
a query rather than a reading. The refusal to disable oneself is audited as a failure too: an
administrator repeatedly trying it is worth seeing.
SetUserEmailAsync(string, string, CancellationToken)
public Task<UserEmailChangeResult> SetUserEmailAsync(string userKey, string email, CancellationToken cancellationToken = default)
Parameters
userKeystringemailstringcancellationTokenCancellationToken
Returns
Remarks
Both the address replaced and the new one are recorded: it is where the user's mail goes and what an invitation to them matches, so "what was it changed from" is what someone investigating asks. A refusal is audited as a failure too, without the address it was given.
SetUserNameAsync(string, string, bool, CancellationToken)
public Task<UserNameChangeResult> SetUserNameAsync(string userKey, string name, bool writeToDirectory, CancellationToken cancellationToken = default)
Parameters
userKeystringnamestringwriteToDirectoryboolcancellationTokenCancellationToken
Returns
Remarks
The directory outcome is recorded rather than just the local write: a rename that succeeded here and failed there is the case someone will later need to explain, and it is invisible otherwise.
UseDirectoryNameAsync(string, CancellationToken)
Replace the user's local name with the display name the directory holds for them, and return it.
public Task<string> UseDirectoryNameAsync(string userKey, CancellationToken cancellationToken = default)
Parameters
userKeystringcancellationTokenCancellationToken
Returns
Remarks
The directory is read here rather than the name being passed in, so the operation can only ever take what the directory actually says. Refused when the directory name is a placeholder (IsPlaceholder(string)): taking "unknown" would overwrite a real name with none. Local only — the name came from the directory, so nothing is written back.
Exceptions
- InvalidOperationException
The user is not found in the directory, or the directory holds only a placeholder name.
- NotSupportedException
The host's user management service does not implement it.
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