Files
PnvPanel/backend/src/PnvPanel.Infrastructure/Identity/RoleService.cs
T
Leonid Pershin 24d9ea1099
CI / Backend (build + test) (push) Successful in 1m14s
CI / Frontend (lint + typecheck + build) (push) Successful in 30s
Implement role and user management enhancements
- Added MaxIpLimit to roles, allowing for the configuration of simultaneous IP limits for users.
- Updated role creation and update commands to include MaxIpLimit, ensuring proper handling in the application logic.
- Enhanced user management by introducing a DELETE endpoint for user accounts, with appropriate checks to prevent self-deletion.
- Updated documentation to reflect changes in role and user management, clarifying the new IP limit functionality and user deletion process.
- Adjusted related tests to cover new functionality and ensure robust validation of role and user management features.
2026-07-13 07:18:13 +03:00

86 lines
3.3 KiB
C#

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<AppRole> roleManager, UserManager<AppUser> userManager) : IRoleService
{
public async Task<Result<RoleDto>> CreateRoleAsync(string name, int maxConfigs, int maxIpLimit, CancellationToken cancellationToken)
{
if (await roleManager.RoleExistsAsync(name))
return Result.Failure<RoleDto>(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<RoleDto>(Error.Validation(
"Roles.CreateFailed", string.Join("; ", result.Errors.Select(e => e.Description))));
}
return Result.Success(ToDto(role));
}
public async Task<Result<RoleDto>> UpdateRoleAsync(Guid roleId, int maxConfigs, int maxIpLimit, CancellationToken cancellationToken)
{
var role = await roleManager.FindByIdAsync(roleId.ToString());
if (role is null)
return Result.Failure<RoleDto>(RoleErrors.NotFound);
role.MaxConfigs = maxConfigs;
role.MaxIpLimit = maxIpLimit;
await roleManager.UpdateAsync(role);
return Result.Success(ToDto(role));
}
public async Task<Result> 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<IReadOnlyList<RoleDto>> 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<Result> 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);
}