rework server responsibilities (#18)
* rework server responsibilities add remote configuration * start metrics only when compiled as not debug * add some more logging to discord bot * fixes of some casts * make metrics port configurable, minor fixes * add docker bullshit * md formatting * adjustments to docker stuff * fix docker json files, fix some stuff in discord bot, add /useradd for Discord bot * adjust docker configs and fix sharded.bat * fixes for logs, cache file provider repeat trying to open filestream Co-authored-by: rootdarkarchon <root.darkarchon@outlook.com>
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
namespace MareSynchronosShared.Utils;
|
||||
|
||||
public interface IMareConfiguration
|
||||
{
|
||||
T GetValueOrDefault<T>(string key, T defaultValue);
|
||||
T GetValue<T>(string key);
|
||||
string SerializeValue(string key, string defaultValue);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
using System.Text;
|
||||
|
||||
namespace MareSynchronosShared.Utils;
|
||||
|
||||
public class MareConfigurationAuthBase : MareConfigurationBase
|
||||
{
|
||||
public Uri MainServerGrpcAddress { get; set; } = null;
|
||||
[RemoteConfiguration]
|
||||
public int FailedAuthForTempBan { get; set; } = 5;
|
||||
[RemoteConfiguration]
|
||||
public int TempBanDurationInMinutes { get; set; } = 5;
|
||||
[RemoteConfiguration]
|
||||
public List<string> WhitelistedIps { get; set; } = new();
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new();
|
||||
sb.AppendLine(base.ToString());
|
||||
sb.AppendLine($"{nameof(MainServerGrpcAddress)} => {MainServerGrpcAddress}");
|
||||
sb.AppendLine($"{nameof(FailedAuthForTempBan)} => {FailedAuthForTempBan}");
|
||||
sb.AppendLine($"{nameof(TempBanDurationInMinutes)} => {TempBanDurationInMinutes}");
|
||||
sb.AppendLine($"{nameof(WhitelistedIps)} => {string.Join(", ", WhitelistedIps)}");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
@@ -1,32 +1,46 @@
|
||||
using System.Text;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace MareSynchronosShared.Utils;
|
||||
|
||||
public class MareConfigurationBase
|
||||
public class MareConfigurationBase : IMareConfiguration
|
||||
{
|
||||
public int DbContextPoolSize { get; set; } = 100;
|
||||
public string ShardName { get; set; } = string.Empty;
|
||||
public int MetricsPort { get; set; } = 4981;
|
||||
|
||||
public T GetValue<T>(string key)
|
||||
{
|
||||
var prop = GetType().GetProperty(key);
|
||||
if (prop == null) throw new KeyNotFoundException(key);
|
||||
if (prop.PropertyType != typeof(T)) throw new ArgumentException($"Requested {key} with T:{typeof(T)}, where {key} is {prop.PropertyType}");
|
||||
return (T)prop.GetValue(this);
|
||||
}
|
||||
|
||||
public T GetValueOrDefault<T>(string key, T defaultValue)
|
||||
{
|
||||
var prop = GetType().GetProperty(key);
|
||||
if (prop.PropertyType != typeof(T)) throw new ArgumentException($"Requested {key} with T:{typeof(T)}, where {key} is {prop.PropertyType}");
|
||||
if (prop == null) return defaultValue;
|
||||
return (T)prop.GetValue(this);
|
||||
}
|
||||
|
||||
public string SerializeValue(string key, string defaultValue)
|
||||
{
|
||||
var prop = GetType().GetProperty(key);
|
||||
if (prop == null) return defaultValue;
|
||||
if (prop.GetCustomAttribute<RemoteConfigurationAttribute>() == null) return defaultValue;
|
||||
return JsonSerializer.Serialize(prop.GetValue(this), prop.PropertyType);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new();
|
||||
sb.AppendLine(base.ToString());
|
||||
sb.AppendLine($"{nameof(ShardName)} => {ShardName}");
|
||||
sb.AppendLine($"{nameof(DbContextPoolSize)} => {DbContextPoolSize}");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public class MareConfigurationAuthBase : MareConfigurationBase
|
||||
{
|
||||
public int DbContextPoolSize { get; set; } = 100;
|
||||
public int FailedAuthForTempBan { get; set; } = 5;
|
||||
public int TempBanDurationInMinutes { get; set; } = 5;
|
||||
public List<string> WhitelistedIps { get; set; } = new();
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new();
|
||||
sb.AppendLine($"{nameof(FailedAuthForTempBan)} => {FailedAuthForTempBan}");
|
||||
sb.AppendLine($"{nameof(TempBanDurationInMinutes)} => {TempBanDurationInMinutes}");
|
||||
sb.AppendLine($"{nameof(WhitelistedIps)} => {string.Join(", ", WhitelistedIps)}");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
namespace MareSynchronosShared.Utils;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
public class RemoteConfigurationAttribute : Attribute { }
|
||||
@@ -0,0 +1,39 @@
|
||||
using System.Text;
|
||||
|
||||
namespace MareSynchronosShared.Utils;
|
||||
|
||||
public class ServerConfiguration : MareConfigurationAuthBase
|
||||
{
|
||||
public string RedisConnectionString { get; set; } = string.Empty;
|
||||
|
||||
[RemoteConfiguration]
|
||||
public Uri CdnFullUrl { get; set; } = null;
|
||||
[RemoteConfiguration]
|
||||
public Uri StaticFileServiceAddress { get; set; } = null;
|
||||
[RemoteConfiguration]
|
||||
public int MaxExistingGroupsByUser { get; set; } = 3;
|
||||
[RemoteConfiguration]
|
||||
public int MaxJoinedGroupsByUser { get; set; } = 6;
|
||||
[RemoteConfiguration]
|
||||
public int MaxGroupUserCount { get; set; } = 100;
|
||||
[RemoteConfiguration]
|
||||
public bool PurgeUnusedAccounts { get; set; } = false;
|
||||
[RemoteConfiguration]
|
||||
public int PurgeUnusedAccountsPeriodInDays { get; set; } = 14;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new();
|
||||
sb.AppendLine(base.ToString());
|
||||
sb.AppendLine($"{nameof(MainServerGrpcAddress)} => {MainServerGrpcAddress}");
|
||||
sb.AppendLine($"{nameof(CdnFullUrl)} => {CdnFullUrl}");
|
||||
sb.AppendLine($"{nameof(StaticFileServiceAddress)} => {StaticFileServiceAddress}");
|
||||
sb.AppendLine($"{nameof(RedisConnectionString)} => {RedisConnectionString}");
|
||||
sb.AppendLine($"{nameof(MaxExistingGroupsByUser)} => {MaxExistingGroupsByUser}");
|
||||
sb.AppendLine($"{nameof(MaxJoinedGroupsByUser)} => {MaxJoinedGroupsByUser}");
|
||||
sb.AppendLine($"{nameof(MaxGroupUserCount)} => {MaxGroupUserCount}");
|
||||
sb.AppendLine($"{nameof(PurgeUnusedAccounts)} => {PurgeUnusedAccounts}");
|
||||
sb.AppendLine($"{nameof(PurgeUnusedAccountsPeriodInDays)} => {PurgeUnusedAccountsPeriodInDays}");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System.Text;
|
||||
|
||||
namespace MareSynchronosShared.Utils;
|
||||
|
||||
public class ServicesConfiguration : MareConfigurationBase
|
||||
{
|
||||
public string DiscordBotToken { get; set; } = string.Empty;
|
||||
public Uri MainServerGrpcAddress { get; set; } = null;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new();
|
||||
sb.AppendLine(base.ToString());
|
||||
sb.AppendLine($"{nameof(DiscordBotToken)} => {DiscordBotToken}");
|
||||
sb.AppendLine($"{nameof(MainServerGrpcAddress)} => {MainServerGrpcAddress}");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,68 @@
|
||||
using MareSynchronosShared.Data;
|
||||
using MareSynchronosShared.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace MareSynchronosShared.Utils;
|
||||
|
||||
public static class SharedDbFunctions
|
||||
{
|
||||
public static async Task PurgeUser(ILogger _logger, User user, MareDbContext dbContext, int maxGroupsByUser)
|
||||
{
|
||||
_logger.LogInformation("Purging user: {uid}", user.UID);
|
||||
|
||||
var lodestone = dbContext.LodeStoneAuth.SingleOrDefault(a => a.User.UID == user.UID);
|
||||
|
||||
if (lodestone != null)
|
||||
{
|
||||
dbContext.Remove(lodestone);
|
||||
}
|
||||
|
||||
var auth = dbContext.Auth.Single(a => a.UserUID == user.UID);
|
||||
|
||||
var userFiles = dbContext.Files.Where(f => f.Uploaded && f.Uploader.UID == user.UID).ToList();
|
||||
dbContext.Files.RemoveRange(userFiles);
|
||||
|
||||
var ownPairData = dbContext.ClientPairs.Where(u => u.User.UID == user.UID).ToList();
|
||||
dbContext.ClientPairs.RemoveRange(ownPairData);
|
||||
var otherPairData = dbContext.ClientPairs.Include(u => u.User)
|
||||
.Where(u => u.OtherUser.UID == user.UID).ToList();
|
||||
dbContext.ClientPairs.RemoveRange(otherPairData);
|
||||
|
||||
var userJoinedGroups = await dbContext.GroupPairs.Include(g => g.Group).Where(u => u.GroupUserUID == user.UID).ToListAsync().ConfigureAwait(false);
|
||||
|
||||
foreach (var userGroupPair in userJoinedGroups)
|
||||
{
|
||||
bool ownerHasLeft = string.Equals(userGroupPair.Group.OwnerUID, user.UID, StringComparison.Ordinal);
|
||||
|
||||
if (ownerHasLeft)
|
||||
{
|
||||
var groupPairs = await dbContext.GroupPairs.Where(g => g.GroupGID == userGroupPair.GroupGID && g.GroupUserUID != user.UID).ToListAsync().ConfigureAwait(false);
|
||||
|
||||
if (!groupPairs.Any())
|
||||
{
|
||||
_logger.LogInformation("Group {gid} has no new owner, deleting", userGroupPair.GroupGID);
|
||||
dbContext.Groups.Remove(userGroupPair.Group);
|
||||
}
|
||||
else
|
||||
{
|
||||
_ = await MigrateOrDeleteGroup(dbContext, userGroupPair.Group, groupPairs, maxGroupsByUser).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
dbContext.GroupPairs.Remove(userGroupPair);
|
||||
|
||||
await dbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
_logger.LogInformation("User purged: {uid}", user.UID);
|
||||
|
||||
dbContext.Auth.Remove(auth);
|
||||
dbContext.Users.Remove(user);
|
||||
|
||||
await dbContext.SaveChangesAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public static async Task<(bool, string)> MigrateOrDeleteGroup(MareDbContext context, Group group, List<GroupPair> groupPairs, int maxGroupsByUser)
|
||||
{
|
||||
bool groupHasMigrated = false;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
using MareSynchronosShared.Utils;
|
||||
using System.Text;
|
||||
|
||||
namespace MareSynchronosStaticFilesServer;
|
||||
|
||||
public class StaticFilesServerConfiguration : MareConfigurationBase
|
||||
{
|
||||
public Uri FileServerGrpcAddress { get; set; } = null;
|
||||
public int ForcedDeletionOfFilesAfterHours { get; set; } = -1;
|
||||
public double CacheSizeHardLimitInGiB { get; set; } = -1;
|
||||
public int UnusedFileRetentionPeriodInDays { get; set; } = 14;
|
||||
public string CacheDirectory { get; set; }
|
||||
public Uri? RemoteCacheSourceUri { get; set; } = null;
|
||||
public Uri MainServerGrpcAddress { get; set; } = null;
|
||||
public override string ToString()
|
||||
{
|
||||
StringBuilder sb = new();
|
||||
sb.AppendLine(base.ToString());
|
||||
sb.AppendLine($"{nameof(FileServerGrpcAddress)} => {FileServerGrpcAddress}");
|
||||
sb.AppendLine($"{nameof(MainServerGrpcAddress)} => {MainServerGrpcAddress}");
|
||||
sb.AppendLine($"{nameof(ForcedDeletionOfFilesAfterHours)} => {ForcedDeletionOfFilesAfterHours}");
|
||||
sb.AppendLine($"{nameof(CacheSizeHardLimitInGiB)} => {CacheSizeHardLimitInGiB}");
|
||||
sb.AppendLine($"{nameof(UnusedFileRetentionPeriodInDays)} => {UnusedFileRetentionPeriodInDays}");
|
||||
sb.AppendLine($"{nameof(CacheDirectory)} => {CacheDirectory}");
|
||||
sb.AppendLine($"{nameof(RemoteCacheSourceUri)} => {RemoteCacheSourceUri}");
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user