feat: add a return of the data that has been configured
This commit is contained in:
parent
fd578aa61e
commit
e9ff1cabe8
17
ApiDto/Common/CacheType.cs
Normal file
17
ApiDto/Common/CacheType.cs
Normal file
@ -0,0 +1,17 @@
|
||||
namespace Mirea.Api.Dto.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the types of caching mechanisms available.
|
||||
/// </summary>
|
||||
public enum CacheType
|
||||
{
|
||||
/// <summary>
|
||||
/// Memcached caching type.
|
||||
/// </summary>
|
||||
Memcached,
|
||||
|
||||
/// <summary>
|
||||
/// Redis caching type.
|
||||
/// </summary>
|
||||
Redis
|
||||
}
|
22
ApiDto/Common/DatabaseType.cs
Normal file
22
ApiDto/Common/DatabaseType.cs
Normal file
@ -0,0 +1,22 @@
|
||||
namespace Mirea.Api.Dto.Common;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the types of databases supported.
|
||||
/// </summary>
|
||||
public enum DatabaseType
|
||||
{
|
||||
/// <summary>
|
||||
/// MySQL database type.
|
||||
/// </summary>
|
||||
Mysql,
|
||||
|
||||
/// <summary>
|
||||
/// SQLite database type.
|
||||
/// </summary>
|
||||
Sqlite,
|
||||
|
||||
/// <summary>
|
||||
/// PostgreSQL database type.
|
||||
/// </summary>
|
||||
PostgresSql
|
||||
}
|
@ -10,27 +10,18 @@ public class CreateUserRequest
|
||||
/// <summary>
|
||||
/// Gets or sets the email address of the user.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The email address is a required field.
|
||||
/// </remarks>
|
||||
[Required]
|
||||
public required string Email { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the username of the user.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The username is a required field.
|
||||
/// </remarks>
|
||||
[Required]
|
||||
public required string Username { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the password of the user.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The password is a required field.
|
||||
/// </remarks>
|
||||
[Required]
|
||||
public required string Password { get; set; }
|
||||
}
|
||||
|
@ -1,16 +1,17 @@
|
||||
using Mirea.Api.Dto.Common;
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Mirea.Api.Dto.Responses;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the response containing information about available OAuth providers.
|
||||
/// </summary>
|
||||
public class AvailableProvidersResponse
|
||||
public class AvailableOAuthProvidersResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the OAuth provider.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public required string ProviderName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@ -19,7 +20,8 @@ public class AvailableProvidersResponse
|
||||
public OAuthProvider Provider { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the redirect URI for the OAuth provider.
|
||||
/// Gets or sets the redirect URL for the OAuth provider's authorization process.
|
||||
/// </summary>
|
||||
public required Uri Redirect { get; set; }
|
||||
[Required]
|
||||
public required string Redirect { get; set; }
|
||||
}
|
29
ApiDto/Responses/Configuration/CacheResponse.cs
Normal file
29
ApiDto/Responses/Configuration/CacheResponse.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using Mirea.Api.Dto.Common;
|
||||
|
||||
namespace Mirea.Api.Dto.Responses.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a response containing cache configuration details.
|
||||
/// </summary>
|
||||
public class CacheResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the type of cache database.
|
||||
/// </summary>
|
||||
public CacheType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the server address.
|
||||
/// </summary>
|
||||
public string? Server { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the port number.
|
||||
/// </summary>
|
||||
public int Port { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the password.
|
||||
/// </summary>
|
||||
public string? Password { get; set; }
|
||||
}
|
49
ApiDto/Responses/Configuration/DatabaseResponse.cs
Normal file
49
ApiDto/Responses/Configuration/DatabaseResponse.cs
Normal file
@ -0,0 +1,49 @@
|
||||
using Mirea.Api.Dto.Common;
|
||||
|
||||
namespace Mirea.Api.Dto.Responses.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a response containing database configuration details.
|
||||
/// </summary>
|
||||
public class DatabaseResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the type of database.
|
||||
/// </summary>
|
||||
public DatabaseType Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the server address.
|
||||
/// </summary>
|
||||
public string? Server { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the port number.
|
||||
/// </summary>
|
||||
public int Port { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the database name.
|
||||
/// </summary>
|
||||
public string? Database { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the username.
|
||||
/// </summary>
|
||||
public string? User { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether SSL is enabled.
|
||||
/// </summary>
|
||||
public bool Ssl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the password.
|
||||
/// </summary>
|
||||
public string? Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the path to database. Only for Sqlite
|
||||
/// </summary>
|
||||
public string? PathToDatabase { get; set; }
|
||||
}
|
17
ApiDto/Responses/TotpKeyResponse.cs
Normal file
17
ApiDto/Responses/TotpKeyResponse.cs
Normal file
@ -0,0 +1,17 @@
|
||||
namespace Mirea.Api.Dto.Responses;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the response containing the TOTP (Time-Based One-Time Password) key details.
|
||||
/// </summary>
|
||||
public class TotpKeyResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the secret key used for TOTP generation.
|
||||
/// </summary>
|
||||
public required string Secret { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the image (QR code) representing the TOTP key.
|
||||
/// </summary>
|
||||
public required string Image { get; set; }
|
||||
}
|
35
ApiDto/Responses/UserResponse.cs
Normal file
35
ApiDto/Responses/UserResponse.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using Mirea.Api.Dto.Common;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Mirea.Api.Dto.Responses;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a response containing user information.
|
||||
/// </summary>
|
||||
public class UserResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the email address of the user.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public required string Email { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the username of the user.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public required string Username { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the user has two-factor authentication enabled.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public bool TwoFactorAuthenticatorEnabled { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a collection of OAuth providers used by the user.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public required IEnumerable<OAuthProvider> UsedOAuthProviders { get; set; }
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Mirea.Api.Dto.Common;
|
||||
using Mirea.Api.Endpoint.Configuration.Model;
|
||||
using Mirea.Api.Endpoint.Configuration.Model.GeneralSettings;
|
||||
|
||||
namespace Mirea.Api.Endpoint.Configuration.Core.Startup;
|
||||
|
||||
@ -10,7 +10,7 @@ public static class CacheConfiguration
|
||||
public static IServiceCollection AddCustomRedis(this IServiceCollection services, IConfiguration configuration, IHealthChecksBuilder? healthChecksBuilder = null)
|
||||
{
|
||||
var cache = configuration.Get<GeneralConfig>()?.CacheSettings;
|
||||
if (cache?.TypeDatabase != CacheSettings.CacheEnum.Redis)
|
||||
if (cache?.TypeDatabase != CacheType.Redis)
|
||||
return services;
|
||||
|
||||
services.AddStackExchangeRedisCache(options =>
|
||||
|
@ -1,8 +1,8 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Mirea.Api.Dto.Common;
|
||||
using Mirea.Api.Endpoint.Common.Services.Security;
|
||||
using Mirea.Api.Endpoint.Configuration.Model;
|
||||
using Mirea.Api.Endpoint.Configuration.Model.GeneralSettings;
|
||||
using Mirea.Api.Security;
|
||||
using Mirea.Api.Security.Common.Interfaces;
|
||||
|
||||
@ -16,7 +16,7 @@ public static class SecureConfiguration
|
||||
|
||||
services.AddSingleton<IRevokedToken, MemoryRevokedTokenService>();
|
||||
|
||||
if (configuration.Get<GeneralConfig>()?.CacheSettings?.TypeDatabase == CacheSettings.CacheEnum.Redis)
|
||||
if (configuration.Get<GeneralConfig>()?.CacheSettings?.TypeDatabase == CacheType.Redis)
|
||||
services.AddSingleton<ICacheService, DistributedCacheService>();
|
||||
else
|
||||
services.AddSingleton<ICacheService, MemoryCacheService>();
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Mirea.Api.Endpoint.Configuration.Validation.Attributes;
|
||||
using Mirea.Api.Dto.Common;
|
||||
using Mirea.Api.Endpoint.Configuration.Validation.Attributes;
|
||||
using Mirea.Api.Endpoint.Configuration.Validation.Interfaces;
|
||||
|
||||
namespace Mirea.Api.Endpoint.Configuration.Model.GeneralSettings;
|
||||
@ -6,18 +7,12 @@ namespace Mirea.Api.Endpoint.Configuration.Model.GeneralSettings;
|
||||
[RequiredSettings]
|
||||
public class CacheSettings : IIsConfigured
|
||||
{
|
||||
public enum CacheEnum
|
||||
{
|
||||
Memcached,
|
||||
Redis
|
||||
}
|
||||
|
||||
public CacheEnum TypeDatabase { get; set; }
|
||||
public CacheType TypeDatabase { get; set; }
|
||||
public string? ConnectionString { get; set; }
|
||||
|
||||
public bool IsConfigured()
|
||||
{
|
||||
return TypeDatabase == CacheEnum.Memcached ||
|
||||
return TypeDatabase == CacheType.Memcached ||
|
||||
!string.IsNullOrEmpty(ConnectionString);
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using Mirea.Api.DataAccess.Persistence.Common;
|
||||
using Mirea.Api.Dto.Common;
|
||||
using Mirea.Api.Endpoint.Configuration.Validation.Attributes;
|
||||
using Mirea.Api.Endpoint.Configuration.Validation.Interfaces;
|
||||
using System;
|
||||
@ -9,22 +10,16 @@ namespace Mirea.Api.Endpoint.Configuration.Model.GeneralSettings;
|
||||
[RequiredSettings]
|
||||
public class DbSettings : IIsConfigured
|
||||
{
|
||||
public enum DatabaseEnum
|
||||
{
|
||||
Mysql,
|
||||
Sqlite,
|
||||
PostgresSql
|
||||
}
|
||||
public DatabaseEnum TypeDatabase { get; set; }
|
||||
public DatabaseType TypeDatabase { get; set; }
|
||||
public required string ConnectionStringSql { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public DatabaseProvider DatabaseProvider =>
|
||||
TypeDatabase switch
|
||||
{
|
||||
DatabaseEnum.PostgresSql => DatabaseProvider.Postgresql,
|
||||
DatabaseEnum.Mysql => DatabaseProvider.Mysql,
|
||||
DatabaseEnum.Sqlite => DatabaseProvider.Sqlite,
|
||||
DatabaseType.PostgresSql => DatabaseProvider.Postgresql,
|
||||
DatabaseType.Mysql => DatabaseProvider.Mysql,
|
||||
DatabaseType.Sqlite => DatabaseProvider.Sqlite,
|
||||
_ => throw new ArgumentOutOfRangeException()
|
||||
};
|
||||
|
||||
|
@ -4,15 +4,21 @@ using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Mirea.Api.Dto.Common;
|
||||
using Mirea.Api.Dto.Requests;
|
||||
using Mirea.Api.Dto.Requests.Configuration;
|
||||
using Mirea.Api.Dto.Responses;
|
||||
using Mirea.Api.Dto.Responses.Configuration;
|
||||
using Mirea.Api.Endpoint.Common.Attributes;
|
||||
using Mirea.Api.Endpoint.Common.Exceptions;
|
||||
using Mirea.Api.Endpoint.Common.Interfaces;
|
||||
using Mirea.Api.Endpoint.Common.MapperDto;
|
||||
using Mirea.Api.Endpoint.Common.Services;
|
||||
using Mirea.Api.Endpoint.Configuration.Model;
|
||||
using Mirea.Api.Endpoint.Configuration.Model.GeneralSettings;
|
||||
using Mirea.Api.Endpoint.Configuration.Validation.Validators;
|
||||
using Mirea.Api.Security.Common.Domain;
|
||||
using Mirea.Api.Security.Services;
|
||||
using MySqlConnector;
|
||||
using Npgsql;
|
||||
@ -36,7 +42,8 @@ public class SetupController(
|
||||
ISetupToken setupToken,
|
||||
IMaintenanceModeNotConfigureService notConfigureService,
|
||||
IMemoryCache cache,
|
||||
PasswordHashService passwordHashService) : BaseController
|
||||
PasswordHashService passwordHashService,
|
||||
IOptionsSnapshot<Admin> user) : BaseController
|
||||
{
|
||||
private const string CacheGeneralKey = "config_general";
|
||||
private const string CacheAdminKey = "config_admin";
|
||||
@ -95,7 +102,12 @@ public class SetupController(
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
private ActionResult<bool> SetDatabase<TConnection, TException>(string connectionString, DbSettings.DatabaseEnum databaseType)
|
||||
[HttpGet("IsConfiguredToken")]
|
||||
[TokenAuthentication]
|
||||
public ActionResult<bool> IsConfiguredToken() =>
|
||||
Ok(true);
|
||||
|
||||
private void SetDatabase<TConnection, TException>(string connectionString, DatabaseType databaseType)
|
||||
where TConnection : class, IDbConnection, new()
|
||||
where TException : Exception
|
||||
{
|
||||
@ -118,8 +130,6 @@ public class SetupController(
|
||||
TypeDatabase = databaseType
|
||||
};
|
||||
GeneralConfig = general;
|
||||
|
||||
return Ok(true);
|
||||
}
|
||||
catch (TException ex)
|
||||
{
|
||||
@ -138,7 +148,20 @@ public class SetupController(
|
||||
if (request.Ssl)
|
||||
connectionString += ";SSL Mode=Require;";
|
||||
|
||||
return SetDatabase<NpgsqlConnection, NpgsqlException>(connectionString, DbSettings.DatabaseEnum.PostgresSql);
|
||||
|
||||
SetDatabase<NpgsqlConnection, NpgsqlException>(connectionString, DatabaseType.PostgresSql);
|
||||
cache.Set("database", new DatabaseResponse
|
||||
{
|
||||
Type = DatabaseType.PostgresSql,
|
||||
Database = request.Database,
|
||||
Password = request.Password,
|
||||
Ssl = request.Ssl,
|
||||
Port = request.Port,
|
||||
Server = request.Server,
|
||||
User = request.User
|
||||
});
|
||||
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
[HttpPost("SetMysql")]
|
||||
@ -152,7 +175,19 @@ public class SetupController(
|
||||
if (request.Ssl)
|
||||
connectionString += "SslMode=Require;";
|
||||
|
||||
return SetDatabase<MySqlConnection, MySqlException>(connectionString, DbSettings.DatabaseEnum.Mysql);
|
||||
SetDatabase<MySqlConnection, MySqlException>(connectionString, DatabaseType.Mysql);
|
||||
cache.Set("database", new DatabaseResponse
|
||||
{
|
||||
Type = DatabaseType.Mysql,
|
||||
Database = request.Database,
|
||||
Password = request.Password,
|
||||
Ssl = request.Ssl,
|
||||
Port = request.Port,
|
||||
Server = request.Server,
|
||||
User = request.User
|
||||
});
|
||||
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
[HttpPost("SetSqlite")]
|
||||
@ -179,14 +214,26 @@ public class SetupController(
|
||||
var filePath = Path.Combine(path, "database.db3");
|
||||
var connectionString = $"Data Source={filePath}";
|
||||
|
||||
var result = SetDatabase<SqliteConnection, SqliteException>(connectionString, DbSettings.DatabaseEnum.Sqlite);
|
||||
SetDatabase<SqliteConnection, SqliteException>(connectionString, DatabaseType.Sqlite);
|
||||
|
||||
foreach (var file in Directory.GetFiles(path))
|
||||
System.IO.File.Delete(file);
|
||||
|
||||
return result;
|
||||
cache.Set("database", new DatabaseResponse
|
||||
{
|
||||
Type = DatabaseType.Sqlite,
|
||||
PathToDatabase = path
|
||||
});
|
||||
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
[HttpGet("DatabaseConfiguration")]
|
||||
[TokenAuthentication]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public ActionResult<DatabaseRequest> DatabaseConfiguration() =>
|
||||
cache.TryGetValue<DatabaseResponse>("database", out var response) ? Ok(response) : NoContent();
|
||||
|
||||
[HttpPost("SetRedis")]
|
||||
[TokenAuthentication]
|
||||
[BadRequestResponse]
|
||||
@ -205,10 +252,17 @@ public class SetupController(
|
||||
general.CacheSettings = new CacheSettings
|
||||
{
|
||||
ConnectionString = connectionString,
|
||||
TypeDatabase = CacheSettings.CacheEnum.Redis
|
||||
TypeDatabase = CacheType.Redis
|
||||
};
|
||||
GeneralConfig = general;
|
||||
|
||||
cache.Set("cache", new CacheResponse
|
||||
{
|
||||
Type = CacheType.Redis,
|
||||
Server = request.Server,
|
||||
Password = request.Password,
|
||||
Port = request.Port
|
||||
});
|
||||
return Ok(true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -226,20 +280,29 @@ public class SetupController(
|
||||
general.CacheSettings = new CacheSettings
|
||||
{
|
||||
ConnectionString = null,
|
||||
TypeDatabase = CacheSettings.CacheEnum.Memcached
|
||||
TypeDatabase = CacheType.Memcached
|
||||
};
|
||||
GeneralConfig = general;
|
||||
|
||||
cache.Set("cache", new CacheResponse
|
||||
{
|
||||
Type = CacheType.Memcached
|
||||
});
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
[HttpGet("CacheConfiguration")]
|
||||
[TokenAuthentication]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public ActionResult<CacheResponse> CacheConfiguration() =>
|
||||
cache.TryGetValue<CacheResponse>("cache", out var response) ? Ok(response) : NoContent();
|
||||
|
||||
[HttpPost("CreateAdmin")]
|
||||
[TokenAuthentication]
|
||||
[BadRequestResponse]
|
||||
public ActionResult<string> CreateAdmin([FromBody] CreateUserRequest user)
|
||||
{
|
||||
if (!PasswordHashService.HasPasswordInPolicySecurity(user.Password))
|
||||
throw new ControllerArgumentException("The password must be at least 8 characters long and contain at least one uppercase letter and one special character.");
|
||||
new PasswordPolicyService(GeneralConfig.PasswordPolicy).ValidatePasswordOrThrow(user.Password);
|
||||
|
||||
if (!MailAddress.TryCreate(user.Email, out _))
|
||||
throw new ControllerArgumentException("The email address is incorrect.");
|
||||
@ -258,6 +321,73 @@ public class SetupController(
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
[HttpGet("UpdateAdminConfiguration")]
|
||||
[TokenAuthentication]
|
||||
public ActionResult UpdateAdminConfiguration()
|
||||
{
|
||||
if (string.IsNullOrEmpty(user.Value.Email))
|
||||
return Ok();
|
||||
|
||||
if (!cache.TryGetValue<Admin>(CacheAdminKey, out var admin))
|
||||
{
|
||||
admin = user.Value;
|
||||
cache.Set(CacheAdminKey, admin);
|
||||
return Ok();
|
||||
}
|
||||
|
||||
admin!.OAuthProviders = user.Value.OAuthProviders;
|
||||
|
||||
if (string.IsNullOrEmpty(admin.Email))
|
||||
admin.Email = user.Value.Email;
|
||||
|
||||
if (string.IsNullOrEmpty(admin.Username))
|
||||
admin.Username = user.Value.Username;
|
||||
|
||||
cache.Set(CacheAdminKey, admin);
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[HttpGet("AdminConfiguration")]
|
||||
[TokenAuthentication]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public ActionResult<UserResponse> AdminConfiguration() =>
|
||||
cache.TryGetValue<Admin>(CacheAdminKey, out var admin) ? Ok(new UserResponse()
|
||||
{
|
||||
Email = admin!.Email,
|
||||
Username = admin.Username,
|
||||
TwoFactorAuthenticatorEnabled = admin.TwoFactorAuthenticator != TwoFactorAuthenticator.None,
|
||||
UsedOAuthProviders = admin.OAuthProviders == null ? [] : admin.OAuthProviders.Keys.Select(x => x.ConvertToDto())
|
||||
}) : NoContent();
|
||||
|
||||
[HttpGet("GenerateTotpKey")]
|
||||
[TokenAuthentication]
|
||||
public ActionResult<string> GenerateTotpKey()
|
||||
{
|
||||
if (cache.TryGetValue<string>("totpSecret", out var secret))
|
||||
return secret!;
|
||||
|
||||
secret = GeneratorKey.GenerateAlphaNumericBase32Compatible(16);
|
||||
cache.Set("totpSecret", secret);
|
||||
return secret;
|
||||
}
|
||||
|
||||
[HttpGet("VerifyTotp")]
|
||||
[TokenAuthentication]
|
||||
public ActionResult<bool> VerifyTotp([FromQuery] string code)
|
||||
{
|
||||
var isCorrect = cache.TryGetValue<string>("totpSecret", out var secret) &&
|
||||
new TotpService(secret!).VerifyToken(code);
|
||||
|
||||
if (!isCorrect || !cache.TryGetValue<Admin>(CacheAdminKey, out var admin))
|
||||
return false;
|
||||
|
||||
admin!.Secret = secret;
|
||||
admin.TwoFactorAuthenticator = TwoFactorAuthenticator.Totp;
|
||||
cache.Set(CacheAdminKey, admin);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[HttpPost("SetLogging")]
|
||||
[TokenAuthentication]
|
||||
[BadRequestResponse]
|
||||
@ -292,9 +422,22 @@ public class SetupController(
|
||||
general.LogSettings = settings;
|
||||
GeneralConfig = general;
|
||||
|
||||
cache.Set("logging", new LoggingRequest
|
||||
{
|
||||
EnableLogToFile = settings.EnableLogToFile,
|
||||
LogFileName = settings.LogFileName,
|
||||
LogFilePath = settings.LogFilePath
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[HttpGet("LoggingConfiguration")]
|
||||
[TokenAuthentication]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public ActionResult<LoggingRequest> LoggingConfiguration() =>
|
||||
cache.TryGetValue<LoggingRequest>("logging", out var data) ? Ok(data) : NoContent();
|
||||
|
||||
[HttpPost("SetEmail")]
|
||||
[TokenAuthentication]
|
||||
[BadRequestResponse]
|
||||
@ -318,9 +461,16 @@ public class SetupController(
|
||||
general.EmailSettings = settings;
|
||||
GeneralConfig = general;
|
||||
|
||||
cache.Set("email", settings);
|
||||
return true;
|
||||
}
|
||||
|
||||
[HttpGet("EmailConfiguration")]
|
||||
[TokenAuthentication]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public ActionResult<EmailRequest> EmailConfiguration() =>
|
||||
cache.TryGetValue<EmailRequest>("email", out var data) ? Ok(data) : NoContent();
|
||||
|
||||
[HttpPost("SetSchedule")]
|
||||
[TokenAuthentication]
|
||||
[BadRequestResponse]
|
||||
@ -349,8 +499,20 @@ public class SetupController(
|
||||
|
||||
GeneralConfig = general;
|
||||
|
||||
cache.Set("schedule", new ScheduleConfigurationRequest()
|
||||
{
|
||||
StartTerm = general.ScheduleSettings.StartTerm,
|
||||
CronUpdateSchedule = general.ScheduleSettings.CronUpdateSchedule
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
[HttpGet("ScheduleConfiguration")]
|
||||
[TokenAuthentication]
|
||||
[ProducesResponseType(StatusCodes.Status204NoContent)]
|
||||
public ActionResult<ScheduleConfigurationRequest> ScheduleConfiguration() =>
|
||||
cache.TryGetValue<ScheduleConfigurationRequest>("schedule", out var data) ? Ok(data) : NoContent();
|
||||
|
||||
[HttpPost("SetPasswordPolicy")]
|
||||
[TokenAuthentication]
|
||||
public ActionResult<bool> SetPasswordPolicy([FromBody] PasswordPolicy? policy = null)
|
||||
|
Loading…
x
Reference in New Issue
Block a user