Compare commits
11 Commits
07d7fec24f
...
e1ad287da1
Author | SHA1 | Date | |
---|---|---|---|
e1ad287da1 | |||
f9750ef039 | |||
17961ccefc | |||
5d308f1a24 | |||
f5deeec6c9 | |||
29c9c10a53 | |||
c02240077f | |||
2d67a565ca | |||
ba8ccf8b7e | |||
e7ed69169c | |||
eefb049e0e |
26
ApiDto/Requests/Configuration/CacheRequest.cs
Normal file
26
ApiDto/Requests/Configuration/CacheRequest.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Mirea.Api.Dto.Requests.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a request to configure cache settings.
|
||||
/// </summary>
|
||||
public class CacheRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the server address.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public required string Server { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the port number.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public int Port { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the password.
|
||||
/// </summary>
|
||||
public string? Password { get; set; }
|
||||
}
|
44
ApiDto/Requests/Configuration/DatabaseRequest.cs
Normal file
44
ApiDto/Requests/Configuration/DatabaseRequest.cs
Normal file
@ -0,0 +1,44 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Mirea.Api.Dto.Requests.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a request to configure the database connection settings.
|
||||
/// </summary>
|
||||
public class DatabaseRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the server address.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public required string Server { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the port number.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public int Port { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the database name.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public required string Database { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the username.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public required string User { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether SSL is enabled.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public bool Ssl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the password.
|
||||
/// </summary>
|
||||
public string? Password { get; set; }
|
||||
}
|
45
ApiDto/Requests/Configuration/EmailRequest.cs
Normal file
45
ApiDto/Requests/Configuration/EmailRequest.cs
Normal file
@ -0,0 +1,45 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Mirea.Api.Dto.Requests.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a request to configure email settings.
|
||||
/// </summary>
|
||||
public class EmailRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the server address.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public required string Server { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the email address from which emails will be sent.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public required string From { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the password for the email account.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public required string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the port number.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public int Port { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether SSL is enabled.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public bool Ssl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the username.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public required string User { get; set; }
|
||||
}
|
25
ApiDto/Requests/Configuration/LoggingRequest.cs
Normal file
25
ApiDto/Requests/Configuration/LoggingRequest.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Mirea.Api.Dto.Requests.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a request to configure logging settings.
|
||||
/// </summary>
|
||||
public class LoggingRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether logging to file is enabled.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public bool EnableLogToFile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the log file name.
|
||||
/// </summary>
|
||||
public string? LogFileName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the log file path.
|
||||
/// </summary>
|
||||
public string? LogFilePath { get; set; }
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
using Mirea.Api.Dto.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Mirea.Api.Dto.Requests.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a request to configure the schedule settings.
|
||||
/// </summary>
|
||||
public class ScheduleConfigurationRequest
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the cron expression for updating the schedule.
|
||||
/// </summary>
|
||||
public string? CronUpdateSchedule { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the start date of the term.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public DateOnly StartTerm { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the pair period times, keyed by pair number.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public required IDictionary<int, PairPeriodTime> PairPeriod { get; set; }
|
||||
}
|
@ -1,19 +1,40 @@
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using Cronos;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Mirea.Api.Dto.Requests;
|
||||
using Mirea.Api.Dto.Requests.Configuration;
|
||||
using Mirea.Api.Endpoint.Common.Attributes;
|
||||
using Mirea.Api.Endpoint.Common.Exceptions;
|
||||
using Mirea.Api.Endpoint.Common.Interfaces;
|
||||
using Mirea.Api.Endpoint.Common.Services;
|
||||
using Mirea.Api.Endpoint.Configuration.General;
|
||||
using Mirea.Api.Endpoint.Configuration.General.Settings;
|
||||
using MySqlConnector;
|
||||
using Npgsql;
|
||||
using StackExchange.Redis;
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Mirea.Api.Endpoint.Controllers.Configuration;
|
||||
|
||||
[ApiVersion("1.0")]
|
||||
[ApiController]
|
||||
[MaintenanceModeIgnore]
|
||||
public class SetupController(ISetupToken setupToken, IMaintenanceModeNotConfigureService notConfigureService) : BaseController
|
||||
public class SetupController(ISetupToken setupToken, IMaintenanceModeNotConfigureService notConfigureService, IMemoryCache cache) : BaseController
|
||||
{
|
||||
private const string CacheGeneralKey = "config_part";
|
||||
private GeneralConfig GeneralConfig
|
||||
{
|
||||
get => cache.Get<GeneralConfig>(CacheGeneralKey) ?? new GeneralConfig();
|
||||
set => cache.Set(CacheGeneralKey, value);
|
||||
}
|
||||
|
||||
[HttpGet("GenerateToken")]
|
||||
[Localhost]
|
||||
public ActionResult<string> GenerateToken()
|
||||
@ -45,5 +66,205 @@ public class SetupController(ISetupToken setupToken, IMaintenanceModeNotConfigur
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
private ActionResult<bool> SetDatabase<TConnection, TException>(string connectionString, DbSettings.DatabaseEnum databaseType)
|
||||
where TConnection : class, IDbConnection, new()
|
||||
where TException : Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
using var connection = new TConnection();
|
||||
connection.ConnectionString = connectionString;
|
||||
connection.Open();
|
||||
connection.Close();
|
||||
|
||||
var general = GeneralConfig;
|
||||
general.DbSettings = new DbSettings
|
||||
{
|
||||
ConnectionStringSql = connectionString,
|
||||
TypeDatabase = databaseType
|
||||
};
|
||||
GeneralConfig = general;
|
||||
|
||||
return Ok(true);
|
||||
}
|
||||
catch (TException ex)
|
||||
{
|
||||
throw new ControllerArgumentException($"Error when connecting: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("SetPsql")]
|
||||
[TokenAuthentication]
|
||||
[BadRequestResponse]
|
||||
public ActionResult<bool> SetPsql([FromBody] DatabaseRequest request)
|
||||
{
|
||||
string connectionString = $"Host={request.Server}:{request.Port};Username={request.User};Database={request.Database}";
|
||||
if (request.Password != null)
|
||||
connectionString += $";Password={request.Password}";
|
||||
if (request.Ssl)
|
||||
connectionString += ";SSL Mode=Require;";
|
||||
|
||||
return SetDatabase<NpgsqlConnection, NpgsqlException>(connectionString, DbSettings.DatabaseEnum.PostgresSql);
|
||||
}
|
||||
|
||||
[HttpPost("SetMysql")]
|
||||
[TokenAuthentication]
|
||||
[BadRequestResponse]
|
||||
public ActionResult<bool> SetMysql([FromBody] DatabaseRequest request)
|
||||
{
|
||||
string connectionString = $"Server={request.Server}:{request.Port};Uid={request.User};Database={request.Database}";
|
||||
if (request.Password != null)
|
||||
connectionString += $";Pwd={request.Password}";
|
||||
if (request.Ssl)
|
||||
connectionString += ";SslMode=Require;";
|
||||
|
||||
return SetDatabase<MySqlConnection, MySqlException>(connectionString, DbSettings.DatabaseEnum.Mysql);
|
||||
}
|
||||
|
||||
[HttpPost("SetSqlite")]
|
||||
[TokenAuthentication]
|
||||
public ActionResult<bool> SetSqlite([FromQuery] string? path)
|
||||
{
|
||||
if (string.IsNullOrEmpty(path)) path = "database";
|
||||
|
||||
path = PathBuilder.Combine(path);
|
||||
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
Directory.CreateDirectory(path);
|
||||
else
|
||||
Directory.CreateDirectory(path, UnixFileMode.UserRead | UnixFileMode.UserWrite);
|
||||
}
|
||||
else
|
||||
throw new ControllerArgumentException("Such a folder exists. Enter a different name");
|
||||
|
||||
string connectionString = $"Data Source={PathBuilder.Combine(path, "database.db3")}";
|
||||
|
||||
return SetDatabase<SqliteConnection, SqliteException>(connectionString, DbSettings.DatabaseEnum.Sqlite);
|
||||
}
|
||||
|
||||
[HttpPost("SetRedis")]
|
||||
[TokenAuthentication]
|
||||
[BadRequestResponse]
|
||||
public ActionResult<bool> SetRedis([FromBody] CacheRequest request)
|
||||
{
|
||||
string connectionString = $"{request.Server}:{request.Port},ssl=false";
|
||||
if (request.Password != null)
|
||||
connectionString += $",password={request.Password}";
|
||||
|
||||
try
|
||||
{
|
||||
var redis = ConnectionMultiplexer.Connect(connectionString);
|
||||
redis.Close();
|
||||
|
||||
var general = GeneralConfig;
|
||||
general.CacheSettings = new CacheSettings
|
||||
{
|
||||
ConnectionString = connectionString,
|
||||
TypeDatabase = CacheSettings.CacheEnum.Redis
|
||||
};
|
||||
GeneralConfig = general;
|
||||
|
||||
return Ok(true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new ControllerArgumentException("Error when connecting to Redis: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("SetMemcached")]
|
||||
[TokenAuthentication]
|
||||
[BadRequestResponse]
|
||||
public ActionResult<bool> SetMemcached()
|
||||
{
|
||||
var general = GeneralConfig;
|
||||
general.CacheSettings = new CacheSettings
|
||||
{
|
||||
ConnectionString = null,
|
||||
TypeDatabase = CacheSettings.CacheEnum.Memcached
|
||||
};
|
||||
GeneralConfig = general;
|
||||
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
[HttpPost("SetLogging")]
|
||||
[TokenAuthentication]
|
||||
[BadRequestResponse]
|
||||
public ActionResult<bool> SetLogging([FromBody] LoggingRequest? request)
|
||||
{
|
||||
var settings = (request == null) switch
|
||||
{
|
||||
true => new LogSettings
|
||||
{
|
||||
EnableLogToFile = true,
|
||||
LogFileName = "logging-",
|
||||
LogFilePath = "logs"
|
||||
},
|
||||
false => new LogSettings
|
||||
{
|
||||
EnableLogToFile = request.EnableLogToFile,
|
||||
LogFileName = request.LogFileName,
|
||||
LogFilePath = request.LogFilePath
|
||||
}
|
||||
};
|
||||
|
||||
var general = GeneralConfig;
|
||||
general.LogSettings = settings;
|
||||
GeneralConfig = general;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[HttpPost("SetEmail")]
|
||||
[TokenAuthentication]
|
||||
[BadRequestResponse]
|
||||
public ActionResult<bool> SetEmail([FromBody] EmailRequest? request)
|
||||
{
|
||||
var settings = (request == null) switch
|
||||
{
|
||||
true => new EmailSettings(),
|
||||
false => new EmailSettings
|
||||
{
|
||||
Server = request.Server,
|
||||
From = request.From,
|
||||
Password = request.Password,
|
||||
Port = request.Port,
|
||||
Ssl = request.Ssl,
|
||||
User = request.User
|
||||
}
|
||||
};
|
||||
|
||||
var general = GeneralConfig;
|
||||
general.EmailSettings = settings;
|
||||
GeneralConfig = general;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[HttpPost("SetSchedule")]
|
||||
[TokenAuthentication]
|
||||
[BadRequestResponse]
|
||||
public ActionResult<bool> SetSchedule([FromBody] ScheduleConfigurationRequest request)
|
||||
{
|
||||
var general = GeneralConfig;
|
||||
general.ScheduleSettings = new ScheduleSettings
|
||||
{
|
||||
// every 6 hours
|
||||
CronUpdateSchedule = request.CronUpdateSchedule ?? "0 */6 * * *",
|
||||
StartTerm = request.StartTerm,
|
||||
PairPeriod = request.PairPeriod.ConvertFromDto()
|
||||
};
|
||||
|
||||
if (!CronExpression.TryParse(general.ScheduleSettings.CronUpdateSchedule, CronFormat.Standard, out _))
|
||||
throw new ControllerArgumentException("The Cron task could not be parsed. Check the format of the entered data.");
|
||||
|
||||
GeneralConfig = general;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -22,8 +22,9 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.5" />
|
||||
<PackageReference Include="Cronos" Version="0.8.4" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.7.33" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Versioning" Version="2.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user