23 changed files with 1006 additions and 4 deletions
@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
|
||||
using System; |
||||
using System.Threading; |
||||
using System.Threading.Tasks; |
||||
using Bit.CryptoAgent.Repositories.EntityFramework; |
||||
using Microsoft.EntityFrameworkCore; |
||||
using Microsoft.Extensions.DependencyInjection; |
||||
using Microsoft.Extensions.Hosting; |
||||
using Microsoft.Extensions.Logging; |
||||
|
||||
namespace Bit.CryptoAgent.HostedServices |
||||
{ |
||||
public class DatabaseMigrationHostedService : IHostedService, IDisposable |
||||
{ |
||||
private readonly IServiceScopeFactory _serviceScopeFactory; |
||||
private readonly ILogger<DatabaseMigrationHostedService> _logger; |
||||
|
||||
public DatabaseMigrationHostedService( |
||||
IServiceScopeFactory serviceScopeFactory, |
||||
ILogger<DatabaseMigrationHostedService> logger) |
||||
{ |
||||
_serviceScopeFactory = serviceScopeFactory; |
||||
_logger = logger; |
||||
} |
||||
|
||||
public virtual async Task StartAsync(CancellationToken cancellationToken) |
||||
{ |
||||
using var scope = _serviceScopeFactory.CreateScope(); |
||||
var databaseContext = scope.ServiceProvider.GetRequiredService<DatabaseContext>(); |
||||
|
||||
// Wait 1 second to allow database to come online |
||||
await Task.Delay(1000, cancellationToken); |
||||
|
||||
var maxMigrationAttempts = 10; |
||||
for (var i = 1; i <= maxMigrationAttempts; i++) |
||||
{ |
||||
try |
||||
{ |
||||
databaseContext.Database.Migrate(); |
||||
break; |
||||
} |
||||
catch (Exception e) |
||||
{ |
||||
if (i >= maxMigrationAttempts) |
||||
{ |
||||
_logger.LogError(e, "Database failed to migrate."); |
||||
throw; |
||||
} |
||||
else |
||||
{ |
||||
_logger.LogError(e, |
||||
"Database unavailable for migration. Trying again (attempt #{0})...", i + 1); |
||||
// Wait 5 seconds to allow database to come online |
||||
await Task.Delay(5000, cancellationToken); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
public virtual Task StopAsync(CancellationToken cancellationToken) |
||||
{ |
||||
return Task.FromResult(0); |
||||
} |
||||
|
||||
public virtual void Dispose() |
||||
{ } |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,55 @@
@@ -0,0 +1,55 @@
|
||||
// <auto-generated /> |
||||
using System; |
||||
using Bit.CryptoAgent.Repositories.EntityFramework; |
||||
using Microsoft.EntityFrameworkCore; |
||||
using Microsoft.EntityFrameworkCore.Infrastructure; |
||||
using Microsoft.EntityFrameworkCore.Migrations; |
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; |
||||
|
||||
namespace Bit.CryptoAgent.Migrations.MySql |
||||
{ |
||||
[DbContext(typeof(MySqlDatabaseContext))] |
||||
[Migration("20210817205815_InitialCreate")] |
||||
partial class InitialCreate |
||||
{ |
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder) |
||||
{ |
||||
#pragma warning disable 612, 618 |
||||
modelBuilder |
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64) |
||||
.HasAnnotation("ProductVersion", "5.0.9"); |
||||
|
||||
modelBuilder.Entity("Bit.CryptoAgent.Repositories.EntityFramework.ApplicationData", b => |
||||
{ |
||||
b.Property<string>("SymmetricKey") |
||||
.HasColumnType("longtext"); |
||||
|
||||
b.ToTable("ApplicationDatas"); |
||||
}); |
||||
|
||||
modelBuilder.Entity("Bit.CryptoAgent.Repositories.EntityFramework.UserKey", b => |
||||
{ |
||||
b.Property<Guid>("Id") |
||||
.ValueGeneratedOnAdd() |
||||
.HasColumnType("char(36)"); |
||||
|
||||
b.Property<DateTime>("CreationDate") |
||||
.HasColumnType("datetime(6)"); |
||||
|
||||
b.Property<string>("Key") |
||||
.HasColumnType("longtext"); |
||||
|
||||
b.Property<DateTime?>("LastAccessDate") |
||||
.HasColumnType("datetime(6)"); |
||||
|
||||
b.Property<DateTime?>("RevisionDate") |
||||
.HasColumnType("datetime(6)"); |
||||
|
||||
b.HasKey("Id"); |
||||
|
||||
b.ToTable("UserKeys"); |
||||
}); |
||||
#pragma warning restore 612, 618 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,52 @@
@@ -0,0 +1,52 @@
|
||||
using System; |
||||
using Microsoft.EntityFrameworkCore.Migrations; |
||||
|
||||
namespace Bit.CryptoAgent.Migrations.MySql |
||||
{ |
||||
public partial class InitialCreate : Migration |
||||
{ |
||||
protected override void Up(MigrationBuilder migrationBuilder) |
||||
{ |
||||
migrationBuilder.AlterDatabase() |
||||
.Annotation("MySql:CharSet", "utf8mb4"); |
||||
|
||||
migrationBuilder.CreateTable( |
||||
name: "ApplicationDatas", |
||||
columns: table => new |
||||
{ |
||||
SymmetricKey = table.Column<string>(type: "longtext", nullable: true) |
||||
.Annotation("MySql:CharSet", "utf8mb4") |
||||
}, |
||||
constraints: table => |
||||
{ |
||||
}) |
||||
.Annotation("MySql:CharSet", "utf8mb4"); |
||||
|
||||
migrationBuilder.CreateTable( |
||||
name: "UserKeys", |
||||
columns: table => new |
||||
{ |
||||
Id = table.Column<Guid>(type: "char(36)", nullable: false, collation: "ascii_general_ci"), |
||||
Key = table.Column<string>(type: "longtext", nullable: true) |
||||
.Annotation("MySql:CharSet", "utf8mb4"), |
||||
CreationDate = table.Column<DateTime>(type: "datetime(6)", nullable: false), |
||||
RevisionDate = table.Column<DateTime>(type: "datetime(6)", nullable: true), |
||||
LastAccessDate = table.Column<DateTime>(type: "datetime(6)", nullable: true) |
||||
}, |
||||
constraints: table => |
||||
{ |
||||
table.PrimaryKey("PK_UserKeys", x => x.Id); |
||||
}) |
||||
.Annotation("MySql:CharSet", "utf8mb4"); |
||||
} |
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder) |
||||
{ |
||||
migrationBuilder.DropTable( |
||||
name: "ApplicationDatas"); |
||||
|
||||
migrationBuilder.DropTable( |
||||
name: "UserKeys"); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,53 @@
@@ -0,0 +1,53 @@
|
||||
// <auto-generated /> |
||||
using System; |
||||
using Bit.CryptoAgent.Repositories.EntityFramework; |
||||
using Microsoft.EntityFrameworkCore; |
||||
using Microsoft.EntityFrameworkCore.Infrastructure; |
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; |
||||
|
||||
namespace Bit.CryptoAgent.Migrations.MySql |
||||
{ |
||||
[DbContext(typeof(MySqlDatabaseContext))] |
||||
partial class MySqlDatabaseContextModelSnapshot : ModelSnapshot |
||||
{ |
||||
protected override void BuildModel(ModelBuilder modelBuilder) |
||||
{ |
||||
#pragma warning disable 612, 618 |
||||
modelBuilder |
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64) |
||||
.HasAnnotation("ProductVersion", "5.0.9"); |
||||
|
||||
modelBuilder.Entity("Bit.CryptoAgent.Repositories.EntityFramework.ApplicationData", b => |
||||
{ |
||||
b.Property<string>("SymmetricKey") |
||||
.HasColumnType("longtext"); |
||||
|
||||
b.ToTable("ApplicationDatas"); |
||||
}); |
||||
|
||||
modelBuilder.Entity("Bit.CryptoAgent.Repositories.EntityFramework.UserKey", b => |
||||
{ |
||||
b.Property<Guid>("Id") |
||||
.ValueGeneratedOnAdd() |
||||
.HasColumnType("char(36)"); |
||||
|
||||
b.Property<DateTime>("CreationDate") |
||||
.HasColumnType("datetime(6)"); |
||||
|
||||
b.Property<string>("Key") |
||||
.HasColumnType("longtext"); |
||||
|
||||
b.Property<DateTime?>("LastAccessDate") |
||||
.HasColumnType("datetime(6)"); |
||||
|
||||
b.Property<DateTime?>("RevisionDate") |
||||
.HasColumnType("datetime(6)"); |
||||
|
||||
b.HasKey("Id"); |
||||
|
||||
b.ToTable("UserKeys"); |
||||
}); |
||||
#pragma warning restore 612, 618 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,57 @@
@@ -0,0 +1,57 @@
|
||||
// <auto-generated /> |
||||
using System; |
||||
using Bit.CryptoAgent.Repositories.EntityFramework; |
||||
using Microsoft.EntityFrameworkCore; |
||||
using Microsoft.EntityFrameworkCore.Infrastructure; |
||||
using Microsoft.EntityFrameworkCore.Migrations; |
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; |
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; |
||||
|
||||
namespace Bit.CryptoAgent.Migrations.PostgreSql |
||||
{ |
||||
[DbContext(typeof(PostgreSqlDatabaseContext))] |
||||
[Migration("20210817205827_InitialCreate")] |
||||
partial class InitialCreate |
||||
{ |
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder) |
||||
{ |
||||
#pragma warning disable 612, 618 |
||||
modelBuilder |
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63) |
||||
.HasAnnotation("ProductVersion", "5.0.9") |
||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); |
||||
|
||||
modelBuilder.Entity("Bit.CryptoAgent.Repositories.EntityFramework.ApplicationData", b => |
||||
{ |
||||
b.Property<string>("SymmetricKey") |
||||
.HasColumnType("text"); |
||||
|
||||
b.ToTable("ApplicationDatas"); |
||||
}); |
||||
|
||||
modelBuilder.Entity("Bit.CryptoAgent.Repositories.EntityFramework.UserKey", b => |
||||
{ |
||||
b.Property<Guid>("Id") |
||||
.ValueGeneratedOnAdd() |
||||
.HasColumnType("uuid"); |
||||
|
||||
b.Property<DateTime>("CreationDate") |
||||
.HasColumnType("timestamp without time zone"); |
||||
|
||||
b.Property<string>("Key") |
||||
.HasColumnType("text"); |
||||
|
||||
b.Property<DateTime?>("LastAccessDate") |
||||
.HasColumnType("timestamp without time zone"); |
||||
|
||||
b.Property<DateTime?>("RevisionDate") |
||||
.HasColumnType("timestamp without time zone"); |
||||
|
||||
b.HasKey("Id"); |
||||
|
||||
b.ToTable("UserKeys"); |
||||
}); |
||||
#pragma warning restore 612, 618 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
using System; |
||||
using Microsoft.EntityFrameworkCore.Migrations; |
||||
|
||||
namespace Bit.CryptoAgent.Migrations.PostgreSql |
||||
{ |
||||
public partial class InitialCreate : Migration |
||||
{ |
||||
protected override void Up(MigrationBuilder migrationBuilder) |
||||
{ |
||||
migrationBuilder.CreateTable( |
||||
name: "ApplicationDatas", |
||||
columns: table => new |
||||
{ |
||||
SymmetricKey = table.Column<string>(type: "text", nullable: true) |
||||
}, |
||||
constraints: table => |
||||
{ |
||||
}); |
||||
|
||||
migrationBuilder.CreateTable( |
||||
name: "UserKeys", |
||||
columns: table => new |
||||
{ |
||||
Id = table.Column<Guid>(type: "uuid", nullable: false), |
||||
Key = table.Column<string>(type: "text", nullable: true), |
||||
CreationDate = table.Column<DateTime>(type: "timestamp without time zone", nullable: false), |
||||
RevisionDate = table.Column<DateTime>(type: "timestamp without time zone", nullable: true), |
||||
LastAccessDate = table.Column<DateTime>(type: "timestamp without time zone", nullable: true) |
||||
}, |
||||
constraints: table => |
||||
{ |
||||
table.PrimaryKey("PK_UserKeys", x => x.Id); |
||||
}); |
||||
} |
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder) |
||||
{ |
||||
migrationBuilder.DropTable( |
||||
name: "ApplicationDatas"); |
||||
|
||||
migrationBuilder.DropTable( |
||||
name: "UserKeys"); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,55 @@
@@ -0,0 +1,55 @@
|
||||
// <auto-generated /> |
||||
using System; |
||||
using Bit.CryptoAgent.Repositories.EntityFramework; |
||||
using Microsoft.EntityFrameworkCore; |
||||
using Microsoft.EntityFrameworkCore.Infrastructure; |
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; |
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; |
||||
|
||||
namespace Bit.CryptoAgent.Migrations.PostgreSql |
||||
{ |
||||
[DbContext(typeof(PostgreSqlDatabaseContext))] |
||||
partial class PostgreSqlDatabaseContextModelSnapshot : ModelSnapshot |
||||
{ |
||||
protected override void BuildModel(ModelBuilder modelBuilder) |
||||
{ |
||||
#pragma warning disable 612, 618 |
||||
modelBuilder |
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63) |
||||
.HasAnnotation("ProductVersion", "5.0.9") |
||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); |
||||
|
||||
modelBuilder.Entity("Bit.CryptoAgent.Repositories.EntityFramework.ApplicationData", b => |
||||
{ |
||||
b.Property<string>("SymmetricKey") |
||||
.HasColumnType("text"); |
||||
|
||||
b.ToTable("ApplicationDatas"); |
||||
}); |
||||
|
||||
modelBuilder.Entity("Bit.CryptoAgent.Repositories.EntityFramework.UserKey", b => |
||||
{ |
||||
b.Property<Guid>("Id") |
||||
.ValueGeneratedOnAdd() |
||||
.HasColumnType("uuid"); |
||||
|
||||
b.Property<DateTime>("CreationDate") |
||||
.HasColumnType("timestamp without time zone"); |
||||
|
||||
b.Property<string>("Key") |
||||
.HasColumnType("text"); |
||||
|
||||
b.Property<DateTime?>("LastAccessDate") |
||||
.HasColumnType("timestamp without time zone"); |
||||
|
||||
b.Property<DateTime?>("RevisionDate") |
||||
.HasColumnType("timestamp without time zone"); |
||||
|
||||
b.HasKey("Id"); |
||||
|
||||
b.ToTable("UserKeys"); |
||||
}); |
||||
#pragma warning restore 612, 618 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,57 @@
@@ -0,0 +1,57 @@
|
||||
// <auto-generated /> |
||||
using System; |
||||
using Bit.CryptoAgent.Repositories.EntityFramework; |
||||
using Microsoft.EntityFrameworkCore; |
||||
using Microsoft.EntityFrameworkCore.Infrastructure; |
||||
using Microsoft.EntityFrameworkCore.Metadata; |
||||
using Microsoft.EntityFrameworkCore.Migrations; |
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; |
||||
|
||||
namespace Bit.CryptoAgent.Migrations.SqlServer |
||||
{ |
||||
[DbContext(typeof(SqlServerDatabaseContext))] |
||||
[Migration("20210817205227_InitialCreate")] |
||||
partial class InitialCreate |
||||
{ |
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder) |
||||
{ |
||||
#pragma warning disable 612, 618 |
||||
modelBuilder |
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128) |
||||
.HasAnnotation("ProductVersion", "5.0.9") |
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); |
||||
|
||||
modelBuilder.Entity("Bit.CryptoAgent.Repositories.EntityFramework.ApplicationData", b => |
||||
{ |
||||
b.Property<string>("SymmetricKey") |
||||
.HasColumnType("nvarchar(max)"); |
||||
|
||||
b.ToTable("ApplicationDatas"); |
||||
}); |
||||
|
||||
modelBuilder.Entity("Bit.CryptoAgent.Repositories.EntityFramework.UserKey", b => |
||||
{ |
||||
b.Property<Guid>("Id") |
||||
.ValueGeneratedOnAdd() |
||||
.HasColumnType("uniqueidentifier"); |
||||
|
||||
b.Property<DateTime>("CreationDate") |
||||
.HasColumnType("datetime2"); |
||||
|
||||
b.Property<string>("Key") |
||||
.HasColumnType("nvarchar(max)"); |
||||
|
||||
b.Property<DateTime?>("LastAccessDate") |
||||
.HasColumnType("datetime2"); |
||||
|
||||
b.Property<DateTime?>("RevisionDate") |
||||
.HasColumnType("datetime2"); |
||||
|
||||
b.HasKey("Id"); |
||||
|
||||
b.ToTable("UserKeys"); |
||||
}); |
||||
#pragma warning restore 612, 618 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
using System; |
||||
using Microsoft.EntityFrameworkCore.Migrations; |
||||
|
||||
namespace Bit.CryptoAgent.Migrations.SqlServer |
||||
{ |
||||
public partial class InitialCreate : Migration |
||||
{ |
||||
protected override void Up(MigrationBuilder migrationBuilder) |
||||
{ |
||||
migrationBuilder.CreateTable( |
||||
name: "ApplicationDatas", |
||||
columns: table => new |
||||
{ |
||||
SymmetricKey = table.Column<string>(type: "nvarchar(max)", nullable: true) |
||||
}, |
||||
constraints: table => |
||||
{ |
||||
}); |
||||
|
||||
migrationBuilder.CreateTable( |
||||
name: "UserKeys", |
||||
columns: table => new |
||||
{ |
||||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
||||
Key = table.Column<string>(type: "nvarchar(max)", nullable: true), |
||||
CreationDate = table.Column<DateTime>(type: "datetime2", nullable: false), |
||||
RevisionDate = table.Column<DateTime>(type: "datetime2", nullable: true), |
||||
LastAccessDate = table.Column<DateTime>(type: "datetime2", nullable: true) |
||||
}, |
||||
constraints: table => |
||||
{ |
||||
table.PrimaryKey("PK_UserKeys", x => x.Id); |
||||
}); |
||||
} |
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder) |
||||
{ |
||||
migrationBuilder.DropTable( |
||||
name: "ApplicationDatas"); |
||||
|
||||
migrationBuilder.DropTable( |
||||
name: "UserKeys"); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,55 @@
@@ -0,0 +1,55 @@
|
||||
// <auto-generated /> |
||||
using System; |
||||
using Bit.CryptoAgent.Repositories.EntityFramework; |
||||
using Microsoft.EntityFrameworkCore; |
||||
using Microsoft.EntityFrameworkCore.Infrastructure; |
||||
using Microsoft.EntityFrameworkCore.Metadata; |
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; |
||||
|
||||
namespace Bit.CryptoAgent.Migrations.SqlServer |
||||
{ |
||||
[DbContext(typeof(SqlServerDatabaseContext))] |
||||
partial class SqlServerDatabaseContextModelSnapshot : ModelSnapshot |
||||
{ |
||||
protected override void BuildModel(ModelBuilder modelBuilder) |
||||
{ |
||||
#pragma warning disable 612, 618 |
||||
modelBuilder |
||||
.HasAnnotation("Relational:MaxIdentifierLength", 128) |
||||
.HasAnnotation("ProductVersion", "5.0.9") |
||||
.HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); |
||||
|
||||
modelBuilder.Entity("Bit.CryptoAgent.Repositories.EntityFramework.ApplicationData", b => |
||||
{ |
||||
b.Property<string>("SymmetricKey") |
||||
.HasColumnType("nvarchar(max)"); |
||||
|
||||
b.ToTable("ApplicationDatas"); |
||||
}); |
||||
|
||||
modelBuilder.Entity("Bit.CryptoAgent.Repositories.EntityFramework.UserKey", b => |
||||
{ |
||||
b.Property<Guid>("Id") |
||||
.ValueGeneratedOnAdd() |
||||
.HasColumnType("uniqueidentifier"); |
||||
|
||||
b.Property<DateTime>("CreationDate") |
||||
.HasColumnType("datetime2"); |
||||
|
||||
b.Property<string>("Key") |
||||
.HasColumnType("nvarchar(max)"); |
||||
|
||||
b.Property<DateTime?>("LastAccessDate") |
||||
.HasColumnType("datetime2"); |
||||
|
||||
b.Property<DateTime?>("RevisionDate") |
||||
.HasColumnType("datetime2"); |
||||
|
||||
b.HasKey("Id"); |
||||
|
||||
b.ToTable("UserKeys"); |
||||
}); |
||||
#pragma warning restore 612, 618 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,54 @@
@@ -0,0 +1,54 @@
|
||||
// <auto-generated /> |
||||
using System; |
||||
using Bit.CryptoAgent.Repositories.EntityFramework; |
||||
using Microsoft.EntityFrameworkCore; |
||||
using Microsoft.EntityFrameworkCore.Infrastructure; |
||||
using Microsoft.EntityFrameworkCore.Migrations; |
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; |
||||
|
||||
namespace Bit.CryptoAgent.Migrations.Sqlite |
||||
{ |
||||
[DbContext(typeof(SqliteDatabaseContext))] |
||||
[Migration("20210817205807_InitialCreate")] |
||||
partial class InitialCreate |
||||
{ |
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder) |
||||
{ |
||||
#pragma warning disable 612, 618 |
||||
modelBuilder |
||||
.HasAnnotation("ProductVersion", "5.0.9"); |
||||
|
||||
modelBuilder.Entity("Bit.CryptoAgent.Repositories.EntityFramework.ApplicationData", b => |
||||
{ |
||||
b.Property<string>("SymmetricKey") |
||||
.HasColumnType("TEXT"); |
||||
|
||||
b.ToTable("ApplicationDatas"); |
||||
}); |
||||
|
||||
modelBuilder.Entity("Bit.CryptoAgent.Repositories.EntityFramework.UserKey", b => |
||||
{ |
||||
b.Property<Guid>("Id") |
||||
.ValueGeneratedOnAdd() |
||||
.HasColumnType("TEXT"); |
||||
|
||||
b.Property<DateTime>("CreationDate") |
||||
.HasColumnType("TEXT"); |
||||
|
||||
b.Property<string>("Key") |
||||
.HasColumnType("TEXT"); |
||||
|
||||
b.Property<DateTime?>("LastAccessDate") |
||||
.HasColumnType("TEXT"); |
||||
|
||||
b.Property<DateTime?>("RevisionDate") |
||||
.HasColumnType("TEXT"); |
||||
|
||||
b.HasKey("Id"); |
||||
|
||||
b.ToTable("UserKeys"); |
||||
}); |
||||
#pragma warning restore 612, 618 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
using System; |
||||
using Microsoft.EntityFrameworkCore.Migrations; |
||||
|
||||
namespace Bit.CryptoAgent.Migrations.Sqlite |
||||
{ |
||||
public partial class InitialCreate : Migration |
||||
{ |
||||
protected override void Up(MigrationBuilder migrationBuilder) |
||||
{ |
||||
migrationBuilder.CreateTable( |
||||
name: "ApplicationDatas", |
||||
columns: table => new |
||||
{ |
||||
SymmetricKey = table.Column<string>(type: "TEXT", nullable: true) |
||||
}, |
||||
constraints: table => |
||||
{ |
||||
}); |
||||
|
||||
migrationBuilder.CreateTable( |
||||
name: "UserKeys", |
||||
columns: table => new |
||||
{ |
||||
Id = table.Column<Guid>(type: "TEXT", nullable: false), |
||||
Key = table.Column<string>(type: "TEXT", nullable: true), |
||||
CreationDate = table.Column<DateTime>(type: "TEXT", nullable: false), |
||||
RevisionDate = table.Column<DateTime>(type: "TEXT", nullable: true), |
||||
LastAccessDate = table.Column<DateTime>(type: "TEXT", nullable: true) |
||||
}, |
||||
constraints: table => |
||||
{ |
||||
table.PrimaryKey("PK_UserKeys", x => x.Id); |
||||
}); |
||||
} |
||||
|
||||
protected override void Down(MigrationBuilder migrationBuilder) |
||||
{ |
||||
migrationBuilder.DropTable( |
||||
name: "ApplicationDatas"); |
||||
|
||||
migrationBuilder.DropTable( |
||||
name: "UserKeys"); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,52 @@
@@ -0,0 +1,52 @@
|
||||
// <auto-generated /> |
||||
using System; |
||||
using Bit.CryptoAgent.Repositories.EntityFramework; |
||||
using Microsoft.EntityFrameworkCore; |
||||
using Microsoft.EntityFrameworkCore.Infrastructure; |
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion; |
||||
|
||||
namespace Bit.CryptoAgent.Migrations.Sqlite |
||||
{ |
||||
[DbContext(typeof(SqliteDatabaseContext))] |
||||
partial class SqliteDatabaseContextModelSnapshot : ModelSnapshot |
||||
{ |
||||
protected override void BuildModel(ModelBuilder modelBuilder) |
||||
{ |
||||
#pragma warning disable 612, 618 |
||||
modelBuilder |
||||
.HasAnnotation("ProductVersion", "5.0.9"); |
||||
|
||||
modelBuilder.Entity("Bit.CryptoAgent.Repositories.EntityFramework.ApplicationData", b => |
||||
{ |
||||
b.Property<string>("SymmetricKey") |
||||
.HasColumnType("TEXT"); |
||||
|
||||
b.ToTable("ApplicationDatas"); |
||||
}); |
||||
|
||||
modelBuilder.Entity("Bit.CryptoAgent.Repositories.EntityFramework.UserKey", b => |
||||
{ |
||||
b.Property<Guid>("Id") |
||||
.ValueGeneratedOnAdd() |
||||
.HasColumnType("TEXT"); |
||||
|
||||
b.Property<DateTime>("CreationDate") |
||||
.HasColumnType("TEXT"); |
||||
|
||||
b.Property<string>("Key") |
||||
.HasColumnType("TEXT"); |
||||
|
||||
b.Property<DateTime?>("LastAccessDate") |
||||
.HasColumnType("TEXT"); |
||||
|
||||
b.Property<DateTime?>("RevisionDate") |
||||
.HasColumnType("TEXT"); |
||||
|
||||
b.HasKey("Id"); |
||||
|
||||
b.ToTable("UserKeys"); |
||||
}); |
||||
#pragma warning restore 612, 618 |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
using System.Linq; |
||||
using System.Threading.Tasks; |
||||
using Microsoft.Extensions.DependencyInjection; |
||||
|
||||
namespace Bit.CryptoAgent.Repositories.EntityFramework |
||||
{ |
||||
public class ApplicationDataRepository : BaseRepository, IApplicationDataRepository |
||||
{ |
||||
public ApplicationDataRepository(IServiceScopeFactory serviceScopeFactory) |
||||
: base(serviceScopeFactory) |
||||
{ } |
||||
|
||||
public Task<string> ReadSymmetricKeyAsync() |
||||
{ |
||||
using var scope = ServiceScopeFactory.CreateScope(); |
||||
var dbContext = GetDatabaseContext(scope); |
||||
return Task.FromResult(dbContext.ApplicationDatas.FirstOrDefault().SymmetricKey); |
||||
} |
||||
|
||||
public async Task UpdateSymmetricKeyAsync(string key) |
||||
{ |
||||
using var scope = ServiceScopeFactory.CreateScope(); |
||||
var dbContext = GetDatabaseContext(scope); |
||||
if (dbContext.ApplicationDatas.FirstOrDefault() == null) |
||||
{ |
||||
await dbContext.AddAsync(new ApplicationData |
||||
{ |
||||
SymmetricKey = key |
||||
}); |
||||
} |
||||
else |
||||
{ |
||||
dbContext.ApplicationDatas.FirstOrDefault().SymmetricKey = key; |
||||
} |
||||
await dbContext.SaveChangesAsync(); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,20 @@
@@ -0,0 +1,20 @@
|
||||
using System; |
||||
using Microsoft.Extensions.DependencyInjection; |
||||
|
||||
namespace Bit.CryptoAgent.Repositories.EntityFramework |
||||
{ |
||||
public abstract class BaseRepository |
||||
{ |
||||
public BaseRepository(IServiceScopeFactory serviceScopeFactory) |
||||
{ |
||||
ServiceScopeFactory = serviceScopeFactory; |
||||
} |
||||
|
||||
protected IServiceScopeFactory ServiceScopeFactory { get; private set; } |
||||
|
||||
protected DatabaseContext GetDatabaseContext(IServiceScope serviceScope) |
||||
{ |
||||
return serviceScope.ServiceProvider.GetRequiredService<DatabaseContext>(); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,102 @@
@@ -0,0 +1,102 @@
|
||||
using System.Linq; |
||||
using Bit.CryptoAgent.Models; |
||||
using Microsoft.EntityFrameworkCore; |
||||
|
||||
namespace Bit.CryptoAgent.Repositories.EntityFramework |
||||
{ |
||||
public abstract class DatabaseContext : DbContext |
||||
{ |
||||
public DbSet<ApplicationData> ApplicationDatas { get; set; } |
||||
public DbSet<UserKey> UserKeys { get; set; } |
||||
} |
||||
|
||||
public class SqlServerDatabaseContext : DatabaseContext |
||||
{ |
||||
private readonly CryptoAgentSettings _settings; |
||||
|
||||
public SqlServerDatabaseContext(CryptoAgentSettings settings) |
||||
{ |
||||
_settings = settings; |
||||
} |
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder options) |
||||
=> options.UseSqlServer(_settings.Database.SqlServerConnectionString); |
||||
} |
||||
|
||||
public class PostgreSqlDatabaseContext : DatabaseContext |
||||
{ |
||||
private readonly CryptoAgentSettings _settings; |
||||
|
||||
public PostgreSqlDatabaseContext(CryptoAgentSettings settings) |
||||
{ |
||||
_settings = settings; |
||||
} |
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder options) |
||||
=> options.UseNpgsql(_settings.Database.PostgreSqlConnectionString); |
||||
} |
||||
|
||||
public class SqliteDatabaseContext : DatabaseContext |
||||
{ |
||||
private readonly CryptoAgentSettings _settings; |
||||
|
||||
public SqliteDatabaseContext(CryptoAgentSettings settings) |
||||
{ |
||||
_settings = settings; |
||||
} |
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder options) |
||||
=> options.UseSqlite(_settings.Database.SqliteConnectionString); |
||||
} |
||||
|
||||
public class MySqlDatabaseContext : DatabaseContext |
||||
{ |
||||
private readonly CryptoAgentSettings _settings; |
||||
|
||||
public MySqlDatabaseContext(CryptoAgentSettings settings) |
||||
{ |
||||
_settings = settings; |
||||
} |
||||
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder options) |
||||
=> options.UseMySql(_settings.Database.PostgreSqlConnectionString, |
||||
ServerVersion.AutoDetect(_settings.Database.MySqlConnectionString)); |
||||
} |
||||
|
||||
[Keyless] |
||||
public class ApplicationData |
||||
{ |
||||
public string SymmetricKey { get; set; } |
||||
} |
||||
|
||||
public class UserKey : UserKeyModel |
||||
{ |
||||
public UserKey() { } |
||||
|
||||
public UserKey(UserKeyModel model) |
||||
{ |
||||
Load(model); |
||||
} |
||||
|
||||
public void Load(UserKeyModel model) |
||||
{ |
||||
Id = model.Id; |
||||
Key = model.Key; |
||||
RevisionDate = model.RevisionDate; |
||||
CreationDate = model.CreationDate; |
||||
LastAccessDate = model.LastAccessDate; |
||||
} |
||||
|
||||
public UserKeyModel ToUserKeyModel() |
||||
{ |
||||
return new UserKeyModel |
||||
{ |
||||
Id = Id, |
||||
Key = Key, |
||||
RevisionDate = RevisionDate, |
||||
CreationDate = CreationDate, |
||||
LastAccessDate = LastAccessDate |
||||
}; |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,49 @@
@@ -0,0 +1,49 @@
|
||||
using Microsoft.EntityFrameworkCore.Design; |
||||
using Microsoft.Extensions.Configuration; |
||||
|
||||
namespace Bit.CryptoAgent.Repositories.EntityFramework |
||||
{ |
||||
public class SqlServerDatabaseContextFactory : IDesignTimeDbContextFactory<SqlServerDatabaseContext> |
||||
{ |
||||
public SqlServerDatabaseContext CreateDbContext(string[] args) |
||||
{ |
||||
return new SqlServerDatabaseContext(SettingsFactory.Settings); |
||||
} |
||||
} |
||||
|
||||
public class PostgreSqlDatabaseContextFactory : IDesignTimeDbContextFactory<PostgreSqlDatabaseContext> |
||||
{ |
||||
public PostgreSqlDatabaseContext CreateDbContext(string[] args) |
||||
{ |
||||
return new PostgreSqlDatabaseContext(SettingsFactory.Settings); |
||||
} |
||||
} |
||||
|
||||
public class MySqlDatabaseContextFactory : IDesignTimeDbContextFactory<MySqlDatabaseContext> |
||||
{ |
||||
public MySqlDatabaseContext CreateDbContext(string[] args) |
||||
{ |
||||
return new MySqlDatabaseContext(SettingsFactory.Settings); |
||||
} |
||||
} |
||||
|
||||
public class SqliteDatabaseContextFactory : IDesignTimeDbContextFactory<SqliteDatabaseContext> |
||||
{ |
||||
public SqliteDatabaseContext CreateDbContext(string[] args) |
||||
{ |
||||
return new SqliteDatabaseContext(SettingsFactory.Settings); |
||||
} |
||||
} |
||||
|
||||
public static class SettingsFactory |
||||
{ |
||||
public static CryptoAgentSettings Settings { get; } = new CryptoAgentSettings(); |
||||
|
||||
static SettingsFactory() |
||||
{ |
||||
var configBuilder = new ConfigurationBuilder().AddUserSecrets<Startup>(); |
||||
var config = configBuilder.Build(); |
||||
ConfigurationBinder.Bind(config.GetSection("CryptoAgentSettings"), Settings); |
||||
} |
||||
} |
||||
} |
||||
@ -0,0 +1,52 @@
@@ -0,0 +1,52 @@
|
||||
using Bit.CryptoAgent.Models; |
||||
using Microsoft.Extensions.DependencyInjection; |
||||
using System; |
||||
using System.Threading.Tasks; |
||||
|
||||
namespace Bit.CryptoAgent.Repositories.EntityFramework |
||||
{ |
||||
public class UserKeyRepository : BaseRepository, IUserKeyRepository |
||||
{ |
||||
public UserKeyRepository(IServiceScopeFactory serviceScopeFactory) |
||||
: base(serviceScopeFactory) |
||||
{ } |
||||
|
||||
public virtual async Task CreateAsync(UserKeyModel item) |
||||
{ |
||||
using var scope = ServiceScopeFactory.CreateScope(); |
||||
var dbContext = GetDatabaseContext(scope); |
||||
var entity = new UserKey(item); |
||||
await dbContext.AddAsync(entity); |
||||
await dbContext.SaveChangesAsync(); |
||||
} |
||||
|
||||
public virtual async Task<UserKeyModel> ReadAsync(Guid id) |
||||
{ |
||||
using var scope = ServiceScopeFactory.CreateScope(); |
||||
var dbContext = GetDatabaseContext(scope); |
||||
var entity = await dbContext.UserKeys.FindAsync(id); |
||||
return entity.ToUserKeyModel(); |
||||
} |
||||
|
||||
public virtual async Task UpdateAsync(UserKeyModel item) |
||||
{ |
||||
using var scope = ServiceScopeFactory.CreateScope(); |
||||
var dbContext = GetDatabaseContext(scope); |
||||
var entity = await dbContext.UserKeys.FindAsync(item.Id); |
||||
if (entity != null) |
||||
{ |
||||
entity.Load(item); |
||||
await dbContext.SaveChangesAsync(); |
||||
} |
||||
} |
||||
|
||||
public virtual async Task DeleteAsync(Guid id) |
||||
{ |
||||
using var scope = ServiceScopeFactory.CreateScope(); |
||||
var dbContext = GetDatabaseContext(scope); |
||||
var entity = await dbContext.UserKeys.FindAsync(id); |
||||
dbContext.Remove(entity); |
||||
await dbContext.SaveChangesAsync(); |
||||
} |
||||
} |
||||
} |
||||
Loading…
Reference in new issue