mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Allowing untyped sections in the config
This commit is contained in:
parent
5f7604a563
commit
52e7093c26
@ -132,7 +132,7 @@ namespace Kyoo.Authentication
|
|||||||
}
|
}
|
||||||
|
|
||||||
string permStr = $"{permission.ToLower()}.{kind.ToString()!.ToLower()}";
|
string permStr = $"{permission.ToLower()}.{kind.ToString()!.ToLower()}";
|
||||||
string overallStr = $"{_group.ToString()}.{kind.ToString()!.ToLower()}";
|
string overallStr = $"{_group.ToString().ToLower()}.{kind.ToString()!.ToLower()}";
|
||||||
AuthenticateResult res = await context.HttpContext.AuthenticateAsync(JwtBearerDefaults.AuthenticationScheme);
|
AuthenticateResult res = await context.HttpContext.AuthenticateAsync(JwtBearerDefaults.AuthenticationScheme);
|
||||||
if (res.Succeeded)
|
if (res.Succeeded)
|
||||||
{
|
{
|
||||||
|
@ -87,5 +87,11 @@ namespace Kyoo.Models
|
|||||||
{
|
{
|
||||||
return CreateReference(path, typeof(T));
|
return CreateReference(path, typeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static ConfigurationReference CreateUntyped(string path)
|
||||||
|
{
|
||||||
|
return new(path, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -82,6 +82,20 @@ namespace Kyoo
|
|||||||
services.AddSingleton(confRef);
|
services.AddSingleton(confRef);
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Add an editable configuration to the editable configuration list.
|
||||||
|
/// WARNING: this method allow you to add an unmanaged type. This type won't be editable. This can be used
|
||||||
|
/// for external libraries or variable arguments.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="services">The service collection to edit</param>
|
||||||
|
/// <param name="path">The root path of the editable configuration. It should not be a nested type.</param>
|
||||||
|
/// <returns>The given service collection is returned.</returns>
|
||||||
|
public static IServiceCollection AddUntypedConfiguration(this IServiceCollection services, string path)
|
||||||
|
{
|
||||||
|
services.AddSingleton(ConfigurationReference.CreateUntyped(path));
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get the public URL of kyoo using the given configuration instance.
|
/// Get the public URL of kyoo using the given configuration instance.
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Dynamic;
|
using System.Dynamic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -35,13 +36,30 @@ namespace Kyoo.Controllers
|
|||||||
_references = references.ToDictionary(x => x.Path, x => x.Type, StringComparer.OrdinalIgnoreCase);
|
_references = references.ToDictionary(x => x.Path, x => x.Type, StringComparer.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Type GetType(string path)
|
||||||
|
{
|
||||||
|
path = path.Replace("__", ":");
|
||||||
|
|
||||||
|
// TODO handle lists and dictionaries.
|
||||||
|
if (_references.TryGetValue(path, out Type type))
|
||||||
|
{
|
||||||
|
if (type != null)
|
||||||
|
return type;
|
||||||
|
throw new ArgumentException($"The configuration at {path} is not editable or readable.");
|
||||||
|
}
|
||||||
|
|
||||||
|
string parent = path.Contains(':') ? path[..path.IndexOf(':')] : null;
|
||||||
|
if (parent != null && _references.TryGetValue(parent, out type) && type == null)
|
||||||
|
throw new ArgumentException($"The configuration at {path} is not editable or readable.");
|
||||||
|
throw new ItemNotFoundException($"No configuration exists for the name: {path}");
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public object GetValue(string path)
|
public object GetValue(string path)
|
||||||
{
|
{
|
||||||
path = path.Replace("__", ":");
|
path = path.Replace("__", ":");
|
||||||
// TODO handle lists and dictionaries.
|
// TODO handle lists and dictionaries.
|
||||||
if (!_references.TryGetValue(path, out Type type))
|
Type type = GetType(path);
|
||||||
throw new ItemNotFoundException($"No configuration exists for the name: {path}");
|
|
||||||
object ret = _configuration.GetValue(type, path);
|
object ret = _configuration.GetValue(type, path);
|
||||||
if (ret != null)
|
if (ret != null)
|
||||||
return ret;
|
return ret;
|
||||||
@ -55,8 +73,7 @@ namespace Kyoo.Controllers
|
|||||||
{
|
{
|
||||||
path = path.Replace("__", ":");
|
path = path.Replace("__", ":");
|
||||||
// TODO handle lists and dictionaries.
|
// TODO handle lists and dictionaries.
|
||||||
if (!_references.TryGetValue(path, out Type type))
|
Type type = GetType(path);
|
||||||
throw new ItemNotFoundException($"No configuration exists for the name: {path}");
|
|
||||||
if (typeof(T).IsAssignableFrom(type))
|
if (typeof(T).IsAssignableFrom(type))
|
||||||
throw new InvalidCastException($"The type {typeof(T).Name} is not valid for " +
|
throw new InvalidCastException($"The type {typeof(T).Name} is not valid for " +
|
||||||
$"a resource of type {type.Name}.");
|
$"a resource of type {type.Name}.");
|
||||||
@ -67,8 +84,7 @@ namespace Kyoo.Controllers
|
|||||||
public async Task EditValue(string path, object value)
|
public async Task EditValue(string path, object value)
|
||||||
{
|
{
|
||||||
path = path.Replace("__", ":");
|
path = path.Replace("__", ":");
|
||||||
if (!_references.TryGetValue(path, out Type type))
|
Type type = GetType(path);
|
||||||
throw new ItemNotFoundException($"No configuration exists for the name: {path}");
|
|
||||||
value = JObject.FromObject(value).ToObject(type);
|
value = JObject.FromObject(value).ToObject(type);
|
||||||
if (value == null)
|
if (value == null)
|
||||||
throw new ArgumentException("Invalid value format.");
|
throw new ArgumentException("Invalid value format.");
|
||||||
@ -87,18 +103,48 @@ namespace Kyoo.Controllers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="config">The configuration to transform</param>
|
/// <param name="config">The configuration to transform</param>
|
||||||
/// <returns>A strongly typed representation of the configuration.</returns>
|
/// <returns>A strongly typed representation of the configuration.</returns>
|
||||||
|
[SuppressMessage("ReSharper", "RedundantJumpStatement")]
|
||||||
private ExpandoObject ToObject(IConfiguration config)
|
private ExpandoObject ToObject(IConfiguration config)
|
||||||
{
|
{
|
||||||
ExpandoObject obj = new();
|
ExpandoObject obj = new();
|
||||||
|
|
||||||
foreach (IConfigurationSection section in config.GetChildren())
|
foreach (IConfigurationSection section in config.GetChildren())
|
||||||
{
|
{
|
||||||
if (!_references.TryGetValue(section.Path, out Type type))
|
try
|
||||||
|
{
|
||||||
|
Type type = GetType(section.Path);
|
||||||
|
obj.TryAdd(section.Key, section.Get(type));
|
||||||
|
}
|
||||||
|
catch (ArgumentException)
|
||||||
|
{
|
||||||
|
obj.TryAdd(section.Key, ToUntyped(section));
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
obj.TryAdd(section.Key, section.Get(type));
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Transform the configuration section in nested expando objects.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="config">The section to convert</param>
|
||||||
|
/// <returns>The converted section</returns>
|
||||||
|
private static object ToUntyped(IConfigurationSection config)
|
||||||
|
{
|
||||||
|
ExpandoObject obj = new();
|
||||||
|
|
||||||
|
foreach (IConfigurationSection section in config.GetChildren())
|
||||||
|
{
|
||||||
|
obj.TryAdd(section.Key, ToUntyped(section));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!obj.Any())
|
||||||
|
return config.Value;
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -99,6 +99,8 @@ namespace Kyoo
|
|||||||
services.AddConfiguration<TaskOptions>(TaskOptions.Path);
|
services.AddConfiguration<TaskOptions>(TaskOptions.Path);
|
||||||
services.Configure<MediaOptions>(_configuration.GetSection(MediaOptions.Path));
|
services.Configure<MediaOptions>(_configuration.GetSection(MediaOptions.Path));
|
||||||
services.AddConfiguration<MediaOptions>(MediaOptions.Path);
|
services.AddConfiguration<MediaOptions>(MediaOptions.Path);
|
||||||
|
services.AddUntypedConfiguration("database");
|
||||||
|
services.AddUntypedConfiguration("logging");
|
||||||
|
|
||||||
services.AddControllers()
|
services.AddControllers()
|
||||||
.AddNewtonsoftJson(x =>
|
.AddNewtonsoftJson(x =>
|
||||||
|
@ -109,7 +109,7 @@ namespace Kyoo
|
|||||||
.UseKestrel(options => { options.AddServerHeader = false; })
|
.UseKestrel(options => { options.AddServerHeader = false; })
|
||||||
.UseIIS()
|
.UseIIS()
|
||||||
.UseIISIntegration()
|
.UseIISIntegration()
|
||||||
.UseUrls(configuration.GetValue<string>("basics:urls"))
|
.UseUrls(configuration.GetValue<string>("basics:url"))
|
||||||
.UseStartup<Startup>();
|
.UseStartup<Startup>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,9 +71,9 @@ namespace Kyoo.Api
|
|||||||
{
|
{
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
catch (ArgumentException)
|
catch (ArgumentException ex)
|
||||||
{
|
{
|
||||||
return BadRequest();
|
return BadRequest(ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user