using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using PnvPanel.Application.Admin.Roles; using PnvPanel.Application.Admin.Users; using PnvPanel.Application.Common.Interfaces; using PnvPanel.Application.Common.Models; namespace PnvPanel.Infrastructure.Identity; internal sealed class RoleService(RoleManager roleManager, UserManager userManager) : IRoleService { public async Task> CreateRoleAsync(string name, int maxConfigs, int maxIpLimit, CancellationToken cancellationToken) { if (await roleManager.RoleExistsAsync(name)) return Result.Failure(RoleErrors.DuplicateName); var role = new AppRole(name) { MaxConfigs = maxConfigs, MaxIpLimit = maxIpLimit, IsSystem = false }; var result = await roleManager.CreateAsync(role); if (!result.Succeeded) { return Result.Failure(Error.Validation( "Roles.CreateFailed", string.Join("; ", result.Errors.Select(e => e.Description)))); } return Result.Success(ToDto(role)); } public async Task> UpdateRoleAsync(Guid roleId, int maxConfigs, int maxIpLimit, CancellationToken cancellationToken) { var role = await roleManager.FindByIdAsync(roleId.ToString()); if (role is null) return Result.Failure(RoleErrors.NotFound); role.MaxConfigs = maxConfigs; role.MaxIpLimit = maxIpLimit; await roleManager.UpdateAsync(role); return Result.Success(ToDto(role)); } public async Task DeleteRoleAsync(Guid roleId, CancellationToken cancellationToken) { var role = await roleManager.FindByIdAsync(roleId.ToString()); if (role is null) return Result.Failure(RoleErrors.NotFound); if (role.IsSystem) return Result.Failure(RoleErrors.CannotModifySystemRole); var usersInRole = await userManager.GetUsersInRoleAsync(role.Name!); if (usersInRole.Count > 0) return Result.Failure(RoleErrors.RoleInUse); await roleManager.DeleteAsync(role); return Result.Success(); } public async Task> ListRolesAsync(CancellationToken cancellationToken) { return await roleManager.Roles .OrderBy(r => r.Name) .Select(r => new RoleDto(r.Id, r.Name!, r.MaxConfigs, r.MaxIpLimit, r.IsSystem)) .ToListAsync(cancellationToken); } public async Task ChangeUserRoleAsync(Guid userId, Guid roleId, CancellationToken cancellationToken) { var user = await userManager.FindByIdAsync(userId.ToString()); if (user is null) return Result.Failure(UserErrors.NotFound); var role = await roleManager.FindByIdAsync(roleId.ToString()); if (role is null) return Result.Failure(RoleErrors.NotFound); var currentRoles = await userManager.GetRolesAsync(user); if (currentRoles.Count > 0) await userManager.RemoveFromRolesAsync(user, currentRoles); await userManager.AddToRoleAsync(user, role.Name!); return Result.Success(); } private static RoleDto ToDto(AppRole role) => new(role.Id, role.Name!, role.MaxConfigs, role.MaxIpLimit, role.IsSystem); }