Add settings endpoints and registration status check: implement new API endpoints for settings management, including registration status retrieval, and update the registration command handler to enforce registration rules based on site settings.
This commit is contained in:
@@ -26,4 +26,9 @@ public static class AuthErrors
|
||||
"Auth.UserNameTaken",
|
||||
"Это имя пользователя уже занято."
|
||||
);
|
||||
|
||||
public static readonly Error RegistrationDisabled = Error.Forbidden(
|
||||
"Auth.RegistrationDisabled",
|
||||
"Регистрация на сайте отключена администратором."
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,8 @@ namespace TeleWave.Application.Auth.Register;
|
||||
public sealed class RegisterCommandHandler(
|
||||
IIdentityService identityService,
|
||||
IJwtTokenService jwtTokenService,
|
||||
IRefreshTokenService refreshTokenService
|
||||
IRefreshTokenService refreshTokenService,
|
||||
ISiteSettings siteSettings
|
||||
) : ICommandHandler<RegisterCommand, Result<AuthResult>>
|
||||
{
|
||||
public async Task<Result<AuthResult>> Handle(
|
||||
@@ -15,6 +16,10 @@ public sealed class RegisterCommandHandler(
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
// Открытая регистрация должна быть явно включена админом; иначе учётки заводит только он.
|
||||
if (!await siteSettings.IsRegistrationEnabledAsync(cancellationToken))
|
||||
return Result.Failure<AuthResult>(AuthErrors.RegistrationDisabled);
|
||||
|
||||
var createResult = await identityService.CreateUserAsync(
|
||||
command.UserName,
|
||||
command.Password,
|
||||
|
||||
@@ -3,6 +3,7 @@ using TeleWave.Domain.Auth;
|
||||
using TeleWave.Domain.Broadcast;
|
||||
using TeleWave.Domain.Library;
|
||||
using TeleWave.Domain.Media;
|
||||
using TeleWave.Domain.Settings;
|
||||
|
||||
namespace TeleWave.Application.Common.Interfaces;
|
||||
|
||||
@@ -14,6 +15,7 @@ public interface IAppDbContext
|
||||
DbSet<Channel> Channels { get; }
|
||||
DbSet<ScheduleEntry> ScheduleEntries { get; }
|
||||
DbSet<BumperAsset> BumperAssets { get; }
|
||||
DbSet<AppSetting> AppSettings { get; }
|
||||
|
||||
Task<int> SaveChangesAsync(CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace TeleWave.Application.Common.Interfaces;
|
||||
|
||||
/// <summary>Доступ к глобальным настройкам сайта (key-value), скрывающий хранилище от хендлеров.</summary>
|
||||
public interface ISiteSettings
|
||||
{
|
||||
Task<bool> IsRegistrationEnabledAsync(CancellationToken cancellationToken);
|
||||
|
||||
/// <summary>Пишет значение в контекст (сохранение — за UnitOfWorkBehavior вызывающей команды).</summary>
|
||||
Task SetRegistrationEnabledAsync(bool enabled, CancellationToken cancellationToken);
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using TeleWave.Application.Common.Interfaces;
|
||||
|
||||
namespace TeleWave.Application.Settings;
|
||||
|
||||
/// <summary>Чтение типизированных значений из key-value настроек с дефолтом при отсутствии ключа.</summary>
|
||||
public static class AppSettingsReader
|
||||
{
|
||||
public static async Task<bool> GetBoolSettingAsync(
|
||||
this IAppDbContext db,
|
||||
string key,
|
||||
bool defaultValue,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
var value = await db.AppSettings.AsNoTracking()
|
||||
.Where(s => s.Key == key)
|
||||
.Select(s => s.Value)
|
||||
.FirstOrDefaultAsync(cancellationToken);
|
||||
|
||||
return value is not null && bool.TryParse(value, out var parsed) ? parsed : defaultValue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
using LiteCqrs;
|
||||
|
||||
namespace TeleWave.Application.Settings.GetSiteSettings;
|
||||
|
||||
public sealed record GetSiteSettingsQuery : IQuery<SiteSettingsDto>;
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
using LiteCqrs;
|
||||
using TeleWave.Application.Common.Interfaces;
|
||||
|
||||
namespace TeleWave.Application.Settings.GetSiteSettings;
|
||||
|
||||
public sealed class GetSiteSettingsQueryHandler(ISiteSettings siteSettings)
|
||||
: IQueryHandler<GetSiteSettingsQuery, SiteSettingsDto>
|
||||
{
|
||||
public async Task<SiteSettingsDto> Handle(
|
||||
GetSiteSettingsQuery query,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
var registrationEnabled = await siteSettings.IsRegistrationEnabledAsync(cancellationToken);
|
||||
return new SiteSettingsDto(registrationEnabled);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
namespace TeleWave.Application.Settings;
|
||||
|
||||
/// <summary>Стабильные ключи глобальных настроек сайта в key-value хранилище (AppSetting).</summary>
|
||||
public static class SettingKeys
|
||||
{
|
||||
/// <summary>Разрешена ли открытая регистрация пользователей (по умолчанию — нет).</summary>
|
||||
public const string RegistrationEnabled = "registration.enabled";
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
namespace TeleWave.Application.Settings;
|
||||
|
||||
/// <summary>Глобальные настройки сайта, управляемые администратором.</summary>
|
||||
public sealed record SiteSettingsDto(bool RegistrationEnabled);
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
using LiteCqrs;
|
||||
using TeleWave.Application.Common.Models;
|
||||
|
||||
namespace TeleWave.Application.Settings.UpdateSiteSettings;
|
||||
|
||||
public sealed record UpdateSiteSettingsCommand(bool RegistrationEnabled) : ICommand<Result>;
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
using LiteCqrs;
|
||||
using TeleWave.Application.Common.Interfaces;
|
||||
using TeleWave.Application.Common.Models;
|
||||
|
||||
namespace TeleWave.Application.Settings.UpdateSiteSettings;
|
||||
|
||||
public sealed class UpdateSiteSettingsCommandHandler(ISiteSettings siteSettings)
|
||||
: ICommandHandler<UpdateSiteSettingsCommand, Result>
|
||||
{
|
||||
public async Task<Result> Handle(
|
||||
UpdateSiteSettingsCommand command,
|
||||
CancellationToken cancellationToken
|
||||
)
|
||||
{
|
||||
// Сохранение выполняет UnitOfWorkBehavior команды.
|
||||
await siteSettings.SetRegistrationEnabledAsync(command.RegistrationEnabled, cancellationToken);
|
||||
return Result.Success();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user