Skip to content

Commit

Permalink
Merge pull request #434 from Moonlight-Panel/v2_UpgradeMoonCore
Browse files Browse the repository at this point in the history
Upgrade to new MoonCore version
  • Loading branch information
Masu-Baumgartner authored Jul 6, 2024
2 parents 1eb63d7 + ae2634f commit 5e61526
Show file tree
Hide file tree
Showing 122 changed files with 2,491 additions and 1,575 deletions.
10 changes: 10 additions & 0 deletions Moonlight/Core/Configuration/CoreConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,16 @@ public class AuthenticationData
[JsonProperty("DenyRegister")]
[Description("This disables the register function. No user will be able to sign up anymore. Its recommended to enable this for private instances")]
public bool DenyRegister { get; set; } = false;

[JsonProperty("EnablePeriodicReAuth")]
[Description(
"If this option is enabled, every session will reauthenticate perdiodicly to track state changes in real time without the user refreshing the page")]
public bool EnablePeriodicReAuth { get; set; } = true;

[JsonProperty("PeriodicReAuthDelay")]
[Description(
"This option specifies how long the intervals are between reauthentications. The value is specified in minutes")]
public int PeriodicReAuthDelay { get; set; } = 5;
}

public class SecurityData
Expand Down
47 changes: 24 additions & 23 deletions Moonlight/Core/CoreFeature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,10 @@
using MoonCore.Abstractions;
using MoonCore.Helpers;
using MoonCore.Services;
using MoonCoreUI.Extensions;
using MoonCoreUI.Services;
using Moonlight.Core.Configuration;
using Moonlight.Core.Database;
using Moonlight.Core.Database.Entities;
using Moonlight.Core.Implementations.Diagnose;
using Moonlight.Core.Implementations.UI.Admin.AdminColumns;
using Moonlight.Core.Implementations.UI.Index;
using Moonlight.Core.Interfaces;
using Moonlight.Core.Interfaces.Ui.Admin;
using Moonlight.Core.Interfaces.UI.User;
Expand All @@ -21,10 +17,16 @@
using Moonlight.Core.Repositories;
using Moonlight.Core.Services;
using Microsoft.OpenApi.Models;
using MoonCore.Blazor.Extensions;
using MoonCore.Blazor.Services;
using MoonCore.Extensions;
using Moonlight.Core.Attributes;
using Moonlight.Core.Http.Middleware;
using Moonlight.Core.Implementations.AdminDashboard;
using Moonlight.Core.Implementations.ApiDefinition;
using Moonlight.Core.Implementations.UserDashboard;
using Swashbuckle.AspNetCore.SwaggerGen;
using AuthenticationStateProvider = Moonlight.Core.Helpers.AuthenticationStateProvider;
using Microsoft.AspNetCore.Http.Features;

namespace Moonlight.Core;
Expand Down Expand Up @@ -55,25 +57,24 @@ public override Task OnPreInitialized(PreInitContext context)
builder.Services.AddDbContext<DataContext>();

//
builder.Services.AddSingleton(new JwtService<CoreJwtType>(config.Security.Token));
builder.Services.AddSingleton(new JwtService<CoreJwtType>(
config.Security.Token,
context.LoggerFactory.CreateLogger<JwtService<CoreJwtType>>()
)
);

// Mooncore services
builder.Services.AddScoped(typeof(Repository<>), typeof(GenericRepository<>));
builder.Services.AddScoped<CookieService>();
builder.Services.AddScoped<FileDownloadService>();
builder.Services.AddScoped<AlertService>();
builder.Services.AddScoped<ToastService>();
builder.Services.AddScoped<ClipboardService>();
builder.Services.AddScoped<ModalService>();

builder.Services.AddMoonCoreUi(configuration =>

builder.Services.AddMoonCore(configuration =>
{
configuration.ToastJavascriptPrefix = "moonlight.toasts";
configuration.ModalJavascriptPrefix = "moonlight.modals";
configuration.AlertJavascriptPrefix = "moonlight.alerts";
configuration.ClipboardJavascriptPrefix = "moonlight.clipboard";
configuration.FileDownloadJavascriptPrefix = "moonlight.utils";
configuration.Identity.Token = config.Security.Token;
configuration.Identity.PeriodicReAuthDelay = TimeSpan.FromMinutes(config.Authentication.PeriodicReAuthDelay);
configuration.Identity.EnablePeriodicReAuth = config.Authentication.EnablePeriodicReAuth;
configuration.Identity.Provider = new AuthenticationStateProvider();
});

builder.Services.AddMoonCoreBlazor();

// Add external services and blazor/asp.net stuff
builder.Services.AddRazorPages();
Expand Down Expand Up @@ -191,7 +192,7 @@ public override async Task OnInitialized(InitContext context)
Name = "Manage admin api access",
Description = "Allows access to manage api keys and their permissions"
});

await permissionService.Register(9999, new()
{
Name = "Manage system",
Expand Down Expand Up @@ -226,9 +227,9 @@ await startupJobService.AddJob("Default user creation", TimeSpan.FromSeconds(3),
{
using var scope = provider.CreateScope();

var configService = scope.ServiceProvider.GetRequiredService<ConfigService<CoreConfiguration>>();
var userRepo = scope.ServiceProvider.GetRequiredService<Repository<User>>();
var authenticationProvider = scope.ServiceProvider.GetRequiredService<IAuthenticationProvider>();
var logger = scope.ServiceProvider.GetRequiredService<ILogger<CoreFeature>>();

if (!configService.Get().Authentication.UseDefaultAuthentication)
return;
Expand All @@ -246,7 +247,7 @@ await startupJobService.AddJob("Default user creation", TimeSpan.FromSeconds(3),

if (registeredUser == null)
{
Logger.Warn("Unable to create default user. Register function returned null");
logger.LogWarning("Unable to create default user. Register function returned null");
return;
}

Expand All @@ -255,15 +256,15 @@ await startupJobService.AddJob("Default user creation", TimeSpan.FromSeconds(3),
user.Permissions = 9999;
userRepo.Update(user);

Logger.Info($"Default login: Email: '{email}' Password: '{password}'");
logger.LogInformation("Default login: Email: '{email}' Password: '{password}'", email, password);
});

// Api
if (config.Development.EnableApiReference)
app.MapSwagger("/api/core/reference/openapi/{documentName}");

app.UseMiddleware<ApiPermissionMiddleware>();

await pluginService.RegisterImplementation<IApiDefinition>(new InternalApiDefinition());
}

Expand Down
5 changes: 5 additions & 0 deletions Moonlight/Core/Database/DataContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,9 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
);
}
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{

}
}
11 changes: 9 additions & 2 deletions Moonlight/Core/Events/CoreEvents.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
using MoonCore.Helpers;
using MoonCore.Attributes;
using MoonCore.Helpers;

namespace Moonlight.Core.Events;

[Singleton]
public class CoreEvents
{
public static SmartEventHandler OnMoonlightRestart { get; set; } = new();
public CoreEvents(ILogger<SmartEventHandler> logger)
{
OnMoonlightRestart = new(logger);
}

public SmartEventHandler OnMoonlightRestart { get; set; }
}
54 changes: 54 additions & 0 deletions Moonlight/Core/Extensions/IdentityServiceExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using MoonCore.Abstractions;
using MoonCore.Services;
using Moonlight.Core.Database.Entities;

namespace Moonlight.Core.Extensions;

public static class IdentityServiceExtensions
{
public static User GetUser(this IdentityService identityService)
{
return identityService.Storage.Get<User>();
}

public static Task<bool> HasFlag(this IdentityService identityService, string flag)
{
if (!identityService.IsAuthenticated)
return Task.FromResult(false);

var result = identityService.GetUser().Flags.Split(";").Contains(flag);
return Task.FromResult(result);
}

public static Task SetFlag(this IdentityService identityService, string flag, bool toggle)
{
if (!identityService.IsAuthenticated)
return Task.CompletedTask;

var user = identityService.GetUser();

// Rebuild flags
var flags = user.Flags.Split(";").ToList();

if (toggle)
{
if(!flags.Contains(flag))
flags.Add(flag);
}
else
{
if (flags.Contains(flag))
flags.Remove(flag);
}

user.Flags = string.Join(';', flags);

// Save changes
var serviceProvider = identityService.Storage.Get<IServiceProvider>();
var userRepo = serviceProvider.GetRequiredService<Repository<User>>();

userRepo.Update(user);

return Task.CompletedTask;
}
}
50 changes: 50 additions & 0 deletions Moonlight/Core/Helpers/AuthenticationStateProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using MoonCore.Abstractions;
using MoonCore.Helpers;
using Moonlight.Core.Database.Entities;

namespace Moonlight.Core.Helpers;

public class AuthenticationStateProvider : MoonCore.Abstractions.AuthenticationStateProvider
{
public override Task<bool> IsValidIdentifier(IServiceProvider provider, string identifier)
{
if(!int.TryParse(identifier, out int searchId))
return Task.FromResult(false);

var userRepo = provider.GetRequiredService<Repository<User>>();
var result = userRepo.Get().Any(x => x.Id == searchId);

return Task.FromResult(result);
}

public override Task LoadFromIdentifier(IServiceProvider provider, string identifier, DynamicStorage storage)
{
if(!int.TryParse(identifier, out int searchId))
return Task.CompletedTask;

var userRepo = provider.GetRequiredService<Repository<User>>();
var user = userRepo.Get().FirstOrDefault(x => x.Id == searchId);

if(user == null)
return Task.CompletedTask;

storage.Set("User", user);
storage.Set("ServiceProvider", provider);

return Task.CompletedTask;
}

public override Task<DateTime> DetermineTokenValidTimestamp(IServiceProvider provider, string identifier)
{
if(!int.TryParse(identifier, out int searchId))
return Task.FromResult(DateTime.MaxValue);

var userRepo = provider.GetRequiredService<Repository<User>>();
var user = userRepo.Get().FirstOrDefault(x => x.Id == searchId);

if(user == null)
return Task.FromResult(DateTime.MaxValue);

return Task.FromResult(user.TokenValidTimestamp);
}
}
20 changes: 14 additions & 6 deletions Moonlight/Core/Helpers/HostSystemHelper.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
using System.Diagnostics;
using System.Runtime.InteropServices;
using MoonCore.Attributes;
using MoonCore.Helpers;

namespace Moonlight.Core.Helpers;

public static class HostSystemHelper
[Singleton]
public class HostSystemHelper
{
public static Task<string> GetOsName()
private readonly ILogger<HostSystemHelper> Logger;

public HostSystemHelper(ILogger<HostSystemHelper> logger)
{
Logger = logger;
}

public Task<string> GetOsName()
{
try
{
Expand Down Expand Up @@ -48,21 +57,20 @@ public static Task<string> GetOsName()
}
catch (Exception e)
{
Logger.Warn("Error retrieving os information");
Logger.Warn(e);
Logger.LogWarning("Error retrieving os information: {e}", e);

return Task.FromResult("N/A");
}
}

public static Task<long> GetMemoryUsage()
public Task<long> GetMemoryUsage()
{
var process = Process.GetCurrentProcess();
var bytes = process.PrivateMemorySize64;
return Task.FromResult(bytes);
}

public static Task<int> GetCpuUsage()
public Task<int> GetCpuUsage()
{
var process = Process.GetCurrentProcess();
var cpuTime = process.TotalProcessorTime;
Expand Down
9 changes: 8 additions & 1 deletion Moonlight/Core/Http/Controllers/AssetController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,20 @@ namespace Moonlight.Core.Http.Controllers;
[Route("api/core/asset")]
public class AssetController : Controller
{
private readonly ILogger<AssetController> Logger;

public AssetController(ILogger<AssetController> logger)
{
Logger = logger;
}

[HttpGet("{name}/{*path}")]
public async Task<ActionResult> Get(string name, string path)
{
// Check for path transversal attacks
if (path.Contains("..") || name.Contains(".."))
{
Logger.Warn($"{HttpContext.Connection.RemoteIpAddress} tried to use path transversal attack: {name}/{path}");
Logger.LogWarning("{remoteIp} tried to use path transversal attack: {name}/{path}", HttpContext.Connection.RemoteIpAddress, name, path);
return NotFound();
}

Expand Down
Loading

0 comments on commit 5e61526

Please sign in to comment.