Starting to rework authentification to use Bearer tokens

This commit is contained in:
Zoe Roux 2020-03-30 07:20:53 +02:00
parent 90cc54446a
commit 77123ad870
18 changed files with 555 additions and 625 deletions

View File

@ -25,8 +25,7 @@ namespace Kyoo.Controllers
using (IServiceScope serviceScope = _serviceProvider.CreateScope()) using (IServiceScope serviceScope = _serviceProvider.CreateScope())
{ {
serviceScope.ServiceProvider.GetService<DatabaseContext>().Database.Migrate();; serviceScope.ServiceProvider.GetService<DatabaseContext>().Database.Migrate();;
serviceScope.ServiceProvider.GetService<PersistedGrantDbContext>().Database.Migrate();
ConfigurationDbContext identityContext = serviceScope.ServiceProvider.GetService<ConfigurationDbContext>(); ConfigurationDbContext identityContext = serviceScope.ServiceProvider.GetService<ConfigurationDbContext>();
identityContext.Database.Migrate(); identityContext.Database.Migrate();
if (!identityContext.Clients.Any()) if (!identityContext.Clients.Any())

View File

@ -18,28 +18,23 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Serilog" Version="2.9.0" />
<PackageReference Include="Serilog.AspNetCore" Version="3.2.0" />
<ProjectReference Include="../Kyoo.Common/Kyoo.Common.csproj" /> <ProjectReference Include="../Kyoo.Common/Kyoo.Common.csproj" />
<PackageReference Include="IdentityServer4" Version="3.1.2" />
<PackageReference Include="IdentityServer4.AspNetIdentity" Version="3.1.2" />
<PackageReference Include="IdentityServer4.EntityFramework" Version="3.1.2" />
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" /> <PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="3.1.2" /> <PackageReference Include="Microsoft.AspNetCore.ApiAuthorization.IdentityServer" Version="3.1.3" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.2" /> <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="3.1.3" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.2" /> <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="3.1.3" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="3.1.2" /> <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.3" />
<PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="3.1.2" /> <PackageReference Include="Microsoft.AspNetCore.SpaServices" Version="3.1.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.2" /> <PackageReference Include="Microsoft.AspNetCore.SpaServices.Extensions" Version="3.1.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="3.1.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.2"> <PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="3.1.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="3.1.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="3.1.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="3.1.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.2" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.1.3" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup> </ItemGroup>
@ -90,10 +85,6 @@
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="Models\DatabaseMigrations\IdentityPeristant" />
<Folder Include="Models\DatabaseMigrations\Internal" />
</ItemGroup>
<Target Name="CreatePluginFolder" AfterTargets="Build"> <Target Name="CreatePluginFolder" AfterTargets="Build">
<MakeDir Directories="$(OutputPath)/plugins" /> <MakeDir Directories="$(OutputPath)/plugins" />

View File

@ -1,17 +1,20 @@
using System; using System;
using System.Linq; using System.Linq;
using IdentityServer4.EntityFramework.Options;
using Kyoo.Models; using Kyoo.Models;
using Microsoft.AspNetCore.ApiAuthorization.IdentityServer;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Microsoft.Extensions.Options;
namespace Kyoo namespace Kyoo
{ {
public class DatabaseContext : IdentityDbContext<User> public class DatabaseContext : ApiAuthorizationDbContext<User>
{ {
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options) { } public DatabaseContext(DbContextOptions<DatabaseContext> options, IOptions<OperationalStoreOptions> operationalStoreOptions)
: base(options, operationalStoreOptions) { }
public DbSet<User> Accounts { get; set; } public DbSet<User> Accounts { get; set; }
@ -66,13 +69,13 @@ namespace Kyoo
modelBuilder.Entity<Show>() modelBuilder.Entity<Show>()
.Ignore(x => x.Genres); .Ignore(x => x.Genres);
modelBuilder.Entity<User>().ToTable("User"); // modelBuilder.Entity<User>().ToTable("User");
modelBuilder.Entity<IdentityUserRole<string>>().ToTable("UserRole"); // modelBuilder.Entity<IdentityUserRole<string>>().ToTable("UserRole");
modelBuilder.Entity<IdentityUserLogin<string>>().ToTable("UserLogin"); // modelBuilder.Entity<IdentityUserLogin<string>>().ToTable("UserLogin");
modelBuilder.Entity<IdentityUserClaim<string>>().ToTable("UserClaim"); // modelBuilder.Entity<IdentityUserClaim<string>>().ToTable("UserClaim");
modelBuilder.Entity<IdentityRole>().ToTable("UserRoles"); // modelBuilder.Entity<IdentityRole>().ToTable("UserRoles");
modelBuilder.Entity<IdentityRoleClaim<string>>().ToTable("UserRoleClaim"); // modelBuilder.Entity<IdentityRoleClaim<string>>().ToTable("UserRoleClaim");
modelBuilder.Entity<IdentityUserToken<string>>().ToTable("UserToken"); // modelBuilder.Entity<IdentityUserToken<string>>().ToTable("UserToken");
} }
} }
} }

View File

@ -6,17 +6,17 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace Kyoo.Models.DatabaseMigrations namespace Kyoo.Models.DatabaseMigrations.IdentityConfiguration
{ {
[DbContext(typeof(ConfigurationDbContext))] [DbContext(typeof(ConfigurationDbContext))]
[Migration("20200303213949_IS_Configuration")] [Migration("20200330032447_Initial")]
partial class IS_Configuration partial class Initial
{ {
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected override void BuildTargetModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasAnnotation("ProductVersion", "3.1.2"); .HasAnnotation("ProductVersion", "3.1.3");
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResource", b => modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResource", b =>
{ {

View File

@ -1,9 +1,9 @@
using System; using System;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
namespace Kyoo.Models.DatabaseMigrations namespace Kyoo.Models.DatabaseMigrations.IdentityConfiguration
{ {
public partial class IS_Configuration : Migration public partial class Initial : Migration
{ {
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {

View File

@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace Kyoo.Models.DatabaseMigrations namespace Kyoo.Models.DatabaseMigrations.IdentityConfiguration
{ {
[DbContext(typeof(ConfigurationDbContext))] [DbContext(typeof(ConfigurationDbContext))]
partial class ConfigurationDbContextModelSnapshot : ModelSnapshot partial class ConfigurationDbContextModelSnapshot : ModelSnapshot
@ -14,7 +14,7 @@ namespace Kyoo.Models.DatabaseMigrations
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasAnnotation("ProductVersion", "3.1.2"); .HasAnnotation("ProductVersion", "3.1.3");
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResource", b => modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResource", b =>
{ {

View File

@ -1,105 +0,0 @@
// <auto-generated />
using System;
using IdentityServer4.EntityFramework.DbContexts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace Kyoo.Models.DatabaseMigrations.IdentityPeristant
{
[DbContext(typeof(PersistedGrantDbContext))]
[Migration("20200303214150_IS_Configuration")]
partial class IS_Configuration
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.1.2");
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.DeviceFlowCodes", b =>
{
b.Property<string>("UserCode")
.HasColumnType("TEXT")
.HasMaxLength(200);
b.Property<string>("ClientId")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(200);
b.Property<DateTime>("CreationTime")
.HasColumnType("TEXT");
b.Property<string>("Data")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(50000);
b.Property<string>("DeviceCode")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(200);
b.Property<DateTime?>("Expiration")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("SubjectId")
.HasColumnType("TEXT")
.HasMaxLength(200);
b.HasKey("UserCode");
b.HasIndex("DeviceCode")
.IsUnique();
b.HasIndex("Expiration");
b.ToTable("DeviceCodes");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.PersistedGrant", b =>
{
b.Property<string>("Key")
.HasColumnType("TEXT")
.HasMaxLength(200);
b.Property<string>("ClientId")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(200);
b.Property<DateTime>("CreationTime")
.HasColumnType("TEXT");
b.Property<string>("Data")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(50000);
b.Property<DateTime?>("Expiration")
.HasColumnType("TEXT");
b.Property<string>("SubjectId")
.HasColumnType("TEXT")
.HasMaxLength(200);
b.Property<string>("Type")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(50);
b.HasKey("Key");
b.HasIndex("Expiration");
b.HasIndex("SubjectId", "ClientId", "Type");
b.ToTable("PersistedGrants");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -1,75 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Kyoo.Models.DatabaseMigrations.IdentityPeristant
{
public partial class IS_Configuration : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "DeviceCodes",
columns: table => new
{
UserCode = table.Column<string>(maxLength: 200, nullable: false),
DeviceCode = table.Column<string>(maxLength: 200, nullable: false),
SubjectId = table.Column<string>(maxLength: 200, nullable: true),
ClientId = table.Column<string>(maxLength: 200, nullable: false),
CreationTime = table.Column<DateTime>(nullable: false),
Expiration = table.Column<DateTime>(nullable: false),
Data = table.Column<string>(maxLength: 50000, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_DeviceCodes", x => x.UserCode);
});
migrationBuilder.CreateTable(
name: "PersistedGrants",
columns: table => new
{
Key = table.Column<string>(maxLength: 200, nullable: false),
Type = table.Column<string>(maxLength: 50, nullable: false),
SubjectId = table.Column<string>(maxLength: 200, nullable: true),
ClientId = table.Column<string>(maxLength: 200, nullable: false),
CreationTime = table.Column<DateTime>(nullable: false),
Expiration = table.Column<DateTime>(nullable: true),
Data = table.Column<string>(maxLength: 50000, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_PersistedGrants", x => x.Key);
});
migrationBuilder.CreateIndex(
name: "IX_DeviceCodes_DeviceCode",
table: "DeviceCodes",
column: "DeviceCode",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_DeviceCodes_Expiration",
table: "DeviceCodes",
column: "Expiration");
migrationBuilder.CreateIndex(
name: "IX_PersistedGrants_Expiration",
table: "PersistedGrants",
column: "Expiration");
migrationBuilder.CreateIndex(
name: "IX_PersistedGrants_SubjectId_ClientId_Type",
table: "PersistedGrants",
columns: new[] { "SubjectId", "ClientId", "Type" });
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "DeviceCodes");
migrationBuilder.DropTable(
name: "PersistedGrants");
}
}
}

View File

@ -1,103 +0,0 @@
// <auto-generated />
using System;
using IdentityServer4.EntityFramework.DbContexts;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace Kyoo.Models.DatabaseMigrations.IdentityPeristant
{
[DbContext(typeof(PersistedGrantDbContext))]
partial class PersistedGrantDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "3.1.2");
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.DeviceFlowCodes", b =>
{
b.Property<string>("UserCode")
.HasColumnType("TEXT")
.HasMaxLength(200);
b.Property<string>("ClientId")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(200);
b.Property<DateTime>("CreationTime")
.HasColumnType("TEXT");
b.Property<string>("Data")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(50000);
b.Property<string>("DeviceCode")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(200);
b.Property<DateTime?>("Expiration")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("SubjectId")
.HasColumnType("TEXT")
.HasMaxLength(200);
b.HasKey("UserCode");
b.HasIndex("DeviceCode")
.IsUnique();
b.HasIndex("Expiration");
b.ToTable("DeviceCodes");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.PersistedGrant", b =>
{
b.Property<string>("Key")
.HasColumnType("TEXT")
.HasMaxLength(200);
b.Property<string>("ClientId")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(200);
b.Property<DateTime>("CreationTime")
.HasColumnType("TEXT");
b.Property<string>("Data")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(50000);
b.Property<DateTime?>("Expiration")
.HasColumnType("TEXT");
b.Property<string>("SubjectId")
.HasColumnType("TEXT")
.HasMaxLength(200);
b.Property<string>("Type")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(50);
b.HasKey("Key");
b.HasIndex("Expiration");
b.HasIndex("SubjectId", "ClientId", "Type");
b.ToTable("PersistedGrants");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -6,17 +6,99 @@ using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace Kyoo.Models.DatabaseMigrations.Internal namespace Kyoo.Models.DatabaseMigrations
{ {
[DbContext(typeof(DatabaseContext))] [DbContext(typeof(DatabaseContext))]
[Migration("20200316003155_Initial")] [Migration("20200330024910_Initial")]
partial class Initial partial class Initial
{ {
protected override void BuildTargetModel(ModelBuilder modelBuilder) protected override void BuildTargetModel(ModelBuilder modelBuilder)
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasAnnotation("ProductVersion", "3.1.2"); .HasAnnotation("ProductVersion", "3.1.3");
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.DeviceFlowCodes", b =>
{
b.Property<string>("UserCode")
.HasColumnType("TEXT")
.HasMaxLength(200);
b.Property<string>("ClientId")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(200);
b.Property<DateTime>("CreationTime")
.HasColumnType("TEXT");
b.Property<string>("Data")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(50000);
b.Property<string>("DeviceCode")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(200);
b.Property<DateTime?>("Expiration")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("SubjectId")
.HasColumnType("TEXT")
.HasMaxLength(200);
b.HasKey("UserCode");
b.HasIndex("DeviceCode")
.IsUnique();
b.HasIndex("Expiration");
b.ToTable("DeviceCodes");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.PersistedGrant", b =>
{
b.Property<string>("Key")
.HasColumnType("TEXT")
.HasMaxLength(200);
b.Property<string>("ClientId")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(200);
b.Property<DateTime>("CreationTime")
.HasColumnType("TEXT");
b.Property<string>("Data")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(50000);
b.Property<DateTime?>("Expiration")
.HasColumnType("TEXT");
b.Property<string>("SubjectId")
.HasColumnType("TEXT")
.HasMaxLength(200);
b.Property<string>("Type")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(50);
b.HasKey("Key");
b.HasIndex("Expiration");
b.HasIndex("SubjectId", "ClientId", "Type");
b.ToTable("PersistedGrants");
});
modelBuilder.Entity("Kyoo.Models.Collection", b => modelBuilder.Entity("Kyoo.Models.Collection", b =>
{ {
@ -462,7 +544,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
.IsUnique() .IsUnique()
.HasName("UserNameIndex"); .HasName("UserNameIndex");
b.ToTable("User"); b.ToTable("AspNetUsers");
}); });
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
@ -488,7 +570,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
.IsUnique() .IsUnique()
.HasName("RoleNameIndex"); .HasName("RoleNameIndex");
b.ToTable("UserRoles"); b.ToTable("AspNetRoles");
}); });
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
@ -511,7 +593,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
b.HasIndex("RoleId"); b.HasIndex("RoleId");
b.ToTable("UserRoleClaim"); b.ToTable("AspNetRoleClaims");
}); });
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
@ -534,16 +616,18 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
b.HasIndex("UserId"); b.HasIndex("UserId");
b.ToTable("UserClaim"); b.ToTable("AspNetUserClaims");
}); });
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{ {
b.Property<string>("LoginProvider") b.Property<string>("LoginProvider")
.HasColumnType("TEXT"); .HasColumnType("TEXT")
.HasMaxLength(128);
b.Property<string>("ProviderKey") b.Property<string>("ProviderKey")
.HasColumnType("TEXT"); .HasColumnType("TEXT")
.HasMaxLength(128);
b.Property<string>("ProviderDisplayName") b.Property<string>("ProviderDisplayName")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
@ -556,7 +640,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
b.HasIndex("UserId"); b.HasIndex("UserId");
b.ToTable("UserLogin"); b.ToTable("AspNetUserLogins");
}); });
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
@ -571,7 +655,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
b.HasIndex("RoleId"); b.HasIndex("RoleId");
b.ToTable("UserRole"); b.ToTable("AspNetUserRoles");
}); });
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
@ -580,17 +664,19 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<string>("LoginProvider") b.Property<string>("LoginProvider")
.HasColumnType("TEXT"); .HasColumnType("TEXT")
.HasMaxLength(128);
b.Property<string>("Name") b.Property<string>("Name")
.HasColumnType("TEXT"); .HasColumnType("TEXT")
.HasMaxLength(128);
b.Property<string>("Value") b.Property<string>("Value")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.HasKey("UserId", "LoginProvider", "Name"); b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("UserToken"); b.ToTable("AspNetUserTokens");
}); });
modelBuilder.Entity("Kyoo.Models.CollectionLink", b => modelBuilder.Entity("Kyoo.Models.CollectionLink", b =>

View File

@ -1,12 +1,53 @@
using System; using System;
using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Migrations;
namespace Kyoo.Models.DatabaseMigrations.Internal namespace Kyoo.Models.DatabaseMigrations
{ {
public partial class Initial : Migration public partial class Initial : Migration
{ {
protected override void Up(MigrationBuilder migrationBuilder) protected override void Up(MigrationBuilder migrationBuilder)
{ {
migrationBuilder.CreateTable(
name: "AspNetRoles",
columns: table => new
{
Id = table.Column<string>(nullable: false),
Name = table.Column<string>(maxLength: 256, nullable: true),
NormalizedName = table.Column<string>(maxLength: 256, nullable: true),
ConcurrencyStamp = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetRoles", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AspNetUsers",
columns: table => new
{
Id = table.Column<string>(nullable: false),
UserName = table.Column<string>(maxLength: 256, nullable: true),
NormalizedUserName = table.Column<string>(maxLength: 256, nullable: true),
Email = table.Column<string>(maxLength: 256, nullable: true),
NormalizedEmail = table.Column<string>(maxLength: 256, nullable: true),
EmailConfirmed = table.Column<bool>(nullable: false),
PasswordHash = table.Column<string>(nullable: true),
SecurityStamp = table.Column<string>(nullable: true),
ConcurrencyStamp = table.Column<string>(nullable: true),
PhoneNumber = table.Column<string>(nullable: true),
PhoneNumberConfirmed = table.Column<bool>(nullable: false),
TwoFactorEnabled = table.Column<bool>(nullable: false),
LockoutEnd = table.Column<DateTimeOffset>(nullable: true),
LockoutEnabled = table.Column<bool>(nullable: false),
AccessFailedCount = table.Column<int>(nullable: false),
OTAC = table.Column<string>(nullable: true),
OTACExpires = table.Column<DateTime>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUsers", x => x.Id);
});
migrationBuilder.CreateTable( migrationBuilder.CreateTable(
name: "Collections", name: "Collections",
columns: table => new columns: table => new
@ -24,6 +65,23 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
table.PrimaryKey("PK_Collections", x => x.ID); table.PrimaryKey("PK_Collections", x => x.ID);
}); });
migrationBuilder.CreateTable(
name: "DeviceCodes",
columns: table => new
{
UserCode = table.Column<string>(maxLength: 200, nullable: false),
DeviceCode = table.Column<string>(maxLength: 200, nullable: false),
SubjectId = table.Column<string>(maxLength: 200, nullable: true),
ClientId = table.Column<string>(maxLength: 200, nullable: false),
CreationTime = table.Column<DateTime>(nullable: false),
Expiration = table.Column<DateTime>(nullable: false),
Data = table.Column<string>(maxLength: 50000, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_DeviceCodes", x => x.UserCode);
});
migrationBuilder.CreateTable( migrationBuilder.CreateTable(
name: "Genres", name: "Genres",
columns: table => new columns: table => new
@ -68,6 +126,23 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
table.PrimaryKey("PK_Peoples", x => x.Slug); table.PrimaryKey("PK_Peoples", x => x.Slug);
}); });
migrationBuilder.CreateTable(
name: "PersistedGrants",
columns: table => new
{
Key = table.Column<string>(maxLength: 200, nullable: false),
Type = table.Column<string>(maxLength: 50, nullable: false),
SubjectId = table.Column<string>(maxLength: 200, nullable: true),
ClientId = table.Column<string>(maxLength: 200, nullable: false),
CreationTime = table.Column<DateTime>(nullable: false),
Expiration = table.Column<DateTime>(nullable: true),
Data = table.Column<string>(maxLength: 50000, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_PersistedGrants", x => x.Key);
});
migrationBuilder.CreateTable( migrationBuilder.CreateTable(
name: "Studios", name: "Studios",
columns: table => new columns: table => new
@ -83,44 +158,109 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
}); });
migrationBuilder.CreateTable( migrationBuilder.CreateTable(
name: "User", name: "AspNetRoleClaims",
columns: table => new columns: table => new
{ {
Id = table.Column<string>(nullable: false), Id = table.Column<int>(nullable: false)
UserName = table.Column<string>(maxLength: 256, nullable: true), .Annotation("Sqlite:Autoincrement", true),
NormalizedUserName = table.Column<string>(maxLength: 256, nullable: true), RoleId = table.Column<string>(nullable: false),
Email = table.Column<string>(maxLength: 256, nullable: true), ClaimType = table.Column<string>(nullable: true),
NormalizedEmail = table.Column<string>(maxLength: 256, nullable: true), ClaimValue = table.Column<string>(nullable: true)
EmailConfirmed = table.Column<bool>(nullable: false),
PasswordHash = table.Column<string>(nullable: true),
SecurityStamp = table.Column<string>(nullable: true),
ConcurrencyStamp = table.Column<string>(nullable: true),
PhoneNumber = table.Column<string>(nullable: true),
PhoneNumberConfirmed = table.Column<bool>(nullable: false),
TwoFactorEnabled = table.Column<bool>(nullable: false),
LockoutEnd = table.Column<DateTimeOffset>(nullable: true),
LockoutEnabled = table.Column<bool>(nullable: false),
AccessFailedCount = table.Column<int>(nullable: false),
OTAC = table.Column<string>(nullable: true),
OTACExpires = table.Column<DateTime>(nullable: true)
}, },
constraints: table => constraints: table =>
{ {
table.PrimaryKey("PK_User", x => x.Id); table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
table.ForeignKey(
name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
column: x => x.RoleId,
principalTable: "AspNetRoles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}); });
migrationBuilder.CreateTable( migrationBuilder.CreateTable(
name: "UserRoles", name: "AspNetUserClaims",
columns: table => new columns: table => new
{ {
Id = table.Column<string>(nullable: false), Id = table.Column<int>(nullable: false)
Name = table.Column<string>(maxLength: 256, nullable: true), .Annotation("Sqlite:Autoincrement", true),
NormalizedName = table.Column<string>(maxLength: 256, nullable: true), UserId = table.Column<string>(nullable: false),
ConcurrencyStamp = table.Column<string>(nullable: true) ClaimType = table.Column<string>(nullable: true),
ClaimValue = table.Column<string>(nullable: true)
}, },
constraints: table => constraints: table =>
{ {
table.PrimaryKey("PK_UserRoles", x => x.Id); table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
table.ForeignKey(
name: "FK_AspNetUserClaims_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserLogins",
columns: table => new
{
LoginProvider = table.Column<string>(maxLength: 128, nullable: false),
ProviderKey = table.Column<string>(maxLength: 128, nullable: false),
ProviderDisplayName = table.Column<string>(nullable: true),
UserId = table.Column<string>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
table.ForeignKey(
name: "FK_AspNetUserLogins_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserRoles",
columns: table => new
{
UserId = table.Column<string>(nullable: false),
RoleId = table.Column<string>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
table.ForeignKey(
name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
column: x => x.RoleId,
principalTable: "AspNetRoles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_AspNetUserRoles_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserTokens",
columns: table => new
{
UserId = table.Column<string>(nullable: false),
LoginProvider = table.Column<string>(maxLength: 128, nullable: false),
Name = table.Column<string>(maxLength: 128, nullable: false),
Value = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
table.ForeignKey(
name: "FK_AspNetUserTokens_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
}); });
migrationBuilder.CreateTable( migrationBuilder.CreateTable(
@ -157,112 +297,6 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
onDelete: ReferentialAction.Restrict); onDelete: ReferentialAction.Restrict);
}); });
migrationBuilder.CreateTable(
name: "UserClaim",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
UserId = table.Column<string>(nullable: false),
ClaimType = table.Column<string>(nullable: true),
ClaimValue = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_UserClaim", x => x.Id);
table.ForeignKey(
name: "FK_UserClaim_User_UserId",
column: x => x.UserId,
principalTable: "User",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "UserLogin",
columns: table => new
{
LoginProvider = table.Column<string>(nullable: false),
ProviderKey = table.Column<string>(nullable: false),
ProviderDisplayName = table.Column<string>(nullable: true),
UserId = table.Column<string>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_UserLogin", x => new { x.LoginProvider, x.ProviderKey });
table.ForeignKey(
name: "FK_UserLogin_User_UserId",
column: x => x.UserId,
principalTable: "User",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "UserToken",
columns: table => new
{
UserId = table.Column<string>(nullable: false),
LoginProvider = table.Column<string>(nullable: false),
Name = table.Column<string>(nullable: false),
Value = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_UserToken", x => new { x.UserId, x.LoginProvider, x.Name });
table.ForeignKey(
name: "FK_UserToken_User_UserId",
column: x => x.UserId,
principalTable: "User",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "UserRole",
columns: table => new
{
UserId = table.Column<string>(nullable: false),
RoleId = table.Column<string>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_UserRole", x => new { x.UserId, x.RoleId });
table.ForeignKey(
name: "FK_UserRole_UserRoles_RoleId",
column: x => x.RoleId,
principalTable: "UserRoles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_UserRole_User_UserId",
column: x => x.UserId,
principalTable: "User",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "UserRoleClaim",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
RoleId = table.Column<string>(nullable: false),
ClaimType = table.Column<string>(nullable: true),
ClaimValue = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_UserRoleClaim", x => x.Id);
table.ForeignKey(
name: "FK_UserRoleClaim_UserRoles_RoleId",
column: x => x.RoleId,
principalTable: "UserRoles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable( migrationBuilder.CreateTable(
name: "CollectionLinks", name: "CollectionLinks",
columns: table => new columns: table => new
@ -462,6 +496,43 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
onDelete: ReferentialAction.Cascade); onDelete: ReferentialAction.Cascade);
}); });
migrationBuilder.CreateIndex(
name: "IX_AspNetRoleClaims_RoleId",
table: "AspNetRoleClaims",
column: "RoleId");
migrationBuilder.CreateIndex(
name: "RoleNameIndex",
table: "AspNetRoles",
column: "NormalizedName",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_AspNetUserClaims_UserId",
table: "AspNetUserClaims",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_AspNetUserLogins_UserId",
table: "AspNetUserLogins",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_AspNetUserRoles_RoleId",
table: "AspNetUserRoles",
column: "RoleId");
migrationBuilder.CreateIndex(
name: "EmailIndex",
table: "AspNetUsers",
column: "NormalizedEmail");
migrationBuilder.CreateIndex(
name: "UserNameIndex",
table: "AspNetUsers",
column: "NormalizedUserName",
unique: true);
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_CollectionLinks_CollectionID", name: "IX_CollectionLinks_CollectionID",
table: "CollectionLinks", table: "CollectionLinks",
@ -472,6 +543,17 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
table: "CollectionLinks", table: "CollectionLinks",
column: "ShowID"); column: "ShowID");
migrationBuilder.CreateIndex(
name: "IX_DeviceCodes_DeviceCode",
table: "DeviceCodes",
column: "DeviceCode",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_DeviceCodes_Expiration",
table: "DeviceCodes",
column: "Expiration");
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_Episodes_SeasonID", name: "IX_Episodes_SeasonID",
table: "Episodes", table: "Episodes",
@ -512,6 +594,16 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
table: "PeopleLinks", table: "PeopleLinks",
column: "ShowID"); column: "ShowID");
migrationBuilder.CreateIndex(
name: "IX_PersistedGrants_Expiration",
table: "PersistedGrants",
column: "Expiration");
migrationBuilder.CreateIndex(
name: "IX_PersistedGrants_SubjectId_ClientId_Type",
table: "PersistedGrants",
columns: new[] { "SubjectId", "ClientId", "Type" });
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_Seasons_ShowID", name: "IX_Seasons_ShowID",
table: "Seasons", table: "Seasons",
@ -526,50 +618,31 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
name: "IX_Tracks_EpisodeID", name: "IX_Tracks_EpisodeID",
table: "Tracks", table: "Tracks",
column: "EpisodeID"); column: "EpisodeID");
migrationBuilder.CreateIndex(
name: "EmailIndex",
table: "User",
column: "NormalizedEmail");
migrationBuilder.CreateIndex(
name: "UserNameIndex",
table: "User",
column: "NormalizedUserName",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_UserClaim_UserId",
table: "UserClaim",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_UserLogin_UserId",
table: "UserLogin",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_UserRole_RoleId",
table: "UserRole",
column: "RoleId");
migrationBuilder.CreateIndex(
name: "IX_UserRoleClaim_RoleId",
table: "UserRoleClaim",
column: "RoleId");
migrationBuilder.CreateIndex(
name: "RoleNameIndex",
table: "UserRoles",
column: "NormalizedName",
unique: true);
} }
protected override void Down(MigrationBuilder migrationBuilder) protected override void Down(MigrationBuilder migrationBuilder)
{ {
migrationBuilder.DropTable(
name: "AspNetRoleClaims");
migrationBuilder.DropTable(
name: "AspNetUserClaims");
migrationBuilder.DropTable(
name: "AspNetUserLogins");
migrationBuilder.DropTable(
name: "AspNetUserRoles");
migrationBuilder.DropTable(
name: "AspNetUserTokens");
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "CollectionLinks"); name: "CollectionLinks");
migrationBuilder.DropTable(
name: "DeviceCodes");
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "GenreLinks"); name: "GenreLinks");
@ -579,23 +652,17 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "PeopleLinks"); name: "PeopleLinks");
migrationBuilder.DropTable(
name: "PersistedGrants");
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "Tracks"); name: "Tracks");
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "UserClaim"); name: "AspNetRoles");
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "UserLogin"); name: "AspNetUsers");
migrationBuilder.DropTable(
name: "UserRole");
migrationBuilder.DropTable(
name: "UserRoleClaim");
migrationBuilder.DropTable(
name: "UserToken");
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "Genres"); name: "Genres");
@ -612,12 +679,6 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "Episodes"); name: "Episodes");
migrationBuilder.DropTable(
name: "UserRoles");
migrationBuilder.DropTable(
name: "User");
migrationBuilder.DropTable( migrationBuilder.DropTable(
name: "Seasons"); name: "Seasons");

View File

@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace Kyoo.Models.DatabaseMigrations.Internal namespace Kyoo.Models.DatabaseMigrations
{ {
[DbContext(typeof(DatabaseContext))] [DbContext(typeof(DatabaseContext))]
partial class DatabaseContextModelSnapshot : ModelSnapshot partial class DatabaseContextModelSnapshot : ModelSnapshot
@ -14,7 +14,89 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
{ {
#pragma warning disable 612, 618 #pragma warning disable 612, 618
modelBuilder modelBuilder
.HasAnnotation("ProductVersion", "3.1.2"); .HasAnnotation("ProductVersion", "3.1.3");
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.DeviceFlowCodes", b =>
{
b.Property<string>("UserCode")
.HasColumnType("TEXT")
.HasMaxLength(200);
b.Property<string>("ClientId")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(200);
b.Property<DateTime>("CreationTime")
.HasColumnType("TEXT");
b.Property<string>("Data")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(50000);
b.Property<string>("DeviceCode")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(200);
b.Property<DateTime?>("Expiration")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("SubjectId")
.HasColumnType("TEXT")
.HasMaxLength(200);
b.HasKey("UserCode");
b.HasIndex("DeviceCode")
.IsUnique();
b.HasIndex("Expiration");
b.ToTable("DeviceCodes");
});
modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.PersistedGrant", b =>
{
b.Property<string>("Key")
.HasColumnType("TEXT")
.HasMaxLength(200);
b.Property<string>("ClientId")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(200);
b.Property<DateTime>("CreationTime")
.HasColumnType("TEXT");
b.Property<string>("Data")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(50000);
b.Property<DateTime?>("Expiration")
.HasColumnType("TEXT");
b.Property<string>("SubjectId")
.HasColumnType("TEXT")
.HasMaxLength(200);
b.Property<string>("Type")
.IsRequired()
.HasColumnType("TEXT")
.HasMaxLength(50);
b.HasKey("Key");
b.HasIndex("Expiration");
b.HasIndex("SubjectId", "ClientId", "Type");
b.ToTable("PersistedGrants");
});
modelBuilder.Entity("Kyoo.Models.Collection", b => modelBuilder.Entity("Kyoo.Models.Collection", b =>
{ {
@ -460,7 +542,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
.IsUnique() .IsUnique()
.HasName("UserNameIndex"); .HasName("UserNameIndex");
b.ToTable("User"); b.ToTable("AspNetUsers");
}); });
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
@ -486,7 +568,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
.IsUnique() .IsUnique()
.HasName("RoleNameIndex"); .HasName("RoleNameIndex");
b.ToTable("UserRoles"); b.ToTable("AspNetRoles");
}); });
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
@ -509,7 +591,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
b.HasIndex("RoleId"); b.HasIndex("RoleId");
b.ToTable("UserRoleClaim"); b.ToTable("AspNetRoleClaims");
}); });
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
@ -532,16 +614,18 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
b.HasIndex("UserId"); b.HasIndex("UserId");
b.ToTable("UserClaim"); b.ToTable("AspNetUserClaims");
}); });
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{ {
b.Property<string>("LoginProvider") b.Property<string>("LoginProvider")
.HasColumnType("TEXT"); .HasColumnType("TEXT")
.HasMaxLength(128);
b.Property<string>("ProviderKey") b.Property<string>("ProviderKey")
.HasColumnType("TEXT"); .HasColumnType("TEXT")
.HasMaxLength(128);
b.Property<string>("ProviderDisplayName") b.Property<string>("ProviderDisplayName")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
@ -554,7 +638,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
b.HasIndex("UserId"); b.HasIndex("UserId");
b.ToTable("UserLogin"); b.ToTable("AspNetUserLogins");
}); });
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
@ -569,7 +653,7 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
b.HasIndex("RoleId"); b.HasIndex("RoleId");
b.ToTable("UserRole"); b.ToTable("AspNetUserRoles");
}); });
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b => modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
@ -578,17 +662,19 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.Property<string>("LoginProvider") b.Property<string>("LoginProvider")
.HasColumnType("TEXT"); .HasColumnType("TEXT")
.HasMaxLength(128);
b.Property<string>("Name") b.Property<string>("Name")
.HasColumnType("TEXT"); .HasColumnType("TEXT")
.HasMaxLength(128);
b.Property<string>("Value") b.Property<string>("Value")
.HasColumnType("TEXT"); .HasColumnType("TEXT");
b.HasKey("UserId", "LoginProvider", "Name"); b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("UserToken"); b.ToTable("AspNetUserTokens");
}); });
modelBuilder.Entity("Kyoo.Models.CollectionLink", b => modelBuilder.Entity("Kyoo.Models.CollectionLink", b =>

View File

@ -1,12 +1,7 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Kyoo.Controllers;
using Microsoft.AspNetCore; using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Serilog;
using Serilog.Events;
using Serilog.Sinks.SystemConsole.Themes;
namespace Kyoo namespace Kyoo
{ {
@ -14,25 +9,12 @@ namespace Kyoo
{ {
public static async Task Main(string[] args) public static async Task Main(string[] args)
{ {
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Verbose()
.MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
.MinimumLevel.Override("System", LogEventLevel.Warning)
.MinimumLevel.Override("Microsoft.AspNetCore.Authentication", LogEventLevel.Information)
.Enrich.FromLogContext()
.WriteTo.Console(
outputTemplate:
"[{Timestamp:HH:mm:ss} {Level}] {SourceContext}{NewLine}{Message:lj}{NewLine}{Exception}{NewLine}",
theme: AnsiConsoleTheme.Literate)
.CreateLogger();
Console.WriteLine($"Running as: {Environment.UserName}"); Console.WriteLine($"Running as: {Environment.UserName}");
await CreateWebHostBuilder(args).Build().RunAsync(); await CreateWebHostBuilder(args).Build().RunAsync();
} }
public static IWebHostBuilder CreateWebHostBuilder(string[] args) => public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args) WebHost.CreateDefaultBuilder(args)
.UseSerilog()
.UseKestrel((config) => { config.AddServerHeader = false; }) .UseKestrel((config) => { config.AddServerHeader = false; })
.UseUrls("http://*:5000") .UseUrls("http://*:5000")
.UseStartup<Startup>(); .UseStartup<Startup>();

View File

@ -1,14 +1,10 @@
using System;
using System.Net;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks;
using Kyoo.Api; using Kyoo.Api;
using Kyoo.Controllers; using Kyoo.Controllers;
using Kyoo.Models; using Kyoo.Models;
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.SpaServices.AngularCli; using Microsoft.AspNetCore.SpaServices.AngularCli;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@ -30,29 +26,27 @@ namespace Kyoo
// This method gets called by the runtime. Use this method to add services to the container. // This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services) public void ConfigureServices(IServiceCollection services)
{ {
services.Configure<CookiePolicyOptions>(options => // services.AddSpaStaticFiles(configuration =>
// {
// configuration.RootPath = "wwwroot";
// });
//
// services.AddControllers().AddNewtonsoftJson();
// services.AddHttpClient();
//
// string publicUrl = Configuration.GetValue<string>("public_url");
//
services.AddDbContext<DatabaseContext>(options =>
{ {
options.MinimumSameSitePolicy = SameSiteMode.Lax; options.UseLazyLoadingProxies()
.UseSqlite(Configuration.GetConnectionString("Database"));
}); });
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "wwwroot";
});
services.AddControllers().AddNewtonsoftJson();
services.AddHttpClient();
string assemblyName = typeof(Startup).GetTypeInfo().Assembly.GetName().Name; string assemblyName = typeof(Startup).GetTypeInfo().Assembly.GetName().Name;
string publicUrl = Configuration.GetValue<string>("public_url"); string publicUrl = Configuration.GetValue<string>("public_url");
services.AddDbContext<DatabaseContext>(options => options.UseLazyLoadingProxies()
.UseSqlite(Configuration.GetConnectionString("Database")));
services.AddIdentity<User, IdentityRole>() services.AddDefaultIdentity<User>()
.AddEntityFrameworkStores<DatabaseContext>() .AddEntityFrameworkStores<DatabaseContext>();
.AddDefaultTokenProviders();
services.AddIdentityServer(options => services.AddIdentityServer(options =>
{ {
@ -60,6 +54,8 @@ namespace Kyoo
options.UserInteraction.ErrorUrl = publicUrl + "error"; options.UserInteraction.ErrorUrl = publicUrl + "error";
options.UserInteraction.LogoutUrl = publicUrl + "logout"; options.UserInteraction.LogoutUrl = publicUrl + "logout";
}) })
.AddAspNetIdentity<User>()
.AddSigningCredentials()
.AddConfigurationStore(options => .AddConfigurationStore(options =>
{ {
options.ConfigureDbContext = builder => options.ConfigureDbContext = builder =>
@ -75,32 +71,34 @@ namespace Kyoo
}) })
.AddInMemoryIdentityResources(IdentityContext.GetIdentityResources()) .AddInMemoryIdentityResources(IdentityContext.GetIdentityResources())
.AddInMemoryApiResources(IdentityContext.GetApis()) .AddInMemoryApiResources(IdentityContext.GetApis())
.AddAspNetIdentity<User>()
.AddProfileService<AccountController>() .AddProfileService<AccountController>()
.AddDeveloperSigningCredential(); // TODO remove the developer signin .AddDeveloperSigningCredential(); // TODO remove the developer signin
services.AddAuthentication()
.AddIdentityServerJwt();
// services.ConfigureApplicationCookie(options =>
// {
// options.Events.OnRedirectToAccessDenied = context =>
// {
// context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
// return Task.CompletedTask;
// };
// options.Events.OnRedirectToLogin = context =>
// {
// context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
// return Task.CompletedTask;
// };
// });
services.ConfigureApplicationCookie(options => // services.AddAuthorization(options =>
{ // {
options.Events.OnRedirectToAccessDenied = context => // options.AddPolicy("Read", policy => policy.RequireClaim("read"));
{ // options.AddPolicy("Write", policy => policy.RequireClaim("write"));
context.Response.StatusCode = (int)HttpStatusCode.Forbidden; // options.AddPolicy("Play", policy => policy.RequireClaim("play"));
return Task.CompletedTask; // options.AddPolicy("Download", policy => policy.RequireClaim("download"));
}; // options.AddPolicy("Admin", policy => policy.RequireClaim("admin"));
options.Events.OnRedirectToLogin = context => // });
{
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
return Task.CompletedTask;
};
});
services.AddAuthorization(options =>
{
options.AddPolicy("Read", policy => policy.RequireClaim("read"));
options.AddPolicy("Write", policy => policy.RequireClaim("write"));
options.AddPolicy("Play", policy => policy.RequireClaim("play"));
options.AddPolicy("Download", policy => policy.RequireClaim("download"));
options.AddPolicy("Admin", policy => policy.RequireClaim("admin"));
});
services.AddScoped<ILibraryManager, LibraryManager>(); services.AddScoped<ILibraryManager, LibraryManager>();
services.AddScoped<ICrawler, Crawler>(); services.AddScoped<ICrawler, Crawler>();
@ -125,20 +123,18 @@ namespace Kyoo
app.UseHsts(); app.UseHsts();
} }
app.Use((ctx, next) => // app.Use((ctx, next) =>
{ // {
ctx.Response.Headers.Remove("X-Powered-By"); // ctx.Response.Headers.Remove("X-Powered-By");
ctx.Response.Headers.Remove("Server"); // ctx.Response.Headers.Remove("Server");
ctx.Response.Headers.Add("Feature-Policy", "autoplay 'self'; fullscreen"); // ctx.Response.Headers.Add("Feature-Policy", "autoplay 'self'; fullscreen");
ctx.Response.Headers.Add("Content-Security-Policy", "default-src 'self' data: blob:; script-src 'self' 'unsafe-inline' 'unsafe-eval' data: blob:; style-src 'self' 'unsafe-inline'"); // ctx.Response.Headers.Add("Content-Security-Policy", "default-src 'self' data: blob:; script-src 'self' 'unsafe-inline' 'unsafe-eval' data: blob:; style-src 'self' 'unsafe-inline'");
ctx.Response.Headers.Add("X-Frame-Options", "SAMEORIGIN"); // ctx.Response.Headers.Add("X-Frame-Options", "SAMEORIGIN");
ctx.Response.Headers.Add("Referrer-Policy", "no-referrer"); // ctx.Response.Headers.Add("Referrer-Policy", "no-referrer");
ctx.Response.Headers.Add("Access-Control-Allow-Origin", "null"); // ctx.Response.Headers.Add("Access-Control-Allow-Origin", "null");
ctx.Response.Headers.Add("X-Content-Type-Options", "nosniff"); // ctx.Response.Headers.Add("X-Content-Type-Options", "nosniff");
return next(); // return next();
}); // });
app.UseCookiePolicy();
app.UseStaticFiles(); app.UseStaticFiles();
if (!env.IsDevelopment()) if (!env.IsDevelopment())
@ -146,12 +142,13 @@ namespace Kyoo
app.UseRouting(); app.UseRouting();
app.UseAuthentication();
app.UseIdentityServer(); app.UseIdentityServer();
app.UseAuthorization(); app.UseAuthorization();
app.UseEndpoints(endpoints => app.UseEndpoints(endpoints =>
{ {
endpoints.MapControllerRoute("API Route", "api/{controller=Home}/{action=Index}/{id?}"); endpoints.MapControllerRoute("Kyoo", "api/{controller=Home}/{action=Index}/{id?}");
}); });
app.UseSpa(spa => app.UseSpa(spa =>

View File

@ -18,16 +18,16 @@ namespace Kyoo.Api
{ {
public class RegisterRequest public class RegisterRequest
{ {
public string Email; public string Email { get; set; }
public string Username; public string Username { get; set; }
public string Password; public string Password { get; set; }
} }
public class LoginRequest public class LoginRequest
{ {
public string Username; public string Username { get; set; }
public string Password; public string Password { get; set; }
public bool StayLoggedIn; public bool StayLoggedIn { get; set; }
} }
public class OtacRequest public class OtacRequest

View File

@ -19,7 +19,7 @@ namespace Kyoo.Api
} }
[HttpGet] [HttpGet]
[Authorize(Policy="Read")] [Authorize]
public IEnumerable<Show> GetShows() public IEnumerable<Show> GetShows()
{ {
return _libraryManager.GetShows(); return _libraryManager.GetShows();

@ -1 +1 @@
Subproject commit 04e92944eeb2f5617834253d01ef312fee46e435 Subproject commit 3f17ec96dac6cc641b875a0e3b201b8b75336d6d

View File

@ -4,7 +4,9 @@
"https_port": 44300, "https_port": 44300,
"Logging": { "Logging": {
"LogLevel": { "LogLevel": {
"Default": "Warning" "Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
} }
}, },
"AllowedHosts": "*", "AllowedHosts": "*",
@ -13,6 +15,12 @@
"Database": "Data Source=kyoo.db" "Database": "Data Source=kyoo.db"
}, },
"IdentityServer": {
"Key": {
"Type": "Development"
}
},
"transmuxTempPath": "cached/kyoo/transmux", "transmuxTempPath": "cached/kyoo/transmux",
"transcodeTempPath": "cached/kyoo/transcode", "transcodeTempPath": "cached/kyoo/transcode",
"peoplePath": "people", "peoplePath": "people",