Refactored startup. Removed unused usings. Improved nuget package building. Switched to yaml for configuration. Moved asset files. Set correct context type for oauth2 pages. Updated versions
This commit is contained in:
@@ -1,66 +0,0 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Moonlight.ApiServer.Configuration;
|
||||
using Moonlight.ApiServer.Plugins;
|
||||
|
||||
namespace Moonlight.ApiServer.Startup;
|
||||
|
||||
public partial class CleanStartup
|
||||
{
|
||||
// Logger
|
||||
private ILogger Logger;
|
||||
|
||||
// Configuration
|
||||
private AppConfiguration Configuration;
|
||||
|
||||
// WebApplication Stuff
|
||||
private WebApplication WebApplication;
|
||||
private WebApplicationBuilder WebApplicationBuilder;
|
||||
|
||||
public async Task AddMoonlight(
|
||||
WebApplicationBuilder builder,
|
||||
string[] args,
|
||||
IPluginStartup[]? plugins = null
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public async Task AddMoonlight(
|
||||
WebApplication application,
|
||||
string[] args,
|
||||
IPluginStartup[]? plugins = null
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
#region Misc
|
||||
|
||||
private Task PrintVersion()
|
||||
{
|
||||
// Fancy start console output... yes very fancy :>
|
||||
var rainbow = new Crayon.Rainbow(0.5);
|
||||
foreach (var c in "Moonlight")
|
||||
{
|
||||
Console.Write(
|
||||
rainbow
|
||||
.Next()
|
||||
.Bold()
|
||||
.Text(c.ToString())
|
||||
);
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task CreateStorage()
|
||||
{
|
||||
Directory.CreateDirectory("storage");
|
||||
Directory.CreateDirectory(Path.Combine("storage", "logs"));
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -1,6 +1,61 @@
|
||||
using System.Text;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using MoonCore.Extended.JwtInvalidation;
|
||||
using MoonCore.Permissions;
|
||||
using Moonlight.ApiServer.Implementations;
|
||||
using Moonlight.ApiServer.Interfaces;
|
||||
|
||||
namespace Moonlight.ApiServer.Startup;
|
||||
|
||||
public partial class CleanStartup
|
||||
public partial class Startup
|
||||
{
|
||||
|
||||
private Task RegisterAuth()
|
||||
{
|
||||
WebApplicationBuilder.Services
|
||||
.AddAuthentication("coreAuthentication")
|
||||
.AddJwtBearer("coreAuthentication", options =>
|
||||
{
|
||||
options.TokenValidationParameters = new()
|
||||
{
|
||||
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(
|
||||
Configuration.Authentication.Secret
|
||||
)),
|
||||
ValidateIssuerSigningKey = true,
|
||||
ValidateLifetime = true,
|
||||
ClockSkew = TimeSpan.Zero,
|
||||
ValidateAudience = true,
|
||||
ValidAudience = Configuration.PublicUrl,
|
||||
ValidateIssuer = true,
|
||||
ValidIssuer = Configuration.PublicUrl
|
||||
};
|
||||
});
|
||||
|
||||
WebApplicationBuilder.Services.AddJwtBearerInvalidation("coreAuthentication");
|
||||
WebApplicationBuilder.Services.AddScoped<IJwtInvalidateHandler, UserAuthInvalidation>();
|
||||
|
||||
WebApplicationBuilder.Services.AddAuthorization();
|
||||
|
||||
WebApplicationBuilder.Services.AddAuthorizationPermissions(options =>
|
||||
{
|
||||
options.ClaimName = "permissions";
|
||||
options.Prefix = "permissions:";
|
||||
});
|
||||
|
||||
// Add local oauth2 provider if enabled
|
||||
if (Configuration.Authentication.EnableLocalOAuth2)
|
||||
WebApplicationBuilder.Services.AddScoped<IOAuth2Provider, LocalOAuth2Provider>();
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task UseAuth()
|
||||
{
|
||||
WebApplication.UseAuthentication();
|
||||
|
||||
WebApplication.UseAuthorization();
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,17 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using MoonCore.Extended.Extensions;
|
||||
using MoonCore.Extensions;
|
||||
using MoonCore.Helpers;
|
||||
using Moonlight.ApiServer.Plugins;
|
||||
|
||||
namespace Moonlight.ApiServer.Startup;
|
||||
|
||||
public partial class CleanStartup
|
||||
public partial class Startup
|
||||
{
|
||||
private Task RegisterBase(IPluginStartup[] pluginStartups)
|
||||
private Task RegisterBase()
|
||||
{
|
||||
WebApplicationBuilder.Services.AutoAddServices<CleanStartup>();
|
||||
WebApplicationBuilder.Services.AutoAddServices<Startup>();
|
||||
WebApplicationBuilder.Services.AddHttpClient();
|
||||
|
||||
WebApplicationBuilder.Services.AddApiExceptionHandler();
|
||||
@@ -25,7 +23,7 @@ public partial class CleanStartup
|
||||
var mvcBuilder = WebApplicationBuilder.Services.AddControllers();
|
||||
|
||||
// Add plugin assemblies as application parts
|
||||
foreach (var pluginStartup in pluginStartups.Select(x => x.GetType().Assembly).Distinct())
|
||||
foreach (var pluginStartup in PluginStartups.Select(x => x.GetType().Assembly).Distinct())
|
||||
mvcBuilder.AddApplicationPart(pluginStartup.GetType().Assembly);
|
||||
|
||||
return Task.CompletedTask;
|
||||
@@ -36,15 +34,6 @@ public partial class CleanStartup
|
||||
WebApplication.UseRouting();
|
||||
WebApplication.UseExceptionHandler();
|
||||
|
||||
if (Configuration.Client.Enable)
|
||||
{
|
||||
if (WebApplication.Environment.IsDevelopment())
|
||||
WebApplication.UseWebAssemblyDebugging();
|
||||
|
||||
WebApplication.UseBlazorFrameworkFiles();
|
||||
WebApplication.UseStaticFiles();
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
@@ -52,7 +41,7 @@ public partial class CleanStartup
|
||||
{
|
||||
WebApplication.MapControllers();
|
||||
|
||||
if (Configuration.Client.Enable)
|
||||
if (Configuration.Frontend.EnableHosting)
|
||||
WebApplication.MapFallbackToController("Index", "Frontend");
|
||||
|
||||
return Task.CompletedTask;
|
||||
|
||||
@@ -1,6 +1,35 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using MoonCore.EnvConfiguration;
|
||||
using MoonCore.Yaml;
|
||||
using Moonlight.ApiServer.Configuration;
|
||||
|
||||
namespace Moonlight.ApiServer.Startup;
|
||||
|
||||
public partial class CleanStartup
|
||||
public partial class Startup
|
||||
{
|
||||
|
||||
private async Task SetupAppConfiguration()
|
||||
{
|
||||
var configPath = Path.Combine("storage", "config.yml");
|
||||
|
||||
await YamlDefaultGenerator.Generate<AppConfiguration>(configPath);
|
||||
|
||||
// Configure configuration (wow)
|
||||
var configurationBuilder = new ConfigurationBuilder();
|
||||
|
||||
configurationBuilder.AddYamlFile(configPath);
|
||||
configurationBuilder.AddEnvironmentVariables(prefix: "MOONLIGHT_", separator: "_");
|
||||
|
||||
var configurationRoot = configurationBuilder.Build();
|
||||
|
||||
// Retrieve configuration
|
||||
Configuration = AppConfiguration.CreateEmpty();
|
||||
configurationRoot.Bind(Configuration);
|
||||
}
|
||||
|
||||
private Task RegisterAppConfiguration()
|
||||
{
|
||||
WebApplicationBuilder.Services.AddSingleton(Configuration);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,25 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using MoonCore.Extended.Abstractions;
|
||||
using MoonCore.Extended.Extensions;
|
||||
|
||||
namespace Moonlight.ApiServer.Startup;
|
||||
|
||||
public partial class CleanStartup
|
||||
public partial class Startup
|
||||
{
|
||||
|
||||
private Task RegisterDatabase()
|
||||
{
|
||||
WebApplicationBuilder.Services.AddDatabaseMappings();
|
||||
WebApplicationBuilder.Services.AddServiceCollectionAccessor();
|
||||
|
||||
WebApplicationBuilder.Services.AddScoped(typeof(DatabaseRepository<>));
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task PrepareDatabase()
|
||||
{
|
||||
await WebApplication.Services.EnsureDatabaseMigrated();
|
||||
|
||||
WebApplication.Services.GenerateDatabaseMappings();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,48 @@
|
||||
using Hangfire;
|
||||
using Hangfire.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moonlight.ApiServer.Database;
|
||||
|
||||
namespace Moonlight.ApiServer.Startup;
|
||||
|
||||
public partial class CleanStartup
|
||||
public partial class Startup
|
||||
{
|
||||
|
||||
private Task RegisterHangfire()
|
||||
{
|
||||
WebApplicationBuilder.Services.AddHangfire((provider, configuration) =>
|
||||
{
|
||||
configuration.SetDataCompatibilityLevel(CompatibilityLevel.Version_180);
|
||||
configuration.UseSimpleAssemblyNameTypeSerializer();
|
||||
configuration.UseRecommendedSerializerSettings();
|
||||
configuration.UseEFCoreStorage(() =>
|
||||
{
|
||||
var scope = provider.CreateScope();
|
||||
return scope.ServiceProvider.GetRequiredService<CoreDataContext>();
|
||||
}, new EFCoreStorageOptions());
|
||||
});
|
||||
|
||||
WebApplicationBuilder.Services.AddHangfireServer();
|
||||
|
||||
WebApplicationBuilder.Logging.AddFilter(
|
||||
"Hangfire.Server.BackgroundServerProcess",
|
||||
LogLevel.Warning
|
||||
);
|
||||
|
||||
WebApplicationBuilder.Logging.AddFilter(
|
||||
"Hangfire.BackgroundJobServer",
|
||||
LogLevel.Warning
|
||||
);
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task UseHangfire()
|
||||
{
|
||||
if (WebApplication.Environment.IsDevelopment())
|
||||
WebApplication.UseHangfireDashboard();
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,63 @@
|
||||
using System.Text.Json;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using MoonCore.Logging;
|
||||
|
||||
namespace Moonlight.ApiServer.Startup;
|
||||
|
||||
public partial class CleanStartup
|
||||
public partial class Startup
|
||||
{
|
||||
|
||||
private Task SetupLogging()
|
||||
{
|
||||
var loggerFactory = new LoggerFactory();
|
||||
loggerFactory.AddAnsiConsole();
|
||||
|
||||
Logger = loggerFactory.CreateLogger<Startup>();
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private async Task RegisterLogging()
|
||||
{
|
||||
// Configure application logging
|
||||
WebApplicationBuilder.Logging.ClearProviders();
|
||||
WebApplicationBuilder.Logging.AddAnsiConsole();
|
||||
WebApplicationBuilder.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
|
||||
if (!File.Exists(logConfigPath))
|
||||
{
|
||||
var defaultLogLevels = new Dictionary<string, string>
|
||||
{
|
||||
{ "Default", "Information" },
|
||||
{ "Microsoft.AspNetCore", "Warning" },
|
||||
{ "System.Net.Http.HttpClient", "Warning" }
|
||||
};
|
||||
|
||||
var logLevelsJson = JsonSerializer.Serialize(defaultLogLevels);
|
||||
await File.WriteAllTextAsync(logConfigPath, logLevelsJson);
|
||||
}
|
||||
|
||||
// Add logging configuration
|
||||
var logLevels = JsonSerializer.Deserialize<Dictionary<string, string>>(
|
||||
await File.ReadAllTextAsync(logConfigPath)
|
||||
)!;
|
||||
|
||||
foreach (var level in logLevels)
|
||||
WebApplicationBuilder.Logging.AddFilter(level.Key, Enum.Parse<LogLevel>(level.Value));
|
||||
|
||||
// Mute exception handler middleware
|
||||
// https://github.com/dotnet/aspnetcore/issues/19740
|
||||
WebApplicationBuilder.Logging.AddFilter(
|
||||
"Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware",
|
||||
LogLevel.Critical
|
||||
);
|
||||
|
||||
WebApplicationBuilder.Logging.AddFilter(
|
||||
"Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware",
|
||||
LogLevel.Critical
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,73 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Cors.Infrastructure;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Moonlight.ApiServer.Startup;
|
||||
|
||||
public partial class CleanStartup
|
||||
public partial class Startup
|
||||
{
|
||||
private Task PrintVersion()
|
||||
{
|
||||
// Fancy start console output... yes very fancy :>
|
||||
var rainbow = new Crayon.Rainbow(0.5);
|
||||
foreach (var c in "Moonlight")
|
||||
{
|
||||
Console.Write(
|
||||
rainbow
|
||||
.Next()
|
||||
.Bold()
|
||||
.Text(c.ToString())
|
||||
);
|
||||
}
|
||||
|
||||
Console.WriteLine();
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task CreateStorage()
|
||||
{
|
||||
Directory.CreateDirectory("storage");
|
||||
Directory.CreateDirectory(Path.Combine("storage", "logs"));
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task RegisterCors()
|
||||
{
|
||||
var allowedOrigins = Configuration.Kestrel.AllowedOrigins;
|
||||
|
||||
WebApplicationBuilder.Services.AddCors(options =>
|
||||
{
|
||||
var cors = new CorsPolicyBuilder();
|
||||
|
||||
if (allowedOrigins.Contains("*"))
|
||||
{
|
||||
cors.SetIsOriginAllowed(_ => true)
|
||||
.AllowAnyMethod()
|
||||
.AllowAnyHeader()
|
||||
.AllowCredentials();
|
||||
}
|
||||
else
|
||||
{
|
||||
cors.WithOrigins(allowedOrigins)
|
||||
.AllowAnyHeader()
|
||||
.AllowAnyMethod()
|
||||
.AllowCredentials();
|
||||
}
|
||||
|
||||
options.AddDefaultPolicy(
|
||||
cors.Build()
|
||||
);
|
||||
});
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private Task UseCors()
|
||||
{
|
||||
WebApplication.UseCors();
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,12 @@ using Moonlight.ApiServer.Plugins;
|
||||
|
||||
namespace Moonlight.ApiServer.Startup;
|
||||
|
||||
public partial class CleanStartup
|
||||
public partial class Startup
|
||||
{
|
||||
private IServiceProvider PluginLoadServiceProvider;
|
||||
private IPluginStartup[] PluginStartups;
|
||||
|
||||
private Task InitializePlugins(IPluginStartup[] pluginStartups)
|
||||
private Task InitializePlugins()
|
||||
{
|
||||
// Create service provider for starting up
|
||||
var serviceCollection = new ServiceCollection();
|
||||
@@ -24,8 +24,6 @@ public partial class CleanStartup
|
||||
});
|
||||
|
||||
PluginLoadServiceProvider = serviceCollection.BuildServiceProvider();
|
||||
|
||||
PluginStartups = pluginStartups;
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
67
Moonlight.ApiServer/Startup/Startup.cs
Normal file
67
Moonlight.ApiServer/Startup/Startup.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moonlight.ApiServer.Configuration;
|
||||
using Moonlight.ApiServer.Plugins;
|
||||
|
||||
namespace Moonlight.ApiServer.Startup;
|
||||
|
||||
public 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 Initialize(string[] args, IPluginStartup[]? plugins = null)
|
||||
{
|
||||
Args = args;
|
||||
PluginStartups = plugins ?? [];
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public async Task AddMoonlight(WebApplicationBuilder builder)
|
||||
{
|
||||
WebApplicationBuilder = builder;
|
||||
|
||||
await PrintVersion();
|
||||
|
||||
await CreateStorage();
|
||||
await SetupAppConfiguration();
|
||||
await SetupLogging();
|
||||
await InitializePlugins();
|
||||
|
||||
await ConfigureKestrel();
|
||||
await RegisterAppConfiguration();
|
||||
await RegisterLogging();
|
||||
await RegisterBase();
|
||||
await RegisterDatabase();
|
||||
await RegisterAuth();
|
||||
await RegisterCors();
|
||||
await RegisterHangfire();
|
||||
await HookPluginBuild();
|
||||
}
|
||||
|
||||
public async Task AddMoonlight(WebApplication application)
|
||||
{
|
||||
WebApplication = application;
|
||||
|
||||
await PrepareDatabase();
|
||||
|
||||
await UseCors();
|
||||
await UseBase();
|
||||
await UseAuth();
|
||||
await UseHangfire();
|
||||
await HookPluginConfigure();
|
||||
|
||||
await MapBase();
|
||||
await HookPluginEndpoints();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user