diff --git a/.env.example b/.env.example index 47eb9f70..bab81b38 100644 --- a/.env.example +++ b/.env.example @@ -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. diff --git a/back/src/Kyoo.Authentication/AuthenticationModule.cs b/back/src/Kyoo.Authentication/AuthenticationModule.cs index caf5d345..6750b1d9 100644 --- a/back/src/Kyoo.Authentication/AuthenticationModule.cs +++ b/back/src/Kyoo.Authentication/AuthenticationModule.cs @@ -17,6 +17,7 @@ // along with Kyoo. If not, see . 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 /// /// A module that enable OpenID authentication for Kyoo. /// - public class AuthenticationModule : IPlugin + /// + /// Create a new authentication module instance and use the given configuration. + /// + public class AuthenticationModule( + IConfiguration configuration, + ILogger logger + ) : IPlugin { /// public string Name => "Authentication"; @@ -41,16 +49,7 @@ namespace Kyoo.Authentication /// /// The configuration to use. /// - private readonly IConfiguration _configuration; - - /// - /// Create a new authentication module instance and use the given configuration. - /// - /// The configuration to use - public AuthenticationModule(IConfiguration configuration) - { - _configuration = configuration; - } + private readonly IConfiguration _configuration = configuration; /// public void Configure(ContainerBuilder builder) @@ -75,7 +74,53 @@ namespace Kyoo.Authentication NewUser = _configuration .GetValue("DEFAULT_PERMISSIONS", "overall.read")! .Split(','), + PublicUrl = + _configuration.GetValue("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(), + (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( diff --git a/back/src/Kyoo.Authentication/Models/Options/PermissionOption.cs b/back/src/Kyoo.Authentication/Models/Options/PermissionOption.cs index 5c11131c..8d314057 100644 --- a/back/src/Kyoo.Authentication/Models/Options/PermissionOption.cs +++ b/back/src/Kyoo.Authentication/Models/Options/PermissionOption.cs @@ -17,50 +17,55 @@ // along with Kyoo. If not, see . using System; +using System.Collections.Generic; using System.Linq; using Kyoo.Abstractions.Models.Permissions; -namespace Kyoo.Authentication.Models +namespace Kyoo.Authentication.Models; + +/// +/// Permission options. +/// +public class PermissionOption { /// - /// Permission options. + /// The path to get this option from the root configuration. /// - public class PermissionOption - { - /// - /// The path to get this option from the root configuration. - /// - public const string Path = "authentication:permissions"; + public const string Path = "authentication:permissions"; - /// - /// All permissions possibles, this is used to create an admin group. - /// - public static string[] Admin - { - get - { - return Enum.GetNames() - .Where(x => x != nameof(Group.None)) - .SelectMany(group => - Enum.GetNames().Select(kind => $"{group}.{kind}".ToLowerInvariant()) - ) - .ToArray(); - } - } + /// + /// The default permissions that will be given to a non-connected user. + /// + public string[] Default { get; set; } = { "overall.read", "overall.play" }; - /// - /// The default permissions that will be given to a non-connected user. - /// - public string[] Default { get; set; } = { "overall.read", "overall.play" }; + /// + /// Permissions applied to a new user. + /// + public string[] NewUser { get; set; } = { "overall.read", "overall.play" }; - /// - /// Permissions applied to a new user. - /// - public string[] NewUser { get; set; } = { "overall.read", "overall.play" }; + public static string[] Admin => + Enum.GetNames() + .Where(x => x != nameof(Group.None)) + .SelectMany(group => + Enum.GetNames().Select(kind => $"{group}.{kind}".ToLowerInvariant()) + ) + .ToArray(); - /// - /// The list of available ApiKeys. - /// - public string[] ApiKeys { get; set; } = Array.Empty(); - } + /// + /// The list of available ApiKeys. + /// + public string[] ApiKeys { get; set; } = Array.Empty(); + + public string PublicUrl { get; set; } + + public Dictionary 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; } } diff --git a/back/src/Kyoo.Postgresql/PostgresContext.cs b/back/src/Kyoo.Postgresql/PostgresContext.cs index 4a9e12f7..cea9b215 100644 --- a/back/src/Kyoo.Postgresql/PostgresContext.cs +++ b/back/src/Kyoo.Postgresql/PostgresContext.cs @@ -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;