add logging stuff
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.Claims;
|
using System.Security.Claims;
|
||||||
@@ -16,6 +17,7 @@ namespace MareSynchronosServer.Authentication
|
|||||||
{
|
{
|
||||||
public class SecretKeyAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
|
public class SecretKeyAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
|
||||||
{
|
{
|
||||||
|
public static ConcurrentDictionary<string, object> IdentificationLocks = new();
|
||||||
private readonly MareDbContext _mareDbContext;
|
private readonly MareDbContext _mareDbContext;
|
||||||
public const string AuthScheme = "SecretKeyAuth";
|
public const string AuthScheme = "SecretKeyAuth";
|
||||||
|
|
||||||
@@ -45,15 +47,26 @@ namespace MareSynchronosServer.Authentication
|
|||||||
return AuthenticateResult.Fail("Failed Authorization");
|
return AuthenticateResult.Fail("Failed Authorization");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!IdentificationLocks.TryGetValue(charNameHeader, out var lockObject))
|
||||||
|
{
|
||||||
|
lockObject = new();
|
||||||
|
IdentificationLocks[charNameHeader] = lockObject;
|
||||||
|
}
|
||||||
|
|
||||||
if (user.CharacterIdentification != charNameHeader)
|
if (user.CharacterIdentification != charNameHeader)
|
||||||
{
|
{
|
||||||
try
|
lock (lockObject)
|
||||||
{
|
{
|
||||||
user.CharacterIdentification = charNameHeader;
|
try
|
||||||
_mareDbContext.Users.Update(user);
|
{
|
||||||
await _mareDbContext.SaveChangesAsync();
|
user.CharacterIdentification = charNameHeader;
|
||||||
|
_mareDbContext.Users.Update(user);
|
||||||
|
_mareDbContext.SaveChanges();
|
||||||
|
}
|
||||||
|
catch (DbUpdateConcurrencyException)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (DbUpdateConcurrencyException) { }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var claims = new List<Claim> {
|
var claims = new List<Claim> {
|
||||||
|
|||||||
@@ -44,12 +44,13 @@ namespace MareSynchronosServer
|
|||||||
_logger.LogInformation($"Cleaning up files older than {filesOlderThanDays} days");
|
_logger.LogInformation($"Cleaning up files older than {filesOlderThanDays} days");
|
||||||
|
|
||||||
using var scope = _services.CreateScope();
|
using var scope = _services.CreateScope();
|
||||||
var dbContext = scope.ServiceProvider.GetService<MareDbContext>();
|
var dbContext = scope.ServiceProvider.GetService<MareDbContext>()!;
|
||||||
|
|
||||||
var prevTime = DateTime.Now.Subtract(TimeSpan.FromDays(filesOlderThanDays));
|
var prevTime = DateTime.Now.Subtract(TimeSpan.FromDays(filesOlderThanDays));
|
||||||
var filesToDelete =
|
var filesToDelete =
|
||||||
dbContext.Files.Where(f => f.LastAccessTime < prevTime);
|
dbContext.Files.Where(f => f.LastAccessTime < prevTime);
|
||||||
dbContext.RemoveRange(filesToDelete);
|
dbContext.RemoveRange(filesToDelete);
|
||||||
|
dbContext.SaveChanges();
|
||||||
foreach (var file in filesToDelete)
|
foreach (var file in filesToDelete)
|
||||||
{
|
{
|
||||||
var fileName = Path.Combine(_configuration["CacheDirectory"], file.Hash);
|
var fileName = Path.Combine(_configuration["CacheDirectory"], file.Hash);
|
||||||
@@ -59,9 +60,6 @@ namespace MareSynchronosServer
|
|||||||
File.Delete(fileName);
|
File.Delete(fileName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dbContext.SaveChanges();
|
|
||||||
|
|
||||||
var allFiles = dbContext.Files;
|
var allFiles = dbContext.Files;
|
||||||
foreach (var file in allFiles)
|
foreach (var file in allFiles)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace MareSynchronosServer.Hubs
|
|||||||
|
|
||||||
if (userId != null)
|
if (userId != null)
|
||||||
{
|
{
|
||||||
Logger.LogInformation("Heartbeat from " + userId);
|
Logger.LogInformation("Connection from " + userId);
|
||||||
var user = (await DbContext.Users.SingleAsync(u => u.UID == userId));
|
var user = (await DbContext.Users.SingleAsync(u => u.UID == userId));
|
||||||
return new LoggedInUserDto
|
return new LoggedInUserDto
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ namespace MareSynchronosServer.Hubs
|
|||||||
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AuthScheme)]
|
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AuthScheme)]
|
||||||
public async Task<List<UploadFileDto>> SendFiles(List<string> fileListHashes)
|
public async Task<List<UploadFileDto>> SendFiles(List<string> fileListHashes)
|
||||||
{
|
{
|
||||||
|
fileListHashes = fileListHashes.Distinct().ToList();
|
||||||
Logger.LogInformation("User " + AuthenticatedUserId + " sending files");
|
Logger.LogInformation("User " + AuthenticatedUserId + " sending files");
|
||||||
var forbiddenFiles = DbContext.ForbiddenUploadEntries.Where(f => fileListHashes.Contains(f.Hash));
|
var forbiddenFiles = DbContext.ForbiddenUploadEntries.Where(f => fileListHashes.Contains(f.Hash));
|
||||||
var filesToUpload = new List<UploadFileDto>();
|
var filesToUpload = new List<UploadFileDto>();
|
||||||
@@ -51,10 +52,11 @@ namespace MareSynchronosServer.Hubs
|
|||||||
Hash = f.Hash,
|
Hash = f.Hash,
|
||||||
IsForbidden = true
|
IsForbidden = true
|
||||||
}));
|
}));
|
||||||
var existingFiles = DbContext.Files.Where(f => fileListHashes.Contains(f.Hash)).ToList();
|
fileListHashes.RemoveAll(f => filesToUpload.Any(u => u.Hash == f));
|
||||||
|
var existingFiles = DbContext.Files.Where(f => fileListHashes.Contains(f.Hash));
|
||||||
foreach (var file in fileListHashes.Where(f => existingFiles.All(e => e.Hash != f) && filesToUpload.All(u => u.Hash != f)))
|
foreach (var file in fileListHashes.Where(f => existingFiles.All(e => e.Hash != f) && filesToUpload.All(u => u.Hash != f)))
|
||||||
{
|
{
|
||||||
Logger.LogInformation("Needs upload: " + file);
|
Logger.LogInformation("User " + AuthenticatedUserId + " needs upload: " + file);
|
||||||
var userId = AuthenticatedUserId;
|
var userId = AuthenticatedUserId;
|
||||||
await DbContext.Files.AddAsync(new FileCache()
|
await DbContext.Files.AddAsync(new FileCache()
|
||||||
{
|
{
|
||||||
@@ -90,9 +92,26 @@ namespace MareSynchronosServer.Hubs
|
|||||||
var forbiddenFile = DbContext.ForbiddenUploadEntries.SingleOrDefault(f => f.Hash == hash);
|
var forbiddenFile = DbContext.ForbiddenUploadEntries.SingleOrDefault(f => f.Hash == hash);
|
||||||
if (forbiddenFile != null) return;
|
if (forbiddenFile != null) return;
|
||||||
var uploadedFile = new List<byte>();
|
var uploadedFile = new List<byte>();
|
||||||
await foreach (var chunk in fileContent)
|
try
|
||||||
{
|
{
|
||||||
uploadedFile.AddRange(chunk);
|
await foreach (var chunk in fileContent)
|
||||||
|
{
|
||||||
|
uploadedFile.AddRange(chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
DbContext.Files.Remove(relatedFile);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await DbContext.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// already removed
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.LogInformation("User " + AuthenticatedUserId + " upload finished: " + hash + ", size: " + uploadedFile.Count);
|
Logger.LogInformation("User " + AuthenticatedUserId + " upload finished: " + hash + ", size: " + uploadedFile.Count);
|
||||||
@@ -115,6 +134,7 @@ namespace MareSynchronosServer.Hubs
|
|||||||
relatedFile.Uploaded = true;
|
relatedFile.Uploaded = true;
|
||||||
relatedFile.LastAccessTime = DateTime.Now;
|
relatedFile.LastAccessTime = DateTime.Now;
|
||||||
await DbContext.SaveChangesAsync();
|
await DbContext.SaveChangesAsync();
|
||||||
|
Logger.LogInformation("File " + hash + " added to DB");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|||||||
@@ -69,37 +69,11 @@ namespace MareSynchronosServer.Hubs
|
|||||||
return AuthenticatedUserId;
|
return AuthenticatedUserId;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AuthScheme)]
|
|
||||||
public async Task GetCharacterData(Dictionary<string, int> visibleCharacterWithJobs)
|
|
||||||
{
|
|
||||||
var uid = AuthenticatedUserId;
|
|
||||||
Dictionary<string, CharacterCacheDto> ret = new();
|
|
||||||
var entriesHavingThisUser = DbContext.ClientPairs
|
|
||||||
.Include(w => w.User)
|
|
||||||
.Include(w => w.OtherUser)
|
|
||||||
.Where(w => w.OtherUser.UID == uid && !w.IsPaused && visibleCharacterWithJobs.Keys.Contains(w.User.CharacterIdentification))
|
|
||||||
.ToList();
|
|
||||||
foreach (var pair in entriesHavingThisUser)
|
|
||||||
{
|
|
||||||
bool isNotPaused = await DbContext.ClientPairs.AnyAsync(w =>
|
|
||||||
!w.IsPaused && w.User.UID == uid && w.OtherUser.UID == pair.User.UID);
|
|
||||||
if (!isNotPaused) continue;
|
|
||||||
var dictEntry = visibleCharacterWithJobs[pair.User.CharacterIdentification];
|
|
||||||
|
|
||||||
var cachedChar = await
|
|
||||||
DbContext.CharacterData.SingleOrDefaultAsync(c => c.UserId == pair.User.UID && c.JobId == dictEntry);
|
|
||||||
if (cachedChar != null)
|
|
||||||
{
|
|
||||||
await Clients.User(uid).SendAsync("ReceiveCharacterData", cachedChar.CharacterCache,
|
|
||||||
pair.User.CharacterIdentification);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AuthScheme)]
|
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AuthScheme)]
|
||||||
public async Task PushCharacterDataToVisibleClients(CharacterCacheDto characterCache, List<string> visibleCharacterIds)
|
public async Task PushCharacterDataToVisibleClients(CharacterCacheDto characterCache, List<string> visibleCharacterIds)
|
||||||
{
|
{
|
||||||
Logger.LogInformation("User " + AuthenticatedUserId + " pushing character data to visible clients");
|
Logger.LogInformation("User " + AuthenticatedUserId + " pushing character data to " + visibleCharacterIds.Count + " visible clients");
|
||||||
|
|
||||||
var uid = AuthenticatedUserId;
|
var uid = AuthenticatedUserId;
|
||||||
var entriesHavingThisUser = DbContext.ClientPairs
|
var entriesHavingThisUser = DbContext.ClientPairs
|
||||||
@@ -166,7 +140,7 @@ namespace MareSynchronosServer.Hubs
|
|||||||
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AuthScheme)]
|
[Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AuthScheme)]
|
||||||
public async Task<List<string>> GetOnlineCharacters()
|
public async Task<List<string>> GetOnlineCharacters()
|
||||||
{
|
{
|
||||||
Logger.LogInformation("User " + AuthenticatedUserId + " sent character hash");
|
Logger.LogInformation("User " + AuthenticatedUserId + " requested online characters");
|
||||||
|
|
||||||
var ownUser = DbContext.Users.Single(u => u.UID == AuthenticatedUserId);
|
var ownUser = DbContext.Users.Single(u => u.UID == AuthenticatedUserId);
|
||||||
var otherUsers = await DbContext.ClientPairs
|
var otherUsers = await DbContext.ClientPairs
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Bazinga.AspNetCore.Authentication.Basic" Version="2.0.1" />
|
<PackageReference Include="Bazinga.AspNetCore.Authentication.Basic" Version="2.0.1" />
|
||||||
|
<PackageReference Include="Karambolo.Extensions.Logging.File" Version="3.3.0" />
|
||||||
<PackageReference Include="lz4net" Version="1.0.15.93" />
|
<PackageReference Include="lz4net" Version="1.0.15.93" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="6.0.6" />
|
<PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="6.0.6" />
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.6" />
|
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.6" />
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using MareSynchronosServer.Data;
|
using MareSynchronosServer.Data;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace MareSynchronosServer
|
namespace MareSynchronosServer
|
||||||
{
|
{
|
||||||
@@ -36,6 +40,17 @@ namespace MareSynchronosServer
|
|||||||
.UseConsoleLifetime()
|
.UseConsoleLifetime()
|
||||||
.ConfigureWebHostDefaults(webBuilder =>
|
.ConfigureWebHostDefaults(webBuilder =>
|
||||||
{
|
{
|
||||||
|
webBuilder.UseContentRoot(AppContext.BaseDirectory);
|
||||||
|
webBuilder.ConfigureLogging((ctx, builder) =>
|
||||||
|
{
|
||||||
|
builder.AddSimpleConsole(options =>
|
||||||
|
{
|
||||||
|
options.SingleLine = true;
|
||||||
|
options.TimestampFormat = "yyyy-MM-dd HH:mm:ss ";
|
||||||
|
});
|
||||||
|
builder.AddConfiguration(ctx.Configuration.GetSection("Logging"));
|
||||||
|
builder.AddFile(o => o.RootPath = AppContext.BaseDirectory);
|
||||||
|
});
|
||||||
webBuilder.UseStartup<Startup>();
|
webBuilder.UseStartup<Startup>();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,6 @@ namespace MareSynchronosServer
|
|||||||
|
|
||||||
services.AddSingleton<IUserIdProvider, IdBasedUserIdProvider>();
|
services.AddSingleton<IUserIdProvider, IdBasedUserIdProvider>();
|
||||||
|
|
||||||
|
|
||||||
services.AddDbContext<MareDbContext>(options =>
|
services.AddDbContext<MareDbContext>(options =>
|
||||||
{
|
{
|
||||||
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
|
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"));
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"ConnectionStrings": {
|
"ConnectionStrings": {
|
||||||
"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-MareSynchronosServer-BA82A12A-0B30-463C-801D-B7E81318CD50;Trusted_Connection=True;MultipleActiveResultSets=true"
|
"DefaultConnection": "Server=(localdb)\\SQLEXPRESS;Database=mare;Trusted_Connection=True;MultipleActiveResultSets=true"
|
||||||
},
|
},
|
||||||
"Logging": {
|
"Logging": {
|
||||||
"LogLevel": {
|
"LogLevel": {
|
||||||
@@ -9,20 +9,32 @@
|
|||||||
"Microsoft.Hosting.Lifetime": "Information",
|
"Microsoft.Hosting.Lifetime": "Information",
|
||||||
"MareSynchronosServer.Authentication": "Warning",
|
"MareSynchronosServer.Authentication": "Warning",
|
||||||
"System.IO.IOException": "Warning"
|
"System.IO.IOException": "Warning"
|
||||||
|
},
|
||||||
|
"File": {
|
||||||
|
"BasePath": "logs",
|
||||||
|
"FileAccessMode": "KeepOpenAndAutoFlush",
|
||||||
|
"FileEncodingName": "utf-8",
|
||||||
|
"DateFormat": "yyyMMdd",
|
||||||
|
"MaxFileSize": 10485760,
|
||||||
|
"Files": [
|
||||||
|
{
|
||||||
|
"Path": "mare-<counter>.log"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"UnusedFileRetentionPeriodInDays" : 7,
|
"UnusedFileRetentionPeriodInDays": 7,
|
||||||
"CacheDirectory": "G:\\ServerTest", // do not delete this key and set it to the path where the files will be stored
|
"CacheDirectory": "G:\\ServerTest", // do not delete this key and set it to the path where the files will be stored
|
||||||
"AllowedHosts": "*",
|
"AllowedHosts": "*",
|
||||||
"Kestrel": {
|
"Kestrel": {
|
||||||
"Endpoints": {
|
"Endpoints": {
|
||||||
"Https": {
|
"Https": {
|
||||||
"Url": "https://+:5001",
|
"Url": "https://+:5000",
|
||||||
"Certificate": {
|
"Certificate": {
|
||||||
"Subject": "darkarchon.internet-box.ch",
|
"Subject": "darkarchon.internet-box.ch",
|
||||||
"Store": "Root",
|
"Store": "My",
|
||||||
"Location": "LocalMachine",
|
"Location": "LocalMachine",
|
||||||
"AllowInvalid": false
|
//"AllowInvalid": false
|
||||||
// "Path": "", //use path, keypath and password to provide a valid certificate if not using windows key store
|
// "Path": "", //use path, keypath and password to provide a valid certificate if not using windows key store
|
||||||
// "KeyPath": ""
|
// "KeyPath": ""
|
||||||
// "Password": ""
|
// "Password": ""
|
||||||
|
|||||||
Reference in New Issue
Block a user