diff --git a/Kyoo/Kyoo.csproj b/Kyoo/Kyoo.csproj
index ea2b29ef..174707ee 100644
--- a/Kyoo/Kyoo.csproj
+++ b/Kyoo/Kyoo.csproj
@@ -90,6 +90,7 @@
+
diff --git a/Kyoo/Models/DatabaseContext.cs b/Kyoo/Models/DatabaseContext.cs
index f6114a09..3330c04e 100644
--- a/Kyoo/Models/DatabaseContext.cs
+++ b/Kyoo/Models/DatabaseContext.cs
@@ -1,13 +1,15 @@
using System;
using System.Linq;
using Kyoo.Models;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace Kyoo
{
- public class DatabaseContext : DbContext
+ public class DatabaseContext : IdentityDbContext
{
public DatabaseContext(DbContextOptions options) : base(options) { }
@@ -63,9 +65,14 @@ namespace Kyoo
modelBuilder.Entity()
.Ignore(x => x.Genres);
-
- // modelBuilder.Entity()
- // .Ignore(x => x.Shows);
+
+ modelBuilder.Entity().ToTable("Account");
+ modelBuilder.Entity>().ToTable("UserRole");
+ modelBuilder.Entity>().ToTable("UserLogin");
+ modelBuilder.Entity>().ToTable("UserClaim");
+ modelBuilder.Entity().ToTable("UserRoles");
+ modelBuilder.Entity>().ToTable("UserRoleClaim");
+ modelBuilder.Entity>().ToTable("UserToken");
}
}
}
diff --git a/Kyoo/Models/DatabaseMigrations/Internal/20200303213358_Initial.Designer.cs b/Kyoo/Models/DatabaseMigrations/Internal/20200303213358_Initial.Designer.cs
deleted file mode 100644
index ff44ad18..00000000
--- a/Kyoo/Models/DatabaseMigrations/Internal/20200303213358_Initial.Designer.cs
+++ /dev/null
@@ -1,496 +0,0 @@
-//
-using System;
-using Kyoo;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Migrations;
-using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-
-namespace Kyoo.Models.DatabaseMigrations
-{
- [DbContext(typeof(DatabaseContext))]
- [Migration("20200303213358_Initial")]
- partial class Initial
- {
- protected override void BuildTargetModel(ModelBuilder modelBuilder)
- {
-#pragma warning disable 612, 618
- modelBuilder
- .HasAnnotation("ProductVersion", "3.1.2");
-
- modelBuilder.Entity("Kyoo.Models.Collection", b =>
- {
- b.Property("ID")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER");
-
- b.Property("ImgPrimary")
- .HasColumnType("TEXT");
-
- b.Property("Name")
- .HasColumnType("TEXT");
-
- b.Property("Overview")
- .HasColumnType("TEXT");
-
- b.Property("Poster")
- .HasColumnType("TEXT");
-
- b.Property("Slug")
- .HasColumnType("TEXT");
-
- b.HasKey("ID");
-
- b.ToTable("Collections");
- });
-
- modelBuilder.Entity("Kyoo.Models.CollectionLink", b =>
- {
- b.Property("ID")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER");
-
- b.Property("CollectionID")
- .HasColumnType("INTEGER");
-
- b.Property("ShowID")
- .HasColumnType("INTEGER");
-
- b.HasKey("ID");
-
- b.HasIndex("CollectionID");
-
- b.HasIndex("ShowID");
-
- b.ToTable("CollectionLinks");
- });
-
- modelBuilder.Entity("Kyoo.Models.Episode", b =>
- {
- b.Property("ID")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER");
-
- b.Property("AbsoluteNumber")
- .HasColumnType("INTEGER");
-
- b.Property("EpisodeNumber")
- .HasColumnType("INTEGER");
-
- b.Property("ExternalIDs")
- .HasColumnType("TEXT");
-
- b.Property("ImgPrimary")
- .HasColumnType("TEXT");
-
- b.Property("Overview")
- .HasColumnType("TEXT");
-
- b.Property("Path")
- .HasColumnType("TEXT");
-
- b.Property("ReleaseDate")
- .HasColumnType("TEXT");
-
- b.Property("Runtime")
- .HasColumnType("INTEGER");
-
- b.Property("SeasonID")
- .HasColumnType("INTEGER");
-
- b.Property("SeasonNumber")
- .HasColumnType("INTEGER");
-
- b.Property("ShowID")
- .HasColumnType("INTEGER");
-
- b.Property("Title")
- .HasColumnType("TEXT");
-
- b.HasKey("ID");
-
- b.HasIndex("SeasonID");
-
- b.HasIndex("ShowID");
-
- b.ToTable("Episodes");
- });
-
- modelBuilder.Entity("Kyoo.Models.Genre", b =>
- {
- b.Property("ID")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER");
-
- b.Property("Name")
- .HasColumnType("TEXT");
-
- b.Property("Slug")
- .HasColumnType("TEXT");
-
- b.HasKey("ID");
-
- b.ToTable("Genres");
- });
-
- modelBuilder.Entity("Kyoo.Models.GenreLink", b =>
- {
- b.Property("ShowID")
- .HasColumnType("INTEGER");
-
- b.Property("GenreID")
- .HasColumnType("INTEGER");
-
- b.HasKey("ShowID", "GenreID");
-
- b.HasIndex("GenreID");
-
- b.ToTable("GenreLinks");
- });
-
- modelBuilder.Entity("Kyoo.Models.Library", b =>
- {
- b.Property("ID")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER");
-
- b.Property("Name")
- .HasColumnType("TEXT");
-
- b.Property("Paths")
- .HasColumnType("TEXT");
-
- b.Property("Providers")
- .HasColumnType("TEXT");
-
- b.Property("Slug")
- .HasColumnType("TEXT");
-
- b.HasKey("ID");
-
- b.ToTable("Libraries");
- });
-
- modelBuilder.Entity("Kyoo.Models.LibraryLink", b =>
- {
- b.Property("ID")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER");
-
- b.Property("CollectionID")
- .HasColumnType("INTEGER");
-
- b.Property("LibraryID")
- .HasColumnType("INTEGER");
-
- b.Property("ShowID")
- .HasColumnType("INTEGER");
-
- b.HasKey("ID");
-
- b.HasIndex("CollectionID");
-
- b.HasIndex("LibraryID");
-
- b.HasIndex("ShowID");
-
- b.ToTable("LibraryLinks");
- });
-
- modelBuilder.Entity("Kyoo.Models.People", b =>
- {
- b.Property("Slug")
- .HasColumnType("TEXT");
-
- b.Property("ExternalIDs")
- .HasColumnType("TEXT");
-
- b.Property("ImgPrimary")
- .HasColumnType("TEXT");
-
- b.Property("Name")
- .HasColumnType("TEXT");
-
- b.HasKey("Slug");
-
- b.ToTable("Peoples");
- });
-
- modelBuilder.Entity("Kyoo.Models.PeopleLink", b =>
- {
- b.Property("ID")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER");
-
- b.Property("PeopleID")
- .HasColumnType("TEXT");
-
- b.Property("Role")
- .HasColumnType("TEXT");
-
- b.Property("ShowID")
- .HasColumnType("INTEGER");
-
- b.Property("Type")
- .HasColumnType("TEXT");
-
- b.HasKey("ID");
-
- b.HasIndex("PeopleID");
-
- b.HasIndex("ShowID");
-
- b.ToTable("PeopleLinks");
- });
-
- modelBuilder.Entity("Kyoo.Models.Season", b =>
- {
- b.Property("ID")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER");
-
- b.Property("ExternalIDs")
- .HasColumnType("TEXT");
-
- b.Property("ImgPrimary")
- .HasColumnType("TEXT");
-
- b.Property("Overview")
- .HasColumnType("TEXT");
-
- b.Property("SeasonNumber")
- .HasColumnType("INTEGER");
-
- b.Property("ShowID")
- .HasColumnType("INTEGER");
-
- b.Property("Title")
- .HasColumnType("TEXT");
-
- b.Property("Year")
- .HasColumnType("INTEGER");
-
- b.HasKey("ID");
-
- b.HasIndex("ShowID");
-
- b.ToTable("Seasons");
- });
-
- modelBuilder.Entity("Kyoo.Models.Show", b =>
- {
- b.Property("ID")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER");
-
- b.Property("Aliases")
- .HasColumnType("TEXT");
-
- b.Property("EndYear")
- .HasColumnType("INTEGER");
-
- b.Property("ExternalIDs")
- .HasColumnType("TEXT");
-
- b.Property("ImgBackdrop")
- .HasColumnType("TEXT");
-
- b.Property("ImgLogo")
- .HasColumnType("TEXT");
-
- b.Property("ImgPrimary")
- .HasColumnType("TEXT");
-
- b.Property("ImgThumb")
- .HasColumnType("TEXT");
-
- b.Property("IsMovie")
- .HasColumnType("INTEGER");
-
- b.Property("Overview")
- .HasColumnType("TEXT");
-
- b.Property("Path")
- .HasColumnType("TEXT");
-
- b.Property("Slug")
- .HasColumnType("TEXT");
-
- b.Property("StartYear")
- .HasColumnType("INTEGER");
-
- b.Property("Status")
- .HasColumnType("INTEGER");
-
- b.Property("StudioID")
- .HasColumnType("INTEGER");
-
- b.Property("Title")
- .HasColumnType("TEXT");
-
- b.Property("TrailerUrl")
- .HasColumnType("TEXT");
-
- b.HasKey("ID");
-
- b.HasIndex("StudioID");
-
- b.ToTable("Shows");
- });
-
- modelBuilder.Entity("Kyoo.Models.Studio", b =>
- {
- b.Property("ID")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER");
-
- b.Property("Name")
- .HasColumnType("TEXT");
-
- b.Property("Slug")
- .HasColumnType("TEXT");
-
- b.HasKey("ID");
-
- b.ToTable("Studios");
- });
-
- modelBuilder.Entity("Kyoo.Models.Track", b =>
- {
- b.Property("ID")
- .ValueGeneratedOnAdd()
- .HasColumnType("INTEGER");
-
- b.Property("Codec")
- .HasColumnType("TEXT");
-
- b.Property("EpisodeID")
- .HasColumnType("INTEGER");
-
- b.Property("IsDefault")
- .HasColumnType("INTEGER");
-
- b.Property("IsExternal")
- .HasColumnType("INTEGER");
-
- b.Property("IsForced")
- .HasColumnType("INTEGER");
-
- b.Property("Language")
- .HasColumnType("TEXT");
-
- b.Property("Path")
- .HasColumnType("TEXT");
-
- b.Property("Title")
- .HasColumnType("TEXT");
-
- b.Property("Type")
- .HasColumnType("INTEGER");
-
- b.HasKey("ID");
-
- b.HasIndex("EpisodeID");
-
- b.ToTable("Tracks");
- });
-
- modelBuilder.Entity("Kyoo.Models.CollectionLink", b =>
- {
- b.HasOne("Kyoo.Models.Collection", "Collection")
- .WithMany()
- .HasForeignKey("CollectionID");
-
- b.HasOne("Kyoo.Models.Show", "Show")
- .WithMany()
- .HasForeignKey("ShowID")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
- });
-
- modelBuilder.Entity("Kyoo.Models.Episode", b =>
- {
- b.HasOne("Kyoo.Models.Season", "Season")
- .WithMany("Episodes")
- .HasForeignKey("SeasonID");
-
- b.HasOne("Kyoo.Models.Show", "Show")
- .WithMany("Episodes")
- .HasForeignKey("ShowID")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
- });
-
- modelBuilder.Entity("Kyoo.Models.GenreLink", b =>
- {
- b.HasOne("Kyoo.Models.Genre", "Genre")
- .WithMany()
- .HasForeignKey("GenreID")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.HasOne("Kyoo.Models.Show", "Show")
- .WithMany("GenreLinks")
- .HasForeignKey("ShowID")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
- });
-
- modelBuilder.Entity("Kyoo.Models.LibraryLink", b =>
- {
- b.HasOne("Kyoo.Models.Collection", "Collection")
- .WithMany()
- .HasForeignKey("CollectionID");
-
- b.HasOne("Kyoo.Models.Library", "Library")
- .WithMany()
- .HasForeignKey("LibraryID")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.HasOne("Kyoo.Models.Show", "Show")
- .WithMany()
- .HasForeignKey("ShowID");
- });
-
- modelBuilder.Entity("Kyoo.Models.PeopleLink", b =>
- {
- b.HasOne("Kyoo.Models.People", "People")
- .WithMany("Roles")
- .HasForeignKey("PeopleID");
-
- b.HasOne("Kyoo.Models.Show", "Show")
- .WithMany("People")
- .HasForeignKey("ShowID")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
- });
-
- modelBuilder.Entity("Kyoo.Models.Season", b =>
- {
- b.HasOne("Kyoo.Models.Show", "Show")
- .WithMany("Seasons")
- .HasForeignKey("ShowID")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
- });
-
- modelBuilder.Entity("Kyoo.Models.Show", b =>
- {
- b.HasOne("Kyoo.Models.Studio", "Studio")
- .WithMany()
- .HasForeignKey("StudioID");
- });
-
- modelBuilder.Entity("Kyoo.Models.Track", b =>
- {
- b.HasOne("Kyoo.Models.Episode", "Episode")
- .WithMany("Tracks")
- .HasForeignKey("EpisodeID")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
- });
-#pragma warning restore 612, 618
- }
- }
-}
diff --git a/Kyoo/Models/DatabaseMigrations/Internal/20200306000057_Adding accounts.cs b/Kyoo/Models/DatabaseMigrations/Internal/20200306000057_Adding accounts.cs
deleted file mode 100644
index 99fe4424..00000000
--- a/Kyoo/Models/DatabaseMigrations/Internal/20200306000057_Adding accounts.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using System;
-using Microsoft.EntityFrameworkCore.Migrations;
-
-namespace Kyoo.Models.DatabaseMigrations.Internal
-{
- public partial class Addingaccounts : Migration
- {
- protected override void Up(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.CreateTable(
- name: "Accounts",
- columns: table => new
- {
- Id = table.Column(nullable: false),
- UserName = table.Column(nullable: true),
- NormalizedUserName = table.Column(nullable: true),
- Email = table.Column(nullable: true),
- NormalizedEmail = table.Column(nullable: true),
- EmailConfirmed = table.Column(nullable: false),
- PasswordHash = table.Column(nullable: true),
- SecurityStamp = table.Column(nullable: true),
- ConcurrencyStamp = table.Column(nullable: true),
- PhoneNumber = table.Column(nullable: true),
- PhoneNumberConfirmed = table.Column(nullable: false),
- TwoFactorEnabled = table.Column(nullable: false),
- LockoutEnd = table.Column(nullable: true),
- LockoutEnabled = table.Column(nullable: false),
- AccessFailedCount = table.Column(nullable: false),
- OTAC = table.Column(nullable: true),
- OTACExpires = table.Column(nullable: true)
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_Accounts", x => x.Id);
- });
- }
-
- protected override void Down(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.DropTable(
- name: "Accounts");
- }
- }
-}
diff --git a/Kyoo/Models/DatabaseMigrations/Internal/20200306000057_Adding accounts.Designer.cs b/Kyoo/Models/DatabaseMigrations/Internal/20200307014347_Initial.Designer.cs
similarity index 72%
rename from Kyoo/Models/DatabaseMigrations/Internal/20200306000057_Adding accounts.Designer.cs
rename to Kyoo/Models/DatabaseMigrations/Internal/20200307014347_Initial.Designer.cs
index f45bfa68..d78f0deb 100644
--- a/Kyoo/Models/DatabaseMigrations/Internal/20200306000057_Adding accounts.Designer.cs
+++ b/Kyoo/Models/DatabaseMigrations/Internal/20200307014347_Initial.Designer.cs
@@ -9,8 +9,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace Kyoo.Models.DatabaseMigrations.Internal
{
[DbContext(typeof(DatabaseContext))]
- [Migration("20200306000057_Adding accounts")]
- partial class Addingaccounts
+ [Migration("20200307014347_Initial")]
+ partial class Initial
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
@@ -27,10 +27,12 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
.HasColumnType("INTEGER");
b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
.HasColumnType("TEXT");
b.Property("Email")
- .HasColumnType("TEXT");
+ .HasColumnType("TEXT")
+ .HasMaxLength(256);
b.Property("EmailConfirmed")
.HasColumnType("INTEGER");
@@ -42,10 +44,12 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
.HasColumnType("TEXT");
b.Property("NormalizedEmail")
- .HasColumnType("TEXT");
+ .HasColumnType("TEXT")
+ .HasMaxLength(256);
b.Property("NormalizedUserName")
- .HasColumnType("TEXT");
+ .HasColumnType("TEXT")
+ .HasMaxLength(256);
b.Property("OTAC")
.HasColumnType("TEXT");
@@ -69,11 +73,19 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
.HasColumnType("INTEGER");
b.Property("UserName")
- .HasColumnType("TEXT");
+ .HasColumnType("TEXT")
+ .HasMaxLength(256);
b.HasKey("Id");
- b.ToTable("Accounts");
+ b.HasIndex("NormalizedEmail")
+ .HasName("EmailIndex");
+
+ b.HasIndex("NormalizedUserName")
+ .IsUnique()
+ .HasName("UserNameIndex");
+
+ b.ToTable("Account");
});
modelBuilder.Entity("Kyoo.Models.Collection", b =>
@@ -453,6 +465,134 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
b.ToTable("Tracks");
});
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("TEXT");
+
+ b.Property("Name")
+ .HasColumnType("TEXT")
+ .HasMaxLength(256);
+
+ b.Property("NormalizedName")
+ .HasColumnType("TEXT")
+ .HasMaxLength(256);
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName")
+ .IsUnique()
+ .HasName("RoleNameIndex");
+
+ b.ToTable("UserRoles");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("ClaimType")
+ .HasColumnType("TEXT");
+
+ b.Property("ClaimValue")
+ .HasColumnType("TEXT");
+
+ b.Property("RoleId")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("UserRoleClaim");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("ClaimType")
+ .HasColumnType("TEXT");
+
+ b.Property("ClaimValue")
+ .HasColumnType("TEXT");
+
+ b.Property("UserId")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("UserClaim");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
+ {
+ b.Property("LoginProvider")
+ .HasColumnType("TEXT");
+
+ b.Property("ProviderKey")
+ .HasColumnType("TEXT");
+
+ b.Property("ProviderDisplayName")
+ .HasColumnType("TEXT");
+
+ b.Property("UserId")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.HasKey("LoginProvider", "ProviderKey");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("UserLogin");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.Property("RoleId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("UserRole");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.Property("LoginProvider")
+ .HasColumnType("TEXT");
+
+ b.Property("Name")
+ .HasColumnType("TEXT");
+
+ b.Property("Value")
+ .HasColumnType("TEXT");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("UserToken");
+ });
+
modelBuilder.Entity("Kyoo.Models.CollectionLink", b =>
{
b.HasOne("Kyoo.Models.Collection", "Collection")
@@ -548,6 +688,57 @@ namespace Kyoo.Models.DatabaseMigrations.Internal
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
+ {
+ b.HasOne("Kyoo.Models.Account", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
+ {
+ b.HasOne("Kyoo.Models.Account", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Kyoo.Models.Account", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
+ {
+ b.HasOne("Kyoo.Models.Account", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
#pragma warning restore 612, 618
}
}
diff --git a/Kyoo/Models/DatabaseMigrations/Internal/20200303213358_Initial.cs b/Kyoo/Models/DatabaseMigrations/Internal/20200307014347_Initial.cs
similarity index 67%
rename from Kyoo/Models/DatabaseMigrations/Internal/20200303213358_Initial.cs
rename to Kyoo/Models/DatabaseMigrations/Internal/20200307014347_Initial.cs
index e88c29f8..9e4b2f5c 100644
--- a/Kyoo/Models/DatabaseMigrations/Internal/20200303213358_Initial.cs
+++ b/Kyoo/Models/DatabaseMigrations/Internal/20200307014347_Initial.cs
@@ -1,12 +1,39 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
-namespace Kyoo.Models.DatabaseMigrations
+namespace Kyoo.Models.DatabaseMigrations.Internal
{
public partial class Initial : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
+ migrationBuilder.CreateTable(
+ name: "Account",
+ columns: table => new
+ {
+ Id = table.Column(nullable: false),
+ UserName = table.Column(maxLength: 256, nullable: true),
+ NormalizedUserName = table.Column(maxLength: 256, nullable: true),
+ Email = table.Column(maxLength: 256, nullable: true),
+ NormalizedEmail = table.Column(maxLength: 256, nullable: true),
+ EmailConfirmed = table.Column(nullable: false),
+ PasswordHash = table.Column(nullable: true),
+ SecurityStamp = table.Column(nullable: true),
+ ConcurrencyStamp = table.Column(nullable: true),
+ PhoneNumber = table.Column(nullable: true),
+ PhoneNumberConfirmed = table.Column(nullable: false),
+ TwoFactorEnabled = table.Column(nullable: false),
+ LockoutEnd = table.Column(nullable: true),
+ LockoutEnabled = table.Column(nullable: false),
+ AccessFailedCount = table.Column(nullable: false),
+ OTAC = table.Column(nullable: true),
+ OTACExpires = table.Column(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Account", x => x.Id);
+ });
+
migrationBuilder.CreateTable(
name: "Collections",
columns: table => new
@@ -82,6 +109,81 @@ namespace Kyoo.Models.DatabaseMigrations
table.PrimaryKey("PK_Studios", x => x.ID);
});
+ migrationBuilder.CreateTable(
+ name: "UserRoles",
+ columns: table => new
+ {
+ Id = table.Column(nullable: false),
+ Name = table.Column(maxLength: 256, nullable: true),
+ NormalizedName = table.Column(maxLength: 256, nullable: true),
+ ConcurrencyStamp = table.Column(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_UserRoles", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "UserClaim",
+ columns: table => new
+ {
+ Id = table.Column(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ UserId = table.Column(nullable: false),
+ ClaimType = table.Column(nullable: true),
+ ClaimValue = table.Column(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_UserClaim", x => x.Id);
+ table.ForeignKey(
+ name: "FK_UserClaim_Account_UserId",
+ column: x => x.UserId,
+ principalTable: "Account",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "UserLogin",
+ columns: table => new
+ {
+ LoginProvider = table.Column(nullable: false),
+ ProviderKey = table.Column(nullable: false),
+ ProviderDisplayName = table.Column(nullable: true),
+ UserId = table.Column(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_UserLogin", x => new { x.LoginProvider, x.ProviderKey });
+ table.ForeignKey(
+ name: "FK_UserLogin_Account_UserId",
+ column: x => x.UserId,
+ principalTable: "Account",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "UserToken",
+ columns: table => new
+ {
+ UserId = table.Column(nullable: false),
+ LoginProvider = table.Column(nullable: false),
+ Name = table.Column(nullable: false),
+ Value = table.Column(nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_UserToken", x => new { x.UserId, x.LoginProvider, x.Name });
+ table.ForeignKey(
+ name: "FK_UserToken_Account_UserId",
+ column: x => x.UserId,
+ principalTable: "Account",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
migrationBuilder.CreateTable(
name: "Shows",
columns: table => new
@@ -116,6 +218,51 @@ namespace Kyoo.Models.DatabaseMigrations
onDelete: ReferentialAction.Restrict);
});
+ migrationBuilder.CreateTable(
+ name: "UserRole",
+ columns: table => new
+ {
+ UserId = table.Column(nullable: false),
+ RoleId = table.Column(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_Account_UserId",
+ column: x => x.UserId,
+ principalTable: "Account",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "UserRoleClaim",
+ columns: table => new
+ {
+ Id = table.Column(nullable: false)
+ .Annotation("Sqlite:Autoincrement", true),
+ RoleId = table.Column(nullable: false),
+ ClaimType = table.Column(nullable: true),
+ ClaimValue = table.Column(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(
name: "CollectionLinks",
columns: table => new
@@ -315,6 +462,17 @@ namespace Kyoo.Models.DatabaseMigrations
onDelete: ReferentialAction.Cascade);
});
+ migrationBuilder.CreateIndex(
+ name: "EmailIndex",
+ table: "Account",
+ column: "NormalizedEmail");
+
+ migrationBuilder.CreateIndex(
+ name: "UserNameIndex",
+ table: "Account",
+ column: "NormalizedUserName",
+ unique: true);
+
migrationBuilder.CreateIndex(
name: "IX_CollectionLinks_CollectionID",
table: "CollectionLinks",
@@ -379,6 +537,32 @@ namespace Kyoo.Models.DatabaseMigrations
name: "IX_Tracks_EpisodeID",
table: "Tracks",
column: "EpisodeID");
+
+ 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)
@@ -398,6 +582,21 @@ namespace Kyoo.Models.DatabaseMigrations
migrationBuilder.DropTable(
name: "Tracks");
+ migrationBuilder.DropTable(
+ name: "UserClaim");
+
+ migrationBuilder.DropTable(
+ name: "UserLogin");
+
+ migrationBuilder.DropTable(
+ name: "UserRole");
+
+ migrationBuilder.DropTable(
+ name: "UserRoleClaim");
+
+ migrationBuilder.DropTable(
+ name: "UserToken");
+
migrationBuilder.DropTable(
name: "Genres");
@@ -413,6 +612,12 @@ namespace Kyoo.Models.DatabaseMigrations
migrationBuilder.DropTable(
name: "Episodes");
+ migrationBuilder.DropTable(
+ name: "UserRoles");
+
+ migrationBuilder.DropTable(
+ name: "Account");
+
migrationBuilder.DropTable(
name: "Seasons");
diff --git a/Kyoo/Models/DatabaseMigrations/Internal/DatabaseContextModelSnapshot.cs b/Kyoo/Models/DatabaseMigrations/Internal/DatabaseContextModelSnapshot.cs
index 544fb00c..eb976610 100644
--- a/Kyoo/Models/DatabaseMigrations/Internal/DatabaseContextModelSnapshot.cs
+++ b/Kyoo/Models/DatabaseMigrations/Internal/DatabaseContextModelSnapshot.cs
@@ -5,7 +5,7 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-namespace Kyoo.Models.DatabaseMigrations
+namespace Kyoo.Models.DatabaseMigrations.Internal
{
[DbContext(typeof(DatabaseContext))]
partial class DatabaseContextModelSnapshot : ModelSnapshot
@@ -25,10 +25,12 @@ namespace Kyoo.Models.DatabaseMigrations
.HasColumnType("INTEGER");
b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
.HasColumnType("TEXT");
b.Property("Email")
- .HasColumnType("TEXT");
+ .HasColumnType("TEXT")
+ .HasMaxLength(256);
b.Property("EmailConfirmed")
.HasColumnType("INTEGER");
@@ -40,10 +42,12 @@ namespace Kyoo.Models.DatabaseMigrations
.HasColumnType("TEXT");
b.Property("NormalizedEmail")
- .HasColumnType("TEXT");
+ .HasColumnType("TEXT")
+ .HasMaxLength(256);
b.Property("NormalizedUserName")
- .HasColumnType("TEXT");
+ .HasColumnType("TEXT")
+ .HasMaxLength(256);
b.Property("OTAC")
.HasColumnType("TEXT");
@@ -67,11 +71,19 @@ namespace Kyoo.Models.DatabaseMigrations
.HasColumnType("INTEGER");
b.Property("UserName")
- .HasColumnType("TEXT");
+ .HasColumnType("TEXT")
+ .HasMaxLength(256);
b.HasKey("Id");
- b.ToTable("Accounts");
+ b.HasIndex("NormalizedEmail")
+ .HasName("EmailIndex");
+
+ b.HasIndex("NormalizedUserName")
+ .IsUnique()
+ .HasName("UserNameIndex");
+
+ b.ToTable("Account");
});
modelBuilder.Entity("Kyoo.Models.Collection", b =>
@@ -451,6 +463,134 @@ namespace Kyoo.Models.DatabaseMigrations
b.ToTable("Tracks");
});
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("TEXT");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("TEXT");
+
+ b.Property("Name")
+ .HasColumnType("TEXT")
+ .HasMaxLength(256);
+
+ b.Property("NormalizedName")
+ .HasColumnType("TEXT")
+ .HasMaxLength(256);
+
+ b.HasKey("Id");
+
+ b.HasIndex("NormalizedName")
+ .IsUnique()
+ .HasName("RoleNameIndex");
+
+ b.ToTable("UserRoles");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("ClaimType")
+ .HasColumnType("TEXT");
+
+ b.Property("ClaimValue")
+ .HasColumnType("TEXT");
+
+ b.Property("RoleId")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("UserRoleClaim");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("INTEGER");
+
+ b.Property("ClaimType")
+ .HasColumnType("TEXT");
+
+ b.Property("ClaimValue")
+ .HasColumnType("TEXT");
+
+ b.Property("UserId")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("UserClaim");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
+ {
+ b.Property("LoginProvider")
+ .HasColumnType("TEXT");
+
+ b.Property("ProviderKey")
+ .HasColumnType("TEXT");
+
+ b.Property("ProviderDisplayName")
+ .HasColumnType("TEXT");
+
+ b.Property("UserId")
+ .IsRequired()
+ .HasColumnType("TEXT");
+
+ b.HasKey("LoginProvider", "ProviderKey");
+
+ b.HasIndex("UserId");
+
+ b.ToTable("UserLogin");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.Property("RoleId")
+ .HasColumnType("TEXT");
+
+ b.HasKey("UserId", "RoleId");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("UserRole");
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
+ {
+ b.Property("UserId")
+ .HasColumnType("TEXT");
+
+ b.Property("LoginProvider")
+ .HasColumnType("TEXT");
+
+ b.Property("Name")
+ .HasColumnType("TEXT");
+
+ b.Property("Value")
+ .HasColumnType("TEXT");
+
+ b.HasKey("UserId", "LoginProvider", "Name");
+
+ b.ToTable("UserToken");
+ });
+
modelBuilder.Entity("Kyoo.Models.CollectionLink", b =>
{
b.HasOne("Kyoo.Models.Collection", "Collection")
@@ -546,6 +686,57 @@ namespace Kyoo.Models.DatabaseMigrations
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
});
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b =>
+ {
+ b.HasOne("Kyoo.Models.Account", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b =>
+ {
+ b.HasOne("Kyoo.Models.Account", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b =>
+ {
+ b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null)
+ .WithMany()
+ .HasForeignKey("RoleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+
+ b.HasOne("Kyoo.Models.Account", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b =>
+ {
+ b.HasOne("Kyoo.Models.Account", null)
+ .WithMany()
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
#pragma warning restore 612, 618
}
}
diff --git a/Kyoo/Views/API/AccountAPI.cs b/Kyoo/Views/API/AccountAPI.cs
index 583fc204..616f14dd 100644
--- a/Kyoo/Views/API/AccountAPI.cs
+++ b/Kyoo/Views/API/AccountAPI.cs
@@ -3,6 +3,7 @@ using System.Threading.Tasks;
using Kyoo.Models;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
+using SignInResult = Microsoft.AspNetCore.Identity.SignInResult;
namespace Kyoo.Api
{
@@ -11,6 +12,13 @@ namespace Kyoo.Api
public string Email;
public string Username;
public string Password;
+ }
+
+ public class LoginRequest
+ {
+ public string Username;
+ public string Password;
+ public bool StayLoggedIn;
}
[Route("api/[controller]")]
@@ -18,10 +26,12 @@ namespace Kyoo.Api
public class AccountController : Controller
{
private readonly UserManager _accountManager;
+ private readonly SignInManager _signInManager;
- public AccountController(UserManager accountManager)
+ public AccountController(UserManager accountManager, SignInManager siginInManager)
{
_accountManager = accountManager;
+ _signInManager = siginInManager;
}
[HttpPost("register")]
@@ -37,5 +47,16 @@ namespace Kyoo.Api
await _accountManager.UpdateAsync(account);
return Ok(otac);
}
+
+ [HttpPost("login")]
+ public async Task Login([FromBody] LoginRequest login)
+ {
+ if (!ModelState.IsValid)
+ return BadRequest(login);
+ SignInResult result = await _signInManager.PasswordSignInAsync(login.Username, login.Password, login.StayLoggedIn, false);
+ if (result.Succeeded)
+ return Ok();
+ return BadRequest("Invalid username/password");
+ }
}
}
\ No newline at end of file
diff --git a/Kyoo/Views/WebClient b/Kyoo/Views/WebClient
index af2478da..6240bbce 160000
--- a/Kyoo/Views/WebClient
+++ b/Kyoo/Views/WebClient
@@ -1 +1 @@
-Subproject commit af2478da584eacee6377e50dbb4c530cffd7e0b6
+Subproject commit 6240bbce05be87f576fd4326ce26e8bfa8335c73