diff --git a/scripts/AddPostgresSecurityMigration.cmd b/scripts/AddPostgresSecurityMigration.cmd new file mode 100644 index 00000000..706f9873 --- /dev/null +++ b/scripts/AddPostgresSecurityMigration.cmd @@ -0,0 +1 @@ +dotnet ef migrations add --context TagzApp.Web.Data.SecurityContext -p ..\src\TagzApp.Storage.Postgres.Security\ -s ..\src\TagzApp.Web %1 \ No newline at end of file diff --git a/src/TagzApp.Storage.Postgres.Security/Migrations/20231207200417_AddDataProtectionKeys.Designer.cs b/src/TagzApp.Storage.Postgres.Security/Migrations/20231207200417_AddDataProtectionKeys.Designer.cs new file mode 100644 index 00000000..5017b4db --- /dev/null +++ b/src/TagzApp.Storage.Postgres.Security/Migrations/20231207200417_AddDataProtectionKeys.Designer.cs @@ -0,0 +1,317 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using TagzApp.Web.Data; + +#nullable disable + +namespace TagzApp.Storage.Postgres.Security.Migrations +{ + [DbContext(typeof(SecurityContext))] + [Migration("20231207200417_Add DataProtectionKeys")] + partial class AddDataProtectionKeys + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FriendlyName") + .HasColumnType("text"); + + b.Property("Xml") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("DataProtectionKeys"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ProviderKey") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ProviderDisplayName") + .HasColumnType("text"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("text"); + + b.Property("RoleId") + .HasColumnType("text"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("text"); + + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Value") + .HasColumnType("text"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("TagzApp.Common.Models.Settings", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("Value") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Settings"); + }); + + modelBuilder.Entity("TagzApp.Web.Data.TagzAppUser", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("AccessFailedCount") + .HasColumnType("integer"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("DisplayName") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("boolean"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordHash") + .HasColumnType("text"); + + b.Property("PhoneNumber") + .HasColumnType("text"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean"); + + b.Property("SecurityStamp") + .HasColumnType("text"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("TagzApp.Web.Data.TagzAppUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("TagzApp.Web.Data.TagzAppUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("TagzApp.Web.Data.TagzAppUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("TagzApp.Web.Data.TagzAppUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/TagzApp.Storage.Postgres.Security/Migrations/20231207200417_AddDataProtectionKeys.cs b/src/TagzApp.Storage.Postgres.Security/Migrations/20231207200417_AddDataProtectionKeys.cs new file mode 100644 index 00000000..afe28d2d --- /dev/null +++ b/src/TagzApp.Storage.Postgres.Security/Migrations/20231207200417_AddDataProtectionKeys.cs @@ -0,0 +1,36 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace TagzApp.Storage.Postgres.Security.Migrations +{ + /// + public partial class AddDataProtectionKeys : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "DataProtectionKeys", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + FriendlyName = table.Column(type: "text", nullable: true), + Xml = table.Column(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_DataProtectionKeys", x => x.Id); + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "DataProtectionKeys"); + } + } +} diff --git a/src/TagzApp.Storage.Postgres.Security/Migrations/SecurityContextModelSnapshot.cs b/src/TagzApp.Storage.Postgres.Security/Migrations/SecurityContextModelSnapshot.cs index 4bcf23dd..5e001df7 100644 --- a/src/TagzApp.Storage.Postgres.Security/Migrations/SecurityContextModelSnapshot.cs +++ b/src/TagzApp.Storage.Postgres.Security/Migrations/SecurityContextModelSnapshot.cs @@ -17,11 +17,30 @@ protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "8.0.0-rc.1.23419.6") + .HasAnnotation("ProductVersion", "8.0.0") .HasAnnotation("Relational:MaxIdentifierLength", 63); NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + modelBuilder.Entity("Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FriendlyName") + .HasColumnType("text"); + + b.Property("Xml") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("DataProtectionKeys"); + }); + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => { b.Property("Id") diff --git a/src/TagzApp.Web/Areas/Identity/Data/SecurityContext.cs b/src/TagzApp.Web/Areas/Identity/Data/SecurityContext.cs index 6361cba7..56d60854 100644 --- a/src/TagzApp.Web/Areas/Identity/Data/SecurityContext.cs +++ b/src/TagzApp.Web/Areas/Identity/Data/SecurityContext.cs @@ -1,9 +1,10 @@ -using Microsoft.AspNetCore.Identity.EntityFrameworkCore; +using Microsoft.AspNetCore.DataProtection.EntityFrameworkCore; +using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; namespace TagzApp.Web.Data; -public class SecurityContext : IdentityDbContext +public class SecurityContext : IdentityDbContext, IDataProtectionKeyContext { private readonly IConfiguration _Configuration; @@ -22,8 +23,14 @@ protected override void OnModelCreating(ModelBuilder builder) // Customize the ASP.NET Identity model and override the defaults if needed. // For example, you can rename the ASP.NET Identity table names and more. // Add your customizations after calling base.OnModelCreating(builder); + + builder.Entity().Property(d => d.Id) + .UseIdentityColumn(); + } public DbSet Settings => Set(); + public DbSet DataProtectionKeys { get; set; } + } diff --git a/src/TagzApp.Web/Migrations/20231207173854_Add Data Protection Keys.Designer.cs b/src/TagzApp.Web/Migrations/20231207173854_Add Data Protection Keys.Designer.cs new file mode 100644 index 00000000..e8ea0759 --- /dev/null +++ b/src/TagzApp.Web/Migrations/20231207173854_Add Data Protection Keys.Designer.cs @@ -0,0 +1,306 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using TagzApp.Web.Data; + +#nullable disable + +namespace TagzApp.Web.Migrations +{ + [DbContext(typeof(SecurityContext))] + [Migration("20231207173854_Add Data Protection Keys")] + partial class AddDataProtectionKeys + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "8.0.0"); + + modelBuilder.Entity("Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("FriendlyName") + .HasColumnType("TEXT"); + + b.Property("Xml") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("DataProtectionKeys"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("TagzApp.Common.Models.Settings", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Settings"); + }); + + modelBuilder.Entity("TagzApp.Web.Data.TagzAppUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("DisplayName") + .HasMaxLength(50) + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .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") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("TagzApp.Web.Data.TagzAppUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("TagzApp.Web.Data.TagzAppUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("TagzApp.Web.Data.TagzAppUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("TagzApp.Web.Data.TagzAppUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/TagzApp.Web/Migrations/20231207173854_Add Data Protection Keys.cs b/src/TagzApp.Web/Migrations/20231207173854_Add Data Protection Keys.cs new file mode 100644 index 00000000..39ec5614 --- /dev/null +++ b/src/TagzApp.Web/Migrations/20231207173854_Add Data Protection Keys.cs @@ -0,0 +1,35 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace TagzApp.Web.Migrations +{ + /// + public partial class AddDataProtectionKeys : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "DataProtectionKeys", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + FriendlyName = table.Column(type: "TEXT", nullable: true), + Xml = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_DataProtectionKeys", x => x.Id); + }); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "DataProtectionKeys"); + } + } +} diff --git a/src/TagzApp.Web/Migrations/20231207182626_Autoincrement data protection keys.Designer.cs b/src/TagzApp.Web/Migrations/20231207182626_Autoincrement data protection keys.Designer.cs new file mode 100644 index 00000000..57b53599 --- /dev/null +++ b/src/TagzApp.Web/Migrations/20231207182626_Autoincrement data protection keys.Designer.cs @@ -0,0 +1,317 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using TagzApp.Web.Data; + +#nullable disable + +namespace TagzApp.Web.Migrations +{ + [DbContext(typeof(SecurityContext))] + [Migration("20231207182626_Autoincrement data protection keys")] + partial class Autoincrementdataprotectionkeys + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FriendlyName") + .HasColumnType("text"); + + b.Property("Xml") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("DataProtectionKeys"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ProviderKey") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ProviderDisplayName") + .HasColumnType("text"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("text"); + + b.Property("RoleId") + .HasColumnType("text"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("text"); + + b.Property("LoginProvider") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Value") + .HasColumnType("text"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("TagzApp.Common.Models.Settings", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("Value") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Settings"); + }); + + modelBuilder.Entity("TagzApp.Web.Data.TagzAppUser", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("AccessFailedCount") + .HasColumnType("integer"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("DisplayName") + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("boolean"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordHash") + .HasColumnType("text"); + + b.Property("PhoneNumber") + .HasColumnType("text"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean"); + + b.Property("SecurityStamp") + .HasColumnType("text"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("TagzApp.Web.Data.TagzAppUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("TagzApp.Web.Data.TagzAppUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("TagzApp.Web.Data.TagzAppUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("TagzApp.Web.Data.TagzAppUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/TagzApp.Web/Migrations/20231207182626_Autoincrement data protection keys.cs b/src/TagzApp.Web/Migrations/20231207182626_Autoincrement data protection keys.cs new file mode 100644 index 00000000..ed8b46c3 --- /dev/null +++ b/src/TagzApp.Web/Migrations/20231207182626_Autoincrement data protection keys.cs @@ -0,0 +1,802 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace TagzApp.Web.Migrations +{ + /// + public partial class Autoincrementdataprotectionkeys : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Value", + table: "Settings", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Id", + table: "Settings", + type: "text", + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "Xml", + table: "DataProtectionKeys", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "FriendlyName", + table: "DataProtectionKeys", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Id", + table: "DataProtectionKeys", + type: "integer", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER") + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + migrationBuilder.AlterColumn( + name: "Value", + table: "AspNetUserTokens", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Name", + table: "AspNetUserTokens", + type: "character varying(128)", + maxLength: 128, + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT", + oldMaxLength: 128); + + migrationBuilder.AlterColumn( + name: "LoginProvider", + table: "AspNetUserTokens", + type: "character varying(128)", + maxLength: 128, + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT", + oldMaxLength: 128); + + migrationBuilder.AlterColumn( + name: "UserId", + table: "AspNetUserTokens", + type: "text", + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "UserName", + table: "AspNetUsers", + type: "character varying(256)", + maxLength: 256, + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldMaxLength: 256, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "TwoFactorEnabled", + table: "AspNetUsers", + type: "boolean", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "SecurityStamp", + table: "AspNetUsers", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "PhoneNumberConfirmed", + table: "AspNetUsers", + type: "boolean", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "PhoneNumber", + table: "AspNetUsers", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "PasswordHash", + table: "AspNetUsers", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "NormalizedUserName", + table: "AspNetUsers", + type: "character varying(256)", + maxLength: 256, + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldMaxLength: 256, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "NormalizedEmail", + table: "AspNetUsers", + type: "character varying(256)", + maxLength: 256, + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldMaxLength: 256, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "LockoutEnd", + table: "AspNetUsers", + type: "timestamp with time zone", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "LockoutEnabled", + table: "AspNetUsers", + type: "boolean", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "EmailConfirmed", + table: "AspNetUsers", + type: "boolean", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "Email", + table: "AspNetUsers", + type: "character varying(256)", + maxLength: 256, + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldMaxLength: 256, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "DisplayName", + table: "AspNetUsers", + type: "character varying(50)", + maxLength: 50, + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldMaxLength: 50, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ConcurrencyStamp", + table: "AspNetUsers", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "AccessFailedCount", + table: "AspNetUsers", + type: "integer", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "AspNetUsers", + type: "text", + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "RoleId", + table: "AspNetUserRoles", + type: "text", + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "UserId", + table: "AspNetUserRoles", + type: "text", + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "UserId", + table: "AspNetUserLogins", + type: "text", + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "ProviderDisplayName", + table: "AspNetUserLogins", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ProviderKey", + table: "AspNetUserLogins", + type: "character varying(128)", + maxLength: 128, + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT", + oldMaxLength: 128); + + migrationBuilder.AlterColumn( + name: "LoginProvider", + table: "AspNetUserLogins", + type: "character varying(128)", + maxLength: 128, + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT", + oldMaxLength: 128); + + migrationBuilder.AlterColumn( + name: "UserId", + table: "AspNetUserClaims", + type: "text", + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "ClaimValue", + table: "AspNetUserClaims", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ClaimType", + table: "AspNetUserClaims", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Id", + table: "AspNetUserClaims", + type: "integer", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER") + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + migrationBuilder.AlterColumn( + name: "NormalizedName", + table: "AspNetRoles", + type: "character varying(256)", + maxLength: 256, + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldMaxLength: 256, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Name", + table: "AspNetRoles", + type: "character varying(256)", + maxLength: 256, + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldMaxLength: 256, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ConcurrencyStamp", + table: "AspNetRoles", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Id", + table: "AspNetRoles", + type: "text", + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "RoleId", + table: "AspNetRoleClaims", + type: "text", + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "ClaimValue", + table: "AspNetRoleClaims", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ClaimType", + table: "AspNetRoleClaims", + type: "text", + nullable: true, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Id", + table: "AspNetRoleClaims", + type: "integer", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER") + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Value", + table: "Settings", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Id", + table: "Settings", + type: "TEXT", + nullable: false, + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "Xml", + table: "DataProtectionKeys", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "FriendlyName", + table: "DataProtectionKeys", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Id", + table: "DataProtectionKeys", + type: "INTEGER", + nullable: false, + oldClrType: typeof(int), + oldType: "integer") + .OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + migrationBuilder.AlterColumn( + name: "Value", + table: "AspNetUserTokens", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Name", + table: "AspNetUserTokens", + type: "TEXT", + maxLength: 128, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(128)", + oldMaxLength: 128); + + migrationBuilder.AlterColumn( + name: "LoginProvider", + table: "AspNetUserTokens", + type: "TEXT", + maxLength: 128, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(128)", + oldMaxLength: 128); + + migrationBuilder.AlterColumn( + name: "UserId", + table: "AspNetUserTokens", + type: "TEXT", + nullable: false, + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "UserName", + table: "AspNetUsers", + type: "TEXT", + maxLength: 256, + nullable: true, + oldClrType: typeof(string), + oldType: "character varying(256)", + oldMaxLength: 256, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "TwoFactorEnabled", + table: "AspNetUsers", + type: "INTEGER", + nullable: false, + oldClrType: typeof(bool), + oldType: "boolean"); + + migrationBuilder.AlterColumn( + name: "SecurityStamp", + table: "AspNetUsers", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "PhoneNumberConfirmed", + table: "AspNetUsers", + type: "INTEGER", + nullable: false, + oldClrType: typeof(bool), + oldType: "boolean"); + + migrationBuilder.AlterColumn( + name: "PhoneNumber", + table: "AspNetUsers", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "PasswordHash", + table: "AspNetUsers", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "NormalizedUserName", + table: "AspNetUsers", + type: "TEXT", + maxLength: 256, + nullable: true, + oldClrType: typeof(string), + oldType: "character varying(256)", + oldMaxLength: 256, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "NormalizedEmail", + table: "AspNetUsers", + type: "TEXT", + maxLength: 256, + nullable: true, + oldClrType: typeof(string), + oldType: "character varying(256)", + oldMaxLength: 256, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "LockoutEnd", + table: "AspNetUsers", + type: "TEXT", + nullable: true, + oldClrType: typeof(DateTimeOffset), + oldType: "timestamp with time zone", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "LockoutEnabled", + table: "AspNetUsers", + type: "INTEGER", + nullable: false, + oldClrType: typeof(bool), + oldType: "boolean"); + + migrationBuilder.AlterColumn( + name: "EmailConfirmed", + table: "AspNetUsers", + type: "INTEGER", + nullable: false, + oldClrType: typeof(bool), + oldType: "boolean"); + + migrationBuilder.AlterColumn( + name: "Email", + table: "AspNetUsers", + type: "TEXT", + maxLength: 256, + nullable: true, + oldClrType: typeof(string), + oldType: "character varying(256)", + oldMaxLength: 256, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "DisplayName", + table: "AspNetUsers", + type: "TEXT", + maxLength: 50, + nullable: true, + oldClrType: typeof(string), + oldType: "character varying(50)", + oldMaxLength: 50, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ConcurrencyStamp", + table: "AspNetUsers", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "AccessFailedCount", + table: "AspNetUsers", + type: "INTEGER", + nullable: false, + oldClrType: typeof(int), + oldType: "integer"); + + migrationBuilder.AlterColumn( + name: "Id", + table: "AspNetUsers", + type: "TEXT", + nullable: false, + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "RoleId", + table: "AspNetUserRoles", + type: "TEXT", + nullable: false, + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "UserId", + table: "AspNetUserRoles", + type: "TEXT", + nullable: false, + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "UserId", + table: "AspNetUserLogins", + type: "TEXT", + nullable: false, + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "ProviderDisplayName", + table: "AspNetUserLogins", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ProviderKey", + table: "AspNetUserLogins", + type: "TEXT", + maxLength: 128, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(128)", + oldMaxLength: 128); + + migrationBuilder.AlterColumn( + name: "LoginProvider", + table: "AspNetUserLogins", + type: "TEXT", + maxLength: 128, + nullable: false, + oldClrType: typeof(string), + oldType: "character varying(128)", + oldMaxLength: 128); + + migrationBuilder.AlterColumn( + name: "UserId", + table: "AspNetUserClaims", + type: "TEXT", + nullable: false, + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "ClaimValue", + table: "AspNetUserClaims", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ClaimType", + table: "AspNetUserClaims", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Id", + table: "AspNetUserClaims", + type: "INTEGER", + nullable: false, + oldClrType: typeof(int), + oldType: "integer") + .OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + migrationBuilder.AlterColumn( + name: "NormalizedName", + table: "AspNetRoles", + type: "TEXT", + maxLength: 256, + nullable: true, + oldClrType: typeof(string), + oldType: "character varying(256)", + oldMaxLength: 256, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Name", + table: "AspNetRoles", + type: "TEXT", + maxLength: 256, + nullable: true, + oldClrType: typeof(string), + oldType: "character varying(256)", + oldMaxLength: 256, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ConcurrencyStamp", + table: "AspNetRoles", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Id", + table: "AspNetRoles", + type: "TEXT", + nullable: false, + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "RoleId", + table: "AspNetRoleClaims", + type: "TEXT", + nullable: false, + oldClrType: typeof(string), + oldType: "text"); + + migrationBuilder.AlterColumn( + name: "ClaimValue", + table: "AspNetRoleClaims", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ClaimType", + table: "AspNetRoleClaims", + type: "TEXT", + nullable: true, + oldClrType: typeof(string), + oldType: "text", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Id", + table: "AspNetRoleClaims", + type: "INTEGER", + nullable: false, + oldClrType: typeof(int), + oldType: "integer") + .OldAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + } + } +} diff --git a/src/TagzApp.Web/Migrations/SecurityContextModelSnapshot.cs b/src/TagzApp.Web/Migrations/SecurityContextModelSnapshot.cs index 8c3a095a..e9725802 100644 --- a/src/TagzApp.Web/Migrations/SecurityContextModelSnapshot.cs +++ b/src/TagzApp.Web/Migrations/SecurityContextModelSnapshot.cs @@ -3,6 +3,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; using TagzApp.Web.Data; #nullable disable @@ -15,24 +16,47 @@ partial class SecurityContextModelSnapshot : ModelSnapshot protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 - modelBuilder.HasAnnotation("ProductVersion", "8.0.0-rc.1.23419.6"); + modelBuilder + .HasAnnotation("ProductVersion", "8.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.DataProtectionKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FriendlyName") + .HasColumnType("text"); + + b.Property("Xml") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("DataProtectionKeys"); + }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => { b.Property("Id") - .HasColumnType("TEXT"); + .HasColumnType("text"); b.Property("ConcurrencyStamp") .IsConcurrencyToken() - .HasColumnType("TEXT"); + .HasColumnType("text"); b.Property("Name") .HasMaxLength(256) - .HasColumnType("TEXT"); + .HasColumnType("character varying(256)"); b.Property("NormalizedName") .HasMaxLength(256) - .HasColumnType("TEXT"); + .HasColumnType("character varying(256)"); b.HasKey("Id"); @@ -47,17 +71,19 @@ protected override void BuildModel(ModelBuilder modelBuilder) { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("ClaimType") - .HasColumnType("TEXT"); + .HasColumnType("text"); b.Property("ClaimValue") - .HasColumnType("TEXT"); + .HasColumnType("text"); b.Property("RoleId") .IsRequired() - .HasColumnType("TEXT"); + .HasColumnType("text"); b.HasKey("Id"); @@ -70,17 +96,19 @@ protected override void BuildModel(ModelBuilder modelBuilder) { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("ClaimType") - .HasColumnType("TEXT"); + .HasColumnType("text"); b.Property("ClaimValue") - .HasColumnType("TEXT"); + .HasColumnType("text"); b.Property("UserId") .IsRequired() - .HasColumnType("TEXT"); + .HasColumnType("text"); b.HasKey("Id"); @@ -93,18 +121,18 @@ protected override void BuildModel(ModelBuilder modelBuilder) { b.Property("LoginProvider") .HasMaxLength(128) - .HasColumnType("TEXT"); + .HasColumnType("character varying(128)"); b.Property("ProviderKey") .HasMaxLength(128) - .HasColumnType("TEXT"); + .HasColumnType("character varying(128)"); b.Property("ProviderDisplayName") - .HasColumnType("TEXT"); + .HasColumnType("text"); b.Property("UserId") .IsRequired() - .HasColumnType("TEXT"); + .HasColumnType("text"); b.HasKey("LoginProvider", "ProviderKey"); @@ -116,10 +144,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => { b.Property("UserId") - .HasColumnType("TEXT"); + .HasColumnType("text"); b.Property("RoleId") - .HasColumnType("TEXT"); + .HasColumnType("text"); b.HasKey("UserId", "RoleId"); @@ -131,18 +159,18 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => { b.Property("UserId") - .HasColumnType("TEXT"); + .HasColumnType("text"); b.Property("LoginProvider") .HasMaxLength(128) - .HasColumnType("TEXT"); + .HasColumnType("character varying(128)"); b.Property("Name") .HasMaxLength(128) - .HasColumnType("TEXT"); + .HasColumnType("character varying(128)"); b.Property("Value") - .HasColumnType("TEXT"); + .HasColumnType("text"); b.HasKey("UserId", "LoginProvider", "Name"); @@ -152,10 +180,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("TagzApp.Common.Models.Settings", b => { b.Property("Id") - .HasColumnType("TEXT"); + .HasColumnType("text"); b.Property("Value") - .HasColumnType("TEXT"); + .HasColumnType("text"); b.HasKey("Id"); @@ -165,58 +193,58 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("TagzApp.Web.Data.TagzAppUser", b => { b.Property("Id") - .HasColumnType("TEXT"); + .HasColumnType("text"); b.Property("AccessFailedCount") - .HasColumnType("INTEGER"); + .HasColumnType("integer"); b.Property("ConcurrencyStamp") .IsConcurrencyToken() - .HasColumnType("TEXT"); + .HasColumnType("text"); b.Property("DisplayName") .HasMaxLength(50) - .HasColumnType("TEXT"); + .HasColumnType("character varying(50)"); b.Property("Email") .HasMaxLength(256) - .HasColumnType("TEXT"); + .HasColumnType("character varying(256)"); b.Property("EmailConfirmed") - .HasColumnType("INTEGER"); + .HasColumnType("boolean"); b.Property("LockoutEnabled") - .HasColumnType("INTEGER"); + .HasColumnType("boolean"); b.Property("LockoutEnd") - .HasColumnType("TEXT"); + .HasColumnType("timestamp with time zone"); b.Property("NormalizedEmail") .HasMaxLength(256) - .HasColumnType("TEXT"); + .HasColumnType("character varying(256)"); b.Property("NormalizedUserName") .HasMaxLength(256) - .HasColumnType("TEXT"); + .HasColumnType("character varying(256)"); b.Property("PasswordHash") - .HasColumnType("TEXT"); + .HasColumnType("text"); b.Property("PhoneNumber") - .HasColumnType("TEXT"); + .HasColumnType("text"); b.Property("PhoneNumberConfirmed") - .HasColumnType("INTEGER"); + .HasColumnType("boolean"); b.Property("SecurityStamp") - .HasColumnType("TEXT"); + .HasColumnType("text"); b.Property("TwoFactorEnabled") - .HasColumnType("INTEGER"); + .HasColumnType("boolean"); b.Property("UserName") .HasMaxLength(256) - .HasColumnType("TEXT"); + .HasColumnType("character varying(256)"); b.HasKey("Id"); diff --git a/src/TagzApp.Web/Program.cs b/src/TagzApp.Web/Program.cs index 165cab69..6aea1906 100644 --- a/src/TagzApp.Web/Program.cs +++ b/src/TagzApp.Web/Program.cs @@ -1,3 +1,4 @@ +using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Http.Extensions; using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.Identity; @@ -32,6 +33,12 @@ private static void Main(string[] args) // Late bind the connection string so that any changes to the configuration made later on, or in the test fixture can be picked up. builder.Services.AddSecurityContext(builder.Configuration); + // Add DataProtection services + builder.Services.AddDataProtection() + .SetApplicationName("TagzApp") + .SetDefaultKeyLifetime(TimeSpan.FromDays(90)) + .PersistKeysToDbContext(); + builder.Services.AddDefaultIdentity(options => options.SignIn.RequireConfirmedAccount = true ) diff --git a/src/TagzApp.Web/ServicesExtensions.cs b/src/TagzApp.Web/ServicesExtensions.cs index aa45d3e8..784b5050 100644 --- a/src/TagzApp.Web/ServicesExtensions.cs +++ b/src/TagzApp.Web/ServicesExtensions.cs @@ -5,7 +5,6 @@ using TagzApp.Providers.YouTubeChat; using TagzApp.Storage.Postgres; using TagzApp.Web.Data; -using TagzApp.Web.Migrations; using TagzApp.Web.Services; namespace TagzApp.Web; @@ -139,7 +138,7 @@ public static void AddSecurityContext(this IServiceCollection services, IConfigu services.AddDbContext(options => { options.UseNpgsql(configuration.GetConnectionString("TagzAppSecurity"), - pg => pg.MigrationsAssembly(typeof(SecurityContextModelSnapshot).Assembly.FullName)); + pg => pg.MigrationsAssembly("TagzApp.Storage.Postgres.Security")); // "TagzApp.Storage.Postgres.Security, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")); }); @@ -164,6 +163,17 @@ public static void AddSecurityContext(this IServiceCollection services, IConfigu }); } + else + { + + // Add the in-memory provider + services.AddDbContext(options => + { + options.UseInMemoryDatabase("tagzapp"); + }); + + + } } } diff --git a/src/TagzApp.Web/TagzApp.Web.csproj b/src/TagzApp.Web/TagzApp.Web.csproj index bd29b811..dd38b296 100644 --- a/src/TagzApp.Web/TagzApp.Web.csproj +++ b/src/TagzApp.Web/TagzApp.Web.csproj @@ -28,6 +28,7 @@ + diff --git a/src/TagzApp.Web/appsettings.Development.json b/src/TagzApp.Web/appsettings.Development.json index 0b6797d8..38e6d8f6 100644 --- a/src/TagzApp.Web/appsettings.Development.json +++ b/src/TagzApp.Web/appsettings.Development.json @@ -8,7 +8,7 @@ }, "ConnectionStrings": { "TagzApp": "Server=localhost;Port=5432;Database=postgres;User Id=tagz;Password=tagz;", - "_TagzAppSecurity": "Server=localhost;Port=5432;Database=postgres;User Id=tagz;Password=tagz;" + "TagzAppSecurity": "Server=localhost;Port=5432;Database=postgres;User Id=tagz;Password=tagz;" } } diff --git a/src/TagzApp.Web/appsettings.json b/src/TagzApp.Web/appsettings.json index dc4f0e89..61d8aafd 100644 --- a/src/TagzApp.Web/appsettings.json +++ b/src/TagzApp.Web/appsettings.json @@ -7,7 +7,7 @@ }, "ModerationEnabled": true, "ConnectionStrings": { - "SecurityContextConnection": "Data Source=TagzApp.Web.db" + //"SecurityContextConnection": "Data Source=TagzApp.Web.db" }, "AzureContentSafety": { "Enabled": true