diff --git a/Kyoo/Controllers/StartupCode.cs b/Kyoo/Controllers/StartupCode.cs index fd993d61..aebe7376 100644 --- a/Kyoo/Controllers/StartupCode.cs +++ b/Kyoo/Controllers/StartupCode.cs @@ -1,7 +1,11 @@ using System; +using System.Linq; using System.Threading; using System.Threading.Tasks; using IdentityServer4.EntityFramework.DbContexts; +using IdentityServer4.EntityFramework.Mappers; +using IdentityServer4.Models; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -20,12 +24,30 @@ namespace Kyoo.Controllers { using (IServiceScope serviceScope = _serviceProvider.CreateScope()) { - serviceScope.ServiceProvider.GetService().Database.EnsureCreated(); - serviceScope.ServiceProvider.GetService().Database.EnsureCreated(); - serviceScope.ServiceProvider.GetService().Database.EnsureCreated(); - // Use the next line if the database is not SQLite (SQLite doesn't support complexe migrations). - // serviceScope.ServiceProvider.GetService().Database.Migrate();; - + serviceScope.ServiceProvider.GetService().Database.Migrate();; + serviceScope.ServiceProvider.GetService().Database.Migrate(); + + ConfigurationDbContext identityContext = serviceScope.ServiceProvider.GetService(); + identityContext.Database.Migrate(); + if (!identityContext.Clients.Any()) + { + foreach (Client client in IdentityContext.GetClients()) + identityContext.Clients.Add(client.ToEntity()); + identityContext.SaveChanges(); + } + if (!identityContext.IdentityResources.Any()) + { + foreach (IdentityResource resource in IdentityContext.GetIdentityResources()) + identityContext.IdentityResources.Add(resource.ToEntity()); + identityContext.SaveChanges(); + } + if (!identityContext.ApiResources.Any()) + { + foreach (ApiResource resource in IdentityContext.GetApis()) + identityContext.ApiResources.Add(resource.ToEntity()); + identityContext.SaveChanges(); + } + IPluginManager pluginManager = serviceScope.ServiceProvider.GetService(); pluginManager.ReloadPlugins(); diff --git a/Kyoo/Kyoo.csproj b/Kyoo/Kyoo.csproj index 0ad06118..ea2b29ef 100644 --- a/Kyoo/Kyoo.csproj +++ b/Kyoo/Kyoo.csproj @@ -25,6 +25,7 @@ + @@ -87,6 +88,9 @@ PreserveNewest + + + diff --git a/Kyoo/Models/Account.cs b/Kyoo/Models/Account.cs new file mode 100644 index 00000000..b0424ee1 --- /dev/null +++ b/Kyoo/Models/Account.cs @@ -0,0 +1,22 @@ +using System; +using IdentityModel; +using Microsoft.AspNetCore.Identity; + +namespace Kyoo.Models +{ + public class Account : IdentityUser + { + public string OTAC { get; set; } + public DateTime? OTACExpires { get; set; } + + public string GenerateOTAC(TimeSpan validFor) + { + string otac = CryptoRandom.CreateUniqueId(); + string hashed = otac; // TODO should add a good hashing here. + + OTAC = hashed; + OTACExpires = DateTime.UtcNow.Add(validFor); + return otac; + } + } +} \ No newline at end of file diff --git a/Kyoo/DatabaseContext.cs b/Kyoo/Models/DatabaseContext.cs similarity index 98% rename from Kyoo/DatabaseContext.cs rename to Kyoo/Models/DatabaseContext.cs index 4c5712ce..f6114a09 100644 --- a/Kyoo/DatabaseContext.cs +++ b/Kyoo/Models/DatabaseContext.cs @@ -11,6 +11,8 @@ namespace Kyoo { public DatabaseContext(DbContextOptions options) : base(options) { } + public DbSet Accounts { get; set; } + public DbSet Libraries { get; set; } public DbSet Collections { get; set; } public DbSet Shows { get; set; } diff --git a/Kyoo/Models/DatabaseMigrations/IdentityConfiguration/20200303213949_IS_Configuration.Designer.cs b/Kyoo/Models/DatabaseMigrations/IdentityConfiguration/20200303213949_IS_Configuration.Designer.cs new file mode 100644 index 00000000..78d6720d --- /dev/null +++ b/Kyoo/Models/DatabaseMigrations/IdentityConfiguration/20200303213949_IS_Configuration.Designer.cs @@ -0,0 +1,813 @@ +// +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 +{ + [DbContext(typeof(ConfigurationDbContext))] + [Migration("20200303213949_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.ApiResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT") + .HasMaxLength(1000); + + b.Property("DisplayName") + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("LastAccessed") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("NonEditable") + .HasColumnType("INTEGER"); + + b.Property("Updated") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("ApiResources"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApiResourceId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.ToTable("ApiClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApiResourceId") + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.ToTable("ApiProperties"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApiResourceId") + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasColumnType("TEXT") + .HasMaxLength(1000); + + b.Property("DisplayName") + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("Emphasize") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("Required") + .HasColumnType("INTEGER"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("ApiScopes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApiScopeId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ApiScopeId"); + + b.ToTable("ApiScopeClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiSecret", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApiResourceId") + .HasColumnType("INTEGER"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT") + .HasMaxLength(1000); + + b.Property("Expiration") + .HasColumnType("TEXT"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(4000); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.ToTable("ApiSecrets"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AbsoluteRefreshTokenLifetime") + .HasColumnType("INTEGER"); + + b.Property("AccessTokenLifetime") + .HasColumnType("INTEGER"); + + b.Property("AccessTokenType") + .HasColumnType("INTEGER"); + + b.Property("AllowAccessTokensViaBrowser") + .HasColumnType("INTEGER"); + + b.Property("AllowOfflineAccess") + .HasColumnType("INTEGER"); + + b.Property("AllowPlainTextPkce") + .HasColumnType("INTEGER"); + + b.Property("AllowRememberConsent") + .HasColumnType("INTEGER"); + + b.Property("AlwaysIncludeUserClaimsInIdToken") + .HasColumnType("INTEGER"); + + b.Property("AlwaysSendClientClaims") + .HasColumnType("INTEGER"); + + b.Property("AuthorizationCodeLifetime") + .HasColumnType("INTEGER"); + + b.Property("BackChannelLogoutSessionRequired") + .HasColumnType("INTEGER"); + + b.Property("BackChannelLogoutUri") + .HasColumnType("TEXT") + .HasMaxLength(2000); + + b.Property("ClientClaimsPrefix") + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("ClientId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("ClientName") + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("ClientUri") + .HasColumnType("TEXT") + .HasMaxLength(2000); + + b.Property("ConsentLifetime") + .HasColumnType("INTEGER"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT") + .HasMaxLength(1000); + + b.Property("DeviceCodeLifetime") + .HasColumnType("INTEGER"); + + b.Property("EnableLocalLogin") + .HasColumnType("INTEGER"); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("FrontChannelLogoutSessionRequired") + .HasColumnType("INTEGER"); + + b.Property("FrontChannelLogoutUri") + .HasColumnType("TEXT") + .HasMaxLength(2000); + + b.Property("IdentityTokenLifetime") + .HasColumnType("INTEGER"); + + b.Property("IncludeJwtId") + .HasColumnType("INTEGER"); + + b.Property("LastAccessed") + .HasColumnType("TEXT"); + + b.Property("LogoUri") + .HasColumnType("TEXT") + .HasMaxLength(2000); + + b.Property("NonEditable") + .HasColumnType("INTEGER"); + + b.Property("PairWiseSubjectSalt") + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("ProtocolType") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("RefreshTokenExpiration") + .HasColumnType("INTEGER"); + + b.Property("RefreshTokenUsage") + .HasColumnType("INTEGER"); + + b.Property("RequireClientSecret") + .HasColumnType("INTEGER"); + + b.Property("RequireConsent") + .HasColumnType("INTEGER"); + + b.Property("RequirePkce") + .HasColumnType("INTEGER"); + + b.Property("SlidingRefreshTokenLifetime") + .HasColumnType("INTEGER"); + + b.Property("UpdateAccessTokenClaimsOnRefresh") + .HasColumnType("INTEGER"); + + b.Property("Updated") + .HasColumnType("TEXT"); + + b.Property("UserCodeType") + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.Property("UserSsoLifetime") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ClientId") + .IsUnique(); + + b.ToTable("Clients"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(250); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientCorsOrigin", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("Origin") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(150); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientCorsOrigins"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientGrantType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("GrantType") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(250); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientGrantTypes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientIdPRestriction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("Provider") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientIdPRestrictions"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("PostLogoutRedirectUri") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientPostLogoutRedirectUris"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientProperties"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientRedirectUri", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("RedirectUri") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientRedirectUris"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("Scope") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientScopes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientSecret", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT") + .HasMaxLength(2000); + + b.Property("Expiration") + .HasColumnType("TEXT"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(4000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientSecrets"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("IdentityResourceId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("IdentityResourceId"); + + b.ToTable("IdentityClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT") + .HasMaxLength(1000); + + b.Property("DisplayName") + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("Emphasize") + .HasColumnType("INTEGER"); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("NonEditable") + .HasColumnType("INTEGER"); + + b.Property("Required") + .HasColumnType("INTEGER"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("INTEGER"); + + b.Property("Updated") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("IdentityResources"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResourceProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("IdentityResourceId") + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("IdentityResourceId"); + + b.ToTable("IdentityProperties"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("UserClaims") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceProperty", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("Properties") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScope", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("Scopes") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiScope", "ApiScope") + .WithMany("UserClaims") + .HasForeignKey("ApiScopeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiSecret", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("Secrets") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("Claims") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientCorsOrigin", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("AllowedCorsOrigins") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientGrantType", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("AllowedGrantTypes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientIdPRestriction", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("IdentityProviderRestrictions") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("PostLogoutRedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientProperty", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("Properties") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientRedirectUri", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("RedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientScope", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("AllowedScopes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientSecret", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("ClientSecrets") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.IdentityResource", "IdentityResource") + .WithMany("UserClaims") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResourceProperty", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.IdentityResource", "IdentityResource") + .WithMany("Properties") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Kyoo/Models/DatabaseMigrations/IdentityConfiguration/20200303213949_IS_Configuration.cs b/Kyoo/Models/DatabaseMigrations/IdentityConfiguration/20200303213949_IS_Configuration.cs new file mode 100644 index 00000000..b4981bbc --- /dev/null +++ b/Kyoo/Models/DatabaseMigrations/IdentityConfiguration/20200303213949_IS_Configuration.cs @@ -0,0 +1,607 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Kyoo.Models.DatabaseMigrations +{ + public partial class IS_Configuration : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "ApiResources", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Enabled = table.Column(nullable: false), + Name = table.Column(maxLength: 200, nullable: false), + DisplayName = table.Column(maxLength: 200, nullable: true), + Description = table.Column(maxLength: 1000, nullable: true), + Created = table.Column(nullable: false), + Updated = table.Column(nullable: true), + LastAccessed = table.Column(nullable: true), + NonEditable = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiResources", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Clients", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Enabled = table.Column(nullable: false), + ClientId = table.Column(maxLength: 200, nullable: false), + ProtocolType = table.Column(maxLength: 200, nullable: false), + RequireClientSecret = table.Column(nullable: false), + ClientName = table.Column(maxLength: 200, nullable: true), + Description = table.Column(maxLength: 1000, nullable: true), + ClientUri = table.Column(maxLength: 2000, nullable: true), + LogoUri = table.Column(maxLength: 2000, nullable: true), + RequireConsent = table.Column(nullable: false), + AllowRememberConsent = table.Column(nullable: false), + AlwaysIncludeUserClaimsInIdToken = table.Column(nullable: false), + RequirePkce = table.Column(nullable: false), + AllowPlainTextPkce = table.Column(nullable: false), + AllowAccessTokensViaBrowser = table.Column(nullable: false), + FrontChannelLogoutUri = table.Column(maxLength: 2000, nullable: true), + FrontChannelLogoutSessionRequired = table.Column(nullable: false), + BackChannelLogoutUri = table.Column(maxLength: 2000, nullable: true), + BackChannelLogoutSessionRequired = table.Column(nullable: false), + AllowOfflineAccess = table.Column(nullable: false), + IdentityTokenLifetime = table.Column(nullable: false), + AccessTokenLifetime = table.Column(nullable: false), + AuthorizationCodeLifetime = table.Column(nullable: false), + ConsentLifetime = table.Column(nullable: true), + AbsoluteRefreshTokenLifetime = table.Column(nullable: false), + SlidingRefreshTokenLifetime = table.Column(nullable: false), + RefreshTokenUsage = table.Column(nullable: false), + UpdateAccessTokenClaimsOnRefresh = table.Column(nullable: false), + RefreshTokenExpiration = table.Column(nullable: false), + AccessTokenType = table.Column(nullable: false), + EnableLocalLogin = table.Column(nullable: false), + IncludeJwtId = table.Column(nullable: false), + AlwaysSendClientClaims = table.Column(nullable: false), + ClientClaimsPrefix = table.Column(maxLength: 200, nullable: true), + PairWiseSubjectSalt = table.Column(maxLength: 200, nullable: true), + Created = table.Column(nullable: false), + Updated = table.Column(nullable: true), + LastAccessed = table.Column(nullable: true), + UserSsoLifetime = table.Column(nullable: true), + UserCodeType = table.Column(maxLength: 100, nullable: true), + DeviceCodeLifetime = table.Column(nullable: false), + NonEditable = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Clients", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "IdentityResources", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Enabled = table.Column(nullable: false), + Name = table.Column(maxLength: 200, nullable: false), + DisplayName = table.Column(maxLength: 200, nullable: true), + Description = table.Column(maxLength: 1000, nullable: true), + Required = table.Column(nullable: false), + Emphasize = table.Column(nullable: false), + ShowInDiscoveryDocument = table.Column(nullable: false), + Created = table.Column(nullable: false), + Updated = table.Column(nullable: true), + NonEditable = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_IdentityResources", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "ApiClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Type = table.Column(maxLength: 200, nullable: false), + ApiResourceId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiClaims", x => x.Id); + table.ForeignKey( + name: "FK_ApiClaims_ApiResources_ApiResourceId", + column: x => x.ApiResourceId, + principalTable: "ApiResources", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ApiProperties", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Key = table.Column(maxLength: 250, nullable: false), + Value = table.Column(maxLength: 2000, nullable: false), + ApiResourceId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiProperties", x => x.Id); + table.ForeignKey( + name: "FK_ApiProperties_ApiResources_ApiResourceId", + column: x => x.ApiResourceId, + principalTable: "ApiResources", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ApiScopes", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Name = table.Column(maxLength: 200, nullable: false), + DisplayName = table.Column(maxLength: 200, nullable: true), + Description = table.Column(maxLength: 1000, nullable: true), + Required = table.Column(nullable: false), + Emphasize = table.Column(nullable: false), + ShowInDiscoveryDocument = table.Column(nullable: false), + ApiResourceId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiScopes", x => x.Id); + table.ForeignKey( + name: "FK_ApiScopes_ApiResources_ApiResourceId", + column: x => x.ApiResourceId, + principalTable: "ApiResources", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ApiSecrets", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Description = table.Column(maxLength: 1000, nullable: true), + Value = table.Column(maxLength: 4000, nullable: false), + Expiration = table.Column(nullable: true), + Type = table.Column(maxLength: 250, nullable: false), + Created = table.Column(nullable: false), + ApiResourceId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiSecrets", x => x.Id); + table.ForeignKey( + name: "FK_ApiSecrets_ApiResources_ApiResourceId", + column: x => x.ApiResourceId, + principalTable: "ApiResources", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Type = table.Column(maxLength: 250, nullable: false), + Value = table.Column(maxLength: 250, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientClaims", x => x.Id); + table.ForeignKey( + name: "FK_ClientClaims_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientCorsOrigins", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Origin = table.Column(maxLength: 150, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientCorsOrigins", x => x.Id); + table.ForeignKey( + name: "FK_ClientCorsOrigins_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientGrantTypes", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + GrantType = table.Column(maxLength: 250, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientGrantTypes", x => x.Id); + table.ForeignKey( + name: "FK_ClientGrantTypes_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientIdPRestrictions", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Provider = table.Column(maxLength: 200, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientIdPRestrictions", x => x.Id); + table.ForeignKey( + name: "FK_ClientIdPRestrictions_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientPostLogoutRedirectUris", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + PostLogoutRedirectUri = table.Column(maxLength: 2000, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientPostLogoutRedirectUris", x => x.Id); + table.ForeignKey( + name: "FK_ClientPostLogoutRedirectUris_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientProperties", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Key = table.Column(maxLength: 250, nullable: false), + Value = table.Column(maxLength: 2000, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientProperties", x => x.Id); + table.ForeignKey( + name: "FK_ClientProperties_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientRedirectUris", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + RedirectUri = table.Column(maxLength: 2000, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientRedirectUris", x => x.Id); + table.ForeignKey( + name: "FK_ClientRedirectUris_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientScopes", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Scope = table.Column(maxLength: 200, nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientScopes", x => x.Id); + table.ForeignKey( + name: "FK_ClientScopes_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ClientSecrets", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Description = table.Column(maxLength: 2000, nullable: true), + Value = table.Column(maxLength: 4000, nullable: false), + Expiration = table.Column(nullable: true), + Type = table.Column(maxLength: 250, nullable: false), + Created = table.Column(nullable: false), + ClientId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ClientSecrets", x => x.Id); + table.ForeignKey( + name: "FK_ClientSecrets_Clients_ClientId", + column: x => x.ClientId, + principalTable: "Clients", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "IdentityClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Type = table.Column(maxLength: 200, nullable: false), + IdentityResourceId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_IdentityClaims", x => x.Id); + table.ForeignKey( + name: "FK_IdentityClaims_IdentityResources_IdentityResourceId", + column: x => x.IdentityResourceId, + principalTable: "IdentityResources", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "IdentityProperties", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Key = table.Column(maxLength: 250, nullable: false), + Value = table.Column(maxLength: 2000, nullable: false), + IdentityResourceId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_IdentityProperties", x => x.Id); + table.ForeignKey( + name: "FK_IdentityProperties_IdentityResources_IdentityResourceId", + column: x => x.IdentityResourceId, + principalTable: "IdentityResources", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "ApiScopeClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Type = table.Column(maxLength: 200, nullable: false), + ApiScopeId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_ApiScopeClaims", x => x.Id); + table.ForeignKey( + name: "FK_ApiScopeClaims_ApiScopes_ApiScopeId", + column: x => x.ApiScopeId, + principalTable: "ApiScopes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_ApiClaims_ApiResourceId", + table: "ApiClaims", + column: "ApiResourceId"); + + migrationBuilder.CreateIndex( + name: "IX_ApiProperties_ApiResourceId", + table: "ApiProperties", + column: "ApiResourceId"); + + migrationBuilder.CreateIndex( + name: "IX_ApiResources_Name", + table: "ApiResources", + column: "Name", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_ApiScopeClaims_ApiScopeId", + table: "ApiScopeClaims", + column: "ApiScopeId"); + + migrationBuilder.CreateIndex( + name: "IX_ApiScopes_ApiResourceId", + table: "ApiScopes", + column: "ApiResourceId"); + + migrationBuilder.CreateIndex( + name: "IX_ApiScopes_Name", + table: "ApiScopes", + column: "Name", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_ApiSecrets_ApiResourceId", + table: "ApiSecrets", + column: "ApiResourceId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientClaims_ClientId", + table: "ClientClaims", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientCorsOrigins_ClientId", + table: "ClientCorsOrigins", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientGrantTypes_ClientId", + table: "ClientGrantTypes", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientIdPRestrictions_ClientId", + table: "ClientIdPRestrictions", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientPostLogoutRedirectUris_ClientId", + table: "ClientPostLogoutRedirectUris", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientProperties_ClientId", + table: "ClientProperties", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientRedirectUris_ClientId", + table: "ClientRedirectUris", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_Clients_ClientId", + table: "Clients", + column: "ClientId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_ClientScopes_ClientId", + table: "ClientScopes", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_ClientSecrets_ClientId", + table: "ClientSecrets", + column: "ClientId"); + + migrationBuilder.CreateIndex( + name: "IX_IdentityClaims_IdentityResourceId", + table: "IdentityClaims", + column: "IdentityResourceId"); + + migrationBuilder.CreateIndex( + name: "IX_IdentityProperties_IdentityResourceId", + table: "IdentityProperties", + column: "IdentityResourceId"); + + migrationBuilder.CreateIndex( + name: "IX_IdentityResources_Name", + table: "IdentityResources", + column: "Name", + unique: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "ApiClaims"); + + migrationBuilder.DropTable( + name: "ApiProperties"); + + migrationBuilder.DropTable( + name: "ApiScopeClaims"); + + migrationBuilder.DropTable( + name: "ApiSecrets"); + + migrationBuilder.DropTable( + name: "ClientClaims"); + + migrationBuilder.DropTable( + name: "ClientCorsOrigins"); + + migrationBuilder.DropTable( + name: "ClientGrantTypes"); + + migrationBuilder.DropTable( + name: "ClientIdPRestrictions"); + + migrationBuilder.DropTable( + name: "ClientPostLogoutRedirectUris"); + + migrationBuilder.DropTable( + name: "ClientProperties"); + + migrationBuilder.DropTable( + name: "ClientRedirectUris"); + + migrationBuilder.DropTable( + name: "ClientScopes"); + + migrationBuilder.DropTable( + name: "ClientSecrets"); + + migrationBuilder.DropTable( + name: "IdentityClaims"); + + migrationBuilder.DropTable( + name: "IdentityProperties"); + + migrationBuilder.DropTable( + name: "ApiScopes"); + + migrationBuilder.DropTable( + name: "Clients"); + + migrationBuilder.DropTable( + name: "IdentityResources"); + + migrationBuilder.DropTable( + name: "ApiResources"); + } + } +} diff --git a/Kyoo/Models/DatabaseMigrations/IdentityConfiguration/ConfigurationDbContextModelSnapshot.cs b/Kyoo/Models/DatabaseMigrations/IdentityConfiguration/ConfigurationDbContextModelSnapshot.cs new file mode 100644 index 00000000..22c655fe --- /dev/null +++ b/Kyoo/Models/DatabaseMigrations/IdentityConfiguration/ConfigurationDbContextModelSnapshot.cs @@ -0,0 +1,811 @@ +// +using System; +using IdentityServer4.EntityFramework.DbContexts; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace Kyoo.Models.DatabaseMigrations +{ + [DbContext(typeof(ConfigurationDbContext))] + partial class ConfigurationDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2"); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT") + .HasMaxLength(1000); + + b.Property("DisplayName") + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("LastAccessed") + .HasColumnType("TEXT"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("NonEditable") + .HasColumnType("INTEGER"); + + b.Property("Updated") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("ApiResources"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApiResourceId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.ToTable("ApiClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApiResourceId") + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.ToTable("ApiProperties"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApiResourceId") + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasColumnType("TEXT") + .HasMaxLength(1000); + + b.Property("DisplayName") + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("Emphasize") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("Required") + .HasColumnType("INTEGER"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("ApiScopes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApiScopeId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ApiScopeId"); + + b.ToTable("ApiScopeClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiSecret", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApiResourceId") + .HasColumnType("INTEGER"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT") + .HasMaxLength(1000); + + b.Property("Expiration") + .HasColumnType("TEXT"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(4000); + + b.HasKey("Id"); + + b.HasIndex("ApiResourceId"); + + b.ToTable("ApiSecrets"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.Client", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AbsoluteRefreshTokenLifetime") + .HasColumnType("INTEGER"); + + b.Property("AccessTokenLifetime") + .HasColumnType("INTEGER"); + + b.Property("AccessTokenType") + .HasColumnType("INTEGER"); + + b.Property("AllowAccessTokensViaBrowser") + .HasColumnType("INTEGER"); + + b.Property("AllowOfflineAccess") + .HasColumnType("INTEGER"); + + b.Property("AllowPlainTextPkce") + .HasColumnType("INTEGER"); + + b.Property("AllowRememberConsent") + .HasColumnType("INTEGER"); + + b.Property("AlwaysIncludeUserClaimsInIdToken") + .HasColumnType("INTEGER"); + + b.Property("AlwaysSendClientClaims") + .HasColumnType("INTEGER"); + + b.Property("AuthorizationCodeLifetime") + .HasColumnType("INTEGER"); + + b.Property("BackChannelLogoutSessionRequired") + .HasColumnType("INTEGER"); + + b.Property("BackChannelLogoutUri") + .HasColumnType("TEXT") + .HasMaxLength(2000); + + b.Property("ClientClaimsPrefix") + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("ClientId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("ClientName") + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("ClientUri") + .HasColumnType("TEXT") + .HasMaxLength(2000); + + b.Property("ConsentLifetime") + .HasColumnType("INTEGER"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT") + .HasMaxLength(1000); + + b.Property("DeviceCodeLifetime") + .HasColumnType("INTEGER"); + + b.Property("EnableLocalLogin") + .HasColumnType("INTEGER"); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("FrontChannelLogoutSessionRequired") + .HasColumnType("INTEGER"); + + b.Property("FrontChannelLogoutUri") + .HasColumnType("TEXT") + .HasMaxLength(2000); + + b.Property("IdentityTokenLifetime") + .HasColumnType("INTEGER"); + + b.Property("IncludeJwtId") + .HasColumnType("INTEGER"); + + b.Property("LastAccessed") + .HasColumnType("TEXT"); + + b.Property("LogoUri") + .HasColumnType("TEXT") + .HasMaxLength(2000); + + b.Property("NonEditable") + .HasColumnType("INTEGER"); + + b.Property("PairWiseSubjectSalt") + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("ProtocolType") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("RefreshTokenExpiration") + .HasColumnType("INTEGER"); + + b.Property("RefreshTokenUsage") + .HasColumnType("INTEGER"); + + b.Property("RequireClientSecret") + .HasColumnType("INTEGER"); + + b.Property("RequireConsent") + .HasColumnType("INTEGER"); + + b.Property("RequirePkce") + .HasColumnType("INTEGER"); + + b.Property("SlidingRefreshTokenLifetime") + .HasColumnType("INTEGER"); + + b.Property("UpdateAccessTokenClaimsOnRefresh") + .HasColumnType("INTEGER"); + + b.Property("Updated") + .HasColumnType("TEXT"); + + b.Property("UserCodeType") + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.Property("UserSsoLifetime") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ClientId") + .IsUnique(); + + b.ToTable("Clients"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(250); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientCorsOrigin", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("Origin") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(150); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientCorsOrigins"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientGrantType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("GrantType") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(250); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientGrantTypes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientIdPRestriction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("Provider") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientIdPRestrictions"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("PostLogoutRedirectUri") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientPostLogoutRedirectUris"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientProperties"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientRedirectUri", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("RedirectUri") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientRedirectUris"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientScope", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("Scope") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientScopes"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientSecret", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClientId") + .HasColumnType("INTEGER"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT") + .HasMaxLength(2000); + + b.Property("Expiration") + .HasColumnType("TEXT"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(4000); + + b.HasKey("Id"); + + b.HasIndex("ClientId"); + + b.ToTable("ClientSecrets"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("IdentityResourceId") + .HasColumnType("INTEGER"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.HasKey("Id"); + + b.HasIndex("IdentityResourceId"); + + b.ToTable("IdentityClaims"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResource", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Created") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT") + .HasMaxLength(1000); + + b.Property("DisplayName") + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("Emphasize") + .HasColumnType("INTEGER"); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("NonEditable") + .HasColumnType("INTEGER"); + + b.Property("Required") + .HasColumnType("INTEGER"); + + b.Property("ShowInDiscoveryDocument") + .HasColumnType("INTEGER"); + + b.Property("Updated") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Name") + .IsUnique(); + + b.ToTable("IdentityResources"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResourceProperty", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("IdentityResourceId") + .HasColumnType("INTEGER"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(250); + + b.Property("Value") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(2000); + + b.HasKey("Id"); + + b.HasIndex("IdentityResourceId"); + + b.ToTable("IdentityProperties"); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("UserClaims") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiResourceProperty", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("Properties") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScope", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("Scopes") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiScopeClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiScope", "ApiScope") + .WithMany("UserClaims") + .HasForeignKey("ApiScopeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ApiSecret", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.ApiResource", "ApiResource") + .WithMany("Secrets") + .HasForeignKey("ApiResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("Claims") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientCorsOrigin", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("AllowedCorsOrigins") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientGrantType", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("AllowedGrantTypes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientIdPRestriction", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("IdentityProviderRestrictions") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientPostLogoutRedirectUri", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("PostLogoutRedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientProperty", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("Properties") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientRedirectUri", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("RedirectUris") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientScope", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("AllowedScopes") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.ClientSecret", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.Client", "Client") + .WithMany("ClientSecrets") + .HasForeignKey("ClientId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityClaim", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.IdentityResource", "IdentityResource") + .WithMany("UserClaims") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("IdentityServer4.EntityFramework.Entities.IdentityResourceProperty", b => + { + b.HasOne("IdentityServer4.EntityFramework.Entities.IdentityResource", "IdentityResource") + .WithMany("Properties") + .HasForeignKey("IdentityResourceId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Kyoo/Models/DatabaseMigrations/IdentityPeristant/20200303214150_IS_Configuration.Designer.cs b/Kyoo/Models/DatabaseMigrations/IdentityPeristant/20200303214150_IS_Configuration.Designer.cs new file mode 100644 index 00000000..898e36f0 --- /dev/null +++ b/Kyoo/Models/DatabaseMigrations/IdentityPeristant/20200303214150_IS_Configuration.Designer.cs @@ -0,0 +1,105 @@ +// +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("UserCode") + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("ClientId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("CreationTime") + .HasColumnType("TEXT"); + + b.Property("Data") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50000); + + b.Property("DeviceCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("Expiration") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("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("Key") + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("ClientId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("CreationTime") + .HasColumnType("TEXT"); + + b.Property("Data") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50000); + + b.Property("Expiration") + .HasColumnType("TEXT"); + + b.Property("SubjectId") + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("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 + } + } +} diff --git a/Kyoo/Models/DatabaseMigrations/IdentityPeristant/20200303214150_IS_Configuration.cs b/Kyoo/Models/DatabaseMigrations/IdentityPeristant/20200303214150_IS_Configuration.cs new file mode 100644 index 00000000..3fe0f912 --- /dev/null +++ b/Kyoo/Models/DatabaseMigrations/IdentityPeristant/20200303214150_IS_Configuration.cs @@ -0,0 +1,75 @@ +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(maxLength: 200, nullable: false), + DeviceCode = table.Column(maxLength: 200, nullable: false), + SubjectId = table.Column(maxLength: 200, nullable: true), + ClientId = table.Column(maxLength: 200, nullable: false), + CreationTime = table.Column(nullable: false), + Expiration = table.Column(nullable: false), + Data = table.Column(maxLength: 50000, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_DeviceCodes", x => x.UserCode); + }); + + migrationBuilder.CreateTable( + name: "PersistedGrants", + columns: table => new + { + Key = table.Column(maxLength: 200, nullable: false), + Type = table.Column(maxLength: 50, nullable: false), + SubjectId = table.Column(maxLength: 200, nullable: true), + ClientId = table.Column(maxLength: 200, nullable: false), + CreationTime = table.Column(nullable: false), + Expiration = table.Column(nullable: true), + Data = table.Column(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"); + } + } +} diff --git a/Kyoo/Models/DatabaseMigrations/IdentityPeristant/PersistedGrantDbContextModelSnapshot.cs b/Kyoo/Models/DatabaseMigrations/IdentityPeristant/PersistedGrantDbContextModelSnapshot.cs new file mode 100644 index 00000000..3c80c303 --- /dev/null +++ b/Kyoo/Models/DatabaseMigrations/IdentityPeristant/PersistedGrantDbContextModelSnapshot.cs @@ -0,0 +1,103 @@ +// +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("UserCode") + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("ClientId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("CreationTime") + .HasColumnType("TEXT"); + + b.Property("Data") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50000); + + b.Property("DeviceCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("Expiration") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("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("Key") + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("ClientId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("CreationTime") + .HasColumnType("TEXT"); + + b.Property("Data") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50000); + + b.Property("Expiration") + .HasColumnType("TEXT"); + + b.Property("SubjectId") + .HasColumnType("TEXT") + .HasMaxLength(200); + + b.Property("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 + } + } +} diff --git a/Kyoo/Models/DatabaseMigrations/Internal/20200303213358_Initial.Designer.cs b/Kyoo/Models/DatabaseMigrations/Internal/20200303213358_Initial.Designer.cs new file mode 100644 index 00000000..ff44ad18 --- /dev/null +++ b/Kyoo/Models/DatabaseMigrations/Internal/20200303213358_Initial.Designer.cs @@ -0,0 +1,496 @@ +// +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/20200303213358_Initial.cs b/Kyoo/Models/DatabaseMigrations/Internal/20200303213358_Initial.cs new file mode 100644 index 00000000..e88c29f8 --- /dev/null +++ b/Kyoo/Models/DatabaseMigrations/Internal/20200303213358_Initial.cs @@ -0,0 +1,426 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Kyoo.Models.DatabaseMigrations +{ + public partial class Initial : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Collections", + columns: table => new + { + ID = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Slug = table.Column(nullable: true), + Name = table.Column(nullable: true), + Poster = table.Column(nullable: true), + Overview = table.Column(nullable: true), + ImgPrimary = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Collections", x => x.ID); + }); + + migrationBuilder.CreateTable( + name: "Genres", + columns: table => new + { + ID = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Slug = table.Column(nullable: true), + Name = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Genres", x => x.ID); + }); + + migrationBuilder.CreateTable( + name: "Libraries", + columns: table => new + { + ID = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Slug = table.Column(nullable: true), + Name = table.Column(nullable: true), + Paths = table.Column(nullable: true), + Providers = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Libraries", x => x.ID); + }); + + migrationBuilder.CreateTable( + name: "Peoples", + columns: table => new + { + Slug = table.Column(nullable: false), + Name = table.Column(nullable: true), + ImgPrimary = table.Column(nullable: true), + ExternalIDs = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Peoples", x => x.Slug); + }); + + migrationBuilder.CreateTable( + name: "Studios", + columns: table => new + { + ID = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Slug = table.Column(nullable: true), + Name = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Studios", x => x.ID); + }); + + migrationBuilder.CreateTable( + name: "Shows", + columns: table => new + { + ID = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Slug = table.Column(nullable: true), + Title = table.Column(nullable: true), + Aliases = table.Column(nullable: true), + Path = table.Column(nullable: true), + Overview = table.Column(nullable: true), + Status = table.Column(nullable: true), + TrailerUrl = table.Column(nullable: true), + StartYear = table.Column(nullable: true), + EndYear = table.Column(nullable: true), + ImgPrimary = table.Column(nullable: true), + ImgThumb = table.Column(nullable: true), + ImgLogo = table.Column(nullable: true), + ImgBackdrop = table.Column(nullable: true), + ExternalIDs = table.Column(nullable: true), + IsMovie = table.Column(nullable: false), + StudioID = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Shows", x => x.ID); + table.ForeignKey( + name: "FK_Shows_Studios_StudioID", + column: x => x.StudioID, + principalTable: "Studios", + principalColumn: "ID", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "CollectionLinks", + columns: table => new + { + ID = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + CollectionID = table.Column(nullable: true), + ShowID = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CollectionLinks", x => x.ID); + table.ForeignKey( + name: "FK_CollectionLinks_Collections_CollectionID", + column: x => x.CollectionID, + principalTable: "Collections", + principalColumn: "ID", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_CollectionLinks_Shows_ShowID", + column: x => x.ShowID, + principalTable: "Shows", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "GenreLinks", + columns: table => new + { + ShowID = table.Column(nullable: false), + GenreID = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_GenreLinks", x => new { x.ShowID, x.GenreID }); + table.ForeignKey( + name: "FK_GenreLinks_Genres_GenreID", + column: x => x.GenreID, + principalTable: "Genres", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_GenreLinks_Shows_ShowID", + column: x => x.ShowID, + principalTable: "Shows", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "LibraryLinks", + columns: table => new + { + ID = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + LibraryID = table.Column(nullable: false), + ShowID = table.Column(nullable: true), + CollectionID = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_LibraryLinks", x => x.ID); + table.ForeignKey( + name: "FK_LibraryLinks_Collections_CollectionID", + column: x => x.CollectionID, + principalTable: "Collections", + principalColumn: "ID", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_LibraryLinks_Libraries_LibraryID", + column: x => x.LibraryID, + principalTable: "Libraries", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_LibraryLinks_Shows_ShowID", + column: x => x.ShowID, + principalTable: "Shows", + principalColumn: "ID", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "PeopleLinks", + columns: table => new + { + ID = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + PeopleID = table.Column(nullable: true), + ShowID = table.Column(nullable: false), + Role = table.Column(nullable: true), + Type = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_PeopleLinks", x => x.ID); + table.ForeignKey( + name: "FK_PeopleLinks_Peoples_PeopleID", + column: x => x.PeopleID, + principalTable: "Peoples", + principalColumn: "Slug", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_PeopleLinks_Shows_ShowID", + column: x => x.ShowID, + principalTable: "Shows", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Seasons", + columns: table => new + { + ID = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + ShowID = table.Column(nullable: false), + SeasonNumber = table.Column(nullable: false), + Title = table.Column(nullable: true), + Overview = table.Column(nullable: true), + Year = table.Column(nullable: true), + ImgPrimary = table.Column(nullable: true), + ExternalIDs = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Seasons", x => x.ID); + table.ForeignKey( + name: "FK_Seasons_Shows_ShowID", + column: x => x.ShowID, + principalTable: "Shows", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Episodes", + columns: table => new + { + ID = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + ShowID = table.Column(nullable: false), + SeasonID = table.Column(nullable: true), + SeasonNumber = table.Column(nullable: false), + EpisodeNumber = table.Column(nullable: false), + AbsoluteNumber = table.Column(nullable: false), + Path = table.Column(nullable: true), + Title = table.Column(nullable: true), + Overview = table.Column(nullable: true), + ReleaseDate = table.Column(nullable: true), + Runtime = table.Column(nullable: false), + ImgPrimary = table.Column(nullable: true), + ExternalIDs = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Episodes", x => x.ID); + table.ForeignKey( + name: "FK_Episodes_Seasons_SeasonID", + column: x => x.SeasonID, + principalTable: "Seasons", + principalColumn: "ID", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_Episodes_Shows_ShowID", + column: x => x.ShowID, + principalTable: "Shows", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Tracks", + columns: table => new + { + ID = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Title = table.Column(nullable: true), + Language = table.Column(nullable: true), + Codec = table.Column(nullable: true), + Path = table.Column(nullable: true), + Type = table.Column(nullable: false), + EpisodeID = table.Column(nullable: false), + IsDefault = table.Column(nullable: false), + IsForced = table.Column(nullable: false), + IsExternal = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Tracks", x => x.ID); + table.ForeignKey( + name: "FK_Tracks_Episodes_EpisodeID", + column: x => x.EpisodeID, + principalTable: "Episodes", + principalColumn: "ID", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_CollectionLinks_CollectionID", + table: "CollectionLinks", + column: "CollectionID"); + + migrationBuilder.CreateIndex( + name: "IX_CollectionLinks_ShowID", + table: "CollectionLinks", + column: "ShowID"); + + migrationBuilder.CreateIndex( + name: "IX_Episodes_SeasonID", + table: "Episodes", + column: "SeasonID"); + + migrationBuilder.CreateIndex( + name: "IX_Episodes_ShowID", + table: "Episodes", + column: "ShowID"); + + migrationBuilder.CreateIndex( + name: "IX_GenreLinks_GenreID", + table: "GenreLinks", + column: "GenreID"); + + migrationBuilder.CreateIndex( + name: "IX_LibraryLinks_CollectionID", + table: "LibraryLinks", + column: "CollectionID"); + + migrationBuilder.CreateIndex( + name: "IX_LibraryLinks_LibraryID", + table: "LibraryLinks", + column: "LibraryID"); + + migrationBuilder.CreateIndex( + name: "IX_LibraryLinks_ShowID", + table: "LibraryLinks", + column: "ShowID"); + + migrationBuilder.CreateIndex( + name: "IX_PeopleLinks_PeopleID", + table: "PeopleLinks", + column: "PeopleID"); + + migrationBuilder.CreateIndex( + name: "IX_PeopleLinks_ShowID", + table: "PeopleLinks", + column: "ShowID"); + + migrationBuilder.CreateIndex( + name: "IX_Seasons_ShowID", + table: "Seasons", + column: "ShowID"); + + migrationBuilder.CreateIndex( + name: "IX_Shows_StudioID", + table: "Shows", + column: "StudioID"); + + migrationBuilder.CreateIndex( + name: "IX_Tracks_EpisodeID", + table: "Tracks", + column: "EpisodeID"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "CollectionLinks"); + + migrationBuilder.DropTable( + name: "GenreLinks"); + + migrationBuilder.DropTable( + name: "LibraryLinks"); + + migrationBuilder.DropTable( + name: "PeopleLinks"); + + migrationBuilder.DropTable( + name: "Tracks"); + + migrationBuilder.DropTable( + name: "Genres"); + + migrationBuilder.DropTable( + name: "Collections"); + + migrationBuilder.DropTable( + name: "Libraries"); + + migrationBuilder.DropTable( + name: "Peoples"); + + migrationBuilder.DropTable( + name: "Episodes"); + + migrationBuilder.DropTable( + name: "Seasons"); + + migrationBuilder.DropTable( + name: "Shows"); + + migrationBuilder.DropTable( + name: "Studios"); + } + } +} diff --git a/Kyoo/Models/DatabaseMigrations/Internal/20200306000057_Adding accounts.Designer.cs b/Kyoo/Models/DatabaseMigrations/Internal/20200306000057_Adding accounts.Designer.cs new file mode 100644 index 00000000..f45bfa68 --- /dev/null +++ b/Kyoo/Models/DatabaseMigrations/Internal/20200306000057_Adding accounts.Designer.cs @@ -0,0 +1,554 @@ +// +using System; +using Kyoo; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace Kyoo.Models.DatabaseMigrations.Internal +{ + [DbContext(typeof(DatabaseContext))] + [Migration("20200306000057_Adding accounts")] + partial class Addingaccounts + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2"); + + modelBuilder.Entity("Kyoo.Models.Account", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .HasColumnType("TEXT"); + + b.Property("Email") + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasColumnType("TEXT"); + + b.Property("OTAC") + .HasColumnType("TEXT"); + + b.Property("OTACExpires") + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Accounts"); + }); + + 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 new file mode 100644 index 00000000..99fe4424 --- /dev/null +++ b/Kyoo/Models/DatabaseMigrations/Internal/20200306000057_Adding accounts.cs @@ -0,0 +1,44 @@ +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/DatabaseContextModelSnapshot.cs b/Kyoo/Models/DatabaseMigrations/Internal/DatabaseContextModelSnapshot.cs new file mode 100644 index 00000000..544fb00c --- /dev/null +++ b/Kyoo/Models/DatabaseMigrations/Internal/DatabaseContextModelSnapshot.cs @@ -0,0 +1,552 @@ +// +using System; +using Kyoo; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + +namespace Kyoo.Models.DatabaseMigrations +{ + [DbContext(typeof(DatabaseContext))] + partial class DatabaseContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2"); + + modelBuilder.Entity("Kyoo.Models.Account", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .HasColumnType("TEXT"); + + b.Property("Email") + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasColumnType("TEXT"); + + b.Property("OTAC") + .HasColumnType("TEXT"); + + b.Property("OTACExpires") + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Accounts"); + }); + + 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/IdentityContext.cs b/Kyoo/Models/IdentityContext.cs similarity index 68% rename from Kyoo/IdentityContext.cs rename to Kyoo/Models/IdentityContext.cs index d612e321..0728b102 100644 --- a/Kyoo/IdentityContext.cs +++ b/Kyoo/Models/IdentityContext.cs @@ -14,6 +14,22 @@ namespace Kyoo new IdentityResources.Profile() }; } + + public static IEnumerable GetClients() + { + return new List + { + new Client + { + ClientId = "kyoo.webapp", + ClientSecrets = { new Secret("secret".Sha256()) }, + AllowedGrantTypes = GrantTypes.Implicit, + AllowedScopes = { "kyoo.admin", "kyoo.write", "kyoo.read", "openid", "profile" }, + AllowAccessTokensViaBrowser = true, + RequireConsent = false + } + }; + } public static IEnumerable GetApis() { diff --git a/Kyoo/Startup.cs b/Kyoo/Startup.cs index 600d447d..724a2f86 100644 --- a/Kyoo/Startup.cs +++ b/Kyoo/Startup.cs @@ -1,8 +1,6 @@ -using System.Collections.Generic; -using IdentityServer4.EntityFramework.DbContexts; -using IdentityServer4.Models; -using IdentityServer4.Stores; +using System.Reflection; using Kyoo.Controllers; +using Kyoo.Models; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Identity; @@ -35,21 +33,34 @@ namespace Kyoo services.AddControllers().AddNewtonsoftJson(); services.AddHttpClient(); + string assemblyName = typeof(Startup).GetTypeInfo().Assembly.GetName().Name; + string publicUrl = Configuration.GetValue("public_url"); + services.AddDbContext(options => options.UseLazyLoadingProxies() .UseSqlite(Configuration.GetConnectionString("Database"))); - services.AddIdentityServer() + services.AddIdentity() + .AddEntityFrameworkStores() + .AddDefaultTokenProviders(); + + services.AddIdentityServer(options => + { + options.UserInteraction.LoginUrl = publicUrl + "/login"; + options.UserInteraction.ErrorUrl = publicUrl + "/error"; + options.UserInteraction.LogoutUrl = publicUrl + "/logout"; + }) .AddConfigurationStore(options => { - options.ConfigureDbContext = builder => builder.UseSqlite(Configuration.GetConnectionString("Database")); + options.ConfigureDbContext = builder => builder.UseSqlite(Configuration.GetConnectionString("Database"), sql => sql.MigrationsAssembly(assemblyName)); }) .AddOperationalStore(options => { - options.ConfigureDbContext = builder => builder.UseSqlite(Configuration.GetConnectionString("Database")); + options.ConfigureDbContext = builder => builder.UseSqlite(Configuration.GetConnectionString("Database"), sql => sql.MigrationsAssembly(assemblyName)); options.EnableTokenCleanup = true; }) .AddInMemoryIdentityResources(IdentityContext.GetIdentityResources()) - .AddInMemoryApiResources(IdentityContext.GetApis()); + .AddInMemoryApiResources(IdentityContext.GetApis()) + .AddAspNetIdentity(); services.AddScoped(); services.AddScoped(); diff --git a/Kyoo/Views/API/AccountAPI.cs b/Kyoo/Views/API/AccountAPI.cs new file mode 100644 index 00000000..583fc204 --- /dev/null +++ b/Kyoo/Views/API/AccountAPI.cs @@ -0,0 +1,41 @@ +using System; +using System.Threading.Tasks; +using Kyoo.Models; +using Microsoft.AspNetCore.Identity; +using Microsoft.AspNetCore.Mvc; + +namespace Kyoo.Api +{ + public class RegisterRequest + { + public string Email; + public string Username; + public string Password; + } + + [Route("api/[controller]")] + [ApiController] + public class AccountController : Controller + { + private readonly UserManager _accountManager; + + public AccountController(UserManager accountManager) + { + _accountManager = accountManager; + } + + [HttpPost("register")] + public async Task Register([FromBody] RegisterRequest user) + { + if (!ModelState.IsValid) + return BadRequest(user); + Account account = new Account {UserName = user.Username, Email = user.Email}; + IdentityResult result = await _accountManager.CreateAsync(account, user.Password); + if (!result.Succeeded) + return BadRequest(result.Errors); + string otac = account.GenerateOTAC(TimeSpan.FromMinutes(1)); + await _accountManager.UpdateAsync(account); + return Ok(otac); + } + } +} \ No newline at end of file diff --git a/Kyoo/Views/API/AuthentificationAPI.cs b/Kyoo/Views/API/AuthentificationAPI.cs deleted file mode 100644 index b9021ca1..00000000 --- a/Kyoo/Views/API/AuthentificationAPI.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System.Threading; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; - -namespace Kyoo.Api -{ - public class AuthentificationAPI : Controller - { - // [Authorize, HttpGet("/connect/authorize")] - // public async Task Authorize(CancellationToken token) - // { - // //HttpContext.GetOpenIdConnectResponse() - // } - } -} \ No newline at end of file diff --git a/Kyoo/Views/WebClient b/Kyoo/Views/WebClient index 965c5d6a..af2478da 160000 --- a/Kyoo/Views/WebClient +++ b/Kyoo/Views/WebClient @@ -1 +1 @@ -Subproject commit 965c5d6a6125c5b6c3ef949d007e202ad66549df +Subproject commit af2478da584eacee6377e50dbb4c530cffd7e0b6 diff --git a/Kyoo/appsettings.json b/Kyoo/appsettings.json index 14b9695f..feb1809f 100644 --- a/Kyoo/appsettings.json +++ b/Kyoo/appsettings.json @@ -1,5 +1,6 @@ { "server.urls": "http://0.0.0.0:5000", + "public_url": "http://localhost:5000/", "https_port": 44300, "Logging": { "LogLevel": {