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.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using Autofac;
|
||||||
using IdentityServer4.Extensions;
|
using IdentityServer4.Extensions;
|
||||||
using IdentityServer4.Models;
|
using IdentityServer4.Models;
|
||||||
using IdentityServer4.Services;
|
using IdentityServer4.Services;
|
||||||
@ -40,7 +41,9 @@ namespace Kyoo.Authentication
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public Dictionary<string, Type> Configuration => new()
|
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;
|
_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 />
|
/// <inheritdoc />
|
||||||
public void Configure(IServiceCollection services)
|
public void Configure(IServiceCollection services)
|
||||||
{
|
{
|
||||||
@ -115,13 +130,6 @@ namespace Kyoo.Authentication
|
|||||||
options.Audience = "kyoo";
|
options.Audience = "kyoo";
|
||||||
options.RequireHttpsMetadata = false;
|
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 />
|
/// <inheritdoc />
|
||||||
|
@ -34,7 +34,7 @@ namespace Kyoo.Authentication
|
|||||||
X509Certificate2 certificate = GetCertificate(options);
|
X509Certificate2 certificate = GetCertificate(options);
|
||||||
builder.AddSigningCredential(certificate);
|
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.");
|
Console.WriteLine("Signin certificate will expire soon, renewing it.");
|
||||||
if (File.Exists(options.OldFile))
|
if (File.Exists(options.OldFile))
|
||||||
@ -67,7 +67,7 @@ namespace Kyoo.Authentication
|
|||||||
/// <returns>The loaded certificate</returns>
|
/// <returns>The loaded certificate</returns>
|
||||||
private static X509Certificate2 GetExistingCredential(string file, string password)
|
private static X509Certificate2 GetExistingCredential(string file, string password)
|
||||||
{
|
{
|
||||||
return new(file, password,
|
return new X509Certificate2(file, password,
|
||||||
X509KeyStorageFlags.MachineKeySet |
|
X509KeyStorageFlags.MachineKeySet |
|
||||||
X509KeyStorageFlags.PersistKeySet |
|
X509KeyStorageFlags.PersistKeySet |
|
||||||
X509KeyStorageFlags.Exportable
|
X509KeyStorageFlags.Exportable
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using Kyoo.Models;
|
using Kyoo.Models;
|
||||||
using Kyoo.Models.Exceptions;
|
using Kyoo.Models.Exceptions;
|
||||||
|
|
||||||
@ -26,6 +27,15 @@ namespace Kyoo.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">The root path of the editable configuration. It should not be a nested type.</param>
|
/// <param name="path">The root path of the editable configuration. It should not be a nested type.</param>
|
||||||
void AddUntyped(string path);
|
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>
|
/// <summary>
|
||||||
/// Get the value of a setting using it's path.
|
/// Get the value of a setting using it's path.
|
||||||
|
@ -44,8 +44,12 @@ namespace Kyoo.Controllers
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A list of types that will be available via the IOptions interfaces and will be listed inside
|
/// 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.
|
/// 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>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// All use of the configuration must be specified here and not registered elsewhere, if a type is registered
|
/// 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);
|
ConfigurationReference config = ConfigurationReference.CreateUntyped(path);
|
||||||
_references.Add(config.Path, config.Type);
|
_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>
|
/// <summary>
|
||||||
/// Get the type of the resource at the given path
|
/// 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.
|
/// A plugin manager used to load plugins and allow them to configure services / asp net.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly IPluginManager _plugins;
|
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>
|
/// <summary>
|
||||||
/// Created from the DI container, those services are needed to load information and instantiate plugins.s
|
/// Created from the DI container, those services are needed to load information and instantiate plugins.s
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="plugins">The plugin manager to use to load new plugins and configure the host.</param>
|
/// <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;
|
_plugins = plugins;
|
||||||
|
_configuration = configuration;
|
||||||
_plugins.LoadPlugins(
|
_plugins.LoadPlugins(
|
||||||
typeof(CoreModule),
|
typeof(CoreModule),
|
||||||
typeof(AuthenticationModule),
|
typeof(AuthenticationModule),
|
||||||
@ -58,9 +67,9 @@ namespace Kyoo
|
|||||||
{
|
{
|
||||||
services.AddMvc().AddControllersAsServices();
|
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 =>
|
services.AddResponseCompression(x =>
|
||||||
{
|
{
|
||||||
@ -70,6 +79,18 @@ namespace Kyoo
|
|||||||
services.AddHttpClient();
|
services.AddHttpClient();
|
||||||
|
|
||||||
_plugins.ConfigureServices(services);
|
_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>
|
/// <summary>
|
||||||
@ -89,7 +110,7 @@ namespace Kyoo
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="app">The asp net host to configure</param>
|
/// <param name="app">The asp net host to configure</param>
|
||||||
/// <param name="env">The host environment (is the app in development mode?)</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())
|
if (!env.IsDevelopment())
|
||||||
app.UseSpaStaticFiles();
|
app.UseSpaStaticFiles();
|
||||||
@ -111,9 +132,23 @@ namespace Kyoo
|
|||||||
IEnumerable<IStartupAction> steps = _plugins.GetAllPlugins()
|
IEnumerable<IStartupAction> steps = _plugins.GetAllPlugins()
|
||||||
.SelectMany(x => x.ConfigureSteps)
|
.SelectMany(x => x.ConfigureSteps)
|
||||||
.OrderByDescending(x => x.Priority);
|
.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)
|
foreach (IStartupAction step in steps)
|
||||||
step.Run(provider);
|
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 =>
|
app.UseSpa(spa =>
|
||||||
{
|
{
|
||||||
spa.Options.SourcePath = Path.Join(AppDomain.CurrentDomain.BaseDirectory, "Kyoo.WebApp");
|
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>()),
|
Options.Create(host.Configuration.GetSection(BasicOptions.Path).Get<BasicOptions>()),
|
||||||
logger.CreateLogger<PluginManager>()
|
logger.CreateLogger<PluginManager>()
|
||||||
);
|
);
|
||||||
return new PluginsStartup(plugins);
|
return new PluginsStartup(plugins, host.Configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user