Upgraded mooncore versions. Cleaned up code, especially startup code. Changed versions
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using MoonCore.Common;
|
||||
using MoonCore.Extended.Abstractions;
|
||||
using MoonCore.Models;
|
||||
using Moonlight.ApiServer.Database.Entities;
|
||||
using Moonlight.ApiServer.Mappers;
|
||||
using Moonlight.ApiServer.Services;
|
||||
@@ -26,7 +26,7 @@ public class ApiKeysController : Controller
|
||||
|
||||
[HttpGet]
|
||||
[Authorize(Policy = "permissions:admin.apikeys.get")]
|
||||
public async Task<ActionResult<ICountedData<ApiKeyResponse>>> GetAsync(
|
||||
public async Task<ActionResult<CountedData<ApiKeyResponse>>> GetAsync(
|
||||
[FromQuery] int startIndex,
|
||||
[FromQuery] int count,
|
||||
[FromQuery] string? orderBy,
|
||||
|
||||
@@ -1,11 +1,8 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using MoonCore.Exceptions;
|
||||
using MoonCore.Common;
|
||||
using MoonCore.Extended.Abstractions;
|
||||
using MoonCore.Extended.Models;
|
||||
using MoonCore.Models;
|
||||
using Moonlight.ApiServer.Database.Entities;
|
||||
using Moonlight.ApiServer.Mappers;
|
||||
using Moonlight.Shared.Http.Requests.Admin.Sys.Theme;
|
||||
@@ -26,7 +23,7 @@ public class ThemesController : Controller
|
||||
|
||||
[HttpGet]
|
||||
[Authorize(Policy = "permissions:admin.system.customisation.themes.read")]
|
||||
public async Task<ActionResult<ICountedData<ThemeResponse>>> GetAsync(
|
||||
public async Task<ActionResult<CountedData<ThemeResponse>>> GetAsync(
|
||||
[FromQuery] int startIndex,
|
||||
[FromQuery] int count,
|
||||
[FromQuery] string? orderBy,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Moonlight.ApiServer.Services;
|
||||
using Moonlight.Shared.Http.Requests.Admin.Sys;
|
||||
|
||||
@@ -2,10 +2,9 @@ using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using MoonCore.Exceptions;
|
||||
using MoonCore.Common;
|
||||
using MoonCore.Extended.Abstractions;
|
||||
using MoonCore.Extended.Helpers;
|
||||
using MoonCore.Models;
|
||||
using Moonlight.ApiServer.Database.Entities;
|
||||
using Moonlight.ApiServer.Services;
|
||||
using Moonlight.ApiServer.Mappers;
|
||||
@@ -27,7 +26,7 @@ public class UsersController : Controller
|
||||
|
||||
[HttpGet]
|
||||
[Authorize(Policy = "permissions:admin.users.get")]
|
||||
public async Task<ActionResult<ICountedData<UserResponse>>> GetAsync(
|
||||
public async Task<ActionResult<CountedData<UserResponse>>> GetAsync(
|
||||
[FromQuery] int startIndex,
|
||||
[FromQuery] int count,
|
||||
[FromQuery] string? orderBy,
|
||||
|
||||
@@ -4,7 +4,6 @@ using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Moonlight.ApiServer.Configuration;
|
||||
using Moonlight.ApiServer.Implementations.LocalAuth;
|
||||
using Moonlight.ApiServer.Interfaces;
|
||||
using Moonlight.Shared.Http.Responses.Auth;
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
@using Moonlight.ApiServer.Database.Entities
|
||||
@using Moonlight.Shared.Misc
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" class="bg-background text-base-content font-inter">
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using MoonCore.Exceptions;
|
||||
using MoonCore.Extended.Abstractions;
|
||||
using MoonCore.Extended.Helpers;
|
||||
using MoonCore.Helpers;
|
||||
|
||||
3
Moonlight.ApiServer/IAssemblyMarker.cs
Normal file
3
Moonlight.ApiServer/IAssemblyMarker.cs
Normal file
@@ -0,0 +1,3 @@
|
||||
namespace Moonlight.ApiServer;
|
||||
|
||||
public interface IAssemblyMarker;
|
||||
@@ -1,7 +1,6 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Moonlight.ApiServer.Configuration;
|
||||
@@ -21,11 +20,12 @@ namespace Moonlight.ApiServer.Implementations.Startup;
|
||||
|
||||
public class CoreStartup : IPluginStartup
|
||||
{
|
||||
public Task BuildApplicationAsync(IServiceProvider serviceProvider, IHostApplicationBuilder builder)
|
||||
public void AddPlugin(WebApplicationBuilder builder)
|
||||
{
|
||||
var configuration = serviceProvider.GetRequiredService<AppConfiguration>();
|
||||
|
||||
#region Api Docs
|
||||
var configuration = AppConfiguration.CreateEmpty();
|
||||
builder.Configuration.Bind(configuration);
|
||||
|
||||
#region Api Docs
|
||||
|
||||
if (configuration.Development.EnableApiDocs)
|
||||
{
|
||||
@@ -138,31 +138,27 @@ public class CoreStartup : IPluginStartup
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task ConfigureApplicationAsync(IServiceProvider serviceProvider, IApplicationBuilder app)
|
||||
public void UsePlugin(WebApplication app)
|
||||
{
|
||||
var configuration = serviceProvider.GetRequiredService<AppConfiguration>();
|
||||
|
||||
var configuration = AppConfiguration.CreateEmpty();
|
||||
app.Configuration.Bind(configuration);
|
||||
|
||||
#region Prometheus
|
||||
|
||||
if (configuration.OpenTelemetry is { Enable: true, Metrics.EnablePrometheus: true })
|
||||
app.UseOpenTelemetryPrometheusScrapingEndpoint();
|
||||
|
||||
#endregion
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task ConfigureEndpointsAsync(IServiceProvider serviceProvider, IEndpointRouteBuilder routeBuilder)
|
||||
public void MapPlugin(WebApplication app)
|
||||
{
|
||||
var configuration = serviceProvider.GetRequiredService<AppConfiguration>();
|
||||
|
||||
var configuration = AppConfiguration.CreateEmpty();
|
||||
app.Configuration.Bind(configuration);
|
||||
|
||||
if (configuration.Development.EnableApiDocs)
|
||||
routeBuilder.MapSwagger("/api/swagger/{documentName}");
|
||||
|
||||
return Task.CompletedTask;
|
||||
app.MapSwagger("/api/swagger/{documentName}");
|
||||
}
|
||||
}
|
||||
@@ -13,7 +13,7 @@
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<PackageId>Moonlight.ApiServer</PackageId>
|
||||
<Version>2.1.11</Version>
|
||||
<Version>2.1.12</Version>
|
||||
<Authors>Moonlight Panel</Authors>
|
||||
<Description>A build of the api server for moonlight development</Description>
|
||||
<PackageProjectUrl>https://github.com/Moonlight-Panel/Moonlight</PackageProjectUrl>
|
||||
@@ -27,9 +27,9 @@
|
||||
<PackageReference Include="Hangfire.EntityFrameworkCore" Version="0.7.0"/>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.9" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.SignalR.StackExchangeRedis" Version="9.0.9" />
|
||||
<PackageReference Include="MoonCore" Version="2.0.1" />
|
||||
<PackageReference Include="MoonCore.Extended" Version="1.4.0" />
|
||||
<PackageReference Include="MoonCore.PluginFramework.Generator" Version="1.0.2"/>
|
||||
<PackageReference Include="MoonCore" Version="2.0.4" />
|
||||
<PackageReference Include="MoonCore.Extended" Version="1.4.2" />
|
||||
<PackageReference Include="MoonCore.PluginFramework.Generator" Version="1.0.3" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
|
||||
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.12.0" />
|
||||
<PackageReference Include="OpenTelemetry.Exporter.Prometheus.AspNetCore" Version="1.12.0-beta.1"/>
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace Moonlight.ApiServer.Plugins;
|
||||
|
||||
public interface IPluginStartup
|
||||
{
|
||||
public Task BuildApplicationAsync(IServiceProvider serviceProvider, IHostApplicationBuilder builder);
|
||||
public Task ConfigureApplicationAsync(IServiceProvider serviceProvider, IApplicationBuilder app);
|
||||
public Task ConfigureEndpointsAsync(IServiceProvider serviceProvider, IEndpointRouteBuilder routeBuilder);
|
||||
public void AddPlugin(WebApplicationBuilder builder);
|
||||
public void UsePlugin(WebApplication app);
|
||||
public void MapPlugin(WebApplication app);
|
||||
}
|
||||
@@ -3,19 +3,24 @@ using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.DataProtection;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using MoonCore.Permissions;
|
||||
using Moonlight.ApiServer.Configuration;
|
||||
using Moonlight.ApiServer.Implementations.LocalAuth;
|
||||
using Moonlight.ApiServer.Services;
|
||||
|
||||
namespace Moonlight.ApiServer.Startup;
|
||||
|
||||
public partial class Startup
|
||||
public static partial class Startup
|
||||
{
|
||||
private Task RegisterAuthAsync()
|
||||
private static void AddAuth(this WebApplicationBuilder builder)
|
||||
{
|
||||
WebApplicationBuilder.Services
|
||||
var configuration = AppConfiguration.CreateEmpty();
|
||||
builder.Configuration.Bind(configuration);
|
||||
|
||||
builder.Services
|
||||
.AddAuthentication(options => { options.DefaultScheme = "MainScheme"; })
|
||||
.AddPolicyScheme("MainScheme", null, options =>
|
||||
{
|
||||
@@ -42,15 +47,15 @@ public partial class Startup
|
||||
options.TokenValidationParameters = new()
|
||||
{
|
||||
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(
|
||||
Configuration.Authentication.Secret
|
||||
configuration.Authentication.Secret
|
||||
)),
|
||||
ValidateIssuerSigningKey = true,
|
||||
ValidateLifetime = true,
|
||||
ClockSkew = TimeSpan.Zero,
|
||||
ValidateAudience = true,
|
||||
ValidAudience = Configuration.PublicUrl,
|
||||
ValidAudience = configuration.PublicUrl,
|
||||
ValidateIssuer = true,
|
||||
ValidIssuer = Configuration.PublicUrl
|
||||
ValidIssuer = configuration.PublicUrl
|
||||
};
|
||||
|
||||
options.Events = new JwtBearerEvents()
|
||||
@@ -81,11 +86,11 @@ public partial class Startup
|
||||
})
|
||||
.AddCookie("Session", null, options =>
|
||||
{
|
||||
options.ExpireTimeSpan = TimeSpan.FromDays(Configuration.Authentication.Sessions.ExpiresIn);
|
||||
options.ExpireTimeSpan = TimeSpan.FromDays(configuration.Authentication.Sessions.ExpiresIn);
|
||||
|
||||
options.Cookie = new CookieBuilder()
|
||||
{
|
||||
Name = Configuration.Authentication.Sessions.CookieName,
|
||||
Name = configuration.Authentication.Sessions.CookieName,
|
||||
Path = "/",
|
||||
IsEssential = true,
|
||||
SecurePolicy = CookieSecurePolicy.SameAsRequest
|
||||
@@ -150,16 +155,16 @@ public partial class Startup
|
||||
options.SignInScheme = "Session";
|
||||
});
|
||||
|
||||
WebApplicationBuilder.Services.AddAuthorization();
|
||||
builder.Services.AddAuthorization();
|
||||
|
||||
WebApplicationBuilder.Services.AddAuthorizationPermissions(options =>
|
||||
builder.Services.AddAuthorizationPermissions(options =>
|
||||
{
|
||||
options.ClaimName = "Permissions";
|
||||
options.Prefix = "permissions:";
|
||||
});
|
||||
|
||||
WebApplicationBuilder.Services.AddScoped<UserAuthService>();
|
||||
WebApplicationBuilder.Services.AddScoped<ApiKeyAuthService>();
|
||||
builder.Services.AddScoped<UserAuthService>();
|
||||
builder.Services.AddScoped<ApiKeyAuthService>();
|
||||
|
||||
// Setup data protection storage within storage folder
|
||||
// so its persists in containers
|
||||
@@ -167,23 +172,18 @@ public partial class Startup
|
||||
|
||||
Directory.CreateDirectory(dpKeyPath);
|
||||
|
||||
WebApplicationBuilder.Services
|
||||
builder.Services
|
||||
.AddDataProtection()
|
||||
.PersistKeysToFileSystem(
|
||||
new DirectoryInfo(dpKeyPath)
|
||||
);
|
||||
|
||||
WebApplicationBuilder.Services.AddScoped<UserDeletionService>();
|
||||
|
||||
return Task.CompletedTask;
|
||||
builder.Services.AddScoped<UserDeletionService>();
|
||||
}
|
||||
|
||||
private Task UseAuthAsync()
|
||||
private static void UseAuth(this WebApplication application)
|
||||
{
|
||||
WebApplication.UseAuthentication();
|
||||
|
||||
WebApplication.UseAuthorization();
|
||||
|
||||
return Task.CompletedTask;
|
||||
application.UseAuthentication();
|
||||
application.UseAuthorization();
|
||||
}
|
||||
}
|
||||
@@ -1,63 +1,62 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using MoonCore.Extended.Extensions;
|
||||
using MoonCore.Extensions;
|
||||
using MoonCore.Helpers;
|
||||
using Moonlight.ApiServer.Configuration;
|
||||
using Moonlight.ApiServer.Plugins;
|
||||
|
||||
namespace Moonlight.ApiServer.Startup;
|
||||
|
||||
public partial class Startup
|
||||
public static partial class Startup
|
||||
{
|
||||
private Task RegisterBaseAsync()
|
||||
private static void AddBase(this WebApplicationBuilder builder, IPluginStartup[] startups)
|
||||
{
|
||||
WebApplicationBuilder.Services.AutoAddServices<Startup>();
|
||||
WebApplicationBuilder.Services.AddHttpClient();
|
||||
builder.Services.AutoAddServices<IAssemblyMarker>();
|
||||
builder.Services.AddHttpClient();
|
||||
|
||||
WebApplicationBuilder.Services.AddApiExceptionHandler();
|
||||
|
||||
// Add pre-existing services
|
||||
WebApplicationBuilder.Services.AddSingleton(Configuration);
|
||||
builder.Services.AddApiExceptionHandler();
|
||||
|
||||
// Configure controllers
|
||||
var mvcBuilder = WebApplicationBuilder.Services.AddControllers();
|
||||
var mvcBuilder = builder.Services.AddControllers();
|
||||
|
||||
// Add plugin assemblies as application parts
|
||||
foreach (var pluginStartup in PluginStartups.Select(x => x.GetType().Assembly).Distinct())
|
||||
foreach (var pluginStartup in startups.Select(x => x.GetType().Assembly).Distinct())
|
||||
mvcBuilder.AddApplicationPart(pluginStartup.GetType().Assembly);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task UseBaseAsync()
|
||||
private static void UseBase(this WebApplication application)
|
||||
{
|
||||
WebApplication.UseRouting();
|
||||
WebApplication.UseExceptionHandler();
|
||||
|
||||
return Task.CompletedTask;
|
||||
application.UseRouting();
|
||||
application.UseExceptionHandler();
|
||||
}
|
||||
|
||||
private Task MapBaseAsync()
|
||||
private static void MapBase(this WebApplication application)
|
||||
{
|
||||
WebApplication.MapControllers();
|
||||
|
||||
if (Configuration.Frontend.EnableHosting)
|
||||
WebApplication.MapFallbackToController("Index", "Frontend");
|
||||
|
||||
return Task.CompletedTask;
|
||||
application.MapControllers();
|
||||
|
||||
// Frontend
|
||||
var configuration = AppConfiguration.CreateEmpty();
|
||||
application.Configuration.Bind(configuration);
|
||||
|
||||
if (configuration.Frontend.EnableHosting)
|
||||
application.MapFallbackToController("Index", "Frontend");
|
||||
}
|
||||
|
||||
private Task ConfigureKestrelAsync()
|
||||
private static void ConfigureKestrel(this WebApplicationBuilder builder)
|
||||
{
|
||||
WebApplicationBuilder.WebHost.ConfigureKestrel(kestrelOptions =>
|
||||
var configuration = AppConfiguration.CreateEmpty();
|
||||
builder.Configuration.Bind(configuration);
|
||||
|
||||
builder.WebHost.ConfigureKestrel(kestrelOptions =>
|
||||
{
|
||||
var maxUploadInBytes = ByteConverter
|
||||
.FromMegaBytes(Configuration.Kestrel.UploadLimit)
|
||||
.FromMegaBytes(configuration.Kestrel.UploadLimit)
|
||||
.Bytes;
|
||||
|
||||
kestrelOptions.Limits.MaxRequestBodySize = maxUploadInBytes;
|
||||
});
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using MoonCore.EnvConfiguration;
|
||||
@@ -6,30 +7,23 @@ using Moonlight.ApiServer.Configuration;
|
||||
|
||||
namespace Moonlight.ApiServer.Startup;
|
||||
|
||||
public partial class Startup
|
||||
public static partial class Startup
|
||||
{
|
||||
private async Task SetupAppConfigurationAsync()
|
||||
private static void AddConfiguration(this WebApplicationBuilder builder)
|
||||
{
|
||||
var configPath = Path.Combine("storage", "config.yml");
|
||||
// Yaml
|
||||
var yamlPath = Path.Combine("storage", "config.yml");
|
||||
|
||||
await YamlDefaultGenerator.GenerateAsync<AppConfiguration>(configPath);
|
||||
YamlDefaultGenerator.GenerateAsync<AppConfiguration>(yamlPath).Wait();
|
||||
|
||||
// Configure configuration (wow)
|
||||
var configurationBuilder = new ConfigurationBuilder();
|
||||
|
||||
configurationBuilder.AddYamlFile(configPath);
|
||||
configurationBuilder.AddEnvironmentVariables(prefix: "MOONLIGHT_", separator: "_");
|
||||
|
||||
var configurationRoot = configurationBuilder.Build();
|
||||
builder.Configuration.AddYamlFile(yamlPath);
|
||||
|
||||
// Retrieve configuration
|
||||
Configuration = AppConfiguration.CreateEmpty();
|
||||
configurationRoot.Bind(Configuration);
|
||||
}
|
||||
|
||||
private Task RegisterAppConfigurationAsync()
|
||||
{
|
||||
WebApplicationBuilder.Services.AddSingleton(Configuration);
|
||||
return Task.CompletedTask;
|
||||
// Env
|
||||
builder.Configuration.AddEnvironmentVariables(prefix: "MOONLIGHT_", separator: "_");
|
||||
|
||||
var configuration = AppConfiguration.CreateEmpty();
|
||||
builder.Configuration.Bind(configuration);
|
||||
|
||||
builder.Services.AddSingleton(configuration);
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,17 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using MoonCore.Extended.Abstractions;
|
||||
using MoonCore.Extended.Extensions;
|
||||
|
||||
namespace Moonlight.ApiServer.Startup;
|
||||
|
||||
public partial class Startup
|
||||
public static partial class Startup
|
||||
{
|
||||
private Task RegisterDatabaseAsync()
|
||||
private static void AddDatabase(this WebApplicationBuilder builder)
|
||||
{
|
||||
WebApplicationBuilder.Services.AddDatabaseMappings();
|
||||
WebApplicationBuilder.Services.AddServiceCollectionAccessor();
|
||||
builder.Services.AddDbAutoMigrations();
|
||||
builder.Services.AddDatabaseMappings();
|
||||
|
||||
WebApplicationBuilder.Services.AddScoped(typeof(DatabaseRepository<>));
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task PrepareDatabaseAsync()
|
||||
{
|
||||
await WebApplication.Services.EnsureDatabaseMigratedAsync();
|
||||
|
||||
WebApplication.Services.GenerateDatabaseMappings();
|
||||
builder.Services.AddScoped(typeof(DatabaseRepository<>));
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using Hangfire;
|
||||
using Hangfire.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -7,11 +8,11 @@ using Moonlight.ApiServer.Database;
|
||||
|
||||
namespace Moonlight.ApiServer.Startup;
|
||||
|
||||
public partial class Startup
|
||||
public static partial class Startup
|
||||
{
|
||||
private Task RegisterHangfireAsync()
|
||||
private static void AddMoonlightHangfire(this WebApplicationBuilder builder)
|
||||
{
|
||||
WebApplicationBuilder.Services.AddHangfire((provider, configuration) =>
|
||||
builder.Services.AddHangfire((provider, configuration) =>
|
||||
{
|
||||
configuration.SetDataCompatibilityLevel(CompatibilityLevel.Version_180);
|
||||
configuration.UseSimpleAssemblyNameTypeSerializer();
|
||||
@@ -23,26 +24,22 @@ public partial class Startup
|
||||
}, new EFCoreStorageOptions());
|
||||
});
|
||||
|
||||
WebApplicationBuilder.Services.AddHangfireServer();
|
||||
builder.Services.AddHangfireServer();
|
||||
|
||||
WebApplicationBuilder.Logging.AddFilter(
|
||||
builder.Logging.AddFilter(
|
||||
"Hangfire.Server.BackgroundServerProcess",
|
||||
LogLevel.Warning
|
||||
);
|
||||
|
||||
WebApplicationBuilder.Logging.AddFilter(
|
||||
builder.Logging.AddFilter(
|
||||
"Hangfire.BackgroundJobServer",
|
||||
LogLevel.Warning
|
||||
);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task UseHangfireAsync()
|
||||
private static void UseMoonlightHangfire(this WebApplication application)
|
||||
{
|
||||
if (WebApplication.Environment.IsDevelopment())
|
||||
WebApplication.UseHangfireDashboard();
|
||||
|
||||
return Task.CompletedTask;
|
||||
if (application.Environment.IsDevelopment())
|
||||
application.UseHangfireDashboard();
|
||||
}
|
||||
}
|
||||
@@ -1,32 +1,24 @@
|
||||
using System.Text.Json;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using MoonCore.Logging;
|
||||
|
||||
namespace Moonlight.ApiServer.Startup;
|
||||
|
||||
public partial class Startup
|
||||
public static partial class Startup
|
||||
{
|
||||
private Task SetupLoggingAsync()
|
||||
private static void AddLogging(this WebApplicationBuilder builder)
|
||||
{
|
||||
var loggerFactory = new LoggerFactory();
|
||||
loggerFactory.AddAnsiConsole();
|
||||
|
||||
Logger = loggerFactory.CreateLogger<Startup>();
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task RegisterLoggingAsync()
|
||||
{
|
||||
// Configure application logging
|
||||
WebApplicationBuilder.Logging.ClearProviders();
|
||||
WebApplicationBuilder.Logging.AddAnsiConsole();
|
||||
WebApplicationBuilder.Logging.AddFile(Path.Combine("storage", "logs", "moonlight.log"));
|
||||
// Logging providers
|
||||
builder.Logging.ClearProviders();
|
||||
|
||||
builder.Logging.AddAnsiConsole();
|
||||
builder.Logging.AddFile(Path.Combine("storage", "logs", "moonlight.log"));
|
||||
|
||||
// Logging levels
|
||||
var logConfigPath = Path.Combine("storage", "logConfig.json");
|
||||
|
||||
// Ensure logging config, add a default one is missing
|
||||
// Ensure default log levels exist
|
||||
if (!File.Exists(logConfigPath))
|
||||
{
|
||||
var defaultLogLevels = new Dictionary<string, string>
|
||||
@@ -38,25 +30,26 @@ public partial class Startup
|
||||
};
|
||||
|
||||
var logLevelsJson = JsonSerializer.Serialize(defaultLogLevels);
|
||||
await File.WriteAllTextAsync(logConfigPath, logLevelsJson);
|
||||
File.WriteAllText(logConfigPath, logLevelsJson);
|
||||
}
|
||||
|
||||
// Add logging configuration
|
||||
// Read log levels
|
||||
var logLevels = JsonSerializer.Deserialize<Dictionary<string, string>>(
|
||||
await File.ReadAllTextAsync(logConfigPath)
|
||||
File.ReadAllText(logConfigPath)
|
||||
)!;
|
||||
|
||||
// Apply configured log levels
|
||||
foreach (var level in logLevels)
|
||||
WebApplicationBuilder.Logging.AddFilter(level.Key, Enum.Parse<LogLevel>(level.Value));
|
||||
builder.Logging.AddFilter(level.Key, Enum.Parse<LogLevel>(level.Value));
|
||||
|
||||
// Mute exception handler middleware
|
||||
// https://github.com/dotnet/aspnetcore/issues/19740
|
||||
WebApplicationBuilder.Logging.AddFilter(
|
||||
builder.Logging.AddFilter(
|
||||
"Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware",
|
||||
LogLevel.Critical
|
||||
);
|
||||
|
||||
WebApplicationBuilder.Logging.AddFilter(
|
||||
builder.Logging.AddFilter(
|
||||
"Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware",
|
||||
LogLevel.Critical
|
||||
);
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Cors.Infrastructure;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moonlight.ApiServer.Configuration;
|
||||
|
||||
namespace Moonlight.ApiServer.Startup;
|
||||
|
||||
public partial class Startup
|
||||
public static partial class Startup
|
||||
{
|
||||
private Task PrintVersionAsync()
|
||||
private static void PrintVersionAsync()
|
||||
{
|
||||
// Fancy start console output... yes very fancy :>
|
||||
var rainbow = new Crayon.Rainbow(0.5);
|
||||
@@ -21,23 +23,22 @@ public partial class Startup
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task CreateStorageAsync()
|
||||
private static void CreateStorageAsync()
|
||||
{
|
||||
Directory.CreateDirectory("storage");
|
||||
Directory.CreateDirectory(Path.Combine("storage", "logs"));
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task RegisterCorsAsync()
|
||||
{
|
||||
var allowedOrigins = Configuration.Kestrel.AllowedOrigins;
|
||||
|
||||
WebApplicationBuilder.Services.AddCors(options =>
|
||||
private static void AddMoonlightCors(this WebApplicationBuilder builder)
|
||||
{
|
||||
var configuration = AppConfiguration.CreateEmpty();
|
||||
builder.Configuration.Bind(configuration);
|
||||
|
||||
var allowedOrigins = configuration.Kestrel.AllowedOrigins;
|
||||
|
||||
builder.Services.AddCors(options =>
|
||||
{
|
||||
var cors = new CorsPolicyBuilder();
|
||||
|
||||
@@ -60,14 +61,10 @@ public partial class Startup
|
||||
cors.Build()
|
||||
);
|
||||
});
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task UseCorsAsync()
|
||||
private static void UseMoonlightCors(this WebApplication application)
|
||||
{
|
||||
WebApplication.UseCors();
|
||||
|
||||
return Task.CompletedTask;
|
||||
application.UseCors();
|
||||
}
|
||||
}
|
||||
@@ -1,87 +1,25 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using MoonCore.Logging;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Moonlight.ApiServer.Plugins;
|
||||
|
||||
namespace Moonlight.ApiServer.Startup;
|
||||
|
||||
public partial class Startup
|
||||
public static partial class Startup
|
||||
{
|
||||
private IServiceProvider PluginLoadServiceProvider;
|
||||
private IPluginStartup[] PluginStartups;
|
||||
|
||||
private Task InitializePluginsAsync()
|
||||
private static void AddPlugins(this WebApplicationBuilder builder, IPluginStartup[] startups)
|
||||
{
|
||||
// Create service provider for starting up
|
||||
var serviceCollection = new ServiceCollection();
|
||||
|
||||
serviceCollection.AddSingleton(Configuration);
|
||||
|
||||
serviceCollection.AddLogging(builder =>
|
||||
{
|
||||
builder.ClearProviders();
|
||||
builder.AddAnsiConsole();
|
||||
});
|
||||
|
||||
PluginLoadServiceProvider = serviceCollection.BuildServiceProvider();
|
||||
|
||||
return Task.CompletedTask;
|
||||
foreach (var startup in startups)
|
||||
startup.AddPlugin(builder);
|
||||
}
|
||||
|
||||
private async Task HookPluginBuildAsync()
|
||||
private static void UsePlugins(this WebApplication application, IPluginStartup[] startups)
|
||||
{
|
||||
foreach (var pluginAppStartup in PluginStartups)
|
||||
{
|
||||
try
|
||||
{
|
||||
await pluginAppStartup.BuildApplicationAsync(PluginLoadServiceProvider, WebApplicationBuilder);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogError(
|
||||
"An error occured while processing 'BuildApp' for '{name}': {e}",
|
||||
pluginAppStartup.GetType().FullName,
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
foreach (var startup in startups)
|
||||
startup.UsePlugin(application);
|
||||
}
|
||||
|
||||
private async Task HookPluginConfigureAsync()
|
||||
private static void MapPlugins(this WebApplication application, IPluginStartup[] startups)
|
||||
{
|
||||
foreach (var pluginAppStartup in PluginStartups)
|
||||
{
|
||||
try
|
||||
{
|
||||
await pluginAppStartup.ConfigureApplicationAsync(PluginLoadServiceProvider, WebApplication);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogError(
|
||||
"An error occured while processing 'ConfigureApp' for '{name}': {e}",
|
||||
pluginAppStartup.GetType().FullName,
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HookPluginEndpointsAsync()
|
||||
{
|
||||
foreach (var pluginEndpointStartup in PluginStartups)
|
||||
{
|
||||
try
|
||||
{
|
||||
await pluginEndpointStartup.ConfigureEndpointsAsync(PluginLoadServiceProvider, WebApplication);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Logger.LogError(
|
||||
"An error occured while processing 'ConfigureEndpoints' for '{name}': {e}",
|
||||
pluginEndpointStartup.GetType().FullName,
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
foreach (var startup in startups)
|
||||
startup.MapPlugin(application);
|
||||
}
|
||||
}
|
||||
@@ -1,25 +1,26 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Moonlight.ApiServer.Configuration;
|
||||
using Moonlight.ApiServer.Http.Hubs;
|
||||
|
||||
namespace Moonlight.ApiServer.Startup;
|
||||
|
||||
public partial class Startup
|
||||
public static partial class Startup
|
||||
{
|
||||
public Task RegisterSignalRAsync()
|
||||
private static void AddMoonlightSignalR(this WebApplicationBuilder builder)
|
||||
{
|
||||
var signalRBuilder = WebApplicationBuilder.Services.AddSignalR();
|
||||
|
||||
if (Configuration.SignalR.UseRedis)
|
||||
signalRBuilder.AddStackExchangeRedis(Configuration.SignalR.RedisConnectionString);
|
||||
var configuration = AppConfiguration.CreateEmpty();
|
||||
builder.Configuration.Bind(configuration);
|
||||
|
||||
return Task.CompletedTask;
|
||||
var signalRBuilder = builder.Services.AddSignalR();
|
||||
|
||||
if (configuration.SignalR.UseRedis)
|
||||
signalRBuilder.AddStackExchangeRedis(configuration.SignalR.RedisConnectionString);
|
||||
}
|
||||
|
||||
public Task MapSignalRAsync()
|
||||
private static void MapMoonlightSignalR(this WebApplication application)
|
||||
{
|
||||
WebApplication.MapHub<DiagnoseHub>("/api/admin/system/diagnose/ws");
|
||||
|
||||
return Task.CompletedTask;
|
||||
application.MapHub<DiagnoseHub>("/api/admin/system/diagnose/ws");
|
||||
}
|
||||
}
|
||||
@@ -1,69 +1,42 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moonlight.ApiServer.Configuration;
|
||||
using Moonlight.ApiServer.Plugins;
|
||||
|
||||
namespace Moonlight.ApiServer.Startup;
|
||||
|
||||
public partial class Startup
|
||||
public static partial class Startup
|
||||
{
|
||||
private string[] Args;
|
||||
|
||||
// Logger
|
||||
public ILogger<Startup> Logger { get; private set; }
|
||||
|
||||
// Configuration
|
||||
public AppConfiguration Configuration { get; private set; }
|
||||
|
||||
// WebApplication Stuff
|
||||
public WebApplication WebApplication { get; private set; }
|
||||
public WebApplicationBuilder WebApplicationBuilder { get; private set; }
|
||||
|
||||
public Task InitializeAsync(string[] args, IPluginStartup[]? plugins = null)
|
||||
public static void AddMoonlight(this WebApplicationBuilder builder, IPluginStartup[] startups)
|
||||
{
|
||||
Args = args;
|
||||
PluginStartups = plugins ?? [];
|
||||
PrintVersionAsync();
|
||||
CreateStorageAsync();
|
||||
|
||||
return Task.CompletedTask;
|
||||
builder.AddConfiguration();
|
||||
builder.AddLogging();
|
||||
|
||||
builder.ConfigureKestrel();
|
||||
builder.AddBase(startups);
|
||||
builder.AddDatabase();
|
||||
builder.AddAuth();
|
||||
builder.AddMoonlightCors();
|
||||
builder.AddMoonlightHangfire();
|
||||
builder.AddMoonlightSignalR();
|
||||
|
||||
builder.AddPlugins(startups);
|
||||
}
|
||||
|
||||
public async Task AddMoonlightAsync(WebApplicationBuilder builder)
|
||||
public static void UseMoonlight(this WebApplication application, IPluginStartup[] startups)
|
||||
{
|
||||
WebApplicationBuilder = builder;
|
||||
|
||||
await PrintVersionAsync();
|
||||
|
||||
await CreateStorageAsync();
|
||||
await SetupAppConfigurationAsync();
|
||||
await SetupLoggingAsync();
|
||||
await InitializePluginsAsync();
|
||||
|
||||
await ConfigureKestrelAsync();
|
||||
await RegisterAppConfigurationAsync();
|
||||
await RegisterLoggingAsync();
|
||||
await RegisterBaseAsync();
|
||||
await RegisterDatabaseAsync();
|
||||
await RegisterAuthAsync();
|
||||
await RegisterCorsAsync();
|
||||
await RegisterHangfireAsync();
|
||||
await RegisterSignalRAsync();
|
||||
await HookPluginBuildAsync();
|
||||
application.UseBase();
|
||||
application.UseMoonlightCors();
|
||||
application.UseAuth();
|
||||
application.UseMoonlightHangfire();
|
||||
application.UsePlugins(startups);
|
||||
}
|
||||
|
||||
public async Task AddMoonlightAsync(WebApplication application)
|
||||
public static void MapMoonlight(this WebApplication application, IPluginStartup[] startups)
|
||||
{
|
||||
WebApplication = application;
|
||||
|
||||
await PrepareDatabaseAsync();
|
||||
|
||||
await UseCorsAsync();
|
||||
await UseBaseAsync();
|
||||
await UseAuthAsync();
|
||||
await UseHangfireAsync();
|
||||
await HookPluginConfigureAsync();
|
||||
|
||||
await MapBaseAsync();
|
||||
await MapSignalRAsync();
|
||||
await HookPluginEndpointsAsync();
|
||||
application.MapBase();
|
||||
application.MapMoonlightSignalR();
|
||||
application.MapPlugins(startups);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user