Implement activation checks across various commands and queries
- Introduced `IRequiresActivation` interface to enforce activation requirements for multiple commands and queries, ensuring that only activated users can create, edit, or access configurations, news, and applications. - Updated the `RequireActivationBehavior` to handle activation checks uniformly, returning appropriate errors for unauthenticated or inactive users. - Enhanced error handling by adding `NotActivated` error to provide clear feedback for users attempting to access restricted features. - Updated documentation to reflect the new activation requirements and their implications on user access and functionality.
This commit is contained in:
@@ -4,9 +4,6 @@ namespace PnvPanel.Application.Configs;
|
||||
|
||||
public static class ConfigErrors
|
||||
{
|
||||
public static readonly Error NotActivated =
|
||||
Error.Forbidden("Configs.NotActivated", "Аккаунт не активирован — обратитесь к администратору.");
|
||||
|
||||
public static readonly Error InboundNotAvailable =
|
||||
Error.NotFound("Configs.InboundNotAvailable", "Инбаунд недоступен.");
|
||||
|
||||
|
||||
@@ -3,4 +3,4 @@ using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Configs.Create;
|
||||
|
||||
public sealed record CreateVpnConfigCommand(Guid InboundId, string? Label) : ICommand<Result<VpnConfigDto>>;
|
||||
public sealed record CreateVpnConfigCommand(Guid InboundId, string? Label) : ICommand<Result<VpnConfigDto>>, IRequiresActivation;
|
||||
|
||||
@@ -20,9 +20,6 @@ public sealed class CreateVpnConfigCommandHandler(
|
||||
if (profile is null)
|
||||
return Result.Failure<VpnConfigDto>(AuthErrors.Unauthorized);
|
||||
|
||||
if (!profile.IsActivated)
|
||||
return Result.Failure<VpnConfigDto>(ConfigErrors.NotActivated);
|
||||
|
||||
var inbound = await dbContext.Inbounds.AsNoTracking()
|
||||
.FirstOrDefaultAsync(i => i.Id == command.InboundId, cancellationToken);
|
||||
|
||||
|
||||
@@ -3,4 +3,4 @@ using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Configs.Edit;
|
||||
|
||||
public sealed record EditVpnConfigCommand(Guid ConfigId, string? Label) : ICommand<Result<VpnConfigDto>>;
|
||||
public sealed record EditVpnConfigCommand(Guid ConfigId, string? Label) : ICommand<Result<VpnConfigDto>>, IRequiresActivation;
|
||||
|
||||
@@ -3,7 +3,7 @@ using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Configs.GetConfigLink;
|
||||
|
||||
public sealed record GetConfigLinkQuery(Guid ConfigId) : IQuery<Result<ConfigLinkDto>>;
|
||||
public sealed record GetConfigLinkQuery(Guid ConfigId) : IQuery<Result<ConfigLinkDto>>, IRequiresActivation;
|
||||
|
||||
/// <summary>SubscriptionToken — Api-слой строит из него абсолютный URL (знает scheme/host запроса).</summary>
|
||||
public sealed record ConfigLinkDto(string ConnectionString, string SubscriptionToken);
|
||||
|
||||
@@ -3,6 +3,6 @@ using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Configs.GetMyConfigs;
|
||||
|
||||
public sealed record GetMyConfigsQuery : IQuery<Result<GetMyConfigsResult>>;
|
||||
public sealed record GetMyConfigsQuery : IQuery<Result<GetMyConfigsResult>>, IRequiresActivation;
|
||||
|
||||
public sealed record GetMyConfigsResult(IReadOnlyList<VpnConfigDto> Configs, int MaxConfigs);
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@ using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Configs.GetMySubscription;
|
||||
|
||||
public sealed record GetMySubscriptionQuery : IQuery<Result<MySubscriptionDto>>;
|
||||
public sealed record GetMySubscriptionQuery : IQuery<Result<MySubscriptionDto>>, IRequiresActivation;
|
||||
|
||||
/// <summary>SubscriptionToken — Api-слой строит из него абсолютный URL (знает scheme/host запроса), см. GetConfigLinkQuery.</summary>
|
||||
public sealed record MySubscriptionDto(string SubscriptionToken);
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ using PnvPanel.Domain.Inbounds;
|
||||
|
||||
namespace PnvPanel.Application.Configs.ListAvailableInbounds;
|
||||
|
||||
public sealed record ListAvailableInboundsQuery : IQuery<Result<IReadOnlyList<AvailableInboundDto>>>;
|
||||
public sealed record ListAvailableInboundsQuery : IQuery<Result<IReadOnlyList<AvailableInboundDto>>>, IRequiresActivation;
|
||||
|
||||
/// <summary>Витринная карточка инбаунда для выбора при создании конфига — без деталей 3x-ui.</summary>
|
||||
public sealed record AvailableInboundDto(Guid InboundId, string DisplayName, VpnProtocol Protocol);
|
||||
|
||||
@@ -3,4 +3,4 @@ using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Configs.Revoke;
|
||||
|
||||
public sealed record RevokeVpnConfigCommand(Guid ConfigId) : ICommand<Result>;
|
||||
public sealed record RevokeVpnConfigCommand(Guid ConfigId) : ICommand<Result>, IRequiresActivation;
|
||||
|
||||
@@ -3,4 +3,4 @@ using PnvPanel.Application.Common.Models;
|
||||
|
||||
namespace PnvPanel.Application.Configs.Rotate;
|
||||
|
||||
public sealed record RotateVpnConfigCommand(Guid ConfigId) : ICommand<Result<VpnConfigDto>>;
|
||||
public sealed record RotateVpnConfigCommand(Guid ConfigId) : ICommand<Result<VpnConfigDto>>, IRequiresActivation;
|
||||
|
||||
Reference in New Issue
Block a user