Enhance documentation with new features: added dark/light/system theme support, instructions page, and application catalog. Updated API and domain model for app management and automatic migrations on startup. Improved frontend structure with new routes and features for user instructions and app management.
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
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, CancellationToken cancellationToken)
|
||||
{
|
||||
if (await roleManager.RoleExistsAsync(name))
|
||||
return Result.Failure<RoleDto>(RoleErrors.DuplicateName);
|
||||
|
||||
var role = new AppRole(name) { MaxConfigs = maxConfigs, 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, CancellationToken cancellationToken)
|
||||
{
|
||||
var role = await roleManager.FindByIdAsync(roleId.ToString());
|
||||
if (role is null)
|
||||
return Result.Failure<RoleDto>(RoleErrors.NotFound);
|
||||
|
||||
role.MaxConfigs = maxConfigs;
|
||||
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.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.IsSystem);
|
||||
}
|
||||
Reference in New Issue
Block a user