mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Auto generate jwt secret (#432)
This commit is contained in:
commit
58f0f3d74b
@ -32,9 +32,8 @@ COMPOSE_PROFILES=cpu # cpu (no hardware acceleration) or vaapi or qsv or nvidia
|
||||
GOCODER_PRESET=fast
|
||||
|
||||
|
||||
# The following two values should be set to a random sequence of characters.
|
||||
# You MUST change thoses when installing kyoo (for security)
|
||||
AUTHENTICATION_SECRET="4c@mraGB!KRfF@kpS8739y9FcHemKxBsqqxLbdR?"
|
||||
# The following value should be set to a random sequence of characters.
|
||||
# You MUST change it when installing kyoo (for security)
|
||||
# You can input multiple api keys separated by a ,
|
||||
KYOO_APIKEYS=t7H5!@4iMNsAaSJQ49pat4jprJgTcF656if#J3
|
||||
|
||||
|
@ -1,2 +1,4 @@
|
||||
--project
|
||||
src/Kyoo.Postgresql
|
||||
--msbuildprojectextensionspath
|
||||
out/obj/Kyoo.Postgresql
|
||||
|
@ -18,7 +18,6 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Authentication.Models;
|
||||
@ -36,10 +35,6 @@ public static class AuthenticationModule
|
||||
{
|
||||
public static void ConfigureAuthentication(this WebApplicationBuilder builder)
|
||||
{
|
||||
string secret = builder.Configuration.GetValue(
|
||||
"AUTHENTICATION_SECRET",
|
||||
AuthenticationOption.DefaultSecret
|
||||
)!;
|
||||
PermissionOption options =
|
||||
new()
|
||||
{
|
||||
@ -114,9 +109,9 @@ public static class AuthenticationModule
|
||||
),
|
||||
};
|
||||
builder.Services.AddSingleton(options);
|
||||
builder.Services.AddSingleton(
|
||||
new AuthenticationOption() { Secret = secret, Permissions = options, }
|
||||
);
|
||||
|
||||
byte[] secret = builder.Configuration.GetValue<byte[]>("AUTHENTICATION_SECRET")!;
|
||||
builder.Services.AddSingleton(new AuthenticationOption() { Secret = secret });
|
||||
|
||||
builder
|
||||
.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||
@ -145,7 +140,7 @@ public static class AuthenticationModule
|
||||
ValidateAudience = false,
|
||||
ValidateLifetime = true,
|
||||
ValidateIssuerSigningKey = true,
|
||||
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secret))
|
||||
IssuerSigningKey = new SymmetricSecurityKey(secret)
|
||||
};
|
||||
});
|
||||
|
||||
|
@ -21,7 +21,6 @@ using System.Collections.Generic;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Authentication.Models;
|
||||
@ -29,31 +28,14 @@ using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
namespace Kyoo.Authentication;
|
||||
|
||||
/// <summary>
|
||||
/// The service that controls jwt creation and validation.
|
||||
/// </summary>
|
||||
public class TokenController : ITokenController
|
||||
public class TokenController(AuthenticationOption options) : ITokenController
|
||||
{
|
||||
/// <summary>
|
||||
/// The options that this controller will use.
|
||||
/// </summary>
|
||||
private readonly AuthenticationOption _options;
|
||||
|
||||
/// <summary>
|
||||
/// Create a new <see cref="TokenController"/>.
|
||||
/// </summary>
|
||||
/// <param name="options">The options that this controller will use.</param>
|
||||
public TokenController(AuthenticationOption options)
|
||||
{
|
||||
_options = options;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public string CreateAccessToken(User user, out TimeSpan expireIn)
|
||||
{
|
||||
expireIn = new TimeSpan(1, 0, 0);
|
||||
|
||||
SymmetricSecurityKey key = new(Encoding.UTF8.GetBytes(_options.Secret));
|
||||
SymmetricSecurityKey key = new(options.Secret);
|
||||
SigningCredentials credential = new(key, SecurityAlgorithms.HmacSha256Signature);
|
||||
string permissions =
|
||||
user.Permissions != null ? string.Join(',', user.Permissions) : string.Empty;
|
||||
@ -79,7 +61,7 @@ public class TokenController : ITokenController
|
||||
/// <inheritdoc />
|
||||
public Task<string> CreateRefreshToken(User user)
|
||||
{
|
||||
SymmetricSecurityKey key = new(Encoding.UTF8.GetBytes(_options.Secret));
|
||||
SymmetricSecurityKey key = new(options.Secret);
|
||||
SigningCredentials credential = new(key, SecurityAlgorithms.HmacSha256Signature);
|
||||
JwtSecurityToken token =
|
||||
new(
|
||||
@ -99,7 +81,7 @@ public class TokenController : ITokenController
|
||||
/// <inheritdoc />
|
||||
public Guid GetRefreshTokenUserID(string refreshToken)
|
||||
{
|
||||
SymmetricSecurityKey key = new(Encoding.UTF8.GetBytes(_options.Secret));
|
||||
SymmetricSecurityKey key = new(options.Secret);
|
||||
JwtSecurityTokenHandler tokenHandler = new();
|
||||
ClaimsPrincipal principal;
|
||||
try
|
||||
|
@ -18,28 +18,7 @@
|
||||
|
||||
namespace Kyoo.Authentication.Models;
|
||||
|
||||
/// <summary>
|
||||
/// The main authentication options.
|
||||
/// </summary>
|
||||
public class AuthenticationOption
|
||||
{
|
||||
/// <summary>
|
||||
/// The path to get this option from the root configuration.
|
||||
/// </summary>
|
||||
public const string Path = "authentication";
|
||||
|
||||
/// <summary>
|
||||
/// The default jwt secret.
|
||||
/// </summary>
|
||||
public const string DefaultSecret = "4c@mraGB!KRfF@kpS8739y9FcHemKxBsqqxLbdR?";
|
||||
|
||||
/// <summary>
|
||||
/// The secret used to encrypt the jwt.
|
||||
/// </summary>
|
||||
public string Secret { get; set; } = DefaultSecret;
|
||||
|
||||
/// <summary>
|
||||
/// Options for permissions
|
||||
/// </summary>
|
||||
public PermissionOption Permissions { get; set; } = new();
|
||||
public byte[] Secret { get; set; }
|
||||
}
|
||||
|
@ -17,9 +17,11 @@
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Kyoo.Abstractions.Controllers;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Kyoo.Core.Controllers;
|
||||
using Kyoo.Postgresql;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
|
@ -72,9 +72,11 @@ builder.Host.UseSerilog();
|
||||
|
||||
builder.Services.ConfigureMvc();
|
||||
builder.Services.ConfigureOpenApi();
|
||||
|
||||
// configure postgres first to allow other services to depend on db config
|
||||
builder.ConfigurePostgres();
|
||||
builder.ConfigureKyoo();
|
||||
builder.ConfigureAuthentication();
|
||||
builder.ConfigurePostgres();
|
||||
builder.ConfigureMeilisearch();
|
||||
builder.ConfigureRabbitMq();
|
||||
|
||||
|
@ -67,6 +67,8 @@ public abstract class DatabaseContext : DbContext
|
||||
|
||||
public DbSet<Issue> Issues { get; set; }
|
||||
|
||||
public DbSet<ServerOption> Options { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Add a many to many link between two resources.
|
||||
/// </summary>
|
||||
@ -353,6 +355,8 @@ public abstract class DatabaseContext : DbContext
|
||||
_HasJson<User, string>(modelBuilder, x => x.Settings);
|
||||
_HasJson<User, ExternalToken>(modelBuilder, x => x.ExternalId);
|
||||
_HasJson<Issue, object>(modelBuilder, x => x.Extra);
|
||||
|
||||
modelBuilder.Entity<ServerOption>().HasKey(x => x.Key);
|
||||
}
|
||||
|
||||
public override int SaveChanges()
|
||||
|
28
back/src/Kyoo.Postgresql/DbConfigurationProvider.cs
Normal file
28
back/src/Kyoo.Postgresql/DbConfigurationProvider.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Kyoo.Postgresql;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
|
||||
public class DbConfigurationProvider(Action<DbContextOptionsBuilder> action) : ConfigurationProvider
|
||||
{
|
||||
public override void Load()
|
||||
{
|
||||
DbContextOptionsBuilder<PostgresContext> builder = new();
|
||||
action(builder);
|
||||
using var context = new PostgresContext(builder.Options, null!);
|
||||
Data = context.Options.ToDictionary(c => c.Key, c => c.Value)!;
|
||||
}
|
||||
}
|
||||
|
||||
public class DbConfigurationSource(Action<DbContextOptionsBuilder> action) : IConfigurationSource
|
||||
{
|
||||
public IConfigurationProvider Build(IConfigurationBuilder builder) =>
|
||||
new DbConfigurationProvider(action);
|
||||
}
|
||||
|
||||
public class ServerOption
|
||||
{
|
||||
public string Key { get; set; }
|
||||
public string Value { get; set; }
|
||||
}
|
1395
back/src/Kyoo.Postgresql/Migrations/20240423151632_AddServerOptions.Designer.cs
generated
Normal file
1395
back/src/Kyoo.Postgresql/Migrations/20240423151632_AddServerOptions.Designer.cs
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,43 @@
|
||||
using System;
|
||||
using System.Security.Cryptography;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Kyoo.Postgresql.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class AddServerOptions : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "options",
|
||||
columns: table => new
|
||||
{
|
||||
key = table.Column<string>(type: "text", nullable: false),
|
||||
value = table.Column<string>(type: "text", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("pk_options", x => x.key);
|
||||
}
|
||||
);
|
||||
byte[] secret = new byte[128];
|
||||
using var rng = RandomNumberGenerator.Create();
|
||||
rng.GetBytes(secret);
|
||||
migrationBuilder.InsertData(
|
||||
"options",
|
||||
new[] { "key", "value" },
|
||||
new[] { "AUTHENTICATION_SECRET", Convert.ToBase64String(secret) }
|
||||
);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(name: "options");
|
||||
}
|
||||
}
|
||||
}
|
@ -688,6 +688,23 @@ namespace Kyoo.Postgresql.Migrations
|
||||
b.ToTable("users", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ServerOption", b =>
|
||||
{
|
||||
b.Property<string>("Key")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("key");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("value");
|
||||
|
||||
b.HasKey("Key")
|
||||
.HasName("pk_options");
|
||||
|
||||
b.ToTable("options", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("link_collection_movie", b =>
|
||||
{
|
||||
b.Property<Guid>("collection_id")
|
||||
|
@ -16,6 +16,7 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using System.Data.Common;
|
||||
using Kyoo.Abstractions.Models;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
@ -69,5 +70,14 @@ public static class PostgresModule
|
||||
);
|
||||
|
||||
builder.Services.AddHealthChecks().AddDbContextCheck<DatabaseContext>();
|
||||
builder.Configuration.AddDbConfigurationProvider(x => x.UseNpgsql(dataSource));
|
||||
}
|
||||
|
||||
private static void AddDbConfigurationProvider(
|
||||
this IConfigurationBuilder builder,
|
||||
Action<DbContextOptionsBuilder> action
|
||||
)
|
||||
{
|
||||
builder.Add(new DbConfigurationSource(action));
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user