mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Plugins: Reworking ConfigureAspnet to use steps with prorities. Adding a configuration dictionary.
This commit is contained in:
parent
b67e0a629e
commit
d1b3769f4f
@ -9,7 +9,6 @@ using IdentityServer4.Services;
|
||||
using Kyoo.Authentication.Models;
|
||||
using Kyoo.Authentication.Views;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Kyoo.Models.Permissions;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
@ -38,6 +37,12 @@ namespace Kyoo.Authentication
|
||||
/// <inheritdoc />
|
||||
public string Description => "Enable OpenID authentication for Kyoo.";
|
||||
|
||||
/// <inheritdoc />
|
||||
public Dictionary<string, Type> Configuration => new()
|
||||
{
|
||||
{ AuthenticationOption.Path, typeof(AuthenticationOption) }
|
||||
};
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The configuration to use.
|
||||
@ -53,11 +58,6 @@ namespace Kyoo.Authentication
|
||||
/// The environment information to check if the app runs in debug mode
|
||||
/// </summary>
|
||||
private readonly IWebHostEnvironment _environment;
|
||||
|
||||
/// <summary>
|
||||
/// The configuration manager used to register typed/untyped implementations.
|
||||
/// </summary>
|
||||
[Injected] public IConfigurationManager ConfigurationManager { private get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
@ -88,10 +88,6 @@ namespace Kyoo.Authentication
|
||||
// TODO handle direct-videos with bearers (probably add a cookie and a app.Use to translate that for videos)
|
||||
|
||||
// TODO Check if tokens should be stored.
|
||||
|
||||
services.Configure<PermissionOption>(_configuration.GetSection(PermissionOption.Path));
|
||||
services.Configure<CertificateOption>(_configuration.GetSection(CertificateOption.Path));
|
||||
services.Configure<AuthenticationOption>(_configuration.GetSection(AuthenticationOption.Path));
|
||||
|
||||
List<Client> clients = new();
|
||||
_configuration.GetSection("authentication:clients").Bind(clients);
|
||||
@ -129,37 +125,43 @@ namespace Kyoo.Authentication
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ConfigureAspNet(IApplicationBuilder app)
|
||||
public IEnumerable<IStartupAction> ConfigureSteps => new IStartupAction[]
|
||||
{
|
||||
ConfigurationManager.AddTyped<AuthenticationOption>(AuthenticationOption.Path);
|
||||
|
||||
app.UseCookiePolicy(new CookiePolicyOptions
|
||||
SA.New<IApplicationBuilder>(app =>
|
||||
{
|
||||
MinimumSameSitePolicy = SameSiteMode.Strict
|
||||
});
|
||||
app.UseAuthentication();
|
||||
app.Use((ctx, next) =>
|
||||
PhysicalFileProvider provider = new(Path.Combine(
|
||||
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!,
|
||||
"login"));
|
||||
app.UseDefaultFiles(new DefaultFilesOptions
|
||||
{
|
||||
RequestPath = new PathString("/login"),
|
||||
FileProvider = provider,
|
||||
RedirectToAppendTrailingSlash = true
|
||||
});
|
||||
app.UseStaticFiles(new StaticFileOptions
|
||||
{
|
||||
RequestPath = new PathString("/login"),
|
||||
FileProvider = provider
|
||||
});
|
||||
}, SA.StaticFiles),
|
||||
SA.New<IApplicationBuilder>(app =>
|
||||
{
|
||||
ctx.SetIdentityServerOrigin(_configuration.GetPublicUrl());
|
||||
return next();
|
||||
});
|
||||
app.UseIdentityServer();
|
||||
app.UseAuthorization();
|
||||
|
||||
PhysicalFileProvider provider = new(Path.Combine(
|
||||
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!,
|
||||
"login"));
|
||||
app.UseDefaultFiles(new DefaultFilesOptions
|
||||
app.UseCookiePolicy(new CookiePolicyOptions
|
||||
{
|
||||
MinimumSameSitePolicy = SameSiteMode.Strict
|
||||
});
|
||||
app.UseAuthentication();
|
||||
}, SA.Authentication),
|
||||
SA.New<IApplicationBuilder>(app =>
|
||||
{
|
||||
RequestPath = new PathString("/login"),
|
||||
FileProvider = provider,
|
||||
RedirectToAppendTrailingSlash = true
|
||||
});
|
||||
app.UseStaticFiles(new StaticFileOptions
|
||||
{
|
||||
RequestPath = new PathString("/login"),
|
||||
FileProvider = provider
|
||||
});
|
||||
}
|
||||
app.Use((ctx, next) =>
|
||||
{
|
||||
ctx.SetIdentityServerOrigin(_configuration.GetPublicUrl());
|
||||
return next();
|
||||
});
|
||||
app.UseIdentityServer();
|
||||
}, SA.Endpoint),
|
||||
SA.New<IApplicationBuilder>(app => app.UseAuthorization(), SA.Authorization)
|
||||
};
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Autofac;
|
||||
using JetBrains.Annotations;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Kyoo.Controllers
|
||||
@ -41,8 +41,26 @@ namespace Kyoo.Controllers
|
||||
/// By default, a plugin is always enabled. This method can be overriden to change this behavior.
|
||||
/// </remarks>
|
||||
virtual bool Enabled => true;
|
||||
|
||||
/// <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>
|
||||
/// can be specified.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// All use of the configuration must be specified here and not registered elsewhere, if a type is registered
|
||||
/// elsewhere the configuration won't be editable via the <see cref="IConfigurationManager"/> and all values
|
||||
/// will be discarded on edit.
|
||||
/// </remarks>
|
||||
Dictionary<string, Type> Configuration { get; }
|
||||
|
||||
/// <summary>
|
||||
/// An optional configuration step to allow a plugin to change asp net configurations.
|
||||
/// </summary>
|
||||
/// <seealso cref="SA"/>
|
||||
virtual IEnumerable<IStartupAction> ConfigureSteps => ArraySegment<IStartupAction>.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// A configure method that will be run on plugin's startup.
|
||||
/// </summary>
|
||||
/// <param name="builder">The autofac service container to register services.</param>
|
||||
@ -61,20 +79,6 @@ namespace Kyoo.Controllers
|
||||
{
|
||||
// Skipped
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// An optional configuration step to allow a plugin to change asp net configurations.
|
||||
/// WARNING: This is only called on Kyoo's startup so you must restart the app to apply this changes.
|
||||
/// </summary>
|
||||
/// <param name="app">
|
||||
/// The Asp.Net application builder. On most case it is not needed but you can use it to
|
||||
/// add asp net functionalities.
|
||||
/// </param>
|
||||
void ConfigureAspNet(IApplicationBuilder app)
|
||||
{
|
||||
// Skipped
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An optional function to execute and initialize your plugin.
|
||||
|
@ -2,7 +2,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using Autofac;
|
||||
using Kyoo.Models.Exceptions;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Kyoo.Controllers
|
||||
@ -63,11 +62,5 @@ namespace Kyoo.Controllers
|
||||
/// </summary>
|
||||
/// <param name="services">The service collection to populate</param>
|
||||
public void ConfigureServices(IServiceCollection services);
|
||||
|
||||
/// <summary>
|
||||
/// Configure an asp net application applying plugins policies.
|
||||
/// </summary>
|
||||
/// <param name="app">The asp net application to configure</param>
|
||||
public void ConfigureAspnet(IApplicationBuilder app);
|
||||
}
|
||||
}
|
@ -5,7 +5,6 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Kyoo.Models.Exceptions;
|
||||
|
||||
namespace Kyoo.Controllers
|
||||
@ -182,11 +181,6 @@ namespace Kyoo.Controllers
|
||||
/// <param name="cancellationToken">A token to request the task's cancellation.
|
||||
/// If this task is not cancelled quickly, it might be killed by the runner.
|
||||
/// </param>
|
||||
/// <remarks>
|
||||
/// Your task can have any service as a public field and use the <see cref="InjectedAttribute"/>,
|
||||
/// they will be set to an available service from the service container before calling this method.
|
||||
/// They also will be removed after this method return (or throw) to prevent dangling services.
|
||||
/// </remarks>
|
||||
/// <exception cref="TaskFailedException">
|
||||
/// An exception meaning that the task has failed for handled reasons like invalid arguments,
|
||||
/// invalid environment, missing plugins or failures not related to a default in the code.
|
||||
|
221
Kyoo.Common/Controllers/StartupAction.cs
Normal file
221
Kyoo.Common/Controllers/StartupAction.cs
Normal file
@ -0,0 +1,221 @@
|
||||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Kyoo.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// A list of constant priorities used for <see cref="IStartupAction"/>'s <see cref="IStartupAction.Priority"/>.
|
||||
/// It also contains helper methods for creating new <see cref="StartupAction"/>.
|
||||
/// </summary>
|
||||
public static class SA
|
||||
{
|
||||
public const int Before = 5000;
|
||||
public const int Routing = 4000;
|
||||
public const int StaticFiles = 3000;
|
||||
public const int Authentication = 2000;
|
||||
public const int Authorization = 1000;
|
||||
public const int Endpoint = 0;
|
||||
public const int After = -1000;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="StartupAction"/>.
|
||||
/// </summary>
|
||||
/// <param name="action">The action to run</param>
|
||||
/// <param name="priority">The priority of the new action</param>
|
||||
/// <returns>A new <see cref="StartupAction"/></returns>
|
||||
public static StartupAction New(Action action, int priority)
|
||||
=> new(action, priority);
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="StartupAction"/>.
|
||||
/// </summary>
|
||||
/// <param name="action">The action to run</param>
|
||||
/// <param name="priority">The priority of the new action</param>
|
||||
/// <typeparam name="T">A dependency that this action will use.</typeparam>
|
||||
/// <returns>A new <see cref="StartupAction"/></returns>
|
||||
public static StartupAction<T> New<T>(Action<T> action, int priority)
|
||||
=> new(action, priority);
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="StartupAction"/>.
|
||||
/// </summary>
|
||||
/// <param name="action">The action to run</param>
|
||||
/// <param name="priority">The priority of the new action</param>
|
||||
/// <typeparam name="T">A dependency that this action will use.</typeparam>
|
||||
/// <typeparam name="T2">A second dependency that this action will use.</typeparam>
|
||||
/// <returns>A new <see cref="StartupAction"/></returns>
|
||||
public static StartupAction<T, T2> New<T, T2>(Action<T, T2> action, int priority)
|
||||
=> new(action, priority);
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="StartupAction"/>.
|
||||
/// </summary>
|
||||
/// <param name="action">The action to run</param>
|
||||
/// <param name="priority">The priority of the new action</param>
|
||||
/// <typeparam name="T">A dependency that this action will use.</typeparam>
|
||||
/// <typeparam name="T2">A second dependency that this action will use.</typeparam>
|
||||
/// <typeparam name="T3">A third dependency that this action will use.</typeparam>
|
||||
/// <returns>A new <see cref="StartupAction"/></returns>
|
||||
public static StartupAction<T, T2, T3> New<T, T2, T3>(Action<T, T2, T3> action, int priority)
|
||||
=> new(action, priority);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// An action executed on kyoo's startup to initialize the asp-net container.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This is the base interface, see <see cref="StartupAction"/> for a simpler use of this.
|
||||
/// </remarks>
|
||||
public interface IStartupAction
|
||||
{
|
||||
/// <summary>
|
||||
/// The priority of this action. The actions will be executed on descending priority order.
|
||||
/// If two actions have the same priority, their order is undefined.
|
||||
/// </summary>
|
||||
int Priority { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Run this action to configure the container, a service provider containing all services can be used.
|
||||
/// </summary>
|
||||
/// <param name="provider">The service provider containing all services can be used.</param>
|
||||
void Run(IServiceProvider provider);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="IStartupAction"/> with no dependencies.
|
||||
/// </summary>
|
||||
public class StartupAction : IStartupAction
|
||||
{
|
||||
/// <summary>
|
||||
/// The action to execute at startup.
|
||||
/// </summary>
|
||||
private readonly Action _action;
|
||||
|
||||
/// <inheritdoc />
|
||||
public int Priority { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="StartupAction"/>.
|
||||
/// </summary>
|
||||
/// <param name="action">The action to execute on startup.</param>
|
||||
/// <param name="priority">The priority of this action (see <see cref="Priority"/>).</param>
|
||||
public StartupAction(Action action, int priority)
|
||||
{
|
||||
_action = action;
|
||||
Priority = priority;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Run(IServiceProvider provider)
|
||||
{
|
||||
_action.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="IStartupAction"/> with one dependencies.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The dependency to use.</typeparam>
|
||||
public class StartupAction<T> : IStartupAction
|
||||
{
|
||||
/// <summary>
|
||||
/// The action to execute at startup.
|
||||
/// </summary>
|
||||
private readonly Action<T> _action;
|
||||
|
||||
/// <inheritdoc />
|
||||
public int Priority { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="StartupAction{T}"/>.
|
||||
/// </summary>
|
||||
/// <param name="action">The action to execute on startup.</param>
|
||||
/// <param name="priority">The priority of this action (see <see cref="Priority"/>).</param>
|
||||
public StartupAction(Action<T> action, int priority)
|
||||
{
|
||||
_action = action;
|
||||
Priority = priority;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Run(IServiceProvider provider)
|
||||
{
|
||||
_action.Invoke(provider.GetRequiredService<T>());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="IStartupAction"/> with two dependencies.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The dependency to use.</typeparam>
|
||||
/// <typeparam name="T2">The second dependency to use.</typeparam>
|
||||
public class StartupAction<T, T2> : IStartupAction
|
||||
{
|
||||
/// <summary>
|
||||
/// The action to execute at startup.
|
||||
/// </summary>
|
||||
private readonly Action<T, T2> _action;
|
||||
|
||||
/// <inheritdoc />
|
||||
public int Priority { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="StartupAction{T, T2}"/>.
|
||||
/// </summary>
|
||||
/// <param name="action">The action to execute on startup.</param>
|
||||
/// <param name="priority">The priority of this action (see <see cref="Priority"/>).</param>
|
||||
public StartupAction(Action<T, T2> action, int priority)
|
||||
{
|
||||
_action = action;
|
||||
Priority = priority;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Run(IServiceProvider provider)
|
||||
{
|
||||
_action.Invoke(
|
||||
provider.GetRequiredService<T>(),
|
||||
provider.GetRequiredService<T2>()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="IStartupAction"/> with three dependencies.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The dependency to use.</typeparam>
|
||||
/// <typeparam name="T2">The second dependency to use.</typeparam>
|
||||
/// <typeparam name="T3">The third dependency to use.</typeparam>
|
||||
public class StartupAction<T, T2, T3> : IStartupAction
|
||||
{
|
||||
/// <summary>
|
||||
/// The action to execute at startup.
|
||||
/// </summary>
|
||||
private readonly Action<T, T2, T3> _action;
|
||||
|
||||
/// <inheritdoc />
|
||||
public int Priority { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="StartupAction{T, T2, T3}"/>.
|
||||
/// </summary>
|
||||
/// <param name="action">The action to execute on startup.</param>
|
||||
/// <param name="priority">The priority of this action (see <see cref="Priority"/>).</param>
|
||||
public StartupAction(Action<T, T2, T3> action, int priority)
|
||||
{
|
||||
_action = action;
|
||||
Priority = priority;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Run(IServiceProvider provider)
|
||||
{
|
||||
_action.Invoke(
|
||||
provider.GetRequiredService<T>(),
|
||||
provider.GetRequiredService<T2>(),
|
||||
provider.GetRequiredService<T3>()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using Kyoo.Controllers;
|
||||
|
||||
namespace Kyoo.Models.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// An attribute to inform that the service will be injected automatically by a service provider.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// It should only be used on <see cref="IPlugin"/> and it will be injected before
|
||||
/// calling <see cref="IPlugin.ConfigureAspNet"/>.
|
||||
/// </remarks>
|
||||
[AttributeUsage(AttributeTargets.Property)]
|
||||
[MeansImplicitUse(ImplicitUseKindFlags.Assign)]
|
||||
public class InjectedAttribute : Attribute { }
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Kyoo.Controllers;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
@ -22,6 +23,9 @@ namespace Kyoo.Postgresql
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Description => "A database context for postgresql.";
|
||||
|
||||
/// <inheritdoc />
|
||||
public Dictionary<string, Type> Configuration => new();
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Enabled => _configuration.GetSelectedDatabase() == "postgres";
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Kyoo.Controllers;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
@ -22,6 +23,9 @@ namespace Kyoo.SqLite
|
||||
/// <inheritdoc />
|
||||
public string Description => "A database context for sqlite.";
|
||||
|
||||
/// <inheritdoc />
|
||||
public Dictionary<string, Type> Configuration => new();
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool Enabled => _configuration.GetSelectedDatabase() == "sqlite";
|
||||
|
||||
|
@ -1,10 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Autofac;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Kyoo.TheMovieDb.Models;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Kyoo.TheMovieDb
|
||||
{
|
||||
@ -21,45 +19,17 @@ namespace Kyoo.TheMovieDb
|
||||
|
||||
/// <inheritdoc />
|
||||
public string Description => "A metadata provider for TheMovieDB.";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The configuration to use.
|
||||
/// </summary>
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
/// <summary>
|
||||
/// The configuration manager used to register typed/untyped implementations.
|
||||
/// </summary>
|
||||
[Injected] public IConfigurationManager ConfigurationManager { private get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Create a new tmdb module instance and use the given configuration.
|
||||
/// </summary>
|
||||
/// <param name="configuration">The configuration to use</param>
|
||||
public PluginTmdb(IConfiguration configuration)
|
||||
/// <inheritdoc />
|
||||
public Dictionary<string, Type> Configuration => new()
|
||||
{
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
|
||||
{ TheMovieDbOptions.Path, typeof(TheMovieDbOptions) }
|
||||
};
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(ContainerBuilder builder)
|
||||
{
|
||||
builder.RegisterProvider<TheMovieDbProvider>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(IServiceCollection services)
|
||||
{
|
||||
services.Configure<TheMovieDbOptions>(_configuration.GetSection(TheMovieDbOptions.Path));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ConfigureAspNet(IApplicationBuilder app)
|
||||
{
|
||||
ConfigurationManager.AddTyped<TheMovieDbOptions>(TheMovieDbOptions.Path);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,10 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Autofac;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Kyoo.TheTvdb.Models;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using TvDbSharper;
|
||||
|
||||
namespace Kyoo.TheTvdb
|
||||
@ -23,44 +21,17 @@ namespace Kyoo.TheTvdb
|
||||
/// <inheritdoc />
|
||||
public string Description => "A metadata provider for The TVDB.";
|
||||
|
||||
/// <summary>
|
||||
/// The configuration to use.
|
||||
/// </summary>
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
/// <summary>
|
||||
/// The configuration manager used to register typed/untyped implementations.
|
||||
/// </summary>
|
||||
[Injected] public IConfigurationManager ConfigurationManager { private get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Create a new tvdb module instance and use the given configuration.
|
||||
/// </summary>
|
||||
/// <param name="configuration">The configuration to use</param>
|
||||
public PluginTvdb(IConfiguration configuration)
|
||||
/// <inheritdoc />
|
||||
public Dictionary<string, Type> Configuration => new()
|
||||
{
|
||||
_configuration = configuration;
|
||||
}
|
||||
|
||||
|
||||
{ TvdbOption.Path, typeof(TvdbOption) }
|
||||
};
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(ContainerBuilder builder)
|
||||
{
|
||||
builder.RegisterType<TvDbClient>().As<ITvDbClient>();
|
||||
builder.RegisterProvider<ProviderTvdb>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(IServiceCollection services)
|
||||
{
|
||||
services.Configure<TvdbOption>(_configuration.GetSection(TvdbOption.Path));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ConfigureAspNet(IApplicationBuilder app)
|
||||
{
|
||||
ConfigurationManager.AddTyped<TvdbOption>(TvdbOption.Path);
|
||||
}
|
||||
}
|
||||
}
|
@ -6,7 +6,6 @@ using System.Reflection;
|
||||
using System.Runtime.Loader;
|
||||
using Autofac;
|
||||
using Kyoo.Models.Options;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
@ -148,18 +147,6 @@ namespace Kyoo.Controllers
|
||||
plugin.Configure(services);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ConfigureAspnet(IApplicationBuilder app)
|
||||
{
|
||||
foreach (IPlugin plugin in _plugins)
|
||||
{
|
||||
using IServiceScope scope = _provider.CreateScope();
|
||||
Helper.InjectServices(plugin, x => scope.ServiceProvider.GetRequiredService(x));
|
||||
plugin.ConfigureAspNet(app);
|
||||
Helper.InjectServices(plugin, _ => null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A custom <see cref="AssemblyLoadContext"/> to load plugin's dependency if they are on the same folder.
|
||||
/// </summary>
|
||||
|
@ -1,10 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Autofac;
|
||||
using Autofac.Core;
|
||||
using Autofac.Core.Registration;
|
||||
using Kyoo.Controllers;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Kyoo.Models.Options;
|
||||
using Kyoo.Models.Permissions;
|
||||
using Kyoo.Tasks;
|
||||
@ -13,6 +13,7 @@ using Microsoft.AspNetCore.StaticFiles;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
|
||||
namespace Kyoo
|
||||
{
|
||||
@ -30,18 +31,23 @@ namespace Kyoo
|
||||
/// <inheritdoc />
|
||||
public string Description => "The core module containing default implementations.";
|
||||
|
||||
/// <inheritdoc />
|
||||
public Dictionary<string, Type> Configuration => new()
|
||||
{
|
||||
{ BasicOptions.Path, typeof(BasicOptions) },
|
||||
{ TaskOptions.Path, typeof(TaskOptions) },
|
||||
{ MediaOptions.Path, typeof(MediaOptions) },
|
||||
{ "database", null },
|
||||
{ "logging", null }
|
||||
};
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// The configuration to use.
|
||||
/// </summary>
|
||||
private readonly IConfiguration _configuration;
|
||||
|
||||
/// <summary>
|
||||
/// The configuration manager used to register typed/untyped implementations.
|
||||
/// </summary>
|
||||
[Injected] public IConfigurationManager ConfigurationManager { private get; set; }
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Create a new core module instance and use the given configuration.
|
||||
/// </summary>
|
||||
@ -99,10 +105,6 @@ namespace Kyoo
|
||||
{
|
||||
string publicUrl = _configuration.GetPublicUrl();
|
||||
|
||||
services.Configure<BasicOptions>(_configuration.GetSection(BasicOptions.Path));
|
||||
services.Configure<TaskOptions>(_configuration.GetSection(TaskOptions.Path));
|
||||
services.Configure<MediaOptions>(_configuration.GetSection(MediaOptions.Path));
|
||||
|
||||
services.AddControllers()
|
||||
.AddNewtonsoftJson(x =>
|
||||
{
|
||||
@ -114,26 +116,30 @@ namespace Kyoo
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ConfigureAspNet(IApplicationBuilder app)
|
||||
public IEnumerable<IStartupAction> ConfigureSteps => new IStartupAction[]
|
||||
{
|
||||
ConfigurationManager.AddTyped<BasicOptions>(BasicOptions.Path);
|
||||
ConfigurationManager.AddTyped<TaskOptions>(TaskOptions.Path);
|
||||
ConfigurationManager.AddTyped<MediaOptions>(MediaOptions.Path);
|
||||
ConfigurationManager.AddUntyped("database");
|
||||
ConfigurationManager.AddUntyped("logging");
|
||||
|
||||
FileExtensionContentTypeProvider contentTypeProvider = new();
|
||||
contentTypeProvider.Mappings[".data"] = "application/octet-stream";
|
||||
app.UseStaticFiles(new StaticFileOptions
|
||||
SA.New<IApplicationBuilder, IHostEnvironment>((app, env) =>
|
||||
{
|
||||
ContentTypeProvider = contentTypeProvider,
|
||||
FileProvider = new PhysicalFileProvider(Path.Join(AppDomain.CurrentDomain.BaseDirectory, "wwwroot"))
|
||||
});
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
if (env.IsDevelopment())
|
||||
app.UseDeveloperExceptionPage();
|
||||
else
|
||||
{
|
||||
app.UseExceptionHandler("/error");
|
||||
app.UseHsts();
|
||||
}
|
||||
}, SA.Before),
|
||||
SA.New<IApplicationBuilder>(app => app.UseRouting(), SA.Routing),
|
||||
SA.New<IApplicationBuilder>(app =>
|
||||
{
|
||||
endpoints.MapControllers();
|
||||
});
|
||||
}
|
||||
FileExtensionContentTypeProvider contentTypeProvider = new();
|
||||
contentTypeProvider.Mappings[".data"] = "application/octet-stream";
|
||||
app.UseStaticFiles(new StaticFileOptions
|
||||
{
|
||||
ContentTypeProvider = contentTypeProvider,
|
||||
FileProvider = new PhysicalFileProvider(Path.Join(AppDomain.CurrentDomain.BaseDirectory, "wwwroot"))
|
||||
});
|
||||
}, SA.StaticFiles),
|
||||
SA.New<IApplicationBuilder>(app => app.UseEndpoints(x => x.MapControllers()), SA.Endpoint)
|
||||
};
|
||||
}
|
||||
}
|
@ -1,32 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Reflection;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using Kyoo.Models.Attributes;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Kyoo
|
||||
{
|
||||
public static class Helper
|
||||
{
|
||||
/// <summary>
|
||||
/// Inject services into the <see cref="InjectedAttribute"/> marked properties of the given object.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to inject</param>
|
||||
/// <param name="retrieve">The function used to retrieve services. (The function is called immediately)</param>
|
||||
public static void InjectServices(object obj, [InstantHandle] Func<Type, object> retrieve)
|
||||
{
|
||||
IEnumerable<PropertyInfo> properties = obj.GetType().GetProperties()
|
||||
.Where(x => x.GetCustomAttribute<InjectedAttribute>() != null)
|
||||
.Where(x => x.CanWrite);
|
||||
|
||||
foreach (PropertyInfo property in properties)
|
||||
property.SetValue(obj, retrieve(property.PropertyType));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An helper method to get json content from an http server. This is a temporary thing and will probably be
|
||||
/// replaced by a call to the function of the same name in the <c>System.Net.Http.Json</c> namespace when .net6
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Autofac;
|
||||
using Autofac.Extras.AttributeMetadata;
|
||||
using Kyoo.Authentication;
|
||||
@ -90,18 +91,9 @@ namespace Kyoo
|
||||
/// <param name="env">The host environment (is the app in development mode?)</param>
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider provider)
|
||||
{
|
||||
if (env.IsDevelopment())
|
||||
app.UseDeveloperExceptionPage();
|
||||
else
|
||||
{
|
||||
app.UseExceptionHandler("/error");
|
||||
app.UseHsts();
|
||||
}
|
||||
|
||||
if (!env.IsDevelopment())
|
||||
app.UseSpaStaticFiles();
|
||||
|
||||
app.UseRouting();
|
||||
|
||||
app.Use((ctx, next) =>
|
||||
{
|
||||
ctx.Response.Headers.Remove("X-Powered-By");
|
||||
@ -116,9 +108,11 @@ namespace Kyoo
|
||||
});
|
||||
app.UseResponseCompression();
|
||||
|
||||
if (_plugins is PluginManager manager)
|
||||
manager.SetProvider(provider);
|
||||
_plugins.ConfigureAspnet(app);
|
||||
IEnumerable<IStartupAction> steps = _plugins.GetAllPlugins()
|
||||
.SelectMany(x => x.ConfigureSteps)
|
||||
.OrderByDescending(x => x.Priority);
|
||||
foreach (IStartupAction step in steps)
|
||||
step.Run(provider);
|
||||
|
||||
app.UseSpa(spa =>
|
||||
{
|
||||
|
@ -28,8 +28,8 @@ namespace Kyoo
|
||||
[SuppressMessage("ReSharper", "ConditionIsAlwaysTrueOrFalse")]
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
if (!File.Exists("./settings.json"))
|
||||
File.Copy(Path.Join(AppDomain.CurrentDomain.BaseDirectory, "settings.json"), "settings.json");
|
||||
if (!File.Exists(JsonConfigPath))
|
||||
File.Copy(Path.Join(AppDomain.CurrentDomain.BaseDirectory, JsonConfigPath), JsonConfigPath);
|
||||
|
||||
IHostBuilder builder = CreateWebHostBuilder(args);
|
||||
|
||||
@ -77,7 +77,8 @@ namespace Kyoo
|
||||
/// <returns>The modified configuration builder</returns>
|
||||
private static IConfigurationBuilder SetupConfig(IConfigurationBuilder builder, string[] args)
|
||||
{
|
||||
return builder.AddJsonFile(JsonConfigPath, false, true)
|
||||
return builder.SetBasePath(Environment.CurrentDirectory)
|
||||
.AddJsonFile(JsonConfigPath, false, true)
|
||||
.AddEnvironmentVariables()
|
||||
.AddCommandLine(args);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user