Implement role and user management enhancements
CI / Backend (build + test) (push) Successful in 1m14s
CI / Frontend (lint + typecheck + build) (push) Successful in 30s

- 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.
This commit is contained in:
Leonid Pershin
2026-07-13 07:18:13 +03:00
parent 48e8d06a41
commit 24d9ea1099
48 changed files with 1240 additions and 171 deletions
@@ -5,7 +5,8 @@ namespace PnvPanel.Application.Common.Interfaces;
public sealed record AuthenticatedUser(Guid Id, string UserName, string Role);
public sealed record CurrentUserProfile(
Guid Id, string UserName, Guid RoleId, string Role, bool IsActivated, bool IsBlocked, int MaxConfigs, string SubscriptionToken);
Guid Id, string UserName, Guid RoleId, string Role, bool IsActivated, bool IsBlocked, int MaxConfigs, int MaxIpLimit,
string SubscriptionToken);
public sealed record UserSummaryDto(Guid Id, string UserName, string Role, bool IsActivated, bool IsBlocked, DateTimeOffset? ActivatedAt);
@@ -2,13 +2,13 @@ using PnvPanel.Application.Common.Models;
namespace PnvPanel.Application.Common.Interfaces;
public sealed record RoleDto(Guid Id, string Name, int MaxConfigs, bool IsSystem);
public sealed record RoleDto(Guid Id, string Name, int MaxConfigs, int MaxIpLimit, bool IsSystem);
public interface IRoleService
{
Task<Result<RoleDto>> CreateRoleAsync(string name, int maxConfigs, CancellationToken cancellationToken);
Task<Result<RoleDto>> CreateRoleAsync(string name, int maxConfigs, int maxIpLimit, CancellationToken cancellationToken);
Task<Result<RoleDto>> UpdateRoleAsync(Guid roleId, int maxConfigs, CancellationToken cancellationToken);
Task<Result<RoleDto>> UpdateRoleAsync(Guid roleId, int maxConfigs, int maxIpLimit, CancellationToken cancellationToken);
Task<Result> DeleteRoleAsync(Guid roleId, CancellationToken cancellationToken);
@@ -24,9 +24,13 @@ public interface IXuiPanelGateway
void InvalidateClient(Guid nodeId);
/// <summary>Возвращает ClientExternalId, присвоенный панелью (UUID для VLESS/VMess, пароль для Trojan/Shadowsocks).</summary>
/// <summary>
/// Возвращает ClientExternalId, присвоенный панелью (UUID для VLESS/VMess, пароль для Trojan/Shadowsocks).
/// <paramref name="limitIp"/> — лимит одновременных IP клиента (квота роли, см. AppRole.MaxIpLimit);
/// -1 (RoleQuota.Unlimited) означает без лимита — гейтвей сам переводит его в нативное значение 3x-ui.
/// </summary>
Task<Result<string>> AddClientAsync(
Node node, string inboundRemoteId, VpnProtocol protocol, string clientEmail, string clientName,
Node node, string inboundRemoteId, VpnProtocol protocol, string clientEmail, string clientName, int limitIp,
CancellationToken cancellationToken);
Task<Result> RemoveClientAsync(