mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-31 04:04:21 -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.Models;
|
||||||
using Kyoo.Authentication.Views;
|
using Kyoo.Authentication.Views;
|
||||||
using Kyoo.Controllers;
|
using Kyoo.Controllers;
|
||||||
using Kyoo.Models.Attributes;
|
|
||||||
using Kyoo.Models.Permissions;
|
using Kyoo.Models.Permissions;
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
@ -38,6 +37,12 @@ namespace Kyoo.Authentication
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string Description => "Enable OpenID authentication for Kyoo.";
|
public string Description => "Enable OpenID authentication for Kyoo.";
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Dictionary<string, Type> Configuration => new()
|
||||||
|
{
|
||||||
|
{ AuthenticationOption.Path, typeof(AuthenticationOption) }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The configuration to use.
|
/// The configuration to use.
|
||||||
@ -53,11 +58,6 @@ namespace Kyoo.Authentication
|
|||||||
/// The environment information to check if the app runs in debug mode
|
/// The environment information to check if the app runs in debug mode
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly IWebHostEnvironment _environment;
|
private readonly IWebHostEnvironment _environment;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The configuration manager used to register typed/untyped implementations.
|
|
||||||
/// </summary>
|
|
||||||
[Injected] public IConfigurationManager ConfigurationManager { private get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <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 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.
|
// 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();
|
List<Client> clients = new();
|
||||||
_configuration.GetSection("authentication:clients").Bind(clients);
|
_configuration.GetSection("authentication:clients").Bind(clients);
|
||||||
@ -129,37 +125,43 @@ namespace Kyoo.Authentication
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void ConfigureAspNet(IApplicationBuilder app)
|
public IEnumerable<IStartupAction> ConfigureSteps => new IStartupAction[]
|
||||||
{
|
{
|
||||||
ConfigurationManager.AddTyped<AuthenticationOption>(AuthenticationOption.Path);
|
SA.New<IApplicationBuilder>(app =>
|
||||||
|
|
||||||
app.UseCookiePolicy(new CookiePolicyOptions
|
|
||||||
{
|
{
|
||||||
MinimumSameSitePolicy = SameSiteMode.Strict
|
PhysicalFileProvider provider = new(Path.Combine(
|
||||||
});
|
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!,
|
||||||
app.UseAuthentication();
|
"login"));
|
||||||
app.Use((ctx, next) =>
|
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());
|
app.UseCookiePolicy(new CookiePolicyOptions
|
||||||
return next();
|
{
|
||||||
});
|
MinimumSameSitePolicy = SameSiteMode.Strict
|
||||||
app.UseIdentityServer();
|
});
|
||||||
app.UseAuthorization();
|
app.UseAuthentication();
|
||||||
|
}, SA.Authentication),
|
||||||
PhysicalFileProvider provider = new(Path.Combine(
|
SA.New<IApplicationBuilder>(app =>
|
||||||
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!,
|
|
||||||
"login"));
|
|
||||||
app.UseDefaultFiles(new DefaultFilesOptions
|
|
||||||
{
|
{
|
||||||
RequestPath = new PathString("/login"),
|
app.Use((ctx, next) =>
|
||||||
FileProvider = provider,
|
{
|
||||||
RedirectToAppendTrailingSlash = true
|
ctx.SetIdentityServerOrigin(_configuration.GetPublicUrl());
|
||||||
});
|
return next();
|
||||||
app.UseStaticFiles(new StaticFileOptions
|
});
|
||||||
{
|
app.UseIdentityServer();
|
||||||
RequestPath = new PathString("/login"),
|
}, SA.Endpoint),
|
||||||
FileProvider = provider
|
SA.New<IApplicationBuilder>(app => app.UseAuthorization(), SA.Authorization)
|
||||||
});
|
};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Autofac;
|
using Autofac;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace Kyoo.Controllers
|
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.
|
/// By default, a plugin is always enabled. This method can be overriden to change this behavior.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
virtual bool Enabled => true;
|
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>
|
/// <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.
|
/// A configure method that will be run on plugin's startup.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="builder">The autofac service container to register services.</param>
|
/// <param name="builder">The autofac service container to register services.</param>
|
||||||
@ -61,20 +79,6 @@ namespace Kyoo.Controllers
|
|||||||
{
|
{
|
||||||
// Skipped
|
// 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>
|
/// <summary>
|
||||||
/// An optional function to execute and initialize your plugin.
|
/// An optional function to execute and initialize your plugin.
|
||||||
|
@ -2,7 +2,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Autofac;
|
using Autofac;
|
||||||
using Kyoo.Models.Exceptions;
|
using Kyoo.Models.Exceptions;
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
namespace Kyoo.Controllers
|
namespace Kyoo.Controllers
|
||||||
@ -63,11 +62,5 @@ namespace Kyoo.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="services">The service collection to populate</param>
|
/// <param name="services">The service collection to populate</param>
|
||||||
public void ConfigureServices(IServiceCollection services);
|
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 System.Threading.Tasks;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Kyoo.Models;
|
using Kyoo.Models;
|
||||||
using Kyoo.Models.Attributes;
|
|
||||||
using Kyoo.Models.Exceptions;
|
using Kyoo.Models.Exceptions;
|
||||||
|
|
||||||
namespace Kyoo.Controllers
|
namespace Kyoo.Controllers
|
||||||
@ -182,11 +181,6 @@ namespace Kyoo.Controllers
|
|||||||
/// <param name="cancellationToken">A token to request the task's cancellation.
|
/// <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.
|
/// If this task is not cancelled quickly, it might be killed by the runner.
|
||||||
/// </param>
|
/// </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">
|
/// <exception cref="TaskFailedException">
|
||||||
/// An exception meaning that the task has failed for handled reasons like invalid arguments,
|
/// 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.
|
/// 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;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Kyoo.Controllers;
|
using Kyoo.Controllers;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
@ -22,6 +23,9 @@ namespace Kyoo.Postgresql
|
|||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string Description => "A database context for postgresql.";
|
public string Description => "A database context for postgresql.";
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Dictionary<string, Type> Configuration => new();
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool Enabled => _configuration.GetSelectedDatabase() == "postgres";
|
public bool Enabled => _configuration.GetSelectedDatabase() == "postgres";
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Kyoo.Controllers;
|
using Kyoo.Controllers;
|
||||||
using Microsoft.AspNetCore.Hosting;
|
using Microsoft.AspNetCore.Hosting;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
@ -22,6 +23,9 @@ namespace Kyoo.SqLite
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string Description => "A database context for sqlite.";
|
public string Description => "A database context for sqlite.";
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public Dictionary<string, Type> Configuration => new();
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public bool Enabled => _configuration.GetSelectedDatabase() == "sqlite";
|
public bool Enabled => _configuration.GetSelectedDatabase() == "sqlite";
|
||||||
|
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Autofac;
|
using Autofac;
|
||||||
using Kyoo.Controllers;
|
using Kyoo.Controllers;
|
||||||
using Kyoo.Models.Attributes;
|
|
||||||
using Kyoo.TheMovieDb.Models;
|
using Kyoo.TheMovieDb.Models;
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
|
|
||||||
namespace Kyoo.TheMovieDb
|
namespace Kyoo.TheMovieDb
|
||||||
{
|
{
|
||||||
@ -21,45 +19,17 @@ namespace Kyoo.TheMovieDb
|
|||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string Description => "A metadata provider for TheMovieDB.";
|
public string Description => "A metadata provider for TheMovieDB.";
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The configuration to use.
|
|
||||||
/// </summary>
|
|
||||||
private readonly IConfiguration _configuration;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// The configuration manager used to register typed/untyped implementations.
|
public Dictionary<string, Type> Configuration => new()
|
||||||
/// </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)
|
|
||||||
{
|
{
|
||||||
_configuration = configuration;
|
{ TheMovieDbOptions.Path, typeof(TheMovieDbOptions) }
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void Configure(ContainerBuilder builder)
|
public void Configure(ContainerBuilder builder)
|
||||||
{
|
{
|
||||||
builder.RegisterProvider<TheMovieDbProvider>();
|
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 Autofac;
|
||||||
using Kyoo.Controllers;
|
using Kyoo.Controllers;
|
||||||
using Kyoo.Models.Attributes;
|
|
||||||
using Kyoo.TheTvdb.Models;
|
using Kyoo.TheTvdb.Models;
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.Extensions.Configuration;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using TvDbSharper;
|
using TvDbSharper;
|
||||||
|
|
||||||
namespace Kyoo.TheTvdb
|
namespace Kyoo.TheTvdb
|
||||||
@ -23,44 +21,17 @@ namespace Kyoo.TheTvdb
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string Description => "A metadata provider for The TVDB.";
|
public string Description => "A metadata provider for The TVDB.";
|
||||||
|
|
||||||
/// <summary>
|
/// <inheritdoc />
|
||||||
/// The configuration to use.
|
public Dictionary<string, Type> Configuration => new()
|
||||||
/// </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)
|
|
||||||
{
|
{
|
||||||
_configuration = configuration;
|
{ TvdbOption.Path, typeof(TvdbOption) }
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void Configure(ContainerBuilder builder)
|
public void Configure(ContainerBuilder builder)
|
||||||
{
|
{
|
||||||
builder.RegisterType<TvDbClient>().As<ITvDbClient>();
|
builder.RegisterType<TvDbClient>().As<ITvDbClient>();
|
||||||
builder.RegisterProvider<ProviderTvdb>();
|
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 System.Runtime.Loader;
|
||||||
using Autofac;
|
using Autofac;
|
||||||
using Kyoo.Models.Options;
|
using Kyoo.Models.Options;
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
@ -148,18 +147,6 @@ namespace Kyoo.Controllers
|
|||||||
plugin.Configure(services);
|
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>
|
/// <summary>
|
||||||
/// A custom <see cref="AssemblyLoadContext"/> to load plugin's dependency if they are on the same folder.
|
/// A custom <see cref="AssemblyLoadContext"/> to load plugin's dependency if they are on the same folder.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Autofac;
|
using Autofac;
|
||||||
using Autofac.Core;
|
using Autofac.Core;
|
||||||
using Autofac.Core.Registration;
|
using Autofac.Core.Registration;
|
||||||
using Kyoo.Controllers;
|
using Kyoo.Controllers;
|
||||||
using Kyoo.Models.Attributes;
|
|
||||||
using Kyoo.Models.Options;
|
using Kyoo.Models.Options;
|
||||||
using Kyoo.Models.Permissions;
|
using Kyoo.Models.Permissions;
|
||||||
using Kyoo.Tasks;
|
using Kyoo.Tasks;
|
||||||
@ -13,6 +13,7 @@ using Microsoft.AspNetCore.StaticFiles;
|
|||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.FileProviders;
|
using Microsoft.Extensions.FileProviders;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
|
||||||
namespace Kyoo
|
namespace Kyoo
|
||||||
{
|
{
|
||||||
@ -30,18 +31,23 @@ namespace Kyoo
|
|||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public string Description => "The core module containing default implementations.";
|
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>
|
/// <summary>
|
||||||
/// The configuration to use.
|
/// The configuration to use.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly IConfiguration _configuration;
|
private readonly IConfiguration _configuration;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The configuration manager used to register typed/untyped implementations.
|
|
||||||
/// </summary>
|
|
||||||
[Injected] public IConfigurationManager ConfigurationManager { private get; set; }
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a new core module instance and use the given configuration.
|
/// Create a new core module instance and use the given configuration.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -99,10 +105,6 @@ namespace Kyoo
|
|||||||
{
|
{
|
||||||
string publicUrl = _configuration.GetPublicUrl();
|
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()
|
services.AddControllers()
|
||||||
.AddNewtonsoftJson(x =>
|
.AddNewtonsoftJson(x =>
|
||||||
{
|
{
|
||||||
@ -114,26 +116,30 @@ namespace Kyoo
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public void ConfigureAspNet(IApplicationBuilder app)
|
public IEnumerable<IStartupAction> ConfigureSteps => new IStartupAction[]
|
||||||
{
|
{
|
||||||
ConfigurationManager.AddTyped<BasicOptions>(BasicOptions.Path);
|
SA.New<IApplicationBuilder, IHostEnvironment>((app, env) =>
|
||||||
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
|
|
||||||
{
|
{
|
||||||
ContentTypeProvider = contentTypeProvider,
|
if (env.IsDevelopment())
|
||||||
FileProvider = new PhysicalFileProvider(Path.Join(AppDomain.CurrentDomain.BaseDirectory, "wwwroot"))
|
app.UseDeveloperExceptionPage();
|
||||||
});
|
else
|
||||||
|
{
|
||||||
app.UseEndpoints(endpoints =>
|
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.Net.Http;
|
||||||
using System.Reflection;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Kyoo.Models.Attributes;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Kyoo
|
namespace Kyoo
|
||||||
{
|
{
|
||||||
public static class Helper
|
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>
|
/// <summary>
|
||||||
/// An helper method to get json content from an http server. This is a temporary thing and will probably be
|
/// 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
|
/// 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;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using Autofac;
|
using Autofac;
|
||||||
using Autofac.Extras.AttributeMetadata;
|
using Autofac.Extras.AttributeMetadata;
|
||||||
using Kyoo.Authentication;
|
using Kyoo.Authentication;
|
||||||
@ -90,18 +91,9 @@ namespace Kyoo
|
|||||||
/// <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, IServiceProvider provider)
|
||||||
{
|
{
|
||||||
if (env.IsDevelopment())
|
|
||||||
app.UseDeveloperExceptionPage();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
app.UseExceptionHandler("/error");
|
|
||||||
app.UseHsts();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!env.IsDevelopment())
|
if (!env.IsDevelopment())
|
||||||
app.UseSpaStaticFiles();
|
app.UseSpaStaticFiles();
|
||||||
|
|
||||||
app.UseRouting();
|
|
||||||
app.Use((ctx, next) =>
|
app.Use((ctx, next) =>
|
||||||
{
|
{
|
||||||
ctx.Response.Headers.Remove("X-Powered-By");
|
ctx.Response.Headers.Remove("X-Powered-By");
|
||||||
@ -116,9 +108,11 @@ namespace Kyoo
|
|||||||
});
|
});
|
||||||
app.UseResponseCompression();
|
app.UseResponseCompression();
|
||||||
|
|
||||||
if (_plugins is PluginManager manager)
|
IEnumerable<IStartupAction> steps = _plugins.GetAllPlugins()
|
||||||
manager.SetProvider(provider);
|
.SelectMany(x => x.ConfigureSteps)
|
||||||
_plugins.ConfigureAspnet(app);
|
.OrderByDescending(x => x.Priority);
|
||||||
|
foreach (IStartupAction step in steps)
|
||||||
|
step.Run(provider);
|
||||||
|
|
||||||
app.UseSpa(spa =>
|
app.UseSpa(spa =>
|
||||||
{
|
{
|
||||||
|
@ -28,8 +28,8 @@ namespace Kyoo
|
|||||||
[SuppressMessage("ReSharper", "ConditionIsAlwaysTrueOrFalse")]
|
[SuppressMessage("ReSharper", "ConditionIsAlwaysTrueOrFalse")]
|
||||||
public static async Task Main(string[] args)
|
public static async Task Main(string[] args)
|
||||||
{
|
{
|
||||||
if (!File.Exists("./settings.json"))
|
if (!File.Exists(JsonConfigPath))
|
||||||
File.Copy(Path.Join(AppDomain.CurrentDomain.BaseDirectory, "settings.json"), "settings.json");
|
File.Copy(Path.Join(AppDomain.CurrentDomain.BaseDirectory, JsonConfigPath), JsonConfigPath);
|
||||||
|
|
||||||
IHostBuilder builder = CreateWebHostBuilder(args);
|
IHostBuilder builder = CreateWebHostBuilder(args);
|
||||||
|
|
||||||
@ -77,7 +77,8 @@ namespace Kyoo
|
|||||||
/// <returns>The modified configuration builder</returns>
|
/// <returns>The modified configuration builder</returns>
|
||||||
private static IConfigurationBuilder SetupConfig(IConfigurationBuilder builder, string[] args)
|
private static IConfigurationBuilder SetupConfig(IConfigurationBuilder builder, string[] args)
|
||||||
{
|
{
|
||||||
return builder.AddJsonFile(JsonConfigPath, false, true)
|
return builder.SetBasePath(Environment.CurrentDirectory)
|
||||||
|
.AddJsonFile(JsonConfigPath, false, true)
|
||||||
.AddEnvironmentVariables()
|
.AddEnvironmentVariables()
|
||||||
.AddCommandLine(args);
|
.AddCommandLine(args);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user