mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Plugin: Handling custom configurations
This commit is contained in:
parent
d1b3769f4f
commit
16eca6da8e
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Autofac;
|
||||
using IdentityServer4.Extensions;
|
||||
using IdentityServer4.Models;
|
||||
using IdentityServer4.Services;
|
||||
@ -40,7 +41,9 @@ namespace Kyoo.Authentication
|
||||
/// <inheritdoc />
|
||||
public Dictionary<string, Type> Configuration => new()
|
||||
{
|
||||
{ AuthenticationOption.Path, typeof(AuthenticationOption) }
|
||||
{ AuthenticationOption.Path, typeof(AuthenticationOption) },
|
||||
{ PermissionOption.Path, typeof(PermissionOption) },
|
||||
{ CertificateOption.Path, typeof(CertificateOption) }
|
||||
};
|
||||
|
||||
|
||||
@ -75,6 +78,18 @@ namespace Kyoo.Authentication
|
||||
_environment = environment;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(ContainerBuilder builder)
|
||||
{
|
||||
builder.RegisterType<PermissionValidatorFactory>().As<IPermissionValidator>().SingleInstance();
|
||||
|
||||
DefaultCorsPolicyService cors = new(_loggerFactory.CreateLogger<DefaultCorsPolicyService>())
|
||||
{
|
||||
AllowedOrigins = { new Uri(_configuration.GetPublicUrl()).GetLeftPart(UriPartial.Authority) }
|
||||
};
|
||||
builder.RegisterInstance(cors).As<ICorsPolicyService>().SingleInstance();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(IServiceCollection services)
|
||||
{
|
||||
@ -115,13 +130,6 @@ namespace Kyoo.Authentication
|
||||
options.Audience = "kyoo";
|
||||
options.RequireHttpsMetadata = false;
|
||||
});
|
||||
services.AddSingleton<IPermissionValidator, PermissionValidatorFactory>();
|
||||
|
||||
DefaultCorsPolicyService cors = new(_loggerFactory.CreateLogger<DefaultCorsPolicyService>())
|
||||
{
|
||||
AllowedOrigins = {new Uri(publicUrl).GetLeftPart(UriPartial.Authority)}
|
||||
};
|
||||
services.AddSingleton<ICorsPolicyService>(cors);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
@ -34,7 +34,7 @@ namespace Kyoo.Authentication
|
||||
X509Certificate2 certificate = GetCertificate(options);
|
||||
builder.AddSigningCredential(certificate);
|
||||
|
||||
if (certificate.NotAfter.AddDays(7) <= DateTime.UtcNow)
|
||||
if (certificate.NotAfter.AddDays(-7) <= DateTime.UtcNow)
|
||||
{
|
||||
Console.WriteLine("Signin certificate will expire soon, renewing it.");
|
||||
if (File.Exists(options.OldFile))
|
||||
@ -67,7 +67,7 @@ namespace Kyoo.Authentication
|
||||
/// <returns>The loaded certificate</returns>
|
||||
private static X509Certificate2 GetExistingCredential(string file, string password)
|
||||
{
|
||||
return new(file, password,
|
||||
return new X509Certificate2(file, password,
|
||||
X509KeyStorageFlags.MachineKeySet |
|
||||
X509KeyStorageFlags.PersistKeySet |
|
||||
X509KeyStorageFlags.Exportable
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Models.Exceptions;
|
||||
|
||||
@ -26,6 +27,15 @@ namespace Kyoo.Controllers
|
||||
/// </summary>
|
||||
/// <param name="path">The root path of the editable configuration. It should not be a nested type.</param>
|
||||
void AddUntyped(string path);
|
||||
|
||||
/// <summary>
|
||||
/// An helper method of <see cref="AddTyped{T}"/> and <see cref="AddUntyped"/>.
|
||||
/// This register a typed value if <paramref name="type"/> is not <c>null</c> and registers an untyped type
|
||||
/// if <paramref name="type"/> is <c>null</c>.
|
||||
/// </summary>
|
||||
/// <param name="path">The root path of the editable configuration. It should not be a nested type.</param>
|
||||
/// <param name="type">The type of the configuration or null.</param>
|
||||
void Register(string path, [CanBeNull] Type type);
|
||||
|
||||
/// <summary>
|
||||
/// Get the value of a setting using it's path.
|
||||
|
@ -44,8 +44,12 @@ namespace Kyoo.Controllers
|
||||
|
||||
/// <summary>
|
||||
/// A list of types that will be available via the IOptions interfaces and will be listed inside
|
||||
/// an IConfiguration. If a field should be loosely typed, <see cref="Dictionary{TKey,TValue}"/> or <c>null</c>
|
||||
/// an IConfiguration.
|
||||
///
|
||||
/// If a field should be loosely typed, <see cref="Dictionary{TKey,TValue}"/> or <c>null</c>
|
||||
/// can be specified.
|
||||
/// WARNING: null means an unmanaged type that won't be editable. This can be used
|
||||
/// for external libraries or variable arguments.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// All use of the configuration must be specified here and not registered elsewhere, if a type is registered
|
||||
|
@ -50,6 +50,21 @@ namespace Kyoo.Controllers
|
||||
ConfigurationReference config = ConfigurationReference.CreateUntyped(path);
|
||||
_references.Add(config.Path, config.Type);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Register(string path, Type type)
|
||||
{
|
||||
if (type == null)
|
||||
{
|
||||
ConfigurationReference config = ConfigurationReference.CreateUntyped(path);
|
||||
_references.Add(config.Path, config.Type);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (ConfigurationReference confRef in ConfigurationReference.CreateReference(path, type))
|
||||
_references.Add(confRef.Path, confRef.Type);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the type of the resource at the given path
|
||||
|
@ -32,14 +32,23 @@ namespace Kyoo
|
||||
/// A plugin manager used to load plugins and allow them to configure services / asp net.
|
||||
/// </summary>
|
||||
private readonly IPluginManager _plugins;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The configuration used to register <see cref="IOptions{TOptions}"/> and so on for plugin's specified types.
|
||||
/// </summary>
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
/// <summary>
|
||||
/// Created from the DI container, those services are needed to load information and instantiate plugins.s
|
||||
/// </summary>
|
||||
/// <param name="plugins">The plugin manager to use to load new plugins and configure the host.</param>
|
||||
public PluginsStartup(IPluginManager plugins)
|
||||
/// <param name="configuration">
|
||||
/// The configuration used to register <see cref="IOptions{TOptions}"/> and so on for plugin's specified types.
|
||||
/// </param>
|
||||
public PluginsStartup(IPluginManager plugins, IConfiguration configuration)
|
||||
{
|
||||
_plugins = plugins;
|
||||
_configuration = configuration;
|
||||
_plugins.LoadPlugins(
|
||||
typeof(CoreModule),
|
||||
typeof(AuthenticationModule),
|
||||
@ -58,9 +67,9 @@ namespace Kyoo
|
||||
{
|
||||
services.AddMvc().AddControllersAsServices();
|
||||
|
||||
services.AddSpaStaticFiles(configuration =>
|
||||
services.AddSpaStaticFiles(x =>
|
||||
{
|
||||
configuration.RootPath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "wwwroot");
|
||||
x.RootPath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "wwwroot");
|
||||
});
|
||||
services.AddResponseCompression(x =>
|
||||
{
|
||||
@ -70,6 +79,18 @@ namespace Kyoo
|
||||
services.AddHttpClient();
|
||||
|
||||
_plugins.ConfigureServices(services);
|
||||
IEnumerable<KeyValuePair<string, Type>> configTypes = _plugins.GetAllPlugins()
|
||||
.SelectMany(x => x.Configuration)
|
||||
.Where(x => x.Value != null);
|
||||
foreach ((string path, Type type) in configTypes)
|
||||
{
|
||||
Utility.RunGenericMethod<object>(
|
||||
typeof(OptionsConfigurationServiceCollectionExtensions),
|
||||
nameof(OptionsConfigurationServiceCollectionExtensions.Configure),
|
||||
type,
|
||||
services, _configuration.GetSection(path)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -89,7 +110,7 @@ namespace Kyoo
|
||||
/// </summary>
|
||||
/// <param name="app">The asp net host to configure</param>
|
||||
/// <param name="env">The host environment (is the app in development mode?)</param>
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider provider)
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IConfigurationManager config, ILifetimeScope container)
|
||||
{
|
||||
if (!env.IsDevelopment())
|
||||
app.UseSpaStaticFiles();
|
||||
@ -111,9 +132,23 @@ namespace Kyoo
|
||||
IEnumerable<IStartupAction> steps = _plugins.GetAllPlugins()
|
||||
.SelectMany(x => x.ConfigureSteps)
|
||||
.OrderByDescending(x => x.Priority);
|
||||
|
||||
using ILifetimeScope scope = container.BeginLifetimeScope(x =>
|
||||
x.RegisterInstance(app).SingleInstance().ExternallyOwned());
|
||||
IServiceProvider provider = scope.Resolve<IServiceProvider>();
|
||||
foreach (IStartupAction step in steps)
|
||||
step.Run(provider);
|
||||
|
||||
IEnumerable<KeyValuePair<string, Type>> pluginConfig = _plugins.GetAllPlugins()
|
||||
.SelectMany(x => x.Configuration)
|
||||
.GroupBy(x => x.Key.Split(':').First())
|
||||
.Select(x => x
|
||||
.OrderBy(y => y.Key.Length)
|
||||
.First()
|
||||
);
|
||||
foreach ((string path, Type type) in pluginConfig)
|
||||
config.Register(path, type);
|
||||
|
||||
app.UseSpa(spa =>
|
||||
{
|
||||
spa.Options.SourcePath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "Kyoo.WebApp");
|
||||
@ -148,7 +183,7 @@ namespace Kyoo
|
||||
Options.Create(host.Configuration.GetSection(BasicOptions.Path).Get<BasicOptions>()),
|
||||
logger.CreateLogger<PluginManager>()
|
||||
);
|
||||
return new PluginsStartup(plugins);
|
||||
return new PluginsStartup(plugins, host.Configuration);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
Loading…
x
Reference in New Issue
Block a user