=== Summary: 675 files | 7 generated | 484 fresh | 4605 untracked | 4268 adopted | 355 marked | 466 validated-ok | 2+0 stale (sig+body) | 0 skipped | 0 failed | elapsed 11:08:11.442 (40091.44s) ===
This commit is contained in:
@@ -13,6 +13,8 @@ namespace adas_core.Authentication.Attributes;
|
||||
/// Constrained by <see cref="System.AttributeUsageAttribute"/> to <see cref="AttributeTargets.Method"/>, the attribute is configured at construction with the required <paramref name="type"/>.
|
||||
/// </remarks>
|
||||
/// <!-- aidoc:v1 sig=b5093e9 -->
|
||||
/// <!-- aidoc-review:v1 severity=medium kind=missing_param
|
||||
/// "The primary constructor parameter 'type' is referenced via <paramref> in remarks but lacks a formal <param> tag describing its purpose." -->
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class AuthorizeRolesAttribute(PermissionEnum.RolesType type) : Attribute, IAuthorizationFilter
|
||||
{
|
||||
@@ -22,6 +24,7 @@ public class AuthorizeRolesAttribute(PermissionEnum.RolesType type) : Attribute,
|
||||
/// and otherwise responds with a forbid result when no user role starts with the permission type value.
|
||||
/// </summary>
|
||||
/// <param name="context">The authorization filter context providing access to the HTTP context and where the authorization result is assigned.</param>
|
||||
/// <!-- aidoc:v1 sig=6368c5d body=ab6a306 -->
|
||||
public void OnAuthorization(AuthorizationFilterContext context)
|
||||
{
|
||||
var user = context.HttpContext.User;
|
||||
|
||||
@@ -19,6 +19,7 @@ public class AuthorizePermissionsAttribute(
|
||||
/// Handles authorization by validating the presence of the <c>Displayid</c> request header and ensuring the authenticated user exists in the user service. If the header is missing or the user cannot be found, the request is short-circuited with a <see cref="NotFoundObjectResult"/>.
|
||||
/// </summary>
|
||||
/// <param name="context">The <see cref="AuthorizationFilterContext"/> for the current request, providing access to the HTTP context, user identity, and the ability to set the action result.</param>
|
||||
/// <!-- aidoc:v1 sig=6368c5d body=527e8e0 -->
|
||||
public void OnAuthorization(AuthorizationFilterContext context)
|
||||
{
|
||||
var user = context.HttpContext.User;
|
||||
|
||||
@@ -27,6 +27,7 @@ public class PermissionAuthorizeAttribute(string source, string? resourceIdHeade
|
||||
/// </summary>
|
||||
/// <param name="context">The <see cref="AuthorizationFilterContext"/> for the current authorization request, providing access to the HTTP context, services, and the result to set when authorization fails.</param>
|
||||
/// <exception cref="ForbbidenException">Thrown when the <see cref="IPermissionService"/> cannot be resolved from the request services.</exception>
|
||||
/// <!-- aidoc:v1 sig=2cfde77 body=c01efe9 -->
|
||||
public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
|
||||
{
|
||||
// Obtener el servicio de permisos.
|
||||
|
||||
@@ -25,6 +25,7 @@ public class AuthorityService(
|
||||
/// </summary>
|
||||
/// <param name="roleName">The name of the role to associate with the authority.</param>
|
||||
/// <param name="userId">The unique identifier of the user for whom the authority is being created.</param>
|
||||
/// <!-- aidoc:v1 sig=e8925cb body=6481017 -->
|
||||
public void CreateNew(string roleName, ObjectId userId)
|
||||
{
|
||||
authorityRepository.CreateNewAuthority(roleName, userId);
|
||||
@@ -34,6 +35,7 @@ public class AuthorityService(
|
||||
/// Inserts a new <paramref name="authorization"/> into the authority repository and records an audit log entry for the operation using the current HTTP context user.
|
||||
/// </summary>
|
||||
/// <param name="authorization">The authorization entity to be inserted and tracked in the audit log.</param>
|
||||
/// <!-- aidoc:v1 sig=ae025de body=a51a17b -->
|
||||
public async Task InsertOne(Authorization authorization)
|
||||
{
|
||||
await authorityRepository.InsertOneAsync(authorization);
|
||||
@@ -44,6 +46,7 @@ public class AuthorityService(
|
||||
/// Updates an existing authorization record in the repository and records an audit log entry capturing the previous and updated states for the current user.
|
||||
/// </summary>
|
||||
/// <param name="authorization">The authorization entity containing the identifier of the record to update and its new values.</param>
|
||||
/// <!-- aidoc:v1 sig=0061b8f body=ec8308f -->
|
||||
public async Task updateOne(Authorization authorization)
|
||||
{
|
||||
var oldAuth = await authorityRepository.GetById(authorization.Id);
|
||||
@@ -56,6 +59,7 @@ public class AuthorityService(
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <returns>A list of the user's authorities.</returns>
|
||||
/// <!-- aidoc:v1 sig=f9a2a8a body=7e449b3 -->
|
||||
public Task<List<Authorization>> GetUserAuthorities(ObjectId userId)
|
||||
{
|
||||
return authorityRepository.GetUserAuthorities(userId);
|
||||
@@ -65,6 +69,7 @@ public class AuthorityService(
|
||||
/// Retrieves all available authorities from the underlying repository.
|
||||
/// </summary>
|
||||
/// <returns>A task that represents the asynchronous operation, containing a list of all <see cref="Authorization"/> records.</returns>
|
||||
/// <!-- aidoc:v1 sig=db31dc4 body=3106354 -->
|
||||
public Task<List<Authorization>> GetAllAuthorities()
|
||||
{
|
||||
return authorityRepository.GetAllAuthorities();
|
||||
@@ -75,6 +80,7 @@ public class AuthorityService(
|
||||
/// </summary>
|
||||
/// <param name="id">The unique identifier of the user whose authorities should be deleted.</param>
|
||||
/// <returns><c>true</c> if the authorities were successfully deleted; otherwise, <c>false</c>.</returns>
|
||||
/// <!-- aidoc:v1 sig=abc4727 body=4c48116 -->
|
||||
public async Task<bool> DeleteAuthoritiesForUser(ObjectId id)
|
||||
{
|
||||
try
|
||||
@@ -99,6 +105,7 @@ public class AuthorityService(
|
||||
/// </summary>
|
||||
/// <param name="authorization">The authorization entity to be created and stored.</param>
|
||||
/// <returns>The created <see cref="Authorization"/> entity.</returns>
|
||||
/// <!-- aidoc:v1 sig=dd7f92d body=801be1a -->
|
||||
public async Task<Authorization?> CreateNewUserAuthority(Authorization authorization)
|
||||
{
|
||||
await authorityRepository.InsertOneAsync(authorization);
|
||||
@@ -112,6 +119,7 @@ public class AuthorityService(
|
||||
/// </summary>
|
||||
/// <param name="userAuthorityIdParsed">The parsed identifier of the user authority to delete.</param>
|
||||
/// <returns><c>true</c> if the user authority was successfully deleted; otherwise, <c>false</c>.</returns>
|
||||
/// <!-- aidoc:v1 sig=73f08c6 body=0b2f9a8 -->
|
||||
public async Task<bool> DeleteUserAuthority(ObjectId userAuthorityIdParsed)
|
||||
{
|
||||
try
|
||||
@@ -135,6 +143,7 @@ public class AuthorityService(
|
||||
/// </summary>
|
||||
/// <param name="authorization">The authorization entity containing the updated information to persist.</param>
|
||||
/// <returns>The updated <see cref="Authorization"/> on success, or <c>null</c> if an error occurs during the operation.</returns>
|
||||
/// <!-- aidoc:v1 sig=21fd169 body=9a8dcf9 -->
|
||||
public async Task<Authorization?> EditUserAuthority(Authorization authorization)
|
||||
{
|
||||
try
|
||||
|
||||
@@ -10,29 +10,34 @@ public interface IAuthorityService
|
||||
/// </summary>
|
||||
/// <param name="userId">The unique identifier of the user whose authorizations are being requested.</param>
|
||||
/// <returns>A task that represents the asynchronous operation, containing a list of <see cref="Authorization"/> objects for the user.</returns>
|
||||
/// <!-- aidoc:v1 sig=1476a1a -->
|
||||
public Task<List<Authorization>> GetUserAuthorities(ObjectId userId);
|
||||
/// <summary>
|
||||
/// Creates a new role with the specified name and associates it with the given user.
|
||||
/// </summary>
|
||||
/// <param name="roleName">The name of the role to create.</param>
|
||||
/// <param name="userId">The identifier of the user to associate with the new role.</param>
|
||||
/// <!-- aidoc:v1 sig=ea6d5b6 -->
|
||||
public void CreateNew(string roleName, ObjectId userId);
|
||||
/// <summary>
|
||||
/// Inserts a new authorization record into the data store.
|
||||
/// </summary>
|
||||
/// <param name="authorization">The authorization entity to insert.</param>
|
||||
/// <returns>A task that represents the asynchronous insert operation.</returns>
|
||||
/// <!-- aidoc:v1 sig=bf14da0 -->
|
||||
public Task InsertOne(Authorization authorization);
|
||||
/// <summary>
|
||||
/// Updates a single authorization record.
|
||||
/// </summary>
|
||||
/// <param name="authorization">The authorization object containing the data to be updated.</param>
|
||||
/// <!-- aidoc:v1 sig=2e9fb22 -->
|
||||
public Task updateOne(Authorization authorization);
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously retrieves all authorizations.
|
||||
/// </summary>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains a list of all authorization objects.</returns>
|
||||
/// <!-- aidoc:v1 sig=dd351e0 -->
|
||||
public Task<List<Authorization>> GetAllAuthorities();
|
||||
|
||||
/// <summary>
|
||||
@@ -40,23 +45,27 @@ public interface IAuthorityService
|
||||
/// </summary>
|
||||
/// <param name="id">The unique identifier of the user whose authorities should be removed.</param>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains <c>true</c> if authorities were deleted; otherwise, <c>false</c>.</returns>
|
||||
/// <!-- aidoc:v1 sig=851a476 -->
|
||||
Task<bool> DeleteAuthoritiesForUser(ObjectId id);
|
||||
/// <summary>
|
||||
/// Creates a new user authority based on the provided <paramref name="authorization"/>.
|
||||
/// </summary>
|
||||
/// <param name="authorization">The authorization data used to create the new user authority.</param>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains the created <see cref="Authorization"/>, or <c>null</c> if the authority could not be created.</returns>
|
||||
/// <!-- aidoc:v1 sig=adb1353 -->
|
||||
Task<Authorization?> CreateNewUserAuthority(Authorization authorization);
|
||||
/// <summary>
|
||||
/// Asynchronously deletes a user authority identified by the provided parsed identifier.
|
||||
/// </summary>
|
||||
/// <param name="userAuthorityIdParsed">The parsed identifier of the user authority to delete.</param>
|
||||
/// <returns>A task that represents the asynchronous delete operation. The task result is <see langword="true"/> if the user authority was successfully deleted; otherwise, <see langword="false"/>.</returns>
|
||||
/// <!-- aidoc:v1 sig=d8ae827 -->
|
||||
Task<bool> DeleteUserAuthority(ObjectId userAuthorityIdParsed);
|
||||
/// <summary>
|
||||
/// Edits the user authority using the provided authorization data.
|
||||
/// </summary>
|
||||
/// <param name="authorization">The authorization object containing the user authority details to be updated.</param>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains the updated <see cref="Authorization"/>, or <c>null</c> if the authorization was not found.</returns>
|
||||
/// <!-- aidoc:v1 sig=857d49a -->
|
||||
Task<Authorization?> EditUserAuthority(Authorization authorization);
|
||||
}
|
||||
@@ -15,12 +15,14 @@ public interface ILoginService
|
||||
/// <param name="username">The username of the user attempting to log in.</param>
|
||||
/// <param name="password">The password associated with the username.</param>
|
||||
/// <returns>A <see cref="Task{User}"/> representing the asynchronous operation, containing the authenticated <see cref="User"/>.</returns>
|
||||
/// <!-- aidoc:v1 sig=a4700d5 -->
|
||||
Task<User> Login(string username, string password);
|
||||
/// <summary>
|
||||
/// Authenticates a user based on the provided HTTP context.
|
||||
/// </summary>
|
||||
/// <param name="context">The HTTP context containing the request information used to perform the login.</param>
|
||||
/// <returns>A task that represents the asynchronous login operation. The task result contains the authenticated <see cref="User"/>.</returns>
|
||||
/// <!-- aidoc:v1 sig=ff09cb3 -->
|
||||
Task<User> Login(HttpContext context);
|
||||
|
||||
/// <summary>
|
||||
@@ -29,29 +31,34 @@ public interface ILoginService
|
||||
/// <param name="username">The username of the user to authenticate.</param>
|
||||
/// <param name="password">The password of the user to authenticate.</param>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains the authenticated <see cref="User"/>.</returns>
|
||||
/// <!-- aidoc:v1 sig=a232f05 -->
|
||||
Task<User> Authenticate(string username, string password);
|
||||
/// <summary>
|
||||
/// Retrieves a user by their unique identifier, returning null if no matching user is found.
|
||||
/// </summary>
|
||||
/// <param name="id">The unique identifier of the user to look up.</param>
|
||||
/// <returns>The user with the specified identifier, or null if no user is found.</returns>
|
||||
/// <!-- aidoc:v1 sig=ab4b64e -->
|
||||
Task<User?> GetById(ObjectId id);
|
||||
/// <summary>
|
||||
/// Retrieves a user from the data store by their email address, or returns null if no matching user is found.
|
||||
/// </summary>
|
||||
/// <param name="email">The email address used to look up the user.</param>
|
||||
/// <returns>A task that resolves to the <see cref="User"/> matching the provided email, or null if no user is found.</returns>
|
||||
/// <!-- aidoc:v1 sig=aad49e4 -->
|
||||
Task<User?> GetByEmail(string email);
|
||||
/// <summary>
|
||||
/// Retrieves a user by their username asynchronously, returning <c>null</c> if no matching user is found.
|
||||
/// </summary>
|
||||
/// <param name="username">The username to look up.</param>
|
||||
/// <returns>A <see cref="Task{User}"/> that resolves to the matching <see cref="User"/>, or <c>null</c> if no user exists with the specified username.</returns>
|
||||
/// <!-- aidoc:v1 sig=d91b767 -->
|
||||
Task<User?> GetByUsername(string username);
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously retrieves a list of all users in the system.
|
||||
/// </summary>
|
||||
/// <returns>A task that represents the asynchronous operation, containing a list of all <see cref="User"/> entities.</returns>
|
||||
/// <!-- aidoc:v1 sig=850c090 -->
|
||||
Task<List<User>> GetAllUsers();
|
||||
}
|
||||
@@ -13,12 +13,14 @@ public interface ITokenService
|
||||
/// <param name="username">The username used to look up the security token.</param>
|
||||
/// <param name="claims">The list of claims associated with the token.</param>
|
||||
/// <returns>A <see cref="SecurityToken"/> if a matching token is found; otherwise, <see langword="null"/>.</returns>
|
||||
/// <!-- aidoc:v1 sig=78fe633 -->
|
||||
SecurityToken? GetToken(string username, List<Claim> claims);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the current refresh token used to obtain new access tokens for authentication.
|
||||
/// </summary>
|
||||
/// <returns>The refresh token as a string.</returns>
|
||||
/// <!-- aidoc:v1 sig=575d89a -->
|
||||
string GetRefreshToken();
|
||||
|
||||
/// <summary>
|
||||
@@ -26,5 +28,6 @@ public interface ITokenService
|
||||
/// </summary>
|
||||
/// <param name="token">The security token to serialize.</param>
|
||||
/// <returns>A string containing the serialized form of the security token.</returns>
|
||||
/// <!-- aidoc:v1 sig=0e94bd2 -->
|
||||
string Serialize(SecurityToken token);
|
||||
}
|
||||
@@ -20,6 +20,7 @@ public interface IUserService
|
||||
/// <param name="username">The username of the user attempting to log in.</param>
|
||||
/// <param name="password">The password associated with the specified username.</param>
|
||||
/// <returns>A task that represents the asynchronous login operation, containing the <see cref="TokenResult"/> with the authentication token information.</returns>
|
||||
/// <!-- aidoc:v1 sig=d557171 -->
|
||||
Task<TokenResult> Login(string username, string password);
|
||||
/// <summary>
|
||||
/// Authenticates a user based on the provided username and password and returns the corresponding user.
|
||||
@@ -27,12 +28,14 @@ public interface IUserService
|
||||
/// <param name="username">The username of the user to authenticate.</param>
|
||||
/// <param name="password">The password of the user to authenticate.</param>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains the authenticated <see cref="User"/>.</returns>
|
||||
/// <!-- aidoc:v1 sig=b9ab570 -->
|
||||
Task<User> GetUser(string username, string password);
|
||||
/// <summary>
|
||||
/// Refreshes an authentication token using the provided refresh token and returns the resulting token information.
|
||||
/// </summary>
|
||||
/// <param name="refreshToken">The refresh token used to obtain a new access token.</param>
|
||||
/// <returns>A <see cref="Task{TResult}"/> that represents the asynchronous operation, containing the <see cref="TokenResult"/> with the refreshed token details.</returns>
|
||||
/// <!-- aidoc:v1 sig=c0187cf -->
|
||||
Task<TokenResult> RefreshToken(string refreshToken);
|
||||
|
||||
/// <summary>
|
||||
@@ -40,6 +43,7 @@ public interface IUserService
|
||||
/// </summary>
|
||||
/// <param name="token">The access token used to authenticate the user.</param>
|
||||
/// <returns>A task that represents the asynchronous login operation, containing the <see cref="TokenResult"/> with the outcome of the authentication.</returns>
|
||||
/// <!-- aidoc:v1 sig=b806672 -->
|
||||
Task<TokenResult> LoginWithAccessToken(string token);
|
||||
/// <summary>
|
||||
/// Validates the specified token according to its type and outputs the corresponding <see cref="SecurityToken"/>.
|
||||
@@ -47,6 +51,7 @@ public interface IUserService
|
||||
/// <param name="token">The token string to be validated.</param>
|
||||
/// <param name="tokenType">The type of the token, used to determine the appropriate validation strategy.</param>
|
||||
/// <param name="securityToken">When the method returns, contains the validated <see cref="SecurityToken"/> if validation succeeds.</param>
|
||||
/// <!-- aidoc:v1 sig=994e231 -->
|
||||
void ValidateToken(string token, string tokenType, out SecurityToken securityToken);
|
||||
/// <summary>
|
||||
/// Retrieves the user associated with the provided JWT security token.
|
||||
@@ -54,6 +59,7 @@ public interface IUserService
|
||||
/// </summary>
|
||||
/// <param name="jwtToken">The JWT security token used to identify the user. May be <c>null</c>.</param>
|
||||
/// <returns>A task that resolves to the <see cref="User"/> associated with the token, or <c>null</c> if the token is invalid or no user matches.</returns>
|
||||
/// <!-- aidoc:v1 sig=4e2d176 -->
|
||||
Task<User?> GetUserByToken(JwtSecurityToken? jwtToken);
|
||||
/// <summary>
|
||||
/// Asynchronously retrieves a user by validating a CAS (Central Authentication Service) ticket against the specified service.
|
||||
@@ -61,41 +67,48 @@ public interface IUserService
|
||||
/// <param name="service">The service URL or identifier that the ticket was issued for and must be validated against.</param>
|
||||
/// <param name="ticket">The CAS ticket string used to authenticate and identify the user.</param>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains the associated <see cref="User"/> if the ticket is valid, or <c>null</c> if the user cannot be found.</returns>
|
||||
/// <!-- aidoc:v1 sig=35a0f18 -->
|
||||
Task<User?> GetUserByCasTicket(string service, string ticket);
|
||||
/// <summary>
|
||||
/// Asynchronously generates a JSON Web Token (JWT) for the specified user and returns the token result.
|
||||
/// </summary>
|
||||
/// <param name="user">The user for whom the JWT is being generated.</param>
|
||||
/// <returns>A task that represents the asynchronous operation, containing the <see cref="TokenResult"/> with the generated token details.</returns>
|
||||
/// <!-- aidoc:v1 sig=87e065c -->
|
||||
Task<TokenResult> GenerateJwt(User user);
|
||||
/// <summary>
|
||||
/// Asynchronously retrieves all users from the data store.
|
||||
/// </summary>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains a list of all <see cref="User"/> entities.</returns>
|
||||
/// <!-- aidoc:v1 sig=52f36eb -->
|
||||
Task<List<User>> GetAll();
|
||||
/// <summary>
|
||||
/// Asynchronously retrieves a user by their unique identifier, returning <c>null</c> when no user matches the provided id.
|
||||
/// </summary>
|
||||
/// <param name="id">The unique <see cref="ObjectId"/> identifier of the user to look up.</param>
|
||||
/// <returns>A task that resolves to the matching <see cref="User"/>, or <c>null</c> if no user is found for the given id.</returns>
|
||||
/// <!-- aidoc:v1 sig=9fe25b3 -->
|
||||
Task<User?> GetUserById(ObjectId id);
|
||||
/// <summary>
|
||||
/// Asynchronously retrieves a user by their unique username, returning null when no matching user is found.
|
||||
/// </summary>
|
||||
/// <param name="name">The username used to look up the user.</param>
|
||||
/// <returns>A task that represents the asynchronous operation, containing the matching user if found; otherwise, null.</returns>
|
||||
/// <!-- aidoc:v1 sig=917e8bd -->
|
||||
Task<User?> GetUserByUserName(string name);
|
||||
/// <summary>
|
||||
/// Asynchronously retrieves a user matching the specified name, returning <c>null</c> when no matching user is found.
|
||||
/// </summary>
|
||||
/// <param name="name">The name used to look up the user.</param>
|
||||
/// <returns>A task that resolves to the matching <see cref="User"/>, or <c>null</c> if no user with the given name exists.</returns>
|
||||
/// <!-- aidoc:v1 sig=ea58eab -->
|
||||
Task<User?> GetUserByName(string name);
|
||||
/// <summary>
|
||||
/// Creates a user from the provided LDAP user entry.
|
||||
/// </summary>
|
||||
/// <param name="userEntryLdap">The LDAP user entry used to create the user.</param>
|
||||
/// <returns>A task that represents the asynchronous create operation, containing the created <see cref="User"/> or <c>null</c>.</returns>
|
||||
/// <!-- aidoc:v1 sig=aefe667 -->
|
||||
Task<User?> CreateUser(User userEntryLdap);
|
||||
/// <summary>
|
||||
/// Creates a new user based on the provided user data, typically originating from an incoming request.
|
||||
@@ -103,6 +116,7 @@ public interface IUserService
|
||||
/// </summary>
|
||||
/// <param name="user">The user data to use for creating the new user.</param>
|
||||
/// <returns>A task that represents the asynchronous operation. The result is the created <see cref="User"/>, or <see langword="null"/> if creation failed.</returns>
|
||||
/// <!-- aidoc:v1 sig=658bda4 -->
|
||||
Task<User?> CreateNewUserByRequest(User user);
|
||||
|
||||
/// <summary>
|
||||
@@ -110,6 +124,7 @@ public interface IUserService
|
||||
/// </summary>
|
||||
/// <param name="createUserWithAuthDto">The data transfer object containing the information required to create the user and its authorities.</param>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains the created <see cref="User"/> instance, or <c>null</c> if no user was created.</returns>
|
||||
/// <!-- aidoc:v1 sig=f76bd48 -->
|
||||
Task<User?> CreateNewUserWithAuthorities(CreateUserWithAuthDto createUserWithAuthDto);
|
||||
/// <summary>
|
||||
/// Updates an existing user along with the associated authorities, optionally updating the password.
|
||||
@@ -117,6 +132,7 @@ public interface IUserService
|
||||
/// <param name="createUserWithAuthDto">The data transfer object containing the user information and authorities to update.</param>
|
||||
/// <param name="updatePass">A flag indicating whether the user's password should be updated as part of the operation.</param>
|
||||
/// <returns>A task that represents the asynchronous operation, containing the updated <see cref="User"/> or <c>null</c> if the user was not found.</returns>
|
||||
/// <!-- aidoc:v1 sig=a4bc265 -->
|
||||
Task<User?> UpdateUserWithAuthorities(UpdateUserWithAuthDto createUserWithAuthDto, bool updatePass);
|
||||
/// <summary>
|
||||
/// Updates a user's information based on the provided user data, with an option to include password updates.
|
||||
@@ -124,6 +140,7 @@ public interface IUserService
|
||||
/// <param name="user">The user entity containing the updated information to be persisted.</param>
|
||||
/// <param name="updatePass">A flag indicating whether the user's password should be updated during this operation.</param>
|
||||
/// <returns>A task that returns the updated <see cref="User"/>, or null if the user could not be found.</returns>
|
||||
/// <!-- aidoc:v1 sig=4c6a1ca -->
|
||||
Task<User?> UpdateUsersByRequest(User user, bool updatePass);
|
||||
/// <summary>
|
||||
/// Updates the password for the user identified by the specified identifier, verifying the old password before applying the new one.
|
||||
@@ -132,41 +149,48 @@ public interface IUserService
|
||||
/// <param name="oldPassword">The user's current password, used to verify the request.</param>
|
||||
/// <param name="newPassword">The new password to set for the user.</param>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result is <c>true</c> if the password was updated successfully; otherwise, <c>false</c>.</returns>
|
||||
/// <!-- aidoc:v1 sig=38635ef -->
|
||||
Task<bool> UpdateUserPassword(ObjectId id, string oldPassword, string newPassword);
|
||||
/// <summary>
|
||||
/// Asynchronously deletes a user identified by the specified identifier.
|
||||
/// </summary>
|
||||
/// <param name="id">The unique identifier of the user to delete.</param>
|
||||
/// <returns>A task that represents the asynchronous operation, containing a value indicating whether the user was successfully deleted.</returns>
|
||||
/// <!-- aidoc:v1 sig=8d34422 -->
|
||||
Task<bool> DeleteUser(ObjectId id);
|
||||
/// <summary>
|
||||
/// Retrieves a paginated list of users based on the provided pagination filter configuration.
|
||||
/// </summary>
|
||||
/// <param name="config">The pagination filter that defines paging parameters such as page number and page size.</param>
|
||||
/// <returns>A task that represents the asynchronous operation, containing the paginated response of <see cref="User"/> entries.</returns>
|
||||
/// <!-- aidoc:v1 sig=e324e87 -->
|
||||
Task<PaginationResponse<User>> GetPaginatedUsers(PaginationFilter config);
|
||||
/// <summary>
|
||||
/// Asynchronously creates a new authority based on the provided authorization data.
|
||||
/// </summary>
|
||||
/// <param name="auth">The authorization information used to create the new authority.</param>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains the created <see cref="Authorization"/>.</returns>
|
||||
/// <!-- aidoc:v1 sig=d636b5c -->
|
||||
Task<Authorization> CreateNewAuthority(Authorization auth);
|
||||
/// <summary>
|
||||
/// Asynchronously deletes an authority identified by the specified identifier.
|
||||
/// </summary>
|
||||
/// <param name="id">The unique identifier of the authority to delete.</param>
|
||||
/// <returns>A task that represents the asynchronous delete operation. The task result contains a boolean indicating whether the authority was successfully deleted.</returns>
|
||||
/// <!-- aidoc:v1 sig=e85ede9 -->
|
||||
Task<bool> DeleteAuthority(string id);
|
||||
/// <summary>
|
||||
/// Updates the authority information based on the provided authorization data.
|
||||
/// </summary>
|
||||
/// <param name="authorization">The authorization entity containing the authority details to be updated.</param>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result is <c>true</c> if the update was successful; otherwise, <c>false</c>.</returns>
|
||||
/// <!-- aidoc:v1 sig=0295989 -->
|
||||
Task<bool> UpdateAuthority(Authorization authorization);
|
||||
/// <summary>
|
||||
/// Authenticates the user using the provided access token and returns the resulting token information.
|
||||
/// </summary>
|
||||
/// <param name="token">The access token used to perform the login.</param>
|
||||
/// <returns>A task that represents the asynchronous login operation, containing the token result.</returns>
|
||||
/// <!-- aidoc:v1 sig=485f1d7 -->
|
||||
Task<TokenResult> LoginWithGivenAccessToken(string token);
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
/// <summary>
|
||||
/// Represents a container for login-related information.
|
||||
/// </summary>
|
||||
/// <!-- aidoc:v1 sig=3e9909a -->
|
||||
public class LoginInfo
|
||||
{
|
||||
public string Username { get; set; } = null!;
|
||||
|
||||
@@ -6,6 +6,7 @@ namespace adas_core.Authentication.Models;
|
||||
/// <summary>
|
||||
/// Represents the result of a token-related operation, encapsulating the outcome and any associated token data.
|
||||
/// </summary>
|
||||
/// <!-- aidoc:v1 sig=3a6d234 -->
|
||||
public class TokenResult
|
||||
{
|
||||
public string AccessToken { get; set; } = null!;
|
||||
@@ -18,6 +19,7 @@ public class TokenResult
|
||||
/// <summary>
|
||||
/// Represents a panel UI component responsible for displaying token-related results.
|
||||
/// </summary>
|
||||
/// <!-- aidoc:v1 sig=2bd900f -->
|
||||
public class TokenResultPanel
|
||||
{
|
||||
public TokenResult TokenResult { get; set; } = null!;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
/// Represents a generic response in the Universal Chess Interface (UCI) protocol, encapsulating a payload of type <typeparamref name="T"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the response payload.</typeparam>
|
||||
/// <!-- aidoc:v1 sig=edd025b -->
|
||||
public class UciResponse<T>
|
||||
{
|
||||
/// <summary>
|
||||
@@ -40,6 +41,7 @@ public class UciResponse<T>
|
||||
/// </summary>
|
||||
/// <param name="entity">The entity to include in the response payload.</param>
|
||||
/// <returns>A <see cref="UciResponse{T}"/> containing the provided entity.</returns>
|
||||
/// <!-- aidoc:v1 sig=193e85b body=f1d7691 -->
|
||||
public static UciResponse<T> FromSuccess(T entity)
|
||||
{
|
||||
return new UciResponse<T>(entity);
|
||||
@@ -51,6 +53,7 @@ public class UciResponse<T>
|
||||
/// </summary>
|
||||
/// <param name="ex">The exception whose type name and message are used to populate the error response.</param>
|
||||
/// <returns>A <see cref="UciResponse{T}"/> containing the cleaned exception type name and the exception message as the error details.</returns>
|
||||
/// <!-- aidoc:v1 sig=f4afb5b body=80d56b7 -->
|
||||
public static UciResponse<T> FromError(Exception ex)
|
||||
{
|
||||
var error = ex.GetType().Name;
|
||||
@@ -65,6 +68,7 @@ public class UciResponse<T>
|
||||
/// <param name="error">The error code or identifier describing the failure.</param>
|
||||
/// <param name="message">An optional human-readable message providing additional context about the error.</param>
|
||||
/// <returns>A <see cref="UciResponse{T}"/> with <c>Success</c> set to <c>false</c>, the specified <paramref name="error"/>, and the optional <paramref name="message"/>.</returns>
|
||||
/// <!-- aidoc:v1 sig=43834ba body=b488e43 -->
|
||||
public static UciResponse<T> FromError(string error, string? message = null)
|
||||
{
|
||||
return new UciResponse<T>
|
||||
|
||||
@@ -9,12 +9,14 @@ namespace adas_core.Authentication.RegistrationExtensions;
|
||||
/// <remarks>
|
||||
/// This static class serves as a container for registration-related authentication operations.
|
||||
/// </remarks>
|
||||
/// <!-- aidoc:v1 sig=adfaf21 -->
|
||||
public static class AuthRegistration
|
||||
{
|
||||
/// <summary>
|
||||
/// Registers authentication-related services in the dependency injection container, including a singleton <see cref="IUserService"/> and a lazy wrapper for deferred resolution.
|
||||
/// </summary>
|
||||
/// <param name="serviceCollection">The service collection to which the authentication services are added.</param>
|
||||
/// <!-- aidoc:v1 sig=01f4b10 body=0bc4709 -->
|
||||
public static void AddAuth(this IServiceCollection serviceCollection)
|
||||
{
|
||||
serviceCollection.AddSingleton<IUserService, UserService>();
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace adas_core.Authentication;
|
||||
/// <remarks>
|
||||
/// This class is the default service component responsible for handling user domain logic and delegating persistence or infrastructure concerns as required by the interface.
|
||||
/// </remarks>
|
||||
/// <!-- aidoc:v1 sig=ea2e8b0 -->
|
||||
public class UserService : IUserService
|
||||
{
|
||||
private readonly ILocalAuditService _auditService;
|
||||
@@ -109,6 +110,7 @@ public class UserService : IUserService
|
||||
/// <returns>A <see cref="Task{TResult}"/> containing the generated <see cref="TokenResult"/> for the authenticated user.</returns>
|
||||
/// <exception cref="UnauthorizedException">Thrown when no user matches the provided credentials, or when the user is not in the whitelist or valid groups.</exception>
|
||||
/// <exception cref="ForbbidenException">Thrown when the user account is disabled or currently locked.</exception>
|
||||
/// <!-- aidoc:v1 sig=1e8af8c body=0dd331a -->
|
||||
public async Task<TokenResult> Login(string username, string password)
|
||||
{
|
||||
var user = await GetUser(username, password);
|
||||
@@ -134,6 +136,7 @@ public class UserService : IUserService
|
||||
/// <param name="tokenType">The type of the token being validated.</param>
|
||||
/// <param name="validatedToken">When the method returns, contains the validated <see cref="SecurityToken"/> if validation succeeds.</param>
|
||||
/// <exception cref="TokenException">Thrown when the token is invalid, is not signed with the HmacSha256 algorithm, or any other validation error occurs.</exception>
|
||||
/// <!-- aidoc:v1 sig=cd90202 body=4ddd4b1 -->
|
||||
public void ValidateToken(string token, string tokenType, out SecurityToken validatedToken)
|
||||
{
|
||||
try
|
||||
@@ -176,6 +179,8 @@ public class UserService : IUserService
|
||||
/// <param name="jwtToken">The <see cref="JwtSecurityToken"/> containing the user identity claims, or <see langword="null"/> to indicate no token was supplied.</param>
|
||||
/// <returns>A <see cref="Task{User}"/> that resolves to the matching <see cref="User"/> with its password cleared and authorization loaded if required, or <see langword="null"/> when the token is missing or no user matches the extracted username.</returns>
|
||||
/// <!-- aidoc:v1 sig=29f6fec body=a7970c3 -->
|
||||
/// <!-- aidoc-review:v1 severity=low kind=wrong_returns
|
||||
/// "The <see cref=\"Task{User}\"/> reference indicates a non-nullable Task<User>, but the method actually returns Task<User?> with a nullable User." -->
|
||||
public async Task<User?> GetUserByToken(JwtSecurityToken? jwtToken)
|
||||
{
|
||||
User? user = null;
|
||||
@@ -204,6 +209,8 @@ public class UserService : IUserService
|
||||
/// <exception cref="LoginServicesException">Thrown when the CAS login method is not available, or when an unexpected error occurs during authentication.</exception>
|
||||
/// <exception cref="UnauthorizedAccessException">Thrown when the authenticated user is not in the users whitelist and does not belong to any valid group.</exception>
|
||||
/// <exception cref="BusinessException">Rethrown when a business-level error occurs during the login process.</exception>
|
||||
/// <!-- aidoc-review:v1 severity=high kind=stale_summary
|
||||
/// "Summary states the method 'authenticates a user using a CAS ticket', but the ticket parameter is never used in the active code path - authentication is performed via service.Login(_httpContextAccessor.HttpContext). The <returns> clause also references ticket validity ('if the ticket is valid'), which is not checked." -->
|
||||
public async Task<User?> GetUserByCasTicket(string serviceUrl, string ticket)
|
||||
{
|
||||
var service = _availableLoginServices.FirstOrDefault(s => s.Method == UserEnum.LoginMethod.Cas);
|
||||
@@ -250,6 +257,7 @@ public class UserService : IUserService
|
||||
/// </summary>
|
||||
/// <param name="refreshToken">The refresh token used to generate a new JWT.</param>
|
||||
/// <returns>A TokenResult containing the new JWT, or an empty result if the user associated with the token is not found.</returns>
|
||||
/// <!-- aidoc:v1 sig=1902a2f body=bb5bba0 -->
|
||||
public async Task<TokenResult> RefreshToken(string refreshToken)
|
||||
{
|
||||
ValidateToken(refreshToken, IUserService.TokenTypeRefresh, out var validatedToken);
|
||||
@@ -269,6 +277,7 @@ public class UserService : IUserService
|
||||
/// <param name="password">The password to authenticate against.</param>
|
||||
/// <returns>The authenticated <see cref="User"/> returned by the first successful login service.</returns>
|
||||
/// <exception cref="LoginServicesNotFoundException">Thrown when no configured login service successfully authenticates the user.</exception>
|
||||
/// <!-- aidoc:v1 sig=b90d52e body=0ab820c -->
|
||||
public async Task<User> GetUser(string username, string password)
|
||||
{
|
||||
//BusinessException? loginException = null;
|
||||
@@ -297,6 +306,7 @@ public class UserService : IUserService
|
||||
/// </summary>
|
||||
/// <param name="id">The unique identifier of the user to retrieve.</param>
|
||||
/// <returns>A <see cref="Task{User}"/> containing the user with its authorization populated, or <c>null</c> if the user cannot be found or an exception is thrown during retrieval.</returns>
|
||||
/// <!-- aidoc:v1 sig=6af9d13 body=5ffaaf2 -->
|
||||
public async Task<User?> GetUserById(ObjectId id)
|
||||
{
|
||||
try
|
||||
@@ -316,6 +326,7 @@ public class UserService : IUserService
|
||||
/// </summary>
|
||||
/// <param name="name">The username to look up.</param>
|
||||
/// <returns>The matching <see cref="User"/> with its <c>Authorization</c> property populated from the authority service, or <c>null</c> if no user is found.</returns>
|
||||
/// <!-- aidoc:v1 sig=f6a5557 body=812fa43 -->
|
||||
public async Task<User?> GetUserByUserName(string name)
|
||||
{
|
||||
var u = await _userRepository.GetByUserName(name);
|
||||
@@ -330,6 +341,7 @@ public class UserService : IUserService
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the user to look up.</param>
|
||||
/// <returns>A <see cref="User"/> instance with its <c>Authorization</c> populated when found; otherwise, <c>null</c>.</returns>
|
||||
/// <!-- aidoc:v1 sig=5fce94d body=3ae1c25 -->
|
||||
public async Task<User?> GetUserByName(string name)
|
||||
{
|
||||
try
|
||||
@@ -349,6 +361,7 @@ public class UserService : IUserService
|
||||
/// </summary>
|
||||
/// <param name="userEntryLdap">The user information sourced from LDAP to be created in the system.</param>
|
||||
/// <returns>The created user retrieved by username, or null if the user cannot be found after insertion.</returns>
|
||||
/// <!-- aidoc:v1 sig=191573e body=81f390b -->
|
||||
public async Task<User?> CreateUser(User userEntryLdap)
|
||||
{
|
||||
CheckIfUserNameExists(userEntryLdap.UserName);
|
||||
@@ -366,6 +379,7 @@ public class UserService : IUserService
|
||||
/// <returns>The created user retrieved by username after insertion.</returns>
|
||||
/// <exception cref="UnprocessableEntityException">Thrown when a local user's password is not considered strong.</exception>
|
||||
/// <exception cref="NotFoundException">Thrown when the user cannot be retrieved by username after insertion.</exception>
|
||||
/// <!-- aidoc:v1 sig=82465f8 body=d4f7721 -->
|
||||
public async Task<User?> CreateNewUserByRequest(User user)
|
||||
{
|
||||
CheckIfEmailExists(user.Email);
|
||||
@@ -391,6 +405,7 @@ public class UserService : IUserService
|
||||
/// <param name="createUserWithAuthDto">The data transfer object containing the user details and the list of authorizations to associate with the new user.</param>
|
||||
/// <returns>The newly created user, or <c>null</c> if creation fails (in which case an exception is thrown instead).</returns>
|
||||
/// <exception cref="NotFoundException">Thrown when the user cannot be created by the underlying request, indicating a missing resource.</exception>
|
||||
/// <!-- aidoc:v1 sig=b28ec32 body=6f231bc -->
|
||||
public async Task<User?> CreateNewUserWithAuthorities(CreateUserWithAuthDto createUserWithAuthDto)
|
||||
{
|
||||
var user = createUserWithAuthDto.User;
|
||||
@@ -413,6 +428,7 @@ public class UserService : IUserService
|
||||
/// <param name="updatePass">Indicates whether the user's password should be updated and re-hashed.</param>
|
||||
/// <returns>The updated user returned by the repository, or <c>null</c> if the user could not be found or updated.</returns>
|
||||
/// <exception cref="UnprocessableEntityException">Thrown when <paramref name="updatePass"/> is <c>true</c> and the provided password does not meet the strong password policy.</exception>
|
||||
/// <!-- aidoc:v1 sig=4a0b955 body=0eb37fa -->
|
||||
public async Task<User?> UpdateUsersByRequest(User user, bool updatePass)
|
||||
{
|
||||
var oldUser = await _userRepository.GetByUserName(user.UserName);
|
||||
@@ -443,6 +459,8 @@ public class UserService : IUserService
|
||||
/// <param name="elementUpdated">The element that has been updated and should be transmitted to the subscribers.</param>
|
||||
/// <param name="userName">The user name used to filter the subscribers that will receive the broadcast.</param>
|
||||
/// <param name="operation">The type of operation (e.g., create, update, delete) associated with the broadcast.</param>
|
||||
/// <!-- aidoc-review:v1 severity=medium kind=wrong_summary
|
||||
/// "Summary says the broadcast notifies subscribers of 'an update operation', but the code passes through any OperationType (which the param description itself lists as create/update/delete), not just update operations." -->
|
||||
private async Task SendBroadcastUser(object elementUpdated, string userName, OperationType operation)
|
||||
{
|
||||
var subscribers = _subscribersService.GetSubscribers().Where(s =>
|
||||
@@ -459,6 +477,7 @@ public class UserService : IUserService
|
||||
/// <param name="elementUpdated">The updated element to send as the notification payload to non-admin subscribers.</param>
|
||||
/// <param name="userName">The username whose subscribers will receive the broadcast.</param>
|
||||
/// <param name="operation">The operation type that describes the nature of the update.</param>
|
||||
/// <!-- aidoc:v1 sig=4f775b6 body=1033854 -->
|
||||
private async Task SendBroadcastPermissions(object elementUpdated, string userName, OperationType operation)
|
||||
{
|
||||
var subscribers = _subscribersService.GetSubscribers().Where(s =>
|
||||
@@ -491,6 +510,7 @@ public class UserService : IUserService
|
||||
/// <param name="updatePass">Flag indicating whether the user's password should be updated as part of the operation.</param>
|
||||
/// <returns>The updated <see cref="User"/>.</returns>
|
||||
/// <exception cref="ConflictException">Thrown when the underlying user update returns no result.</exception>
|
||||
/// <!-- aidoc:v1 sig=99d7acb body=7cdfa30 -->
|
||||
public async Task<User?> UpdateUserWithAuthorities(UpdateUserWithAuthDto updateUserWithAuthDto, bool updatePass)
|
||||
{
|
||||
var u = updateUserWithAuthDto.User;
|
||||
@@ -525,6 +545,7 @@ public class UserService : IUserService
|
||||
/// <exception cref="BadRequestException">Thrown when <paramref name="newPassword"/> is equal to <paramref name="oldPassword"/>.</exception>
|
||||
/// <exception cref="NotFoundException">Thrown when no user exists for the supplied <paramref name="id"/>.</exception>
|
||||
/// <exception cref="UnprocessableEntityException">Thrown when <paramref name="oldPassword"/> does not match the user's current password, or when <paramref name="newPassword"/> does not satisfy the strength policy.</exception>
|
||||
/// <!-- aidoc:v1 sig=0243044 body=c52695d -->
|
||||
public async Task<bool> UpdateUserPassword(ObjectId id, string oldPassword, string newPassword)
|
||||
{
|
||||
if (oldPassword == newPassword)
|
||||
@@ -561,6 +582,7 @@ public class UserService : IUserService
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier of the user to delete.</param>
|
||||
/// <returns>A task that resolves to <c>true</c> when the user is successfully deleted; otherwise, <c>false</c> if an error is encountered.</returns>
|
||||
/// <!-- aidoc:v1 sig=72679b2 body=c3e6d4f -->
|
||||
public async Task<bool> DeleteUser(ObjectId id)
|
||||
{
|
||||
try
|
||||
@@ -582,6 +604,7 @@ public class UserService : IUserService
|
||||
/// </summary>
|
||||
/// <param name="filter">The pagination filter containing the page number and page size used to skip, limit, and shape the result set.</param>
|
||||
/// <returns>A task that represents the asynchronous operation. The task result contains a <see cref="PaginationResponse{User}"/> with the requested page of users and pagination details.</returns>
|
||||
/// <!-- aidoc:v1 sig=0367293 body=27c2222 -->
|
||||
public async Task<PaginationResponse<User>> GetPaginatedUsers(PaginationFilter filter)
|
||||
{
|
||||
var result = _userRepository.GetPaginatedUsers(filter);
|
||||
@@ -603,6 +626,7 @@ public class UserService : IUserService
|
||||
/// </summary>
|
||||
/// <param name="user">The user whose identity, email, IP address, and authorization claims will be embedded in the generated tokens.</param>
|
||||
/// <returns>A <see cref="TokenResult"/> containing the serialized access and refresh tokens, their respective expiration times, and the associated user.</returns>
|
||||
/// <!-- aidoc:v1 sig=67521e7 body=d87cd16 -->
|
||||
public async Task<TokenResult> GenerateJwt(User user)
|
||||
{
|
||||
var claims = new List<Claim>
|
||||
@@ -650,6 +674,7 @@ public class UserService : IUserService
|
||||
/// <returns>A task that resolves to the list of <see cref="User"/> objects returned by the first successful login service.</returns>
|
||||
/// <exception cref="LoginServicesException">Thrown when a non-business exception occurs while retrieving users from a service.</exception>
|
||||
/// <exception cref="LoginServicesNotFoundException">Thrown when no login service matches the valid login methods or all attempts fail without a captured business exception.</exception>
|
||||
/// <!-- aidoc:v1 sig=b9380e5 body=b90883c -->
|
||||
public async Task<List<User>> GetAll()
|
||||
{
|
||||
BusinessException? loginException = null;
|
||||
@@ -688,6 +713,7 @@ public class UserService : IUserService
|
||||
/// <param name="token">The access token to validate and use for user authentication.</param>
|
||||
/// <returns>A <see cref="TokenResult"/> containing the new access token, refresh token, their expiry times, and the authenticated user.</returns>
|
||||
/// <exception cref="NotFoundException">Thrown when no user can be resolved from the provided token.</exception>
|
||||
/// <!-- aidoc:v1 sig=4a410ea body=f486923 -->
|
||||
public async Task<TokenResult> LoginWithGivenAccessToken(string token)
|
||||
{
|
||||
ValidateToken(token, IUserService.TokenTypeUser, out var validatedToken);
|
||||
@@ -742,6 +768,7 @@ public class UserService : IUserService
|
||||
/// <param name="token">The access token used to identify and authenticate the user.</param>
|
||||
/// <returns>A <see cref="Task{TokenResult}"/> containing the generated JWT for the authenticated user.</returns>
|
||||
/// <exception cref="NotFoundException">Thrown when no user is found that matches the validated access token.</exception>
|
||||
/// <!-- aidoc:v1 sig=58a9e83 body=98c26eb -->
|
||||
public async Task<TokenResult> LoginWithAccessToken(string token)
|
||||
{
|
||||
ValidateToken(token, IUserService.TokenTypeUser, out var validatedToken);
|
||||
@@ -759,6 +786,7 @@ public class UserService : IUserService
|
||||
/// <param name="auth">The authorization used to create the new user authority.</param>
|
||||
/// <returns>The newly created <see cref="Authorization"/> instance.</returns>
|
||||
/// <exception cref="ConflictException">Thrown when the authority service fails to create the user authority (returns null).</exception>
|
||||
/// <!-- aidoc:v1 sig=b73cf48 body=71c9c28 -->
|
||||
public async Task<Authorization> CreateNewAuthority(Authorization auth)
|
||||
{
|
||||
var newUserAuthority = await _authorityService.CreateNewUserAuthority(auth) ??
|
||||
@@ -773,6 +801,7 @@ public class UserService : IUserService
|
||||
/// <returns>A task that resolves to <c>true</c> when the authority is successfully deleted.</returns>
|
||||
/// <exception cref="BadRequestException">Thrown when the provided <paramref name="id"/> is not a valid ObjectId format.</exception>
|
||||
/// <exception cref="ConflictException">Thrown when the underlying delete operation fails.</exception>
|
||||
/// <!-- aidoc:v1 sig=eaa5d92 body=8a73373 -->
|
||||
public async Task<bool> DeleteAuthority(string id)
|
||||
{
|
||||
if (!ObjectId.TryParse(id, out var userAuthorityIdParsed))
|
||||
@@ -788,6 +817,7 @@ public class UserService : IUserService
|
||||
/// <param name="authorization">The authorization details used to update the user's authority.</param>
|
||||
/// <returns>A task that resolves to <c>true</c> when the authority is successfully updated.</returns>
|
||||
/// <exception cref="ConflictException">Thrown when the authority service returns a null response, indicating the update failed.</exception>
|
||||
/// <!-- aidoc:v1 sig=544e59f body=c079022 -->
|
||||
public async Task<bool> UpdateAuthority(Authorization authorization)
|
||||
{
|
||||
_ = await _authorityService.EditUserAuthority(authorization) ??
|
||||
@@ -801,6 +831,7 @@ public class UserService : IUserService
|
||||
/// </summary>
|
||||
/// <param name="authorities">The list of authorizations to convert into claims.</param>
|
||||
/// <returns>A task that represents the asynchronous operation, containing the list of claims built from the supplied authorities.</returns>
|
||||
/// <!-- aidoc:v1 sig=527b34e body=d91d2bf -->
|
||||
public async Task<List<Claim>> ClaimsFromAuthorities(List<Authorization> authorities)
|
||||
{
|
||||
var claims = new List<Claim>();
|
||||
@@ -828,6 +859,7 @@ public class UserService : IUserService
|
||||
/// </summary>
|
||||
/// <param name="auth">The authorization source whose role and display identifier are used to build the claim value.</param>
|
||||
/// <param name="claims">The list of claims to which the new role claim is appended when not already present.</param>
|
||||
/// <!-- aidoc:v1 sig=85111ea body=f681ceb -->
|
||||
private static void AddClaim(Authorization auth, List<Claim> claims)
|
||||
{
|
||||
var newClaim = new Claim(ClaimTypes.Role,
|
||||
@@ -844,6 +876,7 @@ public class UserService : IUserService
|
||||
/// <param name="userName">The username to validate against existing users.</param>
|
||||
/// <param name="userId">Optional identifier of the user being updated; when provided, that user is excluded from the duplicate check.</param>
|
||||
/// <exception cref="BadRequestException">Thrown when another user with the same <paramref name="userName"/> already exists.</exception>
|
||||
/// <!-- aidoc:v1 sig=cd63db7 body=c9563e3 -->
|
||||
private void CheckIfUserNameExists(string userName, ObjectId? userId = null)
|
||||
{
|
||||
var users = GetAll().Result;
|
||||
@@ -860,6 +893,7 @@ public class UserService : IUserService
|
||||
/// <param name="email">The email address to verify for uniqueness in the user collection.</param>
|
||||
/// <param name="userId">The optional ID of the current user; when set, it is excluded from the duplicate email check.</param>
|
||||
/// <exception cref="BadRequestException">Thrown when the email is already registered to a different user.</exception>
|
||||
/// <!-- aidoc:v1 sig=074e36e body=4e4b89e -->
|
||||
private void CheckIfEmailExists(string email, ObjectId? userId = null)
|
||||
{
|
||||
var users = GetAll().Result;
|
||||
|
||||
Reference in New Issue
Block a user