diff --git a/ProjectLighthouse.Servers.Website/Pages/Admin/AdminPanelPage.cshtml b/ProjectLighthouse.Servers.Website/Pages/Admin/AdminPanelPage.cshtml
index 8aa31717..53e82fcd 100644
--- a/ProjectLighthouse.Servers.Website/Pages/Admin/AdminPanelPage.cshtml
+++ b/ProjectLighthouse.Servers.Website/Pages/Admin/AdminPanelPage.cshtml
@@ -11,6 +11,17 @@
Model.Title = "Admin Panel";
}
+@if (Model.Log != null)
+{
+
+
Command Output
+ @foreach (string line in Model.Log.Split("\n"))
+ {
+ @line.TrimEnd()
+ }
+
+}
+
@if (!this.Request.IsMobile())
{
diff --git a/ProjectLighthouse.Servers.Website/Pages/Admin/AdminPanelPage.cshtml.cs b/ProjectLighthouse.Servers.Website/Pages/Admin/AdminPanelPage.cshtml.cs
index cb42034e..6df20cfc 100644
--- a/ProjectLighthouse.Servers.Website/Pages/Admin/AdminPanelPage.cshtml.cs
+++ b/ProjectLighthouse.Servers.Website/Pages/Admin/AdminPanelPage.cshtml.cs
@@ -1,7 +1,9 @@
#nullable enable
using LBPUnion.ProjectLighthouse.Administration;
using LBPUnion.ProjectLighthouse.Administration.Maintenance;
+using LBPUnion.ProjectLighthouse.Extensions;
using LBPUnion.ProjectLighthouse.Helpers;
+using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.PlayerData.Profiles;
using LBPUnion.ProjectLighthouse.Servers.Website.Pages.Layouts;
using LBPUnion.ProjectLighthouse.Types;
@@ -17,7 +19,9 @@ public class AdminPanelPage : BaseLayout
public List
Statistics = new();
- public async Task OnGet([FromQuery] string? args, [FromQuery] string? command, [FromQuery] string? maintenanceJob)
+ public string? Log;
+
+ public async Task OnGet([FromQuery] string? args, [FromQuery] string? command, [FromQuery] string? maintenanceJob, [FromQuery] string? log)
{
User? user = this.Database.UserFromWebRequest(this.Request);
if (user == null) return this.Redirect("~/login");
@@ -33,8 +37,9 @@ public class AdminPanelPage : BaseLayout
args ??= "";
args = command + " " + args;
string[] split = args.Split(" ");
- await MaintenanceHelper.RunCommand(split);
- return this.Redirect("~/admin");
+
+ List runCommand = await MaintenanceHelper.RunCommand(split);
+ return this.Redirect($"~/admin?log={CryptoHelper.ToBase64(runCommand.ToLogString())}");
}
if (!string.IsNullOrEmpty(maintenanceJob))
@@ -43,6 +48,11 @@ public class AdminPanelPage : BaseLayout
return this.Redirect("~/admin");
}
+ if (!string.IsNullOrEmpty(log))
+ {
+ this.Log = CryptoHelper.FromBase64(log);
+ }
+
return this.Page();
}
}
\ No newline at end of file
diff --git a/ProjectLighthouse/Administration/Maintenance/Commands/CreateUserCommand.cs b/ProjectLighthouse/Administration/Maintenance/Commands/CreateUserCommand.cs
index 2d433e59..39b86e04 100644
--- a/ProjectLighthouse/Administration/Maintenance/Commands/CreateUserCommand.cs
+++ b/ProjectLighthouse/Administration/Maintenance/Commands/CreateUserCommand.cs
@@ -11,7 +11,7 @@ public class CreateUserCommand : ICommand
{
private readonly Database _database = new();
- public async Task Run(string[] args)
+ public async Task Run(string[] args, Logger logger)
{
string onlineId = args[0];
string password = args[1];
@@ -22,17 +22,17 @@ public class CreateUserCommand : ICommand
if (user == null)
{
user = await this._database.CreateUser(onlineId, CryptoHelper.BCryptHash(password));
- Logger.Success($"Created user {user.UserId} with online ID (username) {user.Username} and the specified password.", LogArea.Login);
+ logger.LogSuccess($"Created user {user.UserId} with online ID (username) {user.Username} and the specified password.", LogArea.Command);
user.PasswordResetRequired = true;
- Logger.Info("This user will need to reset their password when they log in.", LogArea.Login);
+ logger.LogInfo("This user will need to reset their password when they log in.", LogArea.Command);
await this._database.SaveChangesAsync();
- Logger.Info("Database changes saved.", LogArea.Database);
+ logger.LogInfo("Database changes saved.", LogArea.Command);
}
else
{
- Logger.Error("A user with this username already exists.", LogArea.Login);
+ logger.LogError("A user with this username already exists.", LogArea.Command);
}
}
diff --git a/ProjectLighthouse/Administration/Maintenance/Commands/DeleteUserCommand.cs b/ProjectLighthouse/Administration/Maintenance/Commands/DeleteUserCommand.cs
index 880b12a4..cb783dcc 100644
--- a/ProjectLighthouse/Administration/Maintenance/Commands/DeleteUserCommand.cs
+++ b/ProjectLighthouse/Administration/Maintenance/Commands/DeleteUserCommand.cs
@@ -1,6 +1,7 @@
#nullable enable
using System;
using System.Threading.Tasks;
+using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.PlayerData.Profiles;
using Microsoft.EntityFrameworkCore;
@@ -17,7 +18,7 @@ public class DeleteUserCommand : ICommand
};
public string Arguments() => "";
public int RequiredArgs() => 1;
- public async Task Run(string[] args)
+ public async Task Run(string[] args, Logger logger)
{
User? user = await this.database.Users.FirstOrDefaultAsync(u => u.Username == args[0]);
if (user == null)
@@ -28,7 +29,7 @@ public class DeleteUserCommand : ICommand
}
catch
{
- Console.WriteLine($"Could not find user by parameter '{args[0]}'");
+ logger.LogError($"Could not find user by parameter '{args[0]}'", LogArea.Command);
return;
}
diff --git a/ProjectLighthouse/Administration/Maintenance/Commands/MakeUserAdminCommand.cs b/ProjectLighthouse/Administration/Maintenance/Commands/MakeUserAdminCommand.cs
index 2741a86d..0cc0f85f 100644
--- a/ProjectLighthouse/Administration/Maintenance/Commands/MakeUserAdminCommand.cs
+++ b/ProjectLighthouse/Administration/Maintenance/Commands/MakeUserAdminCommand.cs
@@ -1,6 +1,7 @@
#nullable enable
using System;
using System.Threading.Tasks;
+using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.PlayerData.Profiles;
using Microsoft.EntityFrameworkCore;
@@ -19,7 +20,7 @@ public class MakeUserAdminCommand : ICommand
public string Arguments() => "";
public int RequiredArgs() => 1;
- public async Task Run(string[] args)
+ public async Task Run(string[] args, Logger logger)
{
User? user = await this.database.Users.FirstOrDefaultAsync(u => u.Username == args[0]);
if (user == null)
@@ -30,13 +31,13 @@ public class MakeUserAdminCommand : ICommand
}
catch
{
- Console.WriteLine($"Could not find user by parameter '{args[0]}'");
+ logger.LogError($"Could not find user by parameter '{args[0]}'", LogArea.Command);
return;
}
user.IsAdmin = true;
await this.database.SaveChangesAsync();
- Console.WriteLine($"The user {user.Username} (id: {user.UserId}) is now an admin.");
+ logger.LogSuccess($"The user {user.Username} (id: {user.UserId}) is now an admin.", LogArea.Command);
}
}
\ No newline at end of file
diff --git a/ProjectLighthouse/Administration/Maintenance/Commands/RenameUserCommand.cs b/ProjectLighthouse/Administration/Maintenance/Commands/RenameUserCommand.cs
index 875b0539..3995e023 100644
--- a/ProjectLighthouse/Administration/Maintenance/Commands/RenameUserCommand.cs
+++ b/ProjectLighthouse/Administration/Maintenance/Commands/RenameUserCommand.cs
@@ -1,6 +1,7 @@
#nullable enable
using System;
using System.Threading.Tasks;
+using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.PlayerData.Profiles;
using Microsoft.EntityFrameworkCore;
@@ -9,7 +10,7 @@ namespace LBPUnion.ProjectLighthouse.Administration.Maintenance.Commands;
public class RenameUserCommand : ICommand
{
private readonly Database database = new();
- public async Task Run(string[] args)
+ public async Task Run(string[] args, Logger logger)
{
User? user = await this.database.Users.FirstOrDefaultAsync(u => u.Username == args[0]);
if (user == null)
@@ -20,14 +21,14 @@ public class RenameUserCommand : ICommand
}
catch
{
- Console.WriteLine($"Could not find user by parameter '{args[0]}'");
+ logger.LogError($"Could not find user by parameter '{args[0]}'", LogArea.Command);
return;
}
user.Username = args[1];
await this.database.SaveChangesAsync();
- Console.WriteLine($"The username for user {user.Username} (id: {user.UserId}) has been changed.");
+ logger.LogSuccess($"The username for user {user.Username} (id: {user.UserId}) has been changed.", LogArea.Command);
}
public string Name() => "Rename User";
public string[] Aliases()
diff --git a/ProjectLighthouse/Administration/Maintenance/Commands/ResetPasswordCommand.cs b/ProjectLighthouse/Administration/Maintenance/Commands/ResetPasswordCommand.cs
index e5d2c144..0433f866 100644
--- a/ProjectLighthouse/Administration/Maintenance/Commands/ResetPasswordCommand.cs
+++ b/ProjectLighthouse/Administration/Maintenance/Commands/ResetPasswordCommand.cs
@@ -2,6 +2,7 @@
using System;
using System.Threading.Tasks;
using LBPUnion.ProjectLighthouse.Helpers;
+using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.PlayerData.Profiles;
using Microsoft.EntityFrameworkCore;
@@ -19,7 +20,7 @@ public class ResetPasswordCommand : ICommand
public string Arguments() => " ";
public int RequiredArgs() => 2;
- public async Task Run(string[] args)
+ public async Task Run(string[] args, Logger logger)
{
User? user = await this.database.Users.FirstOrDefaultAsync(u => u.Username == args[0]);
if (user == null)
@@ -30,9 +31,10 @@ public class ResetPasswordCommand : ICommand
}
catch
{
- Console.WriteLine($"Could not find user by parameter '{args[0]}'");
+ logger.LogError($"Could not find user by parameter '{args[0]}'", LogArea.Command);
return;
}
+
string password = args[1];
if (password.Length != 64) password = CryptoHelper.Sha256Hash(password);
@@ -41,6 +43,6 @@ public class ResetPasswordCommand : ICommand
await this.database.SaveChangesAsync();
- Console.WriteLine($"The password for user {user.Username} (id: {user.UserId}) has been reset.");
+ logger.LogSuccess($"The password for user {user.Username} (id: {user.UserId}) has been reset.", LogArea.Command);
}
}
\ No newline at end of file
diff --git a/ProjectLighthouse/Administration/Maintenance/Commands/TestWebhookCommand.cs b/ProjectLighthouse/Administration/Maintenance/Commands/TestWebhookCommand.cs
index 9beadef8..c6c70bf4 100644
--- a/ProjectLighthouse/Administration/Maintenance/Commands/TestWebhookCommand.cs
+++ b/ProjectLighthouse/Administration/Maintenance/Commands/TestWebhookCommand.cs
@@ -1,11 +1,12 @@
using System.Threading.Tasks;
using LBPUnion.ProjectLighthouse.Helpers;
+using LBPUnion.ProjectLighthouse.Logging;
namespace LBPUnion.ProjectLighthouse.Administration.Maintenance.Commands;
public class TestWebhookCommand : ICommand
{
- public async Task Run(string[] args)
+ public async Task Run(string[] args, Logger logger)
{
await WebhookHelper.SendWebhook("Testing 123", "Someone is testing the Discord webhook from the admin panel.");
}
diff --git a/ProjectLighthouse/Administration/Maintenance/Commands/WipeTokensForUserCommand.cs b/ProjectLighthouse/Administration/Maintenance/Commands/WipeTokensForUserCommand.cs
index 68db13ae..9517bd56 100644
--- a/ProjectLighthouse/Administration/Maintenance/Commands/WipeTokensForUserCommand.cs
+++ b/ProjectLighthouse/Administration/Maintenance/Commands/WipeTokensForUserCommand.cs
@@ -2,6 +2,7 @@
using System;
using System.Linq;
using System.Threading.Tasks;
+using LBPUnion.ProjectLighthouse.Logging;
using LBPUnion.ProjectLighthouse.PlayerData.Profiles;
using Microsoft.EntityFrameworkCore;
@@ -19,7 +20,7 @@ public class WipeTokensForUserCommand : ICommand
};
public string Arguments() => "";
public int RequiredArgs() => 1;
- public async Task Run(string[] args)
+ public async Task Run(string[] args, Logger logger)
{
User? user = await this.database.Users.FirstOrDefaultAsync(u => u.Username == args[0]);
if (user == null)
diff --git a/ProjectLighthouse/Administration/Maintenance/ICommand.cs b/ProjectLighthouse/Administration/Maintenance/ICommand.cs
index 070e73e3..42a3f39f 100644
--- a/ProjectLighthouse/Administration/Maintenance/ICommand.cs
+++ b/ProjectLighthouse/Administration/Maintenance/ICommand.cs
@@ -1,14 +1,14 @@
using System.Threading.Tasks;
using JetBrains.Annotations;
+using LBPUnion.ProjectLighthouse.Logging;
namespace LBPUnion.ProjectLighthouse.Administration.Maintenance;
[UsedImplicitly(ImplicitUseTargetFlags.WithInheritors)]
public interface ICommand
{
-
public string FirstAlias => this.Aliases()[0];
- public Task Run(string[] args);
+ public Task Run(string[] args, Logger logger);
public string Name();
diff --git a/ProjectLighthouse/Administration/Maintenance/MaintenanceHelper.cs b/ProjectLighthouse/Administration/Maintenance/MaintenanceHelper.cs
index 8e434bd8..3d86ad38 100644
--- a/ProjectLighthouse/Administration/Maintenance/MaintenanceHelper.cs
+++ b/ProjectLighthouse/Administration/Maintenance/MaintenanceHelper.cs
@@ -4,6 +4,8 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
+using LBPUnion.ProjectLighthouse.Logging;
+using LBPUnion.ProjectLighthouse.Logging.Loggers;
namespace LBPUnion.ProjectLighthouse.Administration.Maintenance;
@@ -28,7 +30,7 @@ public static class MaintenanceHelper
.ToList()!;
}
- public static async Task RunCommand(string[] args)
+ public static async Task> RunCommand(string[] args)
{
if (args.Length < 1)
throw new Exception
@@ -36,18 +38,27 @@ public static class MaintenanceHelper
string baseCmd = args[0];
args = args.Skip(1).ToArray();
+
+ // Setup memory logger for output
+ Logger logger = new();
+ InMemoryLogger memoryLogger = new();
+ logger.AddLogger(memoryLogger);
IEnumerable suitableCommands = Commands.Where
(command => command.Aliases().Any(a => a.ToLower() == baseCmd.ToLower()))
.Where(command => args.Length >= command.RequiredArgs());
foreach (ICommand command in suitableCommands)
{
- Console.WriteLine("Running command " + command.Name());
- await command.Run(args);
- return;
+ logger.LogInfo("Running command " + command.Name(), LogArea.Command);
+
+ await command.Run(args, logger);
+ logger.Flush();
+ return memoryLogger.Lines;
}
- Console.WriteLine("Command not found.");
+ logger.LogError("Command not found.", LogArea.Command);
+ logger.Flush();
+ return memoryLogger.Lines;
}
public static async Task RunMaintenanceJob(string jobName)
diff --git a/ProjectLighthouse/Extensions/LogLineListExtensions.cs b/ProjectLighthouse/Extensions/LogLineListExtensions.cs
new file mode 100644
index 00000000..e198f0bc
--- /dev/null
+++ b/ProjectLighthouse/Extensions/LogLineListExtensions.cs
@@ -0,0 +1,13 @@
+using System.Collections.Generic;
+using System.Linq;
+using LBPUnion.ProjectLighthouse.Logging;
+
+namespace LBPUnion.ProjectLighthouse.Extensions;
+
+public static class LogLineListExtensions
+{
+ public static string ToLogString(this IEnumerable log) => log.Aggregate(
+ "",
+ (current, logLine) => current + $"[{logLine.Level}] [{logLine.Trace.Name}:{logLine.Trace.Section}] {logLine.Message}\n"
+ );
+}
\ No newline at end of file
diff --git a/ProjectLighthouse/Helpers/CryptoHelper.cs b/ProjectLighthouse/Helpers/CryptoHelper.cs
index 41c3d018..aef06419 100644
--- a/ProjectLighthouse/Helpers/CryptoHelper.cs
+++ b/ProjectLighthouse/Helpers/CryptoHelper.cs
@@ -71,6 +71,18 @@ public static class CryptoHelper
return b;
}
+ public static string ToBase64(string str)
+ {
+ byte[] bytes = Encoding.UTF8.GetBytes(str);
+ return Convert.ToBase64String(bytes);
+ }
+
+ public static string FromBase64(string base64)
+ {
+ byte[] bytes = Convert.FromBase64String(base64);
+ return Encoding.UTF8.GetString(bytes);
+ }
+
#region Hash Functions
public static string Sha256Hash(string str) => Sha256Hash(Encoding.UTF8.GetBytes(str));
@@ -86,5 +98,4 @@ public static class CryptoHelper
public static string BCryptHash(byte[] bytes) => BCrypt.Net.BCrypt.HashPassword(Encoding.UTF8.GetString(bytes));
#endregion
-
}
\ No newline at end of file
diff --git a/ProjectLighthouse/Logging/LoggerBase.cs b/ProjectLighthouse/Logging/ILogger.cs
similarity index 100%
rename from ProjectLighthouse/Logging/LoggerBase.cs
rename to ProjectLighthouse/Logging/ILogger.cs
diff --git a/ProjectLighthouse/Logging/LogArea.cs b/ProjectLighthouse/Logging/LogArea.cs
index ebb74275..dde0f5f4 100644
--- a/ProjectLighthouse/Logging/LogArea.cs
+++ b/ProjectLighthouse/Logging/LogArea.cs
@@ -19,4 +19,5 @@ public enum LogArea
Resources,
Logger,
Redis,
+ Command,
}
\ No newline at end of file
diff --git a/ProjectLighthouse/Logging/Logger.cs b/ProjectLighthouse/Logging/Logger.cs
index 0078d464..183642fb 100644
--- a/ProjectLighthouse/Logging/Logger.cs
+++ b/ProjectLighthouse/Logging/Logger.cs
@@ -10,12 +10,6 @@ using System.Threading.Tasks;
namespace LBPUnion.ProjectLighthouse.Logging;
-// TODO: make into singleton, but with ability to also have instances
-// Logger.LogSuccess() should still work and all, but ideally i'm also able to have another instance and do:
-// Logger logger = new();
-// logger.LogSuccess();
-// I should also be able to access the log queue.
-// This functionality is going to be used in the admin panel to get the output of commands.
public class Logger
{
internal static readonly Logger Instance = new();
@@ -30,7 +24,7 @@ public class Logger
public void AddLogger(ILogger logger)
{
loggers.Add(logger);
- LogSuccess("Initialized " + logger.GetType().Name, LogArea.Logger);
+ LogDebug("Initialized " + logger.GetType().Name, LogArea.Logger);
}
private LogTrace getTrace(int extraTraceLines = 0)
diff --git a/ProjectLighthouse/Logging/Loggers/InMemoryLogger.cs b/ProjectLighthouse/Logging/Loggers/InMemoryLogger.cs
new file mode 100644
index 00000000..24413ec3
--- /dev/null
+++ b/ProjectLighthouse/Logging/Loggers/InMemoryLogger.cs
@@ -0,0 +1,16 @@
+using System.Collections.Generic;
+
+namespace LBPUnion.ProjectLighthouse.Logging.Loggers;
+
+public class InMemoryLogger : ILogger
+{
+ public readonly List Lines = new();
+
+ public void Log(LogLine line)
+ {
+ lock(this.Lines)
+ {
+ this.Lines.Add(line);
+ }
+ }
+}
\ No newline at end of file
diff --git a/ProjectLighthouse/StartupTasks.cs b/ProjectLighthouse/StartupTasks.cs
index 50165011..a9ba4ab5 100644
--- a/ProjectLighthouse/StartupTasks.cs
+++ b/ProjectLighthouse/StartupTasks.cs
@@ -1,7 +1,9 @@
using System;
+using System.Collections.Generic;
using System.Diagnostics;
using LBPUnion.ProjectLighthouse.Administration.Maintenance;
using LBPUnion.ProjectLighthouse.Configuration;
+using LBPUnion.ProjectLighthouse.Extensions;
using LBPUnion.ProjectLighthouse.Files;
using LBPUnion.ProjectLighthouse.Helpers;
using LBPUnion.ProjectLighthouse.Logging;
@@ -71,7 +73,8 @@ public static class StartupTasks
if (args.Length != 0)
{
- MaintenanceHelper.RunCommand(args).Wait();
+ List logLines = MaintenanceHelper.RunCommand(args).Result;
+ Console.WriteLine(logLines.ToLogString());
return;
}