// Kyoo - A portable and vast media library solution.
// Copyright (c) Kyoo.
//
// See AUTHORS.md and LICENSE file in the project root for full license information.
//
// Kyoo is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// any later version.
//
// Kyoo is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Kyoo. If not, see .
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Autofac;
using Kyoo.Abstractions.Controllers;
using Kyoo.Authentication.Models;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
namespace Kyoo.Authentication
{
///
/// A module that enable OpenID authentication for Kyoo.
///
public class AuthenticationModule : IPlugin
{
///
public string Name => "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;
}
///
public void Configure(ContainerBuilder builder)
{
builder.RegisterType().As().SingleInstance();
builder.RegisterType().As().SingleInstance();
}
///
public void Configure(IServiceCollection services)
{
string secret = _configuration.GetValue(
"AUTHENTICATION_SECRET",
AuthenticationOption.DefaultSecret
)!;
PermissionOption permissions =
new()
{
Default = _configuration
.GetValue("UNLOGGED_PERMISSIONS", "overall.read")!
.Split(','),
NewUser = _configuration
.GetValue("DEFAULT_PERMISSIONS", "overall.read")!
.Split(','),
ApiKeys = _configuration.GetValue("KYOO_APIKEYS", string.Empty)!.Split(','),
};
services.AddSingleton(permissions);
services.AddSingleton(
new AuthenticationOption() { Secret = secret, Permissions = permissions, }
);
// TODO handle direct-videos with bearers (probably add a cookie and a app.Use to translate that for videos)
services
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddJwtBearer(options =>
{
options.Events = new()
{
OnMessageReceived = (ctx) =>
{
ctx.Token ??= ctx.Request.Cookies["X-Bearer"];
return Task.CompletedTask;
}
};
options.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuer = false,
ValidateAudience = false,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret))
};
});
}
///
public IEnumerable ConfigureSteps =>
new IStartupAction[]
{
SA.New(app => app.UseAuthentication(), SA.Authentication),
};
}
}