diff --git a/Kyoo.Authentication/Controllers/PremissionValidator.cs b/Kyoo.Authentication/Controllers/PremissionValidator.cs
index 62a4843b..ca3102ed 100644
--- a/Kyoo.Authentication/Controllers/PremissionValidator.cs
+++ b/Kyoo.Authentication/Controllers/PremissionValidator.cs
@@ -132,7 +132,7 @@ namespace Kyoo.Authentication
}
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);
if (res.Succeeded)
{
diff --git a/Kyoo.Common/Models/ConfigurationReference.cs b/Kyoo.Common/Models/ConfigurationReference.cs
index fab6f9d3..00d20b4c 100644
--- a/Kyoo.Common/Models/ConfigurationReference.cs
+++ b/Kyoo.Common/Models/ConfigurationReference.cs
@@ -87,5 +87,11 @@ namespace Kyoo.Models
{
return CreateReference(path, typeof(T));
}
+
+
+ public static ConfigurationReference CreateUntyped(string path)
+ {
+ return new(path, null);
+ }
}
}
\ No newline at end of file
diff --git a/Kyoo.Common/Module.cs b/Kyoo.Common/Module.cs
index 0b5e0d04..a8a81b88 100644
--- a/Kyoo.Common/Module.cs
+++ b/Kyoo.Common/Module.cs
@@ -82,6 +82,20 @@ namespace Kyoo
services.AddSingleton(confRef);
return services;
}
+
+ ///
+ /// 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.
+ ///
+ /// The service collection to edit
+ /// The root path of the editable configuration. It should not be a nested type.
+ /// The given service collection is returned.
+ public static IServiceCollection AddUntypedConfiguration(this IServiceCollection services, string path)
+ {
+ services.AddSingleton(ConfigurationReference.CreateUntyped(path));
+ return services;
+ }
///
/// Get the public URL of kyoo using the given configuration instance.
diff --git a/Kyoo/Controllers/ConfigurationManager.cs b/Kyoo/Controllers/ConfigurationManager.cs
index c0a1340b..c0a63895 100644
--- a/Kyoo/Controllers/ConfigurationManager.cs
+++ b/Kyoo/Controllers/ConfigurationManager.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Dynamic;
using System.IO;
using System.Linq;
@@ -35,13 +36,30 @@ namespace Kyoo.Controllers
_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}");
+ }
+
///
public object GetValue(string path)
{
path = path.Replace("__", ":");
// TODO handle lists and dictionaries.
- if (!_references.TryGetValue(path, out Type type))
- throw new ItemNotFoundException($"No configuration exists for the name: {path}");
+ Type type = GetType(path);
object ret = _configuration.GetValue(type, path);
if (ret != null)
return ret;
@@ -55,8 +73,7 @@ namespace Kyoo.Controllers
{
path = path.Replace("__", ":");
// TODO handle lists and dictionaries.
- if (!_references.TryGetValue(path, out Type type))
- throw new ItemNotFoundException($"No configuration exists for the name: {path}");
+ Type type = GetType(path);
if (typeof(T).IsAssignableFrom(type))
throw new InvalidCastException($"The type {typeof(T).Name} is not valid for " +
$"a resource of type {type.Name}.");
@@ -67,8 +84,7 @@ namespace Kyoo.Controllers
public async Task EditValue(string path, object value)
{
path = path.Replace("__", ":");
- if (!_references.TryGetValue(path, out Type type))
- throw new ItemNotFoundException($"No configuration exists for the name: {path}");
+ Type type = GetType(path);
value = JObject.FromObject(value).ToObject(type);
if (value == null)
throw new ArgumentException("Invalid value format.");
@@ -87,18 +103,48 @@ namespace Kyoo.Controllers
///
/// The configuration to transform
/// A strongly typed representation of the configuration.
+ [SuppressMessage("ReSharper", "RedundantJumpStatement")]
private ExpandoObject ToObject(IConfiguration config)
{
ExpandoObject obj = new();
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;
- obj.TryAdd(section.Key, section.Get(type));
+ }
}
return obj;
}
+
+ ///
+ /// Transform the configuration section in nested expando objects.
+ ///
+ /// The section to convert
+ /// The converted section
+ 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;
+ }
}
}
\ No newline at end of file
diff --git a/Kyoo/CoreModule.cs b/Kyoo/CoreModule.cs
index 726ed36a..34e24e75 100644
--- a/Kyoo/CoreModule.cs
+++ b/Kyoo/CoreModule.cs
@@ -99,6 +99,8 @@ namespace Kyoo
services.AddConfiguration(TaskOptions.Path);
services.Configure(_configuration.GetSection(MediaOptions.Path));
services.AddConfiguration(MediaOptions.Path);
+ services.AddUntypedConfiguration("database");
+ services.AddUntypedConfiguration("logging");
services.AddControllers()
.AddNewtonsoftJson(x =>
diff --git a/Kyoo/Program.cs b/Kyoo/Program.cs
index db83cfd9..12227266 100644
--- a/Kyoo/Program.cs
+++ b/Kyoo/Program.cs
@@ -109,7 +109,7 @@ namespace Kyoo
.UseKestrel(options => { options.AddServerHeader = false; })
.UseIIS()
.UseIISIntegration()
- .UseUrls(configuration.GetValue("basics:urls"))
+ .UseUrls(configuration.GetValue("basics:url"))
.UseStartup();
}
}
diff --git a/Kyoo/Views/ConfigurationApi.cs b/Kyoo/Views/ConfigurationApi.cs
index 13d7f5ca..7830d786 100644
--- a/Kyoo/Views/ConfigurationApi.cs
+++ b/Kyoo/Views/ConfigurationApi.cs
@@ -71,9 +71,9 @@ namespace Kyoo.Api
{
return NotFound();
}
- catch (ArgumentException)
+ catch (ArgumentException ex)
{
- return BadRequest();
+ return BadRequest(ex.Message);
}
}
}