Add oidc options parsing

This commit is contained in:
Zoe Roux 2024-02-29 20:54:42 +01:00
parent bc99408652
commit 07f0862219
4 changed files with 103 additions and 50 deletions

View File

@ -5,7 +5,7 @@ LIBRARY_ROOT=./video
CACHE_ROOT=/tmp/kyoo_cache
LIBRARY_LANGUAGES=en
# Hardware transcoding (equivalent of --profile docker compose option).
# COMPOSE_PROFILES= # vaapi or qsv or nvidia
COMPOSE_PROFILES= # vaapi or qsv or nvidia
# A pattern (regex) to ignore video files.
LIBRARY_IGNORE_PATTERN=.*/[dD]ownloads?/.*
@ -20,8 +20,12 @@ DEFAULT_PERMISSIONS=overall.read,overall.play
UNLOGGED_PERMISSIONS=overall.read,overall.play
THEMOVIEDB_APIKEY=
PUBLIC_BACK_URL=http://localhost:5000
PUBLIC_URL=http://localhost:5000
# You can use as many
OIDC_GOOGLE_URL=https://accounts.google.com/o/oauth2/v2/auth
OIDC_GOOGLE_CLIENTID=
OIDC_GOOGLE_SECRET=
# Following options are optional and only useful for debugging.

View File

@ -17,6 +17,7 @@
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autofac;
@ -26,6 +27,7 @@ using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
namespace Kyoo.Authentication
@ -33,7 +35,13 @@ namespace Kyoo.Authentication
/// <summary>
/// A module that enable OpenID authentication for Kyoo.
/// </summary>
public class AuthenticationModule : IPlugin
/// <remarks>
/// Create a new authentication module instance and use the given configuration.
/// </remarks>
public class AuthenticationModule(
IConfiguration configuration,
ILogger<AuthenticationModule> logger
) : IPlugin
{
/// <inheritdoc />
public string Name => "Authentication";
@ -41,16 +49,7 @@ namespace Kyoo.Authentication
/// <summary>
/// The configuration to use.
/// </summary>
private readonly IConfiguration _configuration;
/// <summary>
/// Create a new authentication module instance and use the given configuration.
/// </summary>
/// <param name="configuration">The configuration to use</param>
public AuthenticationModule(IConfiguration configuration)
{
_configuration = configuration;
}
private readonly IConfiguration _configuration = configuration;
/// <inheritdoc />
public void Configure(ContainerBuilder builder)
@ -75,7 +74,53 @@ namespace Kyoo.Authentication
NewUser = _configuration
.GetValue("DEFAULT_PERMISSIONS", "overall.read")!
.Split(','),
PublicUrl =
_configuration.GetValue<string?>("PUBLIC_URL")
?? "http://localhost:8901",
ApiKeys = _configuration.GetValue("KYOO_APIKEYS", string.Empty)!.Split(','),
OIDC = _configuration
.AsEnumerable()
.Where((pair) => pair.Key.StartsWith("OIDC_"))
.Aggregate(
new Dictionary<string, OidcProvider>(),
(acc, val) =>
{
if (val.Value is null)
return acc;
if (val.Key.Split("_") is not ["OIDC", string provider, string key])
{
logger.LogError("Invalid oidc config value: {}", val.Key);
return acc;
}
provider = provider.ToLowerInvariant();
key = key.ToLowerInvariant();
if (!acc.ContainsKey(provider))
acc.Add(provider, new());
switch (key)
{
case "clientid":
acc[provider].ClientId = val.Value;
break;
case "secret":
acc[provider].Secret = val.Value;
break;
case "scope":
acc[provider].Scope = val.Value;
break;
case "authorization":
acc[provider].AuthorizationUrl = val.Value;
break;
case "userinfo":
acc[provider].UserinfoUrl = val.Value;
break;
default:
logger.LogError("Invalid oidc config value: {}", key);
return acc;
}
return acc;
}
),
};
services.AddSingleton(permissions);
services.AddSingleton(

View File

@ -17,50 +17,55 @@
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
using System.Linq;
using Kyoo.Abstractions.Models.Permissions;
namespace Kyoo.Authentication.Models
namespace Kyoo.Authentication.Models;
/// <summary>
/// Permission options.
/// </summary>
public class PermissionOption
{
/// <summary>
/// Permission options.
/// The path to get this option from the root configuration.
/// </summary>
public class PermissionOption
{
/// <summary>
/// The path to get this option from the root configuration.
/// </summary>
public const string Path = "authentication:permissions";
public const string Path = "authentication:permissions";
/// <summary>
/// All permissions possibles, this is used to create an admin group.
/// </summary>
public static string[] Admin
{
get
{
return Enum.GetNames<Group>()
.Where(x => x != nameof(Group.None))
.SelectMany(group =>
Enum.GetNames<Kind>().Select(kind => $"{group}.{kind}".ToLowerInvariant())
)
.ToArray();
}
}
/// <summary>
/// The default permissions that will be given to a non-connected user.
/// </summary>
public string[] Default { get; set; } = { "overall.read", "overall.play" };
/// <summary>
/// The default permissions that will be given to a non-connected user.
/// </summary>
public string[] Default { get; set; } = { "overall.read", "overall.play" };
/// <summary>
/// Permissions applied to a new user.
/// </summary>
public string[] NewUser { get; set; } = { "overall.read", "overall.play" };
/// <summary>
/// Permissions applied to a new user.
/// </summary>
public string[] NewUser { get; set; } = { "overall.read", "overall.play" };
public static string[] Admin =>
Enum.GetNames<Group>()
.Where(x => x != nameof(Group.None))
.SelectMany(group =>
Enum.GetNames<Kind>().Select(kind => $"{group}.{kind}".ToLowerInvariant())
)
.ToArray();
/// <summary>
/// The list of available ApiKeys.
/// </summary>
public string[] ApiKeys { get; set; } = Array.Empty<string>();
}
/// <summary>
/// The list of available ApiKeys.
/// </summary>
public string[] ApiKeys { get; set; } = Array.Empty<string>();
public string PublicUrl { get; set; }
public Dictionary<string, OidcProvider> OIDC { get; set; }
}
public class OidcProvider
{
public string AuthorizationUrl { get; set; }
public string UserinfoUrl { get; set; }
public string ClientId { get; set; }
public string Secret { get; set; }
public string? Scope { get; set; }
}

View File

@ -20,7 +20,6 @@ using System;
using System.Globalization;
using EFCore.NamingConventions.Internal;
using Kyoo.Abstractions.Models;
using Kyoo.Utils;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;