From 5c3998cb8d8a4ac228974f857b9e583b31841e5e Mon Sep 17 00:00:00 2001 From: UncleSp1d3r Date: Tue, 25 Jul 2023 18:00:29 -0400 Subject: [PATCH] Added support for GetChunk, GetFile, SendKeyspace, and GetTask (#37) --- HashSlinger.Shared/Generated/ChunkDto.g.cs | 4 +- HashSlinger.Shared/Generated/FileDto.g.cs | 6 +- HashSlinger.Shared/Generated/TaskDto.g.cs | 2 +- .../Generated/TaskWrapperDto.g.cs | 2 +- HashSlinger.Shared/Models/Chunk.cs | 6 +- HashSlinger.Shared/Models/Enums/ChunkState.cs | 16 + HashSlinger.Shared/Models/Enums/FileType.cs | 6 + .../Models/Enums/TaskStaticChunking.cs | 3 + HashSlinger.Shared/Models/Enums/TaskType.cs | 3 + HashSlinger.Shared/Models/File.cs | 7 +- HashSlinger.Shared/Models/Task.cs | 9 +- HashSlinger.Shared/Models/TaskWrapper.cs | 3 +- .../FileEndpointIntegrationTests.cs | 69 - HashSlinger.Test/HashSlinger.Test.csproj | 6 +- HashSlinger/Data/HashSlingerContext.cs | 65 +- .../Endpoints/ClientApiV1/FileEndpoints.cs | 30 +- .../HashtopolisApiV2/DTO/GetChunkRequest.cs | 5 +- .../HashtopolisApiV2/DTO/GetChunkResponse.cs | 8 +- .../HashtopolisApiV2/DTO/GetFileRequest.cs | 7 +- .../HashtopolisApiV2/DTO/GetTaskResponse.cs | 2 + .../DTO/SendKeyspaceRequest.cs | 13 +- .../Handlers/GetChunkHandler.cs | 153 ++ .../Handlers/GetFileHandler.cs | 73 + .../Handlers/GetFileStatusHandler.cs | 10 +- .../Handlers/GetTaskHandler.cs | 12 +- .../Handlers/SendHealthCheckHandler.cs | 20 +- .../Handlers/SendKeyspaceHandler.cs | 52 + .../HashtopolisApiV2/HashtopolisConstants.cs | 3 + .../HashtopolisApiV2/HashtopolisEndpoints.cs | 131 +- .../HashtopolisApiV2/HashtopolisRequest.cs | 102 +- .../UserApiV1/FileEndpointHandlers.cs | 92 + .../UserApiV1/TaskEndpointHandlers.cs | 78 +- .../Endpoints/UserApiV1/UserApiEndPoints.cs | 319 +-- .../Commands/PerformInitialSetupCommand.cs | 48 +- .../Handlers/Commands/UpdateTaskCommand.cs | 27 + .../Queries/GetAvailableChunkQuery.cs | 34 + .../Handlers/Queries/GetDeletedFilesQuery.cs | 13 +- HashSlinger/Handlers/Queries/GetFileQuery.cs | 48 + .../GetNextTaskForAgentProjectionQuery.cs | 94 +- .../GetPendingHealthCheckForAgentQuery.cs | 9 +- .../Handlers/Queries/GetTaskByIdHandler.cs | 29 + HashSlinger/HashSlinger.Api.csproj | 14 +- .../20230628011334_InitialSetup.Designer.cs | 15 +- .../Migrations/20230628011334_InitialSetup.cs | 12 +- ...9001850_ModifiedTasksAndChunks.Designer.cs | 1911 ++++++++++++++++ .../20230629001850_ModifiedTasksAndChunks.cs | 52 + .../20230701163527_ExposedChunks.Designer.cs | 1911 ++++++++++++++++ .../20230701163527_ExposedChunks.cs | 156 ++ .../20230701175137_changes.Designer.cs | 1913 ++++++++++++++++ .../Migrations/20230701175137_changes.cs | 64 + ...0701175709_MoreOnDeleteChanges.Designer.cs | 1919 ++++++++++++++++ .../20230701175709_MoreOnDeleteChanges.cs | 156 ++ ...175923_EvenMoreOnDeleteChanges.Designer.cs | 1922 ++++++++++++++++ .../20230701175923_EvenMoreOnDeleteChanges.cs | 87 + ...80247_EvenMoreOnDeleteChanges2.Designer.cs | 1923 ++++++++++++++++ ...20230701180247_EvenMoreOnDeleteChanges2.cs | 65 + .../20230712212853_UpdateDelete.Designer.cs | 1924 ++++++++++++++++ .../Migrations/20230712212853_UpdateDelete.cs | 41 + .../20230712222549_CleanedUpFiles.Designer.cs | 1924 ++++++++++++++++ .../20230712222549_CleanedUpFiles.cs | 52 + ...0712230755_AddedIndexesToFiles.Designer.cs | 1928 ++++++++++++++++ .../20230712230755_AddedIndexesToFiles.cs | 36 + .../20230725215305_ExpandKeyspace.Designer.cs | 1931 +++++++++++++++++ .../20230725215305_ExpandKeyspace.cs | 34 + .../HashSlingerContextModelSnapshot.cs | 37 +- HashSlinger/Program.cs | 11 +- .../Services/LocalFileStorageService.cs | 10 +- 67 files changed, 21113 insertions(+), 554 deletions(-) create mode 100644 HashSlinger.Shared/Models/Enums/ChunkState.cs create mode 100644 HashSlinger.Shared/Models/Enums/FileType.cs create mode 100644 HashSlinger.Shared/Models/Enums/TaskStaticChunking.cs create mode 100644 HashSlinger.Shared/Models/Enums/TaskType.cs delete mode 100644 HashSlinger.Test/FileEndpointIntegrationTests.cs create mode 100644 HashSlinger/Endpoints/HashtopolisApiV2/Handlers/GetChunkHandler.cs create mode 100644 HashSlinger/Endpoints/HashtopolisApiV2/Handlers/GetFileHandler.cs create mode 100644 HashSlinger/Endpoints/HashtopolisApiV2/Handlers/SendKeyspaceHandler.cs create mode 100644 HashSlinger/Endpoints/UserApiV1/FileEndpointHandlers.cs create mode 100644 HashSlinger/Handlers/Commands/UpdateTaskCommand.cs create mode 100644 HashSlinger/Handlers/Queries/GetAvailableChunkQuery.cs create mode 100644 HashSlinger/Handlers/Queries/GetFileQuery.cs create mode 100644 HashSlinger/Handlers/Queries/GetTaskByIdHandler.cs create mode 100644 HashSlinger/Migrations/20230629001850_ModifiedTasksAndChunks.Designer.cs create mode 100644 HashSlinger/Migrations/20230629001850_ModifiedTasksAndChunks.cs create mode 100644 HashSlinger/Migrations/20230701163527_ExposedChunks.Designer.cs create mode 100644 HashSlinger/Migrations/20230701163527_ExposedChunks.cs create mode 100644 HashSlinger/Migrations/20230701175137_changes.Designer.cs create mode 100644 HashSlinger/Migrations/20230701175137_changes.cs create mode 100644 HashSlinger/Migrations/20230701175709_MoreOnDeleteChanges.Designer.cs create mode 100644 HashSlinger/Migrations/20230701175709_MoreOnDeleteChanges.cs create mode 100644 HashSlinger/Migrations/20230701175923_EvenMoreOnDeleteChanges.Designer.cs create mode 100644 HashSlinger/Migrations/20230701175923_EvenMoreOnDeleteChanges.cs create mode 100644 HashSlinger/Migrations/20230701180247_EvenMoreOnDeleteChanges2.Designer.cs create mode 100644 HashSlinger/Migrations/20230701180247_EvenMoreOnDeleteChanges2.cs create mode 100644 HashSlinger/Migrations/20230712212853_UpdateDelete.Designer.cs create mode 100644 HashSlinger/Migrations/20230712212853_UpdateDelete.cs create mode 100644 HashSlinger/Migrations/20230712222549_CleanedUpFiles.Designer.cs create mode 100644 HashSlinger/Migrations/20230712222549_CleanedUpFiles.cs create mode 100644 HashSlinger/Migrations/20230712230755_AddedIndexesToFiles.Designer.cs create mode 100644 HashSlinger/Migrations/20230712230755_AddedIndexesToFiles.cs create mode 100644 HashSlinger/Migrations/20230725215305_ExpandKeyspace.Designer.cs create mode 100644 HashSlinger/Migrations/20230725215305_ExpandKeyspace.cs diff --git a/HashSlinger.Shared/Generated/ChunkDto.g.cs b/HashSlinger.Shared/Generated/ChunkDto.g.cs index 76df79d..aa237e4 100644 --- a/HashSlinger.Shared/Generated/ChunkDto.g.cs +++ b/HashSlinger.Shared/Generated/ChunkDto.g.cs @@ -17,11 +17,11 @@ public partial record ChunkDto public DateTime DispatchTime { get; set; } public int Id { get; set; } public ulong Length { get; set; } - public int? Progress { get; set; } + public float? Progress { get; set; } public ulong Skip { get; set; } public DateTime SolveTime { get; set; } public ulong Speed { get; set; } - public int State { get; set; } + public string State { get; set; } public int TaskId { get; set; } } } \ No newline at end of file diff --git a/HashSlinger.Shared/Generated/FileDto.g.cs b/HashSlinger.Shared/Generated/FileDto.g.cs index a5961f2..9e91c4b 100644 --- a/HashSlinger.Shared/Generated/FileDto.g.cs +++ b/HashSlinger.Shared/Generated/FileDto.g.cs @@ -13,10 +13,10 @@ public partial record FileDto public int AccessGroupId { get; set; } public Guid? FileGuid { get; set; } public string FileName { get; set; } - public int FileType { get; set; } + public string FileType { get; set; } public int Id { get; set; } public bool IsSecret { get; set; } - public long? LineCount { get; set; } - public long Size { get; set; } + public int? LineCount { get; set; } + public int Size { get; set; } } } \ No newline at end of file diff --git a/HashSlinger.Shared/Generated/TaskDto.g.cs b/HashSlinger.Shared/Generated/TaskDto.g.cs index 19f597d..7314f00 100644 --- a/HashSlinger.Shared/Generated/TaskDto.g.cs +++ b/HashSlinger.Shared/Generated/TaskDto.g.cs @@ -33,7 +33,7 @@ public partial record TaskDto public string? PreprocessorCommand { get; set; } public int Priority { get; set; } public ulong SkipKeyspace { get; set; } - public int StaticChunks { get; set; } + public string StaticChunks { get; set; } public int StatusTimer { get; set; } public int TaskWrapperId { get; set; } public bool UseNewBenchmark { get; set; } diff --git a/HashSlinger.Shared/Generated/TaskWrapperDto.g.cs b/HashSlinger.Shared/Generated/TaskWrapperDto.g.cs index a633bd7..a5efbc0 100644 --- a/HashSlinger.Shared/Generated/TaskWrapperDto.g.cs +++ b/HashSlinger.Shared/Generated/TaskWrapperDto.g.cs @@ -15,6 +15,6 @@ public partial record TaskWrapperDto public bool IsArchived { get; set; } public string Name { get; set; } public int Priority { get; set; } - public int TaskType { get; set; } + public string TaskType { get; set; } } } \ No newline at end of file diff --git a/HashSlinger.Shared/Models/Chunk.cs b/HashSlinger.Shared/Models/Chunk.cs index d25b54b..73c5533 100644 --- a/HashSlinger.Shared/Models/Chunk.cs +++ b/HashSlinger.Shared/Models/Chunk.cs @@ -1,5 +1,7 @@ namespace HashSlinger.Shared.Models; +using Enums; + /// A chunk of a cracking task. /// public record Chunk @@ -61,7 +63,7 @@ public record Chunk /// Gets or sets the progress. /// The progress. /// - public int? Progress { get; set; } + public float? Progress { get; set; } /// Gets or sets the skip. /// The skip. @@ -81,7 +83,7 @@ public record Chunk /// Gets or sets the state. /// The state. /// - public int State { get; set; } + public ChunkState State { get; set; } /// Gets or sets the task identifier. /// The task identifier. diff --git a/HashSlinger.Shared/Models/Enums/ChunkState.cs b/HashSlinger.Shared/Models/Enums/ChunkState.cs new file mode 100644 index 0000000..3fcef30 --- /dev/null +++ b/HashSlinger.Shared/Models/Enums/ChunkState.cs @@ -0,0 +1,16 @@ +namespace HashSlinger.Shared.Models.Enums; + +public enum ChunkState +{ + Init, + Autotune, + Running, + Paused, + Exhausted, + Cracked, + Aborted, + Quit, + Bypass, + AbortedCheckpoint, + StatusAbortedRuntime +} diff --git a/HashSlinger.Shared/Models/Enums/FileType.cs b/HashSlinger.Shared/Models/Enums/FileType.cs new file mode 100644 index 0000000..7bd1562 --- /dev/null +++ b/HashSlinger.Shared/Models/Enums/FileType.cs @@ -0,0 +1,6 @@ +namespace HashSlinger.Shared.Models.Enums; + +/// +/// Represents a file type. +/// +public enum FileType { WordList = 1, Rule = 2, HashList = 3, Mask = 4 } diff --git a/HashSlinger.Shared/Models/Enums/TaskStaticChunking.cs b/HashSlinger.Shared/Models/Enums/TaskStaticChunking.cs new file mode 100644 index 0000000..774bcd2 --- /dev/null +++ b/HashSlinger.Shared/Models/Enums/TaskStaticChunking.cs @@ -0,0 +1,3 @@ +namespace HashSlinger.Shared.Models.Enums; + +public enum TaskStaticChunking { Normal, ChunkSize, NumberOfChunks } diff --git a/HashSlinger.Shared/Models/Enums/TaskType.cs b/HashSlinger.Shared/Models/Enums/TaskType.cs new file mode 100644 index 0000000..9a0a740 --- /dev/null +++ b/HashSlinger.Shared/Models/Enums/TaskType.cs @@ -0,0 +1,3 @@ +namespace HashSlinger.Shared.Models.Enums; + +public enum TaskType { Normal, SuperTask } diff --git a/HashSlinger.Shared/Models/File.cs b/HashSlinger.Shared/Models/File.cs index 899abbf..b51b36e 100644 --- a/HashSlinger.Shared/Models/File.cs +++ b/HashSlinger.Shared/Models/File.cs @@ -1,6 +1,7 @@ namespace HashSlinger.Shared.Models; using System.ComponentModel.DataAnnotations; +using Enums; /// Represents a file. /// @@ -44,7 +45,7 @@ public record File /// Gets or sets the type of the file. /// The type of the file. /// - public int FileType { get; set; } + public FileType FileType { get; set; } /// Gets or sets the identifier. /// The identifier. @@ -59,10 +60,10 @@ public record File /// Gets or sets the line count. /// The line count. /// - public long? LineCount { get; set; } + public int? LineCount { get; set; } /// Gets or sets the size. /// The size, in bytes. /// - public long Size { get; set; } + public int Size { get; set; } } diff --git a/HashSlinger.Shared/Models/Task.cs b/HashSlinger.Shared/Models/Task.cs index e6e1188..75b6621 100644 --- a/HashSlinger.Shared/Models/Task.cs +++ b/HashSlinger.Shared/Models/Task.cs @@ -1,6 +1,7 @@ namespace HashSlinger.Shared.Models; using System.ComponentModel.DataAnnotations; +using Enums; /// Represents a cracking task. /// @@ -145,10 +146,10 @@ public record Task /// public ulong SkipKeyspace { get; set; } - /// Gets or sets the number of static chunks. - /// The static chunk count. - /// - public int StaticChunks { get; set; } + + /// Gets or sets the static chunk state. + /// The static chunks. + public TaskStaticChunking StaticChunks { get; set; } /// Gets or sets the status timer. /// The status timer. diff --git a/HashSlinger.Shared/Models/TaskWrapper.cs b/HashSlinger.Shared/Models/TaskWrapper.cs index 23585a9..b83ddd6 100644 --- a/HashSlinger.Shared/Models/TaskWrapper.cs +++ b/HashSlinger.Shared/Models/TaskWrapper.cs @@ -1,6 +1,7 @@ namespace HashSlinger.Shared.Models; using System.ComponentModel.DataAnnotations; +using Enums; /// A wrapper object that maps a task, hashlist, and priority. /// @@ -61,5 +62,5 @@ public record TaskWrapper /// Gets or sets the type of the task. /// The type of the task. /// - public int TaskType { get; set; } + public TaskType TaskType { get; set; } } diff --git a/HashSlinger.Test/FileEndpointIntegrationTests.cs b/HashSlinger.Test/FileEndpointIntegrationTests.cs deleted file mode 100644 index fe3750f..0000000 --- a/HashSlinger.Test/FileEndpointIntegrationTests.cs +++ /dev/null @@ -1,69 +0,0 @@ -namespace HashSlinger.Test; - -using System.Net.Http.Headers; -using Api.Data; -using Api.Endpoints.HashtopolisApiV2; -using Microsoft.Extensions.DependencyInjection; - -[TestFixture] -internal class FileEndpointIntegrationTests -{ - [SetUp] - public void Setup() - { - _factory = new MyWebApplicationFactory(); - _client = _factory.CreateClient(); - - using IServiceScope scope = _factory.Services.CreateScope(); - IServiceProvider scopedServices = scope.ServiceProvider; - HashSlingerContext db = scopedServices.GetRequiredService(); - db.Database.EnsureCreated(); - Utilities.ReinitializeDbForTests(db); - } - - [TearDown] - public void TearDown() - { - using IServiceScope scope = _factory.Services.CreateScope(); - IServiceProvider scopedServices = scope.ServiceProvider; - HashSlingerContext db = scopedServices.GetRequiredService(); - db.Database.EnsureDeleted(); - - _client.Dispose(); - _factory.Dispose(); - } - - private HttpClient _client = null!; - private MyWebApplicationFactory _factory = null!; - - [Test] - public async Task FileUploadDownloadIntegrationTest() - { - const string bucket = "test_bucket"; - var fileId = new Guid(); - var file = await File.ReadAllBytesAsync(Path.Combine("SupportFiles", "test_file.txt")); - var fileContent = new ByteArrayContent(file); - fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("text/plain"); - - using (HttpContent requestContent = new MultipartFormDataContent { { fileContent, "file", "test_file.txt" } }) - { - HttpResponseMessage response = await _client.PostAsync( - $"{HashtopolisConstants.UploadEndPointPrefix}/{bucket}/{fileId}", - requestContent); - - response.EnsureSuccessStatusCode(); - } - - using (HttpResponseMessage response = await _client.GetAsync( - $"{HashtopolisConstants.DownloadEndPointPrefix}/{bucket}/{fileId}")) - { - response.EnsureSuccessStatusCode(); - - var actual = await response.Content.ReadAsByteArrayAsync(); - - Assert.That(actual, Is.EqualTo(file)); - } - - Assert.Pass(); - } -} diff --git a/HashSlinger.Test/HashSlinger.Test.csproj b/HashSlinger.Test/HashSlinger.Test.csproj index c4f9b0e..b6073b2 100644 --- a/HashSlinger.Test/HashSlinger.Test.csproj +++ b/HashSlinger.Test/HashSlinger.Test.csproj @@ -11,9 +11,9 @@ - - - + + + diff --git a/HashSlinger/Data/HashSlingerContext.cs b/HashSlinger/Data/HashSlingerContext.cs index f5712c9..4251faa 100644 --- a/HashSlinger/Data/HashSlingerContext.cs +++ b/HashSlinger/Data/HashSlingerContext.cs @@ -86,6 +86,10 @@ public HashSlingerContext(DbContextOptions options) : base(o /// public DbSet Users { get; set; } = null!; + /// Gets or sets the chunks. + /// The chunks. + public DbSet Chunks { get; set; } = null!; + /// protected override void OnModelCreating(ModelBuilder modelBuilder) { @@ -124,10 +128,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) entity.HasOne(e => e.Chunk).WithMany(e => e.Errors).OnDelete(DeleteBehavior.ClientSetNull); }); - modelBuilder.Entity(entity => - { - entity.HasOne(d => d.Agent).WithMany(p => p.Stats).OnDelete(DeleteBehavior.ClientSetNull); - }); + modelBuilder.Entity(entity => entity.HasOne(d => d.Agent).WithMany(p => p.Stats)); modelBuilder.Entity(entity => { @@ -138,16 +139,16 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { - entity.HasOne(d => d.Agent).WithMany(p => p.Assignments).OnDelete(DeleteBehavior.ClientSetNull); - - entity.HasOne(d => d.Task).WithMany(p => p.Assignments).OnDelete(DeleteBehavior.ClientSetNull); + entity.HasOne(d => d.Agent).WithMany(p => p.Assignments); + entity.HasOne(d => d.Task).WithMany(p => p.Assignments); }); modelBuilder.Entity(entity => { entity.HasOne(d => d.Agent).WithMany(p => p.Chunks); entity.HasMany(e => e.BinaryHashes).WithOne(e => e.Chunk).OnDelete(DeleteBehavior.ClientSetNull); - entity.HasOne(d => d.Task).WithMany(p => p.Chunks).OnDelete(DeleteBehavior.ClientSetNull); + entity.HasMany(e => e.Hashes).WithOne(e => e.Chunk).OnDelete(DeleteBehavior.ClientSetNull); + entity.HasOne(d => d.Task).WithMany(p => p.Chunks); entity.HasMany(e => e.Errors).WithOne(e => e.Chunk).OnDelete(DeleteBehavior.Cascade); }); @@ -165,7 +166,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasBaseType(); - entity.HasOne(d => d.CrackerBinaryType).WithMany(p => p.CrackerBinaries).OnDelete(DeleteBehavior.ClientSetNull); + entity.HasOne(d => d.CrackerBinaryType).WithMany(p => p.CrackerBinaries); entity.HasMany(e => e.HealthChecks).WithOne(e => e.CrackerBinary).OnDelete(DeleteBehavior.Cascade); entity.HasMany(e => e.Tasks).WithOne(e => e.CrackerBinary).OnDelete(DeleteBehavior.Cascade); }); @@ -173,15 +174,14 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { - entity.HasOne(d => d.AccessGroup).WithMany(p => p.Files).OnDelete(DeleteBehavior.ClientSetNull); + entity.HasIndex(e => e.FileName); + entity.HasIndex(e => e.FileGuid); + entity.HasOne(d => d.AccessGroup).WithMany(p => p.Files); entity.HasMany(e => e.PreconfiguredTasks).WithMany(e => e.Files); entity.HasMany(e => e.Tasks).WithMany(e => e.Files); }); - modelBuilder.Entity(entity => - { - entity.HasOne(d => d.File).WithMany(p => p.FileDownloads).OnDelete(DeleteBehavior.ClientSetNull); - }); + modelBuilder.Entity(entity => { entity.HasOne(d => d.File).WithMany(p => p.FileDownloads); }); modelBuilder.Entity(entity => { @@ -203,9 +203,9 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { entity.HasIndex(e => e.IsSecret); - entity.HasOne(d => d.AccessGroup).WithMany(p => p.Hashlists).OnDelete(DeleteBehavior.ClientSetNull); - entity.HasOne(d => d.HashType).WithMany(p => p.Hashlists).OnDelete(DeleteBehavior.ClientSetNull); - entity.HasMany(e => e.TaskWrappers).WithOne(e => e.Hashlist).OnDelete(DeleteBehavior.ClientSetNull); + entity.HasOne(d => d.AccessGroup).WithMany(p => p.Hashlists); + entity.HasOne(d => d.HashType).WithMany(p => p.Hashlists); + entity.HasMany(e => e.TaskWrappers).WithOne(e => e.Hashlist).OnDelete(DeleteBehavior.Cascade); entity.HasMany(e => e.Zaps).WithOne(e => e.Hashlist).OnDelete(DeleteBehavior.Cascade); entity.HasMany(e => e.Hashes).WithOne(b => b.Hashlist).OnDelete(DeleteBehavior.Cascade); entity.HasMany(e => e.BinaryHashes).WithOne(e => e.Hashlist).OnDelete(DeleteBehavior.Cascade); @@ -213,27 +213,30 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { - entity.HasOne(d => d.CrackerBinary).WithMany(p => p.HealthChecks).OnDelete(DeleteBehavior.ClientSetNull); + entity.HasOne(d => d.CrackerBinary).WithMany(p => p.HealthChecks); entity.HasMany(e => e.HealthCheckAgents).WithOne(e => e.HealthCheck).OnDelete(DeleteBehavior.Cascade); - entity.HasOne(e => e.CrackerBinary).WithMany(c => c.HealthChecks).OnDelete(DeleteBehavior.ClientSetNull); - entity.HasOne(e => e.HashType).WithMany(c => c.HealthChecks).OnDelete(DeleteBehavior.ClientSetNull); + entity.HasOne(e => e.CrackerBinary).WithMany(c => c.HealthChecks); + entity.HasOne(e => e.HashType).WithMany(c => c.HealthChecks); }); modelBuilder.Entity(entity => { - entity.HasOne(d => d.Agent).WithMany(p => p.HealthCheckAgents).OnDelete(DeleteBehavior.ClientSetNull); - + entity.HasOne(d => d.Agent).WithMany(p => p.HealthCheckAgents); entity.HasOne(d => d.HealthCheck).WithMany(p => p.HealthCheckAgents).OnDelete(DeleteBehavior.ClientSetNull); }); modelBuilder.Entity(entity => { - entity.HasOne(d => d.User).WithMany(p => p.NotificationSettings).OnDelete(DeleteBehavior.ClientSetNull); + entity.HasOne(d => d.User) + .WithMany(p => p.NotificationSettings) + .OnDelete(DeleteBehavior.ClientSetNull); }); modelBuilder.Entity(entity => { - entity.HasOne(d => d.CrackerBinaryType).WithMany(p => p.Pretasks).OnDelete(DeleteBehavior.ClientSetNull); + entity.HasOne(d => d.CrackerBinaryType) + .WithMany(p => p.Pretasks) + .OnDelete(DeleteBehavior.ClientSetNull); }); modelBuilder.Entity(entity => @@ -244,7 +247,9 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { - entity.HasOne(d => d.User).WithMany(p => p.Sessions).OnDelete(DeleteBehavior.ClientSetNull); + entity.HasOne(d => d.User) + .WithMany(p => p.Sessions) + .OnDelete(DeleteBehavior.ClientSetNull); }); modelBuilder.Entity(entity => @@ -277,19 +282,21 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) modelBuilder.Entity(entity => { - entity.HasOne(d => d.Task).WithMany(p => p.TaskDebugOutputs).OnDelete(DeleteBehavior.ClientSetNull); + entity.HasOne(d => d.Task) + .WithMany(p => p.TaskDebugOutputs) + .OnDelete(DeleteBehavior.ClientSetNull); }); modelBuilder.Entity(entity => { + entity.HasMany(e => e.Tasks).WithOne(e => e.TaskWrapper).OnDelete(DeleteBehavior.Cascade); entity.HasOne(d => d.AccessGroup).WithMany(p => p.TaskWrappers); - - entity.HasOne(d => d.Hashlist).WithMany(p => p.TaskWrappers).OnDelete(DeleteBehavior.ClientSetNull); + entity.HasOne(d => d.Hashlist).WithMany(p => p.TaskWrappers); }); modelBuilder.Entity(entity => { - entity.HasMany(e => e.Agents).WithOne(e => e.User).OnDelete(DeleteBehavior.ClientSetNull); + entity.HasMany(e => e.Agents).WithOne(e => e.User).OnDelete(DeleteBehavior.SetNull); entity.HasMany(e => e.AccessGroups).WithMany(e => e.Users); entity.HasMany(e => e.ApiKeys).WithOne(e => e.User).OnDelete(DeleteBehavior.Cascade); entity.HasMany(e => e.NotificationSettings).WithOne(e => e.User).OnDelete(DeleteBehavior.Cascade); diff --git a/HashSlinger/Endpoints/ClientApiV1/FileEndpoints.cs b/HashSlinger/Endpoints/ClientApiV1/FileEndpoints.cs index 148cc19..034a0b1 100644 --- a/HashSlinger/Endpoints/ClientApiV1/FileEndpoints.cs +++ b/HashSlinger/Endpoints/ClientApiV1/FileEndpoints.cs @@ -16,26 +16,26 @@ public static class FileEndpoints public static void MapFileEndpoints(this IEndpointRouteBuilder routes) { routes.MapGet(ApiPrefix + "/{bucket}/{name}", - async (string bucket, string name, IFileStorageService fileStorageService) => - { - Stream? file = await fileStorageService.GetFileAsync(name, bucket).ConfigureAwait(true); - return file is null ? Results.NotFound() : TypedResults.File(file, "application/octet-stream"); - }) + async (string bucket, string name, IFileStorageService fileStorageService) => + { + Stream? file = await fileStorageService.GetFileAsync(name, bucket).ConfigureAwait(true); + return file is null ? Results.NotFound() : TypedResults.File(file, "text/plain"); + }) .Produces() .Produces(StatusCodes.Status404NotFound) .WithName("GetFile") .WithOpenApi(); - routes.MapPost("/files/{bucket}/{name}", - async (string bucket, string name, IFormFile file, IFileStorageService fileStorageService) => - { - if (file.Length == 0) return Results.BadRequest(); - Log.Information("Temp file: {TempFile}", file.Name); - await using Stream fileStream = file.OpenReadStream(); - return await fileStorageService.StoreFileAsync(name, bucket, fileStream).ConfigureAwait(true) - ? Results.Ok() - : Results.BadRequest(); - }) + routes.MapPost(ApiPrefix + "/{bucket}/{name}", + async (string bucket, string name, IFormFile file, IFileStorageService fileStorageService) => + { + if (file.Length == 0) return Results.BadRequest(); + Log.Information("Temp file: {TempFile}", file.Name); + await using Stream fileStream = file.OpenReadStream(); + return await fileStorageService.StoreFileAsync(name, bucket, fileStream).ConfigureAwait(true) + ? Results.Ok() + : Results.BadRequest(); + }) .Accepts("multipart/form-data") .WithName("PutFile"); } diff --git a/HashSlinger/Endpoints/HashtopolisApiV2/DTO/GetChunkRequest.cs b/HashSlinger/Endpoints/HashtopolisApiV2/DTO/GetChunkRequest.cs index 36dfb10..4f1d120 100644 --- a/HashSlinger/Endpoints/HashtopolisApiV2/DTO/GetChunkRequest.cs +++ b/HashSlinger/Endpoints/HashtopolisApiV2/DTO/GetChunkRequest.cs @@ -1,10 +1,11 @@ namespace HashSlinger.Api.Endpoints.HashtopolisApiV2.DTO; using System.Text.Json.Serialization; +using MediatR; /// The client requests the current task it should work on public record GetChunkRequest( [property: JsonPropertyName("action")] string Action, [property: JsonPropertyName("token")] string Token, - [property: JsonPropertyName("taskId")] int? TaskId -) : IHashtopolisRequest; + [property: JsonPropertyName("taskId")] int TaskId +) : IHashtopolisRequest, IRequest; diff --git a/HashSlinger/Endpoints/HashtopolisApiV2/DTO/GetChunkResponse.cs b/HashSlinger/Endpoints/HashtopolisApiV2/DTO/GetChunkResponse.cs index bdf1eeb..0b0aa54 100644 --- a/HashSlinger/Endpoints/HashtopolisApiV2/DTO/GetChunkResponse.cs +++ b/HashSlinger/Endpoints/HashtopolisApiV2/DTO/GetChunkResponse.cs @@ -8,10 +8,12 @@ public record GetChunkResponse( [property: JsonPropertyName("response")] string Response, [property: JsonPropertyName("status")] string Status, - [property: JsonPropertyName("chunkId")] + [property: JsonPropertyName("chunkId"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] int? ChunkId, - [property: JsonPropertyName("skip")] int? Skip, - [property: JsonPropertyName("length")] int? Length, + [property: JsonPropertyName("skip"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + ulong? Skip, + [property: JsonPropertyName("length"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + ulong? Length, [property: JsonPropertyName("message"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] string? Message = null ) : IHashtopolisMessage; diff --git a/HashSlinger/Endpoints/HashtopolisApiV2/DTO/GetFileRequest.cs b/HashSlinger/Endpoints/HashtopolisApiV2/DTO/GetFileRequest.cs index 3861aac..b160c37 100644 --- a/HashSlinger/Endpoints/HashtopolisApiV2/DTO/GetFileRequest.cs +++ b/HashSlinger/Endpoints/HashtopolisApiV2/DTO/GetFileRequest.cs @@ -1,6 +1,7 @@ namespace HashSlinger.Api.Endpoints.HashtopolisApiV2.DTO; using System.Text.Json.Serialization; +using MediatR; /// /// If the client needs a file for running a task (Wordlist or Rule File) he needs to request the url for @@ -9,6 +10,6 @@ public record GetFileRequest( [property: JsonPropertyName("action")] string Action, [property: JsonPropertyName("token")] string Token, - [property: JsonPropertyName("taskId")] int? TaskId, - [property: JsonPropertyName("file")] string File -) : IHashtopolisRequest; + [property: JsonPropertyName("taskId")] int TaskId, + [property: JsonPropertyName("file")] string FileName +) : IHashtopolisRequest, IRequest; diff --git a/HashSlinger/Endpoints/HashtopolisApiV2/DTO/GetTaskResponse.cs b/HashSlinger/Endpoints/HashtopolisApiV2/DTO/GetTaskResponse.cs index 8e47f0f..40bdd7f 100644 --- a/HashSlinger/Endpoints/HashtopolisApiV2/DTO/GetTaskResponse.cs +++ b/HashSlinger/Endpoints/HashtopolisApiV2/DTO/GetTaskResponse.cs @@ -13,6 +13,8 @@ public record GetTaskResponse( int? TaskId, [property: JsonPropertyName("attackcmd"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] string? AttackCommand, + [property: JsonPropertyName("cmdpars")] + string? CommandParameters, [property: JsonPropertyName("hashlistId"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] int? HashlistId, [property: JsonPropertyName("bench"), JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] diff --git a/HashSlinger/Endpoints/HashtopolisApiV2/DTO/SendKeyspaceRequest.cs b/HashSlinger/Endpoints/HashtopolisApiV2/DTO/SendKeyspaceRequest.cs index 760f563..2ed9e79 100644 --- a/HashSlinger/Endpoints/HashtopolisApiV2/DTO/SendKeyspaceRequest.cs +++ b/HashSlinger/Endpoints/HashtopolisApiV2/DTO/SendKeyspaceRequest.cs @@ -1,12 +1,13 @@ namespace HashSlinger.Api.Endpoints.HashtopolisApiV2.DTO; using System.Text.Json.Serialization; +using MediatR; /// The client sends the calculated keyspace of a task.
public record SendKeyspaceRequest( - [property: JsonPropertyName("action")] string Action, - [property: JsonPropertyName("token")] string Token, - [property: JsonPropertyName("taskId")] int TaskId, - [property: JsonPropertyName("keyspace")] - ulong Keyspace -) : IHashtopolisRequest; + [property: JsonPropertyName("action")] string Action, + [property: JsonPropertyName("token")] string Token, + [property: JsonPropertyName("taskId")] int TaskId, + [property: JsonPropertyName("keyspace")] + ulong Keyspace +) : IHashtopolisRequest, IRequest; diff --git a/HashSlinger/Endpoints/HashtopolisApiV2/Handlers/GetChunkHandler.cs b/HashSlinger/Endpoints/HashtopolisApiV2/Handlers/GetChunkHandler.cs new file mode 100644 index 0000000..c13dbfd --- /dev/null +++ b/HashSlinger/Endpoints/HashtopolisApiV2/Handlers/GetChunkHandler.cs @@ -0,0 +1,153 @@ +namespace HashSlinger.Api.Endpoints.HashtopolisApiV2.Handlers; + +using Api.Handlers.Commands; +using Api.Handlers.Queries; +using DTO; +using Mapster; +using MediatR; +using Serilog; +using Shared.Models; +using Shared.Models.Enums; + +/// +/// Handles the Hashtopolis API v2 GetChunk endpoint. +/// +public class GetChunkHandler : IRequestHandler +{ + private readonly IMediator _mediator; + + /// Initializes a new instance of the class. + /// The mediator. + public GetChunkHandler(IMediator mediator) => _mediator = mediator; + + /// + public async Task Handle(GetChunkRequest request, CancellationToken cancellationToken) + { + // Verify Agent + Log.Information("Verifying agent with token: {request}", request.Token); + Agent? agent = await _mediator.Send(new GetAgentByTokenQuery(request.Token), cancellationToken) + .ConfigureAwait(false); + + if (agent is null) + return request.Adapt() with + { + Response = HashtopolisConstants.ErrorResponse, + Message = "Agent not found." + }; + + if (!agent.IsActive) + return request.Adapt() with + { + Response = HashtopolisConstants.ErrorResponse, + Message = "Agent is not active." + }; + + // Update Agent LastSeen + await _mediator.Send(new TouchAgentCommand(request.Token, AgentActions.GetChunk), cancellationToken) + .ConfigureAwait(false); + + // Check for HealthChecks + Log.Information("Checking for pending health checks for agent: {agent}", agent.Id); + var healthChecksPending = await _mediator.Send(new GetPendingHealthCheckForAgentQuery(agent.Id), cancellationToken) + .ConfigureAwait(true); + if (healthChecksPending) + return request.Adapt() with + { + Response = HashtopolisConstants.SuccessResponse, + Status = GetChuckResponseStatusConstants.HealthCheck + }; + + // Get Task + Log.Information("Getting task for agent: {agent}", agent.Id); + Task? task = await _mediator.Send(new GetTaskByIdQuery(request.Token, request.TaskId), cancellationToken) + .ConfigureAwait(false); + if (task is null) + return request.Adapt() with + { + Response = HashtopolisConstants.ErrorResponse, + Message = "Task not found." + }; + + // Check if task is assigned to agent + Log.Information("Checking if task {task} is assigned to agent: {agent}", task.Id, agent.Id); + Assignment? assignment = task.Assignments.SingleOrDefault(a => a.AgentId == agent.Id); + if (assignment is null) + return request.Adapt() with + { + Response = HashtopolisConstants.ErrorResponse, + Message = "Task not assigned to agent." + }; + + // Check if task is saturated + Log.Information("Checking if task {task} is saturated for agent: {agent}", task.Id, agent.Id); + var otherAssignmentCount = task.Assignments.Count(a => a.AgentId != agent.Id); + if ((task.IsSmall && otherAssignmentCount >= 1) || (task.MaxAgents != 0 && otherAssignmentCount >= task.MaxAgents)) + return request.Adapt() with + { + Response = HashtopolisConstants.SuccessResponse, + Status = GetChuckResponseStatusConstants.FullyDispatched + }; + + + // Check for keyspace + Log.Information("Checking if task {task} has a keyspace.", task.Id); + if (task.Keyspace == 0) + return request.Adapt() with + { + Response = HashtopolisConstants.SuccessResponse, + Status = GetChuckResponseStatusConstants.KeyspaceRequired + }; + + // Check for benchmark + Log.Information("Checking if task {task} has a benchmark.", task.Id); + if (string.IsNullOrWhiteSpace(assignment.Benchmark) + && task is { IsSmall: false, StaticChunks: TaskStaticChunking.Normal }) + return request.Adapt() with + { + Response = HashtopolisConstants.SuccessResponse, + Status = GetChuckResponseStatusConstants.Benchmark + }; + + // Check for fully dispatched + + + // Find an existing chunk to assign + Log.Information("Checking for available chunks for task {task} and agent {agent}", task.Id, agent.Id); + Chunk? chunk = await _mediator.Send(new GetAvailableChunkQuery(task.Id, agent.Id), cancellationToken) + .ConfigureAwait(false); + if (chunk is not null) + { + // Assign Chunk to Agent + Log.Information("Assigning chunk {chunk} to agent {agent}", chunk.Id, agent.Id); + chunk.Agent = agent; + await _mediator.Send(new UpdateTaskCommand(task), cancellationToken).ConfigureAwait(true); + return request.Adapt() with + { + Response = HashtopolisConstants.SuccessResponse, + Status = GetChuckResponseStatusConstants.Ok, + ChunkId = chunk.Id, + Length = chunk.Length, + Skip = chunk.Skip + }; + } + + + // Create a new chunk to assign + + + return request.Adapt() with + { + Response = HashtopolisConstants.ErrorResponse, + Message = "Ran of of implementation time." + }; + } +} + +internal static class GetChuckResponseStatusConstants +{ + internal const string Ok = "OK"; + internal const string KeyspaceRequired = "keyspace_required"; + internal const string FullyDispatched = "fully_dispatched"; + internal const string HealthCheck = "health_check"; + internal const string Benchmark = "benchmark"; +} diff --git a/HashSlinger/Endpoints/HashtopolisApiV2/Handlers/GetFileHandler.cs b/HashSlinger/Endpoints/HashtopolisApiV2/Handlers/GetFileHandler.cs new file mode 100644 index 0000000..8b21c41 --- /dev/null +++ b/HashSlinger/Endpoints/HashtopolisApiV2/Handlers/GetFileHandler.cs @@ -0,0 +1,73 @@ +namespace HashSlinger.Api.Endpoints.HashtopolisApiV2.Handlers; + +using Api.Handlers.Commands; +using Api.Handlers.Queries; +using ClientApiV1; +using DTO; +using Mapster; +using MediatR; +using Serilog; +using Shared.Models; +using Shared.Models.Enums; + +/// +/// Handles the Hashtopolis API v2 GetFile endpoint. +/// +public class GetFileHandler : IRequestHandler +{ + private readonly IMediator _mediator; + + /// Initializes a new instance of the class. + /// The mediator. + public GetFileHandler(IMediator mediator) + { + _mediator = mediator; + } + + /// + public async Task Handle(GetFileRequest request, CancellationToken cancellationToken) + { + var validAgent = await _mediator.Send(new ValidateAgentTokenQuery(request.Token), cancellationToken) + .ConfigureAwait(true); + if (!validAgent) + return request.Adapt() with + { + Response = HashtopolisConstants.ErrorResponse, + Message = "Invalid token" + }; + + await _mediator.Send(new TouchAgentCommand(request.Token, AgentActions.GetFile), cancellationToken) + .ConfigureAwait(false); + + File? theFile = await _mediator.Send(new GetFileQuery(request.TaskId, request.FileName), cancellationToken) + .ConfigureAwait(true); + + Log.Information("Found file {FileName} from task {TaskId}; {theFile}", request.FileName, request.TaskId, theFile); + if (theFile is null) + return request.Adapt() with + { + Response = HashtopolisConstants.ErrorResponse, + Message = "File not found" + }; + + return request.Adapt() with + { + Response = HashtopolisConstants.SuccessResponse, + Extension = ".txt", + FileSize = theFile.Size, + Url = GetDownloadUrl(theFile) + }; + } + + private static string GetDownloadUrl(File theFile) + { + return theFile.FileType switch + { + FileType.WordList => $"/getFile/{theFile.Id}", + FileType.Rule => $"{FileEndpoints.ApiPrefix}/rule/{theFile.FileName}", + FileType.Mask => $"{FileEndpoints.ApiPrefix}/mask/{theFile.FileName}", + FileType.HashList => $"{FileEndpoints.ApiPrefix}/hashlist/{theFile.FileName}", + _ => throw new ArgumentOutOfRangeException(nameof(theFile)) + }; + } +} diff --git a/HashSlinger/Endpoints/HashtopolisApiV2/Handlers/GetFileStatusHandler.cs b/HashSlinger/Endpoints/HashtopolisApiV2/Handlers/GetFileStatusHandler.cs index e729f7b..db3f5ba 100644 --- a/HashSlinger/Endpoints/HashtopolisApiV2/Handlers/GetFileStatusHandler.cs +++ b/HashSlinger/Endpoints/HashtopolisApiV2/Handlers/GetFileStatusHandler.cs @@ -5,7 +5,6 @@ using DTO; using Mapster; using MediatR; -using Shared.Models; using Shared.Models.Enums; /// Handles the Hashtopolis API v2 GetFileStatus endpoint. @@ -22,7 +21,7 @@ public class GetFileStatusHandler : IRequestHandler Handle(GetFileStatusRequest request, CancellationToken cancellationToken) { var validAgent = await _mediator.Send(new ValidateAgentTokenQuery(request.Token), cancellationToken) - .ConfigureAwait(true); + .ConfigureAwait(true); if (!validAgent) return request.Adapt() with { @@ -31,16 +30,15 @@ public async Task Handle(GetFileStatusRequest request, Ca }; await _mediator.Send(new TouchAgentCommand(request.Token, AgentActions.GetFileStatus), cancellationToken) - .ConfigureAwait(false); + .ConfigureAwait(false); - List deletedFiles = await _mediator.Send(new GetDeletedFilesQuery(), cancellationToken) - .ConfigureAwait(true); + var deletedFiles = await _mediator.Send(new GetDeletedFileNamesQuery(), cancellationToken).ConfigureAwait(true); return request.Adapt() with { Response = HashtopolisConstants.SuccessResponse, Message = "Success", - FileNames = deletedFiles.Select(x => x.FileName).ToList() + FileNames = deletedFiles }; } } diff --git a/HashSlinger/Endpoints/HashtopolisApiV2/Handlers/GetTaskHandler.cs b/HashSlinger/Endpoints/HashtopolisApiV2/Handlers/GetTaskHandler.cs index 79ee9c0..0cd59c2 100644 --- a/HashSlinger/Endpoints/HashtopolisApiV2/Handlers/GetTaskHandler.cs +++ b/HashSlinger/Endpoints/HashtopolisApiV2/Handlers/GetTaskHandler.cs @@ -23,7 +23,7 @@ public async Task Handle(GetTaskRequest request, CancellationTo { // Verify Agent Agent? agent = await _mediator.Send(new GetAgentByTokenQuery(request.Token), cancellationToken) - .ConfigureAwait(false); + .ConfigureAwait(false); if (agent is null) { @@ -37,12 +37,12 @@ public async Task Handle(GetTaskRequest request, CancellationTo // Update Agent LastSeen await _mediator.Send(new TouchAgentCommand(request.Token, AgentActions.GetTask), cancellationToken) - .ConfigureAwait(false); + .ConfigureAwait(false); // Check for HealthChecks var healthChecks = await _mediator.Send(new GetPendingHealthCheckForAgentQuery(agent.Id), cancellationToken) - .ConfigureAwait(true); + .ConfigureAwait(true); if (healthChecks) { @@ -69,12 +69,14 @@ await _mediator.Send(new TouchAgentCommand(request.Token, AgentActions.GetTask), // Check for Assigned Task // We need to expand this to support different types of priorities (prioritize by project, hashtype, etc) GetNextTaskForAgentProjectionResponse? nextTask = await _mediator - .Send(new GetNextTaskForAgentProjectionQuery(agent.Id), cancellationToken) - .ConfigureAwait(true); + .Send(new GetNextTaskForAgentProjectionQuery(agent.Id), + cancellationToken) + .ConfigureAwait(true); Log.Information("Next Task for Agent {AgentId} is {@TaskId}", agent.Id, nextTask); if (nextTask is not null) return nextTask.Adapt() with { + Action = request.Action, Response = HashtopolisConstants.SuccessResponse, Bench = HashSlingerConfiguration.BenchmarkTime, StatusTimer = HashSlingerConfiguration.StatusTimer, diff --git a/HashSlinger/Endpoints/HashtopolisApiV2/Handlers/SendHealthCheckHandler.cs b/HashSlinger/Endpoints/HashtopolisApiV2/Handlers/SendHealthCheckHandler.cs index 7dbe16d..a530e53 100644 --- a/HashSlinger/Endpoints/HashtopolisApiV2/Handlers/SendHealthCheckHandler.cs +++ b/HashSlinger/Endpoints/HashtopolisApiV2/Handlers/SendHealthCheckHandler.cs @@ -20,7 +20,7 @@ public class SendHealthCheckHandler : IRequestHandler Handle(SendHealthCheckRequest request, CancellationToken cancellationToken) { var validAgent = await _mediator.Send(new ValidateAgentTokenQuery(request.Token), cancellationToken) - .ConfigureAwait(true); + .ConfigureAwait(true); if (!validAgent) return request.Adapt() with { @@ -29,17 +29,17 @@ public async Task Handle(SendHealthCheckRequest request }; await _mediator.Send(new TouchAgentCommand(request.Token, AgentActions.GetFileStatus), cancellationToken) - .ConfigureAwait(false); + .ConfigureAwait(false); await _mediator.Send(new UpdateHealthCheckWithResultCommand(request.Token, - request.NumCracked, - request.Start, - request.End, - request.NumGpus, - request.Errors, - request.CheckId), - cancellationToken) - .ConfigureAwait(false); + request.NumCracked, + request.Start, + request.End, + request.NumGpus, + request.Errors, + request.CheckId), + cancellationToken) + .ConfigureAwait(false); return request.Adapt() with { Response = HashtopolisConstants.OkResponse diff --git a/HashSlinger/Endpoints/HashtopolisApiV2/Handlers/SendKeyspaceHandler.cs b/HashSlinger/Endpoints/HashtopolisApiV2/Handlers/SendKeyspaceHandler.cs new file mode 100644 index 0000000..d93bd9f --- /dev/null +++ b/HashSlinger/Endpoints/HashtopolisApiV2/Handlers/SendKeyspaceHandler.cs @@ -0,0 +1,52 @@ +namespace HashSlinger.Api.Endpoints.HashtopolisApiV2.Handlers; + +using Api.Handlers.Commands; +using Api.Handlers.Queries; +using DTO; +using Mapster; +using MediatR; +using Shared.Models; +using Shared.Models.Enums; + +/// +/// Handles the Hashtopolis API v2 SendKeyspace endpoint. +/// +public class SendKeyspaceHandler : IRequestHandler +{ + private readonly IMediator _mediator; + + /// Initializes a new instance of the class. + /// The mediator. + public SendKeyspaceHandler(IMediator mediator) => _mediator = mediator; + + /// + public async Task Handle(SendKeyspaceRequest request, CancellationToken cancellationToken) + { + var validAgent = await _mediator.Send(new ValidateAgentTokenQuery(request.Token), cancellationToken) + .ConfigureAwait(true); + if (!validAgent) + return request.Adapt() with + { + Response = HashtopolisConstants.ErrorResponse, + Message = "Invalid token" + }; + + await _mediator.Send(new TouchAgentCommand(request.Token, AgentActions.SendKeyspace), cancellationToken) + .ConfigureAwait(false); + + + Task? task = await _mediator.Send(new GetTaskByIdQuery(request.Token, request.TaskId), cancellationToken) + .ConfigureAwait(true); + + if (task is null) + return request.Adapt() with { Response = "error", Message = "Task not found" }; + + task.Keyspace = request.Keyspace; + await _mediator.Send(new UpdateTaskCommand(task), cancellationToken).ConfigureAwait(true); + return request.Adapt() with + { + Response = HashtopolisConstants.SuccessResponse, + Keyspace = HashtopolisConstants.OkResponse + }; + } +} diff --git a/HashSlinger/Endpoints/HashtopolisApiV2/HashtopolisConstants.cs b/HashSlinger/Endpoints/HashtopolisApiV2/HashtopolisConstants.cs index 37c1f6d..0e8ca3e 100644 --- a/HashSlinger/Endpoints/HashtopolisApiV2/HashtopolisConstants.cs +++ b/HashSlinger/Endpoints/HashtopolisApiV2/HashtopolisConstants.cs @@ -32,4 +32,7 @@ public static class HashtopolisConstants /// The upload end point prefix public const string UploadEndPointPrefix = "/files"; + + /// The keyspace value indicating that the task is a prince task. + public const long PrinceKeyspace = -1605; } diff --git a/HashSlinger/Endpoints/HashtopolisApiV2/HashtopolisEndpoints.cs b/HashSlinger/Endpoints/HashtopolisApiV2/HashtopolisEndpoints.cs index b05bd76..d3a3be4 100644 --- a/HashSlinger/Endpoints/HashtopolisApiV2/HashtopolisEndpoints.cs +++ b/HashSlinger/Endpoints/HashtopolisApiV2/HashtopolisEndpoints.cs @@ -6,7 +6,10 @@ using MediatR; using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; using Serilog; +using Services; +using Shared.Models; /// /// Maps the endpoints for the Hashtopolis API. @@ -17,56 +20,102 @@ /// public static class HashtopolisEndpoints { - /// Maps the hashtopolis endpoints. + /// + /// Maps the hashtopolis endpoints. + /// /// The routes. + /// public static void MapHashtopolisEndpoints(this IEndpointRouteBuilder routes) { RouteGroupBuilder group = routes.MapGroup(HashtopolisConstants.EndPointPrefix); group.MapPost("/", - async (HashtopolisRequest request, [FromServices] HashSlingerContext dbContext, IMediator mediator) => - { - Log.Information("New request: {@Request}", request); + async (HashtopolisRequest request, [FromServices] HashSlingerContext dbContext, IMediator mediator) => + { + Log.Information("New request: {@Request}", request); - IHashtopolisRequest? message = HashtopolisRequest.ToHashtopolisRequest(request); - if (message is null) - { - HashtopolisRequest badRequest = request with { Response = "ERROR" }; - Log.Error("Bad API request: {@BadRequest}", badRequest); - return Results.BadRequest(badRequest); - } + IHashtopolisRequest? message = HashtopolisRequest.ToHashtopolisRequest(request); + if (message is null) + { + HashtopolisRequest badRequest = request with { Response = "ERROR" }; + Log.Error("Bad API request: {@BadRequest}", badRequest); + return Results.BadRequest(badRequest); + } - var result = await mediator.Send(message).ConfigureAwait(true); - Log.Information("Result: {@Result}", result); - return Results.Ok(result); - }) - .Accepts(false, "application/json") - .Produces() - .Produces() - .Produces() - .Produces() - .Produces() - .Produces() - .Produces() - .Produces() - .Produces() - .Produces() - .Produces() - .Produces() - .Produces() - .Produces() - .Produces() - .Produces() - .Produces() - .Produces() - .Produces(StatusCodes.Status400BadRequest); + var result = await mediator.Send(message).ConfigureAwait(true); + Log.Information("Result: {@Result}", result); + return Results.Ok(result); + }) + .Accepts(false, "application/json") + .Produces() + .Produces() + .Produces() + .Produces() + .Produces() + .Produces() + .Produces() + .Produces() + .Produces() + .Produces() + .Produces() + .Produces() + .Produces() + .Produces() + .Produces() + .Produces() + .Produces() + .Produces() + .Produces(StatusCodes.Status400BadRequest); group.MapGet("/getHashlist/{id:int}", - (int id, [FromQuery] string token, IMediator mediator) => - mediator.Send(new GetHashlistDownloadQuery(id, token))) - .Produces() - .Produces(StatusCodes.Status404NotFound) - .WithName("DownloadHashlist") - .WithOpenApi(); + (int id, [FromQuery] string token, IMediator mediator) => + mediator.Send(new GetHashlistDownloadQuery(id, token))) + .Produces() + .Produces(StatusCodes.Status404NotFound) + .WithName("DownloadHashlist") + .WithOpenApi(); + + group.MapGet("/getFile/{id:int}", + async ( + int id, + IMediator mediator, + HashSlingerContext context, + IFileStorageService fileStorageService + ) => + { + // Return the file + File? fileRecord = context.Files.FirstOrDefault(x => x.Id == id); + if (fileRecord is null) + return Results.NotFound(); + + await using Stream? fileData = await fileStorageService.GetFileAsync(fileRecord.FileName, "files") + .ConfigureAwait(true); + return fileData is null + ? Results.NotFound() + : Results.File(fileData, "text/plain", fileRecord.FileName); + }) + .Produces() + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status403Forbidden) + .WithName("DownloadFile") + .WithOpenApi(); + + group.MapMethods("/getFile/{id:int}", + new[] { "HEAD" }, + async ( + int id, + IMediator mediator, + HashSlingerContext context, + IFileStorageService fileStorageService + ) => + { + return await context.Files.AnyAsync(x => x.Id == id).ConfigureAwait(true) + ? Results.Ok() + : Results.NotFound(); + }) + .Produces(StatusCodes.Status404NotFound) + .Produces(StatusCodes.Status200OK) + .WithName("DownloadFileHead") + .WithOpenApi(); } } diff --git a/HashSlinger/Endpoints/HashtopolisApiV2/HashtopolisRequest.cs b/HashSlinger/Endpoints/HashtopolisApiV2/HashtopolisRequest.cs index c85d424..f9c1521 100644 --- a/HashSlinger/Endpoints/HashtopolisApiV2/HashtopolisRequest.cs +++ b/HashSlinger/Endpoints/HashtopolisApiV2/HashtopolisRequest.cs @@ -13,57 +13,57 @@ namespace HashSlinger.Api.Endpoints.HashtopolisApiV2; /// /// This thing is a mess and I welcome ideas on how to clean it up. public record HashtopolisRequest( - [property: JsonPropertyName("action")] string? Action = default, - [property: JsonPropertyName("voucher")] - string? Voucher = default, - [property: JsonPropertyName("name")] string? Name = default, - [property: JsonPropertyName("token")] string? Token = default, - [property: JsonPropertyName("uid")] string? Uid = default, - [property: JsonPropertyName("os")] int? OperatingSystem = default, - [property: JsonPropertyName("devices")] - ICollection? Devices = default, - [property: JsonPropertyName("clientSignature")] - string? ClientSignature = default, - [property: JsonPropertyName("version")] - string? Version = default, - [property: JsonPropertyName("preprocessorId")] - int? PreprocessorId = default, - [property: JsonPropertyName("binaryVersionId")] - int? BinaryVersionId = default, - [property: JsonPropertyName("message")] - string? Message = default, - [property: JsonPropertyName("file")] string? File = default, - [property: JsonPropertyName("hashlistId")] - int? HashlistId = default, - [property: JsonPropertyName("taskId")] int? TaskId = default, - [property: JsonPropertyName("type")] string? Type = default, - [property: JsonPropertyName("result")] string? Result = default, - [property: JsonPropertyName("chunkId")] - int? ChunkId = default, - [property: JsonPropertyName("keyspaceProgress")] - int? KeyspaceProgress = default, - [property: JsonPropertyName("relativeProgress")] - string? RelativeProgress = default, - [property: JsonPropertyName("speed")] int? Speed = default, - [property: JsonPropertyName("state")] int? State = default, - [property: JsonPropertyName("cracks")] ICollection?>? Cracks = default, - [property: JsonPropertyName("gpuTemp")] - ICollection? GpuTemp = default, - [property: JsonPropertyName("gpuUtil")] - ICollection? GpuUtil = default, - [property: JsonPropertyName("numCracked")] - int? NumCracked = default, - [property: JsonPropertyName("start")] ulong? Start = default, - [property: JsonPropertyName("end")] ulong? End = default, - [property: JsonPropertyName("numGpus")] - int? NumGpus = default, - [property: JsonPropertyName("errors")] ICollection? Errors = default, - [property: JsonPropertyName("checkId")] - int? CheckId = default, - [property: JsonPropertyName("keyspace")] - ulong? Keyspace = default, - [property: JsonPropertyName("response")] - string? Response = default + [property: JsonPropertyName("action")] string? Action = default, + [property: JsonPropertyName("voucher")] + string? Voucher = default, + [property: JsonPropertyName("name")] string? Name = default, + [property: JsonPropertyName("token")] string? Token = default, + [property: JsonPropertyName("uid")] string? Uid = default, + [property: JsonPropertyName("os")] int? OperatingSystem = default, + [property: JsonPropertyName("devices")] + ICollection? Devices = default, + [property: JsonPropertyName("clientSignature")] + string? ClientSignature = default, + [property: JsonPropertyName("version")] + string? Version = default, + [property: JsonPropertyName("preprocessorId")] + int? PreprocessorId = default, + [property: JsonPropertyName("binaryVersionId")] + int? BinaryVersionId = default, + [property: JsonPropertyName("message")] + string? Message = default, + [property: JsonPropertyName("file")] string? FileName = default, + [property: JsonPropertyName("hashlistId")] + int? HashlistId = default, + [property: JsonPropertyName("taskId")] int? TaskId = default, + [property: JsonPropertyName("type")] string? Type = default, + [property: JsonPropertyName("result")] string? Result = default, + [property: JsonPropertyName("chunkId")] + int? ChunkId = default, + [property: JsonPropertyName("keyspaceProgress")] + int? KeyspaceProgress = default, + [property: JsonPropertyName("relativeProgress")] + string? RelativeProgress = default, + [property: JsonPropertyName("speed")] int? Speed = default, + [property: JsonPropertyName("state")] int? State = default, + [property: JsonPropertyName("cracks")] ICollection?>? Cracks = default, + [property: JsonPropertyName("gpuTemp")] + ICollection? GpuTemp = default, + [property: JsonPropertyName("gpuUtil")] + ICollection? GpuUtil = default, + [property: JsonPropertyName("numCracked")] + int? NumCracked = default, + [property: JsonPropertyName("start")] ulong? Start = default, + [property: JsonPropertyName("end")] ulong? End = default, + [property: JsonPropertyName("numGpus")] + int? NumGpus = default, + [property: JsonPropertyName("errors")] ICollection? Errors = default, + [property: JsonPropertyName("checkId")] + int? CheckId = default, + [property: JsonPropertyName("keyspace")] + ulong? Keyspace = default, + [property: JsonPropertyName("response")] + string? Response = default ) : IHashtopolisMessage { /// Converts to a specific IHashtopolisRequest implementation. diff --git a/HashSlinger/Endpoints/UserApiV1/FileEndpointHandlers.cs b/HashSlinger/Endpoints/UserApiV1/FileEndpointHandlers.cs new file mode 100644 index 0000000..b46e0db --- /dev/null +++ b/HashSlinger/Endpoints/UserApiV1/FileEndpointHandlers.cs @@ -0,0 +1,92 @@ +namespace HashSlinger.Api.Endpoints.UserApiV1; + +using Data; +using Mapster; +using Microsoft.AspNetCore.Http.HttpResults; +using Microsoft.EntityFrameworkCore; +using Shared.Generated; +using Shared.Models; +using Shared.Models.Enums; + +/// +/// Holds the handlers for the file endpoints. +/// +public static class FileEndpointHandlers +{ + /// + /// Handles deleting a file. + /// + /// The identifier. + /// The database. + /// + public async static Task> DeleteFileHandlerAsync(int id, HashSlingerContext db) + { + var affected = await db.Files.Where(model => model.Id == id).ExecuteDeleteAsync().ConfigureAwait(true); + + return affected == 1 ? TypedResults.Ok() : TypedResults.NotFound(); + } + + /// + /// Handles creating a file. + /// + /// The file. + /// The database. + /// + public async static Task> CreateFileHandlerAsync(FileDto file, HashSlingerContext db) + { + db.Files.Add(file.Adapt()); + await db.SaveChangesAsync().ConfigureAwait(true); + return TypedResults.Created($"{UserApiEndPoints.ApiPrefix}/File/{file.Id}", file); + } + + /// + /// Handles updating a file. + /// + /// The identifier. + /// The file. + /// The database. + /// + public async static Task> UpdateFileHandlerAsync(int id, FileDto file, HashSlingerContext db) + { + var affected = await db.Files.Where(model => model.Id == id) + .ExecuteUpdateAsync(setters => setters.SetProperty(m => m.AccessGroupId, file.AccessGroupId) + .SetProperty(m => m.FileGuid, file.FileGuid) + .SetProperty(m => m.FileName, file.FileName) + .SetProperty( + m => m.FileType, + file.FileType.Adapt()) + .SetProperty(m => m.Id, file.Id) + .SetProperty(m => m.IsSecret, file.IsSecret) + .SetProperty(m => m.LineCount, file.LineCount) + .SetProperty(m => m.Size, file.Size)) + .ConfigureAwait(true); + + return affected == 1 ? TypedResults.Ok() : TypedResults.NotFound(); + } + + /// + /// Handles getting a file by its identifier. + /// + /// The identifier. + /// The database. + /// + public async static Task, NotFound>> GetFileByIdHandlerAsync(int id, HashSlingerContext db) + { + return await db.Files.ProjectToType() + .AsNoTracking() + .FirstOrDefaultAsync(model => model.Id == id) + .ConfigureAwait(true) is FileDto model + ? TypedResults.Ok(model) + : TypedResults.NotFound(); + } + + /// + /// Handles getting all files. + /// + /// The database. + /// + public static Task> GetAllFilesHandlerAsync(HashSlingerContext db) + { + return db.Files.ProjectToType().ToListAsync(); + } +} diff --git a/HashSlinger/Endpoints/UserApiV1/TaskEndpointHandlers.cs b/HashSlinger/Endpoints/UserApiV1/TaskEndpointHandlers.cs index eee34bf..613b2cd 100644 --- a/HashSlinger/Endpoints/UserApiV1/TaskEndpointHandlers.cs +++ b/HashSlinger/Endpoints/UserApiV1/TaskEndpointHandlers.cs @@ -6,6 +6,7 @@ using Microsoft.EntityFrameworkCore; using Shared.Generated; using Shared.Models; +using Shared.Models.Enums; /// Holds the handlers for the Task endpoints. public static class TaskEndpointHandlers @@ -43,16 +44,16 @@ public static Task> GetAllTasksHandlerAsync(HashSlingerContext db) public async static Task, NotFound>> GetTaskByIdHandlerAsync(int id, HashSlingerContext db) { return await db.Tasks.Include(t => t.TaskWrapper) - .ThenInclude(t => t.Hashlist) - .Include(t => t.CrackerBinary) - .Include(t => t.CrackerBinaryType) - .ProjectToType() - .AsSplitQuery() - .AsNoTracking() - .FirstOrDefaultAsync(model => model.Id == id) - .ConfigureAwait(true) is TaskDto model - ? TypedResults.Ok(model) - : TypedResults.NotFound(); + .ThenInclude(t => t.Hashlist) + .Include(t => t.CrackerBinary) + .Include(t => t.CrackerBinaryType) + .ProjectToType() + .AsSplitQuery() + .AsNoTracking() + .FirstOrDefaultAsync(model => model.Id == id) + .ConfigureAwait(true) is TaskDto model + ? TypedResults.Ok(model) + : TypedResults.NotFound(); } /// Handles updating @@ -62,36 +63,41 @@ public async static Task, NotFound>> GetTaskByIdHandlerAsync public async static Task> UpdateTaskHandlerAsync(int id, TaskDto task, HashSlingerContext db) { var affected = await db.Tasks.Where(model => model.Id == id) - .ExecuteUpdateAsync(setters => setters.SetProperty(m => m.AttackCommand, task.AttackCommand) - .SetProperty(m => m.ChunkSize, task.ChunkSize) - .SetProperty(m => m.ChunkTime, task.ChunkTime) - .SetProperty(m => m.Color, task.Color) - .SetProperty(m => m.EnforcePipe, task.EnforcePipe) - .SetProperty(m => m.Id, task.Id) - .SetProperty(m => m.IsArchived, task.IsArchived) - .SetProperty(m => m.IsCpuTask, task.IsCpuTask) - .SetProperty(m => m.IsSmall, task.IsSmall) - .SetProperty(m => m.Keyspace, task.Keyspace) - .SetProperty(m => m.KeyspaceProgress, task.KeyspaceProgress) - .SetProperty(m => m.MaxAgents, task.MaxAgents) - .SetProperty(m => m.Name, task.Name) - .SetProperty(m => m.Notes, task.Notes) - .SetProperty(m => m.PreprocessorCommand, task.PreprocessorCommand) - .SetProperty(m => m.Priority, task.Priority) - .SetProperty(m => m.SkipKeyspace, task.SkipKeyspace) - .SetProperty(m => m.StaticChunks, task.StaticChunks) - .SetProperty(m => m.StatusTimer, task.StatusTimer) - .SetProperty(m => m.TaskWrapperId, task.TaskWrapperId) - .SetProperty(m => m.UseNewBenchmark, task.UseNewBenchmark) - .SetProperty(m => m.UsePreprocessor, task.UsePreprocessor)) - .ConfigureAwait(true); + .ExecuteUpdateAsync(setters => setters.SetProperty(m => m.AttackCommand, task.AttackCommand) + .SetProperty(m => m.ChunkSize, task.ChunkSize) + .SetProperty(m => m.ChunkTime, task.ChunkTime) + .SetProperty(m => m.Color, task.Color) + .SetProperty(m => m.EnforcePipe, task.EnforcePipe) + .SetProperty(m => m.Id, task.Id) + .SetProperty(m => m.IsArchived, task.IsArchived) + .SetProperty(m => m.IsCpuTask, task.IsCpuTask) + .SetProperty(m => m.IsSmall, task.IsSmall) + .SetProperty(m => m.Keyspace, task.Keyspace) + .SetProperty(m => m.KeyspaceProgress, + task.KeyspaceProgress) + .SetProperty(m => m.MaxAgents, task.MaxAgents) + .SetProperty(m => m.Name, task.Name) + .SetProperty(m => m.Notes, task.Notes) + .SetProperty(m => m.PreprocessorCommand, + task.PreprocessorCommand) + .SetProperty(m => m.Priority, task.Priority) + .SetProperty(m => m.SkipKeyspace, task.SkipKeyspace) + .SetProperty(m => m.StaticChunks, + task.StaticChunks.Adapt()) + .SetProperty(m => m.StatusTimer, task.StatusTimer) + .SetProperty(m => m.TaskWrapperId, task.TaskWrapperId) + .SetProperty(m => m.UseNewBenchmark, + task.UseNewBenchmark) + .SetProperty(m => m.UsePreprocessor, + task.UsePreprocessor)) + .ConfigureAwait(true); if (affected != 1) return TypedResults.NotFound(); Task? modifiedTask = await db.Tasks.Include(t => t.TaskWrapper) - .Where(model => model.Id == id) - .SingleOrDefaultAsync() - .ConfigureAwait(true); + .Where(model => model.Id == id) + .SingleOrDefaultAsync() + .ConfigureAwait(true); if (task.TaskWrapper is not null) modifiedTask!.TaskWrapper.HashlistId = task.TaskWrapper.HashlistId; if (task.CrackerBinary is not null) modifiedTask!.CrackerBinaryId = task.CrackerBinary.Id; db.Tasks.Update(modifiedTask!); diff --git a/HashSlinger/Endpoints/UserApiV1/UserApiEndPoints.cs b/HashSlinger/Endpoints/UserApiV1/UserApiEndPoints.cs index 6331632..6a21632 100644 --- a/HashSlinger/Endpoints/UserApiV1/UserApiEndPoints.cs +++ b/HashSlinger/Endpoints/UserApiV1/UserApiEndPoints.cs @@ -19,36 +19,36 @@ public static void MapAgentBinaryEndpoints(this IEndpointRouteBuilder routes) RouteGroupBuilder? group = routes.MapGroup("/AgentBinary").WithTags(nameof(AgentBinary)); group.MapGet("/", AgentBinariesEndpointHandlers.GetAllAgentBinariesHandlerAsync) - .WithName("GetAllAgentBinaries") - .Produces>() - .Produces(StatusCodes.Status404NotFound) - .WithOpenApi(); + .WithName("GetAllAgentBinaries") + .Produces>() + .Produces(StatusCodes.Status404NotFound) + .WithOpenApi(); group.MapGet("/{id:int}", AgentBinariesEndpointHandlers.GetAgentBinaryByIdHandlerAsync) - .WithName("GetAgentBinaryById") - .Produces() - .Produces(StatusCodes.Status404NotFound) - .WithOpenApi(); + .WithName("GetAgentBinaryById") + .Produces() + .Produces(StatusCodes.Status404NotFound) + .WithOpenApi(); group.MapPut("/{id:int}", AgentBinariesEndpointHandlers.UpdateAgentBinaryHandlerAsync) - .WithName("UpdateAgentBinary") - .Produces(StatusCodes.Status200OK) - .Produces(StatusCodes.Status404NotFound) - .Accepts(false, "application/json") - .WithOpenApi(); + .WithName("UpdateAgentBinary") + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status404NotFound) + .Accepts(false, "application/json") + .WithOpenApi(); group.MapPost("/", AgentBinariesEndpointHandlers.CreateAgentBinaryHandlerAsync) - .WithName("CreateAgentBinary") - .Produces(StatusCodes.Status201Created) - .Produces(StatusCodes.Status404NotFound) - .Accepts(false, "application/json") - .WithOpenApi(); + .WithName("CreateAgentBinary") + .Produces(StatusCodes.Status201Created) + .Produces(StatusCodes.Status404NotFound) + .Accepts(false, "application/json") + .WithOpenApi(); group.MapDelete("/{id:int}", AgentBinariesEndpointHandlers.DeleteAgentBinaryHandlerAsync) - .WithName("DeleteAgentBinary") - .Produces(StatusCodes.Status200OK) - .Produces(StatusCodes.Status404NotFound) - .WithOpenApi(); + .WithName("DeleteAgentBinary") + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status404NotFound) + .WithOpenApi(); } /// Maps the cracker binary endpoints. @@ -59,36 +59,36 @@ public static void MapCrackerBinaryEndpoints(this IEndpointRouteBuilder routes) RouteGroupBuilder group = routes.MapGroup("/CrackerBinary").WithTags(nameof(CrackerBinary)); group.MapGet("/", CrackerBinariesEndpointHandler.GetAllCrackerBinariesHandlerAsync) - .WithName("GetAllCrackerBinaries") - .Produces>() - .Produces(StatusCodes.Status404NotFound) - .WithOpenApi(); + .WithName("GetAllCrackerBinaries") + .Produces>() + .Produces(StatusCodes.Status404NotFound) + .WithOpenApi(); group.MapGet("/{id:int}", CrackerBinariesEndpointHandler.GetCrackerBinaryByIdHandlerAsync) - .WithName("GetCrackerBinaryById") - .Produces() - .Produces(StatusCodes.Status404NotFound) - .WithOpenApi(); + .WithName("GetCrackerBinaryById") + .Produces() + .Produces(StatusCodes.Status404NotFound) + .WithOpenApi(); group.MapPut("/{id:int}", CrackerBinariesEndpointHandler.UpdateCrackerBinaryHandlerAsync) - .WithName("UpdateCrackerBinary") - .Produces(StatusCodes.Status200OK) - .Produces(StatusCodes.Status404NotFound) - .Accepts(false, "application/json") - .WithOpenApi(); + .WithName("UpdateCrackerBinary") + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status404NotFound) + .Accepts(false, "application/json") + .WithOpenApi(); group.MapPost("/", CrackerBinariesEndpointHandler.CreateCrackerBinaryHandlerAsync) - .WithName("CreateCrackerBinary") - .Produces(StatusCodes.Status201Created) - .Produces(StatusCodes.Status404NotFound) - .Accepts(false, "application/json") - .WithOpenApi(); + .WithName("CreateCrackerBinary") + .Produces(StatusCodes.Status201Created) + .Produces(StatusCodes.Status404NotFound) + .Accepts(false, "application/json") + .WithOpenApi(); group.MapDelete("/{id:int}", CrackerBinariesEndpointHandler.DeleteCrackerBinaryHandlerAsync) - .WithName("DeleteCrackerBinary") - .Produces(StatusCodes.Status200OK) - .Produces(StatusCodes.Status404NotFound) - .WithOpenApi(); + .WithName("DeleteCrackerBinary") + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status404NotFound) + .WithOpenApi(); } /// Maps the hashlist endpoints. @@ -99,36 +99,36 @@ public static void MapHashlistEndpoints(this IEndpointRouteBuilder routes) RouteGroupBuilder? group = routes.MapGroup("/Hashlist").WithTags(nameof(Hashlist)); group.MapGet("/", HashlistEndpointHandlers.GetAllHashlistsHandlerAsync) - .WithName("GetAllHashlists") - .Produces>() - .Produces(StatusCodes.Status404NotFound) - .WithOpenApi(); + .WithName("GetAllHashlists") + .Produces>() + .Produces(StatusCodes.Status404NotFound) + .WithOpenApi(); group.MapGet("/{id:int}", HashlistEndpointHandlers.GetHashlistByIdHandlerAsync) - .WithName("GetHashlistById") - .Produces() - .Produces(StatusCodes.Status404NotFound) - .WithOpenApi(); + .WithName("GetHashlistById") + .Produces() + .Produces(StatusCodes.Status404NotFound) + .WithOpenApi(); group.MapPut("/{id:int}", HashlistEndpointHandlers.UpdateHashlistHandlerAsync) - .WithName("UpdateHashlist") - .Produces() - .Produces(StatusCodes.Status404NotFound) - .Accepts(false, "application/json") - .WithOpenApi(); + .WithName("UpdateHashlist") + .Produces() + .Produces(StatusCodes.Status404NotFound) + .Accepts(false, "application/json") + .WithOpenApi(); group.MapPost("/", HashlistEndpointHandlers.CreateHashlistHandlerAsync) - .WithName("CreateHashlist") - .Produces(StatusCodes.Status201Created) - .Produces(StatusCodes.Status404NotFound) - .Accepts(false, "application/json") - .WithOpenApi(); + .WithName("CreateHashlist") + .Produces(StatusCodes.Status201Created) + .Produces(StatusCodes.Status404NotFound) + .Accepts(false, "application/json") + .WithOpenApi(); group.MapDelete("/{id:int}", HashlistEndpointHandlers.DeleteHashlistHandlerAsync) - .WithName("DeleteHashlist") - .Produces(StatusCodes.Status200OK) - .Produces(StatusCodes.Status404NotFound) - .WithOpenApi(); + .WithName("DeleteHashlist") + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status404NotFound) + .WithOpenApi(); } /// Maps the task endpoints. @@ -138,36 +138,36 @@ public static void MapTaskEndpoints(this IEndpointRouteBuilder routes) RouteGroupBuilder group = routes.MapGroup("/Task").WithTags(nameof(Task)); group.MapGet("/", TaskEndpointHandlers.GetAllTasksHandlerAsync) - .Produces>() - .Produces(StatusCodes.Status404NotFound) - .WithName("GetAllTasks") - .WithOpenApi(); + .Produces>() + .Produces(StatusCodes.Status404NotFound) + .WithName("GetAllTasks") + .WithOpenApi(); group.MapGet("/{id:int}", TaskEndpointHandlers.GetTaskByIdHandlerAsync) - .Produces() - .Produces(StatusCodes.Status404NotFound) - .WithName("GetTaskById") - .WithOpenApi(); + .Produces() + .Produces(StatusCodes.Status404NotFound) + .WithName("GetTaskById") + .WithOpenApi(); group.MapPut("/{id:int}", TaskEndpointHandlers.UpdateTaskHandlerAsync) - .Produces(StatusCodes.Status200OK) - .Produces(StatusCodes.Status404NotFound) - .Accepts(false, "application/json") - .WithName("UpdateTask") - .WithOpenApi(); + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status404NotFound) + .Accepts(false, "application/json") + .WithName("UpdateTask") + .WithOpenApi(); group.MapPost("/", TaskEndpointHandlers.CreateTaskHandlerAsync) - .Produces(StatusCodes.Status201Created) - .Produces(StatusCodes.Status404NotFound) - .Accepts(false, "application/json") - .WithName("CreateTask") - .WithOpenApi(); + .Produces(StatusCodes.Status201Created) + .Produces(StatusCodes.Status404NotFound) + .Accepts(false, "application/json") + .WithName("CreateTask") + .WithOpenApi(); group.MapDelete("/{id:int}", TaskEndpointHandlers.DeleteTaskHandlerAsync) - .Produces(StatusCodes.Status200OK) - .Produces(StatusCodes.Status404NotFound) - .WithName("DeleteTask") - .WithOpenApi(); + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status404NotFound) + .WithName("DeleteTask") + .WithOpenApi(); } /// Maps the user API endpoints. @@ -182,6 +182,7 @@ public static void MapUserApiEndpoints(this IEndpointRouteBuilder routes) group.MapHashlistEndpoints(); group.MapAgentBinaryEndpoints(); group.MapCrackerBinaryEndpoints(); + group.MapFileEndpoints(); } /// Maps the utility endpoints. @@ -191,12 +192,12 @@ public static void MapUtilityEndpoints(this IEndpointRouteBuilder routes) RouteGroupBuilder group = routes.MapGroup("/Utils").WithTags("Utils"); // Mostly for testing. This is not part of the final API. group.MapPost("/initial-setup", void (IMediator mediator) => mediator.Send(new PerformInitialSetupCommand())) - .WithOpenApi(); + .WithOpenApi(); // Mostly for testing. This is not part of the final API. group.MapPost("/create-health-check", - void (IMediator mediator) => mediator.Send(new AssignAllAgentsHealthCheckCommand())) - .WithOpenApi(); + void (IMediator mediator) => mediator.Send(new AssignAllAgentsHealthCheckCommand())) + .WithOpenApi(); } /// Maps the agent endpoints. @@ -206,38 +207,38 @@ internal static void MapAgentEndpoints(this IEndpointRouteBuilder routes) RouteGroupBuilder group = routes.MapGroup("/Agent").WithTags(nameof(Agent)); group.MapGet("/", AgentEndpointHandlers.GetAllAgentsHandlerAsync) - .WithName("GetAllAgents") - .Produces>() - .Produces(StatusCodes.Status404NotFound) - .WithOpenApi(); + .WithName("GetAllAgents") + .Produces>() + .Produces(StatusCodes.Status404NotFound) + .WithOpenApi(); group.MapGet("/{id:int}", AgentEndpointHandlers.GetAgentByIdHandlerAsync) - .WithName("GetAgentById") - .Produces() - .Produces(StatusCodes.Status404NotFound) - .WithOpenApi(); + .WithName("GetAgentById") + .Produces() + .Produces(StatusCodes.Status404NotFound) + .WithOpenApi(); group.MapPut("/{id:int}", AgentEndpointHandlers.UpdateAgentHandlerAsync) - .Produces(StatusCodes.Status200OK) - .Produces(StatusCodes.Status404NotFound) - .Accepts(false, "application/json") - .WithName("UpdateAgent") - .WithOpenApi(); + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status404NotFound) + .Accepts(false, "application/json") + .WithName("UpdateAgent") + .WithOpenApi(); group.MapPost("/", AgentEndpointHandlers.CreateAgentHandlerAsync) - .Accepts(false, "application/json") - .Produces(StatusCodes.Status201Created) - .Produces(StatusCodes.Status404NotFound) - .Accepts(false, "application/json") - .WithName("CreateAgent") - .WithOpenApi(); + .Accepts(false, "application/json") + .Produces(StatusCodes.Status201Created) + .Produces(StatusCodes.Status404NotFound) + .Accepts(false, "application/json") + .WithName("CreateAgent") + .WithOpenApi(); group.MapDelete("/{id}", AgentEndpointHandlers.DeleteAgentHandlerAsync) - .Accepts(false, "application/json") - .Produces(StatusCodes.Status200OK) - .Produces(StatusCodes.Status404NotFound) - .WithName("DeleteAgent") - .WithOpenApi(); + .Accepts(false, "application/json") + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status404NotFound) + .WithName("DeleteAgent") + .WithOpenApi(); } @@ -248,37 +249,77 @@ internal static void MapRegistrationVoucherEndpoints(this IEndpointRouteBuilder RouteGroupBuilder? group = routes.MapGroup("/RegistrationVoucher").WithTags(nameof(RegistrationVoucher)); group.MapGet("/", RegistrationVoucherEndpointHandlers.GetAllRegistrationVouchersHandlerAsync) - .WithName("GetAllRegistrationVouchers") - .Produces>() - .Produces(StatusCodes.Status404NotFound) - .WithOpenApi(); + .WithName("GetAllRegistrationVouchers") + .Produces>() + .Produces(StatusCodes.Status404NotFound) + .WithOpenApi(); group.MapGet("/{id:int}", RegistrationVoucherEndpointHandlers.GetRegistrationVoucherByIdHandlerAsync) - .WithName("GetRegistrationVoucherById") - .Produces() - .Produces(StatusCodes.Status404NotFound) - .WithOpenApi(); + .WithName("GetRegistrationVoucherById") + .Produces() + .Produces(StatusCodes.Status404NotFound) + .WithOpenApi(); group.MapPut("/{id:int}", RegistrationVoucherEndpointHandlers.UpdateRegistrationVoucherHandlerAsync) - .Accepts(false, "application/json") - .WithName("UpdateRegistrationVoucher") - .Produces(StatusCodes.Status200OK) - .Produces(StatusCodes.Status404NotFound) - .Accepts(false, "application/json") - .WithOpenApi(); + .Accepts(false, "application/json") + .WithName("UpdateRegistrationVoucher") + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status404NotFound) + .Accepts(false, "application/json") + .WithOpenApi(); group.MapPost("/", RegistrationVoucherEndpointHandlers.CreateRegistrationVoucherHandlerAsync) - .Accepts(false, "application/json") - .WithName("CreateRegistrationVoucher") - .Produces(StatusCodes.Status201Created) - .Produces(StatusCodes.Status404NotFound) - .Accepts(false, "application/json") - .WithOpenApi(); + .Accepts(false, "application/json") + .WithName("CreateRegistrationVoucher") + .Produces(StatusCodes.Status201Created) + .Produces(StatusCodes.Status404NotFound) + .Accepts(false, "application/json") + .WithOpenApi(); group.MapDelete("/{id:int}", RegistrationVoucherEndpointHandlers.DeleteRegistrationVoucherHandlerAsync) - .WithName("DeleteRegistrationVoucher") - .Produces(StatusCodes.Status200OK) - .Produces(StatusCodes.Status404NotFound) - .WithOpenApi(); + .WithName("DeleteRegistrationVoucher") + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status404NotFound) + .WithOpenApi(); + } + + /// Maps the file endpoints. + public static void MapFileEndpoints(this IEndpointRouteBuilder routes) + { + RouteGroupBuilder? group = routes.MapGroup("/File").WithTags(nameof(File)); + + group.MapGet("/", FileEndpointHandlers.GetAllFilesHandlerAsync) + .WithName("GetAllFiles") + .Produces>() + .Produces(StatusCodes.Status404NotFound) + .WithOpenApi(); + + group.MapGet("/{id:int}", FileEndpointHandlers.GetFileByIdHandlerAsync) + .WithName("GetFileById") + .Produces() + .Produces(StatusCodes.Status404NotFound) + .WithOpenApi(); + + group.MapPut("/{id:int}", FileEndpointHandlers.UpdateFileHandlerAsync) + .WithName("UpdateFile") + .Accepts(false, "application/json") + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status404NotFound) + .Accepts(false, "application/json") + .WithOpenApi(); + + group.MapPost("/", FileEndpointHandlers.CreateFileHandlerAsync) + .WithName("CreateFile") + .Accepts(false, "application/json") + .Produces(StatusCodes.Status201Created) + .Produces(StatusCodes.Status404NotFound) + .Accepts(false, "application/json") + .WithOpenApi(); + + group.MapDelete("/{id:int}", FileEndpointHandlers.DeleteFileHandlerAsync) + .WithName("DeleteFile") + .Produces(StatusCodes.Status200OK) + .Produces(StatusCodes.Status404NotFound) + .WithOpenApi(); } } diff --git a/HashSlinger/Handlers/Commands/PerformInitialSetupCommand.cs b/HashSlinger/Handlers/Commands/PerformInitialSetupCommand.cs index 78fd25c..494d3fd 100644 --- a/HashSlinger/Handlers/Commands/PerformInitialSetupCommand.cs +++ b/HashSlinger/Handlers/Commands/PerformInitialSetupCommand.cs @@ -6,7 +6,7 @@ using Shared.Models; using Shared.Models.Enums; using Utilities; -using Task = Task; +using Task = System.Threading.Tasks.Task; /// Represents a command to perform the initial setup of the application. public record PerformInitialSetupCommand : IRequest; @@ -40,6 +40,7 @@ public Task Handle(PerformInitialSetupCommand request, CancellationToken cancell _dbContext.LogEntries.RemoveRange(_dbContext.LogEntries); _dbContext.CrackerBinaries.RemoveRange(_dbContext.CrackerBinaries); _dbContext.Hashlists.RemoveRange(_dbContext.Hashlists); + _dbContext.Files.RemoveRange(_dbContext.Files); _dbContext.SaveChanges(); // Seed the database. @@ -51,11 +52,11 @@ public Task Handle(PerformInitialSetupCommand request, CancellationToken cancell Executable = "https://archive.hashtopolis.org/agent/python/stable/0.7.1.zip", Name = "hashtopolis.zip", OperatingSystems = new List - { - AgentOperatingSystems.Windows.Adapt(), - AgentOperatingSystems.Linux.Adapt(), - AgentOperatingSystems.MacOS.Adapt() - }, + { + AgentOperatingSystems.Windows.Adapt(), + AgentOperatingSystems.Linux.Adapt(), + AgentOperatingSystems.MacOS.Adapt() + }, Version = "0.7.1", UpdateAvailable = string.Empty, UpdateTrack = "stable" @@ -93,11 +94,11 @@ public Task Handle(PerformInitialSetupCommand request, CancellationToken cancell DownloadUrl = "https://hashcat.net/files/hashcat-6.2.6.7z", Name = "hashcat", OperatingSystems = new List - { - AgentOperatingSystems.Windows.Adapt(), - AgentOperatingSystems.Linux.Adapt(), - AgentOperatingSystems.MacOS.Adapt() - }, + { + AgentOperatingSystems.Windows.Adapt(), + AgentOperatingSystems.Linux.Adapt(), + AgentOperatingSystems.MacOS.Adapt() + }, Version = "6.2.6", CrackerBinaryType = _dbContext.CrackerBinaryTypes.Single(x => x.TypeName == "hashcat") }; @@ -107,13 +108,13 @@ public Task Handle(PerformInitialSetupCommand request, CancellationToken cancell { AccessGroup = defaultGroup, Hashes = new List - { - new() { - HashValue = "e2fc714c4727ee9395f324cd2e7f331f", - IsCracked = false - } - }, + new() + { + HashValue = "e2fc714c4727ee9395f324cd2e7f331f", + IsCracked = false + } + }, HashType = _dbContext.HashTypes.Single(x => x.HashcatId == 0), BrainFeatures = 0, BrainId = 0, @@ -130,6 +131,16 @@ public Task Handle(PerformInitialSetupCommand request, CancellationToken cancell }; _dbContext.Hashlists.Add(hashlist); + var passwordList = new File + { + AccessGroup = defaultGroup, + FileName = "500-worst-passwords.txt", + IsSecret = false, + FileType = FileType.WordList, + LineCount = 500, + Size = 3491 + }; + _dbContext.Files.Add(passwordList); var newTask = new Shared.Models.Task { @@ -143,12 +154,13 @@ public Task Handle(PerformInitialSetupCommand request, CancellationToken cancell Name = "Test Task", Priority = 0 }, - AttackCommand = "-a 0 #HL#", + AttackCommand = "-a 0 #HL# 500-worst-passwords.txt", ChunkSize = 600, EnforcePipe = false, IsArchived = false, IsCpuTask = false, IsSmall = false, + Files = new List { passwordList }, MaxAgents = 0, Name = "Test Task", Notes = "It's perfect. No notes.", diff --git a/HashSlinger/Handlers/Commands/UpdateTaskCommand.cs b/HashSlinger/Handlers/Commands/UpdateTaskCommand.cs new file mode 100644 index 0000000..9278c70 --- /dev/null +++ b/HashSlinger/Handlers/Commands/UpdateTaskCommand.cs @@ -0,0 +1,27 @@ +namespace HashSlinger.Api.Handlers.Commands; + +using Data; +using MediatR; +using Serilog; +using Task = System.Threading.Tasks.Task; + +/// Represents a command to update an task. +public record UpdateTaskCommand(Shared.Models.Task Task) : IRequest; + +/// Handles updating an task in the database. +public class UpdateTaskHandler : IRequestHandler +{ + private readonly HashSlingerContext _dbContext; + + /// Initializes a new instance of the class. + /// The database context. + public UpdateTaskHandler(HashSlingerContext dbContext) => _dbContext = dbContext; + + /// + public Task Handle(UpdateTaskCommand request, CancellationToken cancellationToken) + { + Log.Debug("Updating task {Task}", request.Task); + _dbContext.Tasks.Update(request.Task); + return _dbContext.SaveChangesAsync(cancellationToken); + } +} diff --git a/HashSlinger/Handlers/Queries/GetAvailableChunkQuery.cs b/HashSlinger/Handlers/Queries/GetAvailableChunkQuery.cs new file mode 100644 index 0000000..662df2a --- /dev/null +++ b/HashSlinger/Handlers/Queries/GetAvailableChunkQuery.cs @@ -0,0 +1,34 @@ +namespace HashSlinger.Api.Handlers.Queries; + +using Data; +using MediatR; +using Microsoft.EntityFrameworkCore; +using Shared.Models; +using Shared.Models.Enums; + +public record GetAvailableChunkQuery(int TaskId, int AgentId) : IRequest; + +public class GetAvailableChunkHandler : IRequestHandler +{ + private readonly HashSlingerContext _context; + public GetAvailableChunkHandler(HashSlingerContext context) => _context = context; + + /// + public Task Handle(GetAvailableChunkQuery request, CancellationToken cancellationToken) + { + // Find chunks for this task. + IQueryable? orderedChunks = _context.Chunks.OrderBy(x => x.Skip).Where(x => x.TaskId == request.TaskId); + + // Find uncracked chunks for this task. + IQueryable? uncrackedChunks = orderedChunks.Where(x => x.State != ChunkState.Cracked) + .Where(x => x.Progress < 100.00 || x.Progress == null); + + // Find chunks that are not assigned to an agent or have been aborted or timed out. + return uncrackedChunks.FirstOrDefaultAsync(x => x.AgentId == request.AgentId + || x.State == ChunkState.Aborted + || x.State == ChunkState.StatusAbortedRuntime + || x.DispatchTime + < DateTime.UtcNow.AddSeconds(-HashSlingerConfiguration.ChunkTimeout), + cancellationToken); + } +} diff --git a/HashSlinger/Handlers/Queries/GetDeletedFilesQuery.cs b/HashSlinger/Handlers/Queries/GetDeletedFilesQuery.cs index ff97b4a..a2facf1 100644 --- a/HashSlinger/Handlers/Queries/GetDeletedFilesQuery.cs +++ b/HashSlinger/Handlers/Queries/GetDeletedFilesQuery.cs @@ -3,24 +3,23 @@ using Data; using MediatR; using Microsoft.EntityFrameworkCore; -using Shared.Models; /// Represents a query to retrieve all deleted files from the database. -public record GetDeletedFilesQuery : IRequest>; +public record GetDeletedFileNamesQuery : IRequest; /// Handles retrieving all deleted files from the database. // ReSharper disable once UnusedMember.Global -public class GetDeletedFilesHandler : IRequestHandler> +public class GetDeletedFileNamesHandler : IRequestHandler { private readonly HashSlingerContext _dbContext; - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// The database context. - public GetDeletedFilesHandler(HashSlingerContext dbContext) => _dbContext = dbContext; + public GetDeletedFileNamesHandler(HashSlingerContext dbContext) => _dbContext = dbContext; /// - public Task> Handle(GetDeletedFilesQuery request, CancellationToken cancellationToken) + public Task Handle(GetDeletedFileNamesQuery request, CancellationToken cancellationToken) { - return _dbContext.FileDeletes.ToListAsync(cancellationToken); + return _dbContext.FileDeletes.Select(x => x.FileName).ToArrayAsync(cancellationToken); } } diff --git a/HashSlinger/Handlers/Queries/GetFileQuery.cs b/HashSlinger/Handlers/Queries/GetFileQuery.cs new file mode 100644 index 0000000..d882769 --- /dev/null +++ b/HashSlinger/Handlers/Queries/GetFileQuery.cs @@ -0,0 +1,48 @@ +namespace HashSlinger.Api.Handlers.Queries; + +using Data; +using MediatR; +using Microsoft.EntityFrameworkCore; +using Serilog; +using Shared.Models; + +/// +/// Represents a query to get a file from a task. +/// +public record GetFileQuery(int TaskId, string FileName) : IRequest; + +/// +/// Handles getting a file from a task. +/// +public class GetFileHandler : IRequestHandler +{ + private readonly HashSlingerContext _dbContext; + + /// Initializes a new instance of the class. + /// The database context. + public GetFileHandler(HashSlingerContext dbContext) => _dbContext = dbContext; + + + /// + public async Task Handle(GetFileQuery request, CancellationToken cancellationToken) + { + Log.Debug("Getting file {FileName} from task {TaskId}", request.FileName, request.TaskId); + //Task? task = await _dbContext.Tasks.FindAsync(request.TaskId).ConfigureAwait(true); + + //File? file = await _dbContext.Files.Where(x => task != null && task.Files.Any(f => f.FileName == request.FileName)) + //.FirstOrDefaultAsync(x => x.FileName == request.FileName, cancellationToken) + //.ConfigureAwait(true); + + File? file = await _dbContext.Files.FirstOrDefaultAsync(x => x.FileName == request.FileName, cancellationToken) + .ConfigureAwait(true); + + + Log.Information("File {FileName} from task {TaskId} found: {FileFound}", + request.FileName, + request.TaskId, + file != null); + + + return file; + } +} diff --git a/HashSlinger/Handlers/Queries/GetNextTaskForAgentProjectionQuery.cs b/HashSlinger/Handlers/Queries/GetNextTaskForAgentProjectionQuery.cs index fcaaec8..c27bfc5 100644 --- a/HashSlinger/Handlers/Queries/GetNextTaskForAgentProjectionQuery.cs +++ b/HashSlinger/Handlers/Queries/GetNextTaskForAgentProjectionQuery.cs @@ -12,7 +12,7 @@ public record GetNextTaskForAgentProjectionQuery(int AgentId) : IRequestHandles getting the next task for an agent.
/// This ugly beast needs to be refined. It's a mess. public class GetNextTaskForAgentProjectionHandler : IRequestHandler + GetNextTaskForAgentProjectionResponse?> { private readonly HashSlingerContext _dbContext; @@ -22,19 +22,19 @@ public class GetNextTaskForAgentProjectionHandler : IRequestHandler public async Task Handle( - GetNextTaskForAgentProjectionQuery request, - CancellationToken cancellationToken + GetNextTaskForAgentProjectionQuery request, + CancellationToken cancellationToken ) { Log.Information("Getting next task for Agent {AgentId}", request.AgentId); var nextTaskId = await _dbContext.Tasks.Where(t => t.Assignments.Any(a => a.AgentId == request.AgentId)) - .OrderByDescending(t => t.Priority) - .ThenBy(t => t.Keyspace) - .AsSplitQuery() - .Select(t => t.Id) - .FirstOrDefaultAsync(cancellationToken) - .ConfigureAwait(true); + .OrderByDescending(t => t.Priority) + .ThenBy(t => t.Keyspace) + .AsSplitQuery() + .Select(t => t.Id) + .FirstOrDefaultAsync(cancellationToken) + .ConfigureAwait(true); Log.Information("Next task ID: {TaskId}", nextTaskId); @@ -42,12 +42,12 @@ CancellationToken cancellationToken { Log.Information("No tasks found for Agent {AgentId}", request.AgentId); Task? nextUnassignedTask = await _dbContext.Tasks.Include(t => t.Assignments) - .Where(t => t.MaxAgents == 0 || t.Assignments.Count != t.MaxAgents) - .OrderByDescending(t => t.Priority) - .ThenBy(t => t.Keyspace) - .AsSplitQuery() - .FirstOrDefaultAsync(cancellationToken) - .ConfigureAwait(true); + .Where(t => t.MaxAgents == 0 || t.Assignments.Count != t.MaxAgents) + .OrderByDescending(t => t.Priority) + .ThenBy(t => t.Keyspace) + .AsSplitQuery() + .FirstOrDefaultAsync(cancellationToken) + .ConfigureAwait(true); if (nextUnassignedTask is null || nextUnassignedTask.Id == 0) { Log.Information("No unassigned tasks found for Agent {AgentId}", request.AgentId); @@ -65,38 +65,44 @@ CancellationToken cancellationToken return await _dbContext.Tasks.Where(t => t.Id == nextTaskId) - .Select(t => new GetNextTaskForAgentProjectionResponse(t.Id, - t.AttackCommand, - t.TaskWrapper.HashlistId, - t.UseNewBenchmark ? "speed" : "run", - t.CrackerBinary!.Id, - t.Files.Select(f => f.FileName).ToList(), - t.Keyspace, - t.UsePreprocessor, - t.Preprocessor != null ? null : t.Preprocessor!.Id, - t.PreprocessorCommand, - t.EnforcePipe, - t.TaskWrapper.Hashlist.HashType.IsSlowHash, - t.Priority)) - .AsSplitQuery() - .FirstOrDefaultAsync(cancellationToken) - .ConfigureAwait(true); + .Select(t => new GetNextTaskForAgentProjectionResponse(t.Id, + t.AttackCommand, + t.TaskWrapper.HashlistId, + t.UseNewBenchmark ? "speed" : "run", + t.CrackerBinary!.Id, + t.Files.Select(f => f.FileName).ToList(), + t.Keyspace, + t.UsePreprocessor, + t.Preprocessor != null + ? null + : t.Preprocessor!.Id, + t.PreprocessorCommand, + t.EnforcePipe, + t.TaskWrapper.Hashlist.HashType.IsSlowHash, + t.Priority, + $" --hash-type={t.TaskWrapper.Hashlist.HashType.HashcatId} {t.Assignments + .Single(a => a.Agent.Id + == request.AgentId) + .Agent.CommandParameters}")) + .FirstOrDefaultAsync(cancellationToken) + .ConfigureAwait(true); } } /// Represents the response from . public record GetNextTaskForAgentProjectionResponse( - int TaskId, - string AttackCommand, - int HashlistId, - string BenchType, - int CrackerId, - List Files, - ulong Keyspace, - bool UsePreprocessor, - int? PreprocessorId, - string? PreprocessorCommand, - bool EnforcePipe, - bool? SlowHash, - int Priority = 0 + int TaskId, + string AttackCommand, + int HashlistId, + string BenchType, + int CrackerId, + List Files, + ulong Keyspace, + bool UsePreprocessor, + int? PreprocessorId, + string? PreprocessorCommand, + bool EnforcePipe, + bool? SlowHash, + int Priority = 0, + string? CommandParameters = null ); diff --git a/HashSlinger/Handlers/Queries/GetPendingHealthCheckForAgentQuery.cs b/HashSlinger/Handlers/Queries/GetPendingHealthCheckForAgentQuery.cs index 5a735bd..616d770 100644 --- a/HashSlinger/Handlers/Queries/GetPendingHealthCheckForAgentQuery.cs +++ b/HashSlinger/Handlers/Queries/GetPendingHealthCheckForAgentQuery.cs @@ -2,9 +2,8 @@ using Data; using MediatR; -using Shared.Models; +using Microsoft.EntityFrameworkCore; using Shared.Models.Enums; -using Task = System.Threading.Tasks.Task; /// Represents a query to check if there is a pending health check for an agent. /// @@ -23,8 +22,8 @@ public class GetPendingHealthCheckForAgentHandler : IRequestHandler public Task Handle(GetPendingHealthCheckForAgentQuery request, CancellationToken cancellationToken) { - IQueryable? agent = _dbContext.Agents.Where(a => - a.Id == request.AgentId && a.HealthCheckAgents.Count(h => h.Status == HealthCheckStatus.Pending) > 0); - return Task.FromResult(agent.Any()); + return _dbContext.Agents.Where(a => + a.Id == request.AgentId && a.HealthCheckAgents.Any(h => h.Status == HealthCheckStatus.Pending)) + .AnyAsync(cancellationToken); } } diff --git a/HashSlinger/Handlers/Queries/GetTaskByIdHandler.cs b/HashSlinger/Handlers/Queries/GetTaskByIdHandler.cs new file mode 100644 index 0000000..d41e0a4 --- /dev/null +++ b/HashSlinger/Handlers/Queries/GetTaskByIdHandler.cs @@ -0,0 +1,29 @@ +namespace HashSlinger.Api.Handlers.Queries; + +using Data; +using MediatR; +using Microsoft.EntityFrameworkCore; +using Shared.Models; + +public record GetTaskByIdQuery(string Token, int TaskId) : IRequest; + +public class GetTaskByIdHandler : IRequestHandler +{ + private readonly HashSlingerContext _context; + public GetTaskByIdHandler(HashSlingerContext context) => _context = context; + + /// + public async Task Handle(GetTaskByIdQuery request, CancellationToken cancellationToken) + { + Agent? agent = await _context.Agents.SingleOrDefaultAsync(x => x.Token == request.Token, cancellationToken) + .ConfigureAwait(false); + if (agent is null) return null; + Task? task = await _context.Tasks.Include(t => t.TaskWrapper) + .Include(t => t.Chunks) + .Include(t => t.Assignments) + .AsSplitQuery() + .SingleOrDefaultAsync(x => x.Id == request.TaskId, cancellationToken) + .ConfigureAwait(false); + return task; + } +} diff --git a/HashSlinger/HashSlinger.Api.csproj b/HashSlinger/HashSlinger.Api.csproj index 0690de4..f2c699b 100644 --- a/HashSlinger/HashSlinger.Api.csproj +++ b/HashSlinger/HashSlinger.Api.csproj @@ -12,23 +12,23 @@ - + - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/HashSlinger/Migrations/20230628011334_InitialSetup.Designer.cs b/HashSlinger/Migrations/20230628011334_InitialSetup.Designer.cs index 1da831a..f8ebceb 100644 --- a/HashSlinger/Migrations/20230628011334_InitialSetup.Designer.cs +++ b/HashSlinger/Migrations/20230628011334_InitialSetup.Designer.cs @@ -1,18 +1,15 @@ // -using System; -using System.Collections.Generic; -using System.Net; -using HashSlinger.Api.Data; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; #nullable disable namespace HashSlinger.Api.Migrations { + using System.Net; + using Data; + using Microsoft.EntityFrameworkCore; + using Microsoft.EntityFrameworkCore.Infrastructure; + using Microsoft.EntityFrameworkCore.Migrations; + [DbContext(typeof(HashSlingerContext))] [Migration("20230628011334_InitialSetup")] partial class InitialSetup diff --git a/HashSlinger/Migrations/20230628011334_InitialSetup.cs b/HashSlinger/Migrations/20230628011334_InitialSetup.cs index e1ab0ec..072b9c3 100644 --- a/HashSlinger/Migrations/20230628011334_InitialSetup.cs +++ b/HashSlinger/Migrations/20230628011334_InitialSetup.cs @@ -1,13 +1,11 @@ -using System; -using System.Collections.Generic; -using System.Net; -using Microsoft.EntityFrameworkCore.Migrations; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -#nullable disable +#nullable disable namespace HashSlinger.Api.Migrations { + using System.Net; + using Microsoft.EntityFrameworkCore.Migrations; + using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + /// public partial class InitialSetup : Migration { diff --git a/HashSlinger/Migrations/20230629001850_ModifiedTasksAndChunks.Designer.cs b/HashSlinger/Migrations/20230629001850_ModifiedTasksAndChunks.Designer.cs new file mode 100644 index 0000000..0310d52 --- /dev/null +++ b/HashSlinger/Migrations/20230629001850_ModifiedTasksAndChunks.Designer.cs @@ -0,0 +1,1911 @@ +// + +#nullable disable + +namespace HashSlinger.Api.Migrations +{ + using System.Net; + using Data; + using Microsoft.EntityFrameworkCore; + using Microsoft.EntityFrameworkCore.Infrastructure; + using Microsoft.EntityFrameworkCore.Migrations; + + [DbContext(typeof(HashSlingerContext))] + [Migration("20230629001850_ModifiedTasksAndChunks")] + partial class ModifiedTasksAndChunks + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("AccessGroupAgent", b => + { + b.Property("AccessGroupsId") + .HasColumnType("integer"); + + b.Property("AgentsId") + .HasColumnType("integer"); + + b.HasKey("AccessGroupsId", "AgentsId"); + + b.HasIndex("AgentsId"); + + b.ToTable("AccessGroupAgent"); + }); + + modelBuilder.Entity("AccessGroupUser", b => + { + b.Property("AccessGroupsId") + .HasColumnType("integer"); + + b.Property("UsersId") + .HasColumnType("integer"); + + b.HasKey("AccessGroupsId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("AccessGroupUser"); + }); + + modelBuilder.Entity("FilePreconfiguredTask", b => + { + b.Property("FilesId") + .HasColumnType("integer"); + + b.Property("PreconfiguredTasksId") + .HasColumnType("integer"); + + b.HasKey("FilesId", "PreconfiguredTasksId"); + + b.HasIndex("PreconfiguredTasksId"); + + b.ToTable("FilePreconfiguredTask"); + }); + + modelBuilder.Entity("FileTask", b => + { + b.Property("FilesId") + .HasColumnType("integer"); + + b.Property("TasksId") + .HasColumnType("integer"); + + b.HasKey("FilesId", "TasksId"); + + b.HasIndex("TasksId"); + + b.ToTable("FileTask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AccessGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("AccessGroups"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClientSignature") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("CommandParameters") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CpuOnly") + .HasColumnType("boolean"); + + b.Property>("Devices") + .HasColumnType("text[]"); + + b.Property("IgnoreErrors") + .HasColumnType("boolean"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("IsTrusted") + .HasColumnType("boolean"); + + b.Property("LastAction") + .HasColumnType("integer"); + + b.Property("LastSeenIpAddress") + .HasColumnType("inet"); + + b.Property("LastSeenTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("OperatingSystem") + .HasColumnType("integer"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.Property("Uid") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("Token"); + + b.HasIndex("Uid"); + + b.HasIndex("UserId"); + + b.ToTable("Agents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentError", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("ChunkId") + .HasColumnType("integer"); + + b.Property("Error") + .IsRequired() + .HasColumnType("text"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("ChunkId"); + + b.HasIndex("TaskId"); + + b.ToTable("AgentError"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentStat", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("StatType") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.ToTable("AgentStat"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Permissions") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("ApiGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessCount") + .HasColumnType("integer"); + + b.Property("AccessKey") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ApiGroupId") + .HasColumnType("integer"); + + b.Property("EndValid") + .HasColumnType("timestamp with time zone"); + + b.Property("StartValid") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ApiGroupId"); + + b.HasIndex("UserId"); + + b.ToTable("ApiKey"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Assignment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Benchmark") + .IsRequired() + .HasColumnType("text"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Assignment"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Checkpoint") + .HasColumnType("numeric(20,0)"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("DispatchTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Length") + .HasColumnType("numeric(20,0)"); + + b.Property("Progress") + .HasColumnType("real"); + + b.Property("Skip") + .HasColumnType("numeric(20,0)"); + + b.Property("SolveTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Speed") + .HasColumnType("numeric(20,0)"); + + b.Property("State") + .HasColumnType("integer"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Chunk"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinaryType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IsChunkingAvailable") + .HasColumnType("boolean"); + + b.Property("TypeName") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.HasKey("Id"); + + b.ToTable("CrackerBinaryTypes"); + + b.HasData( + new + { + Id = 1, + IsChunkingAvailable = true, + TypeName = "hashcat" + }); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.DownloadableBinary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("text"); + + b.Property("DownloadUrl") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("Executable") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("FileId") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property>("OperatingSystems") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("Version") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.ToTable("DownloadableBinaries"); + + b.HasDiscriminator("Discriminator").HasValue("DownloadableBinary"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("FileGuid") + .HasColumnType("uuid"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("FileType") + .HasColumnType("integer"); + + b.Property("IsSecret") + .HasColumnType("boolean"); + + b.Property("LineCount") + .HasColumnType("bigint"); + + b.Property("Size") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.ToTable("Files"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDelete", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("FileDeletes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDownload", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FileId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.ToTable("FileDownload"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashBase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ChunkId") + .HasColumnType("integer"); + + b.Property("CrackPos") + .HasColumnType("numeric(20,0)"); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("IsCracked") + .HasColumnType("boolean"); + + b.Property("Plaintext") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("TimeCracked") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("HashBase"); + + b.HasDiscriminator("Discriminator").HasValue("HashBase"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("HashcatId") + .HasColumnType("integer"); + + b.Property("IsSalted") + .HasColumnType("boolean"); + + b.Property("IsSlowHash") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("HashcatId") + .IsUnique(); + + b.ToTable("HashTypes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("BrainFeatures") + .HasColumnType("smallint"); + + b.Property("BrainId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("Format") + .HasColumnType("integer"); + + b.Property("HashCount") + .HasColumnType("integer"); + + b.Property("HashTypeId") + .HasColumnType("uuid"); + + b.Property("HexSalt") + .HasColumnType("boolean"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("IsSalted") + .HasColumnType("boolean"); + + b.Property("IsSecret") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("text"); + + b.Property("SaltSeparator") + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("HashTypeId"); + + b.HasIndex("IsSecret"); + + b.ToTable("Hashlists"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCmd") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CheckType") + .HasColumnType("integer"); + + b.Property("CrackerBinaryId") + .HasColumnType("integer"); + + b.Property("ExpectedCracks") + .HasColumnType("integer"); + + b.Property("HashListAlias") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashTypeId") + .HasColumnType("uuid"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property>("TestHashes") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryId"); + + b.HasIndex("HashTypeId"); + + b.ToTable("HealthChecks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheckAgent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("End") + .HasColumnType("numeric(20,0)"); + + b.Property>("Errors") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("HealthCheckId") + .HasColumnType("integer"); + + b.Property("NumGpus") + .HasColumnType("integer"); + + b.Property("Start") + .HasColumnType("numeric(20,0)"); + + b.Property("Status") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("HealthCheckId"); + + b.ToTable("HealthCheckAgents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.LogEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Issuer") + .IsRequired() + .HasColumnType("text"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("LogEntries"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.NotificationSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("Notification") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("ObjectId") + .HasColumnType("integer"); + + b.Property("Receiver") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationSetting"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCommand") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ChunkTime") + .HasColumnType("integer"); + + b.Property("Color") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.Property("IsCpuTask") + .HasColumnType("boolean"); + + b.Property("IsMaskImport") + .HasColumnType("boolean"); + + b.Property("IsSmall") + .HasColumnType("boolean"); + + b.Property("MaxAgents") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("StatusTimer") + .HasColumnType("integer"); + + b.Property("UseNewBench") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.ToTable("PreconfiguredTask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.RegistrationVoucher", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("Expiration") + .HasColumnType("timestamp with time zone"); + + b.Property("Voucher") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("Voucher") + .IsUnique(); + + b.ToTable("RegistrationVouchers"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Session", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IsOpen") + .HasColumnType("boolean"); + + b.Property("LastActionDate") + .HasColumnType("timestamp with time zone"); + + b.Property("SessionKey") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("SessionLifetime") + .HasColumnType("integer"); + + b.Property("SessionStartDate") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Session"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Speed", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("SpeedValue") + .HasColumnType("numeric(20,0)"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Speed"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Supertask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("Supertask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.SupertaskPretask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("PreconfiguredTaskId") + .HasColumnType("integer"); + + b.Property("PretaskId") + .HasColumnType("integer"); + + b.Property("SupertaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("PreconfiguredTaskId"); + + b.HasIndex("SupertaskId"); + + b.ToTable("SupertaskPretask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCommand") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ChunkSize") + .HasColumnType("integer"); + + b.Property("ChunkTime") + .HasColumnType("integer"); + + b.Property("Color") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CrackerBinaryId") + .HasColumnType("integer"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.Property("EnforcePipe") + .HasColumnType("boolean"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("IsCpuTask") + .HasColumnType("boolean"); + + b.Property("IsSmall") + .HasColumnType("boolean"); + + b.Property("Keyspace") + .HasColumnType("bigint"); + + b.Property("KeyspaceProgress") + .HasColumnType("numeric(20,0)"); + + b.Property("MaxAgents") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("text"); + + b.Property("PreprocessorCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PreprocessorId") + .HasColumnType("integer"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("SkipKeyspace") + .HasColumnType("numeric(20,0)"); + + b.Property("StaticChunks") + .HasColumnType("integer"); + + b.Property("StatusTimer") + .HasColumnType("integer"); + + b.Property("TaskWrapperId") + .HasColumnType("integer"); + + b.Property("UseNewBenchmark") + .HasColumnType("boolean"); + + b.Property("UsePreprocessor") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryId"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.HasIndex("PreprocessorId"); + + b.HasIndex("TaskWrapperId"); + + b.ToTable("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskDebugOutput", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Output") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("TaskId"); + + b.ToTable("TaskDebugOutput"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("TaskType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("HashlistId"); + + b.ToTable("TaskWrapper"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Email") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("IsValid") + .HasColumnType("boolean"); + + b.Property("LastLoginDate") + .HasColumnType("timestamp with time zone"); + + b.Property("PasswordHash") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordSalt") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("RegisteredSince") + .HasColumnType("timestamp with time zone"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Zap", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Hash") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("SolveTime") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("HashlistId"); + + b.ToTable("Zap"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentBinary", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("UpdateAvailable") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("UpdateTrack") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.HasIndex("Type"); + + b.HasDiscriminator().HasValue("AgentBinary"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.HasDiscriminator().HasValue("CrackerBinary"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Preprocessor", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("KeyspaceCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("LimitCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("SkipCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasDiscriminator().HasValue("Preprocessor"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.BinaryHash", b => + { + b.HasBaseType("HashSlinger.Shared.Models.HashBase"); + + b.Property("Essid") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashBytes") + .IsRequired() + .HasColumnType("bytea"); + + b.HasIndex("ChunkId"); + + b.HasIndex("HashlistId"); + + b.HasIndex("IsCracked"); + + b.HasDiscriminator().HasValue("BinaryHash"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hash", b => + { + b.HasBaseType("HashSlinger.Shared.Models.HashBase"); + + b.Property("HashValue") + .IsRequired() + .HasColumnType("text"); + + b.Property("Salt") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasIndex("ChunkId"); + + b.HasIndex("HashlistId"); + + b.HasIndex("IsCracked"); + + b.HasDiscriminator().HasValue("Hash"); + }); + + modelBuilder.Entity("AccessGroupAgent", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", null) + .WithMany() + .HasForeignKey("AccessGroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Agent", null) + .WithMany() + .HasForeignKey("AgentsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AccessGroupUser", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", null) + .WithMany() + .HasForeignKey("AccessGroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("FilePreconfiguredTask", b => + { + b.HasOne("HashSlinger.Shared.Models.File", null) + .WithMany() + .HasForeignKey("FilesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.PreconfiguredTask", null) + .WithMany() + .HasForeignKey("PreconfiguredTasksId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("FileTask", b => + { + b.HasOne("HashSlinger.Shared.Models.File", null) + .WithMany() + .HasForeignKey("FilesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", null) + .WithMany() + .HasForeignKey("TasksId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("Agents") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentError", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Errors") + .HasForeignKey("AgentId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("Errors") + .HasForeignKey("ChunkId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("AgentErrors") + .HasForeignKey("TaskId"); + + b.Navigation("Agent"); + + b.Navigation("Chunk"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentStat", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Stats") + .HasForeignKey("AgentId") + .IsRequired(); + + b.Navigation("Agent"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiKey", b => + { + b.HasOne("HashSlinger.Shared.Models.ApiGroup", "ApiGroup") + .WithMany("ApiKeys") + .HasForeignKey("ApiGroupId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("ApiKeys") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ApiGroup"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Assignment", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Assignments") + .HasForeignKey("AgentId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Assignments") + .HasForeignKey("TaskId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Chunks") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Chunks") + .HasForeignKey("TaskId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.DownloadableBinary", b => + { + b.HasOne("HashSlinger.Shared.Models.File", "File") + .WithMany() + .HasForeignKey("FileId"); + + b.Navigation("File"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("Files") + .HasForeignKey("AccessGroupId") + .IsRequired(); + + b.Navigation("AccessGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDownload", b => + { + b.HasOne("HashSlinger.Shared.Models.File", "File") + .WithMany("FileDownloads") + .HasForeignKey("FileId") + .IsRequired(); + + b.Navigation("File"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("Hashlists") + .HasForeignKey("AccessGroupId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HashType", "HashType") + .WithMany("Hashlists") + .HasForeignKey("HashTypeId") + .IsRequired(); + + b.Navigation("AccessGroup"); + + b.Navigation("HashType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinary", "CrackerBinary") + .WithMany("HealthChecks") + .HasForeignKey("CrackerBinaryId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HashType", "HashType") + .WithMany("HealthChecks") + .HasForeignKey("HashTypeId") + .IsRequired(); + + b.Navigation("CrackerBinary"); + + b.Navigation("HashType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheckAgent", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("HealthCheckAgents") + .HasForeignKey("AgentId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HealthCheck", "HealthCheck") + .WithMany("HealthCheckAgents") + .HasForeignKey("HealthCheckId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("HealthCheck"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.NotificationSetting", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("NotificationSettings") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("Pretasks") + .HasForeignKey("CrackerBinaryTypeId") + .IsRequired(); + + b.Navigation("CrackerBinaryType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.RegistrationVoucher", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("RegistrationVouchers") + .HasForeignKey("AccessGroupId"); + + b.Navigation("AccessGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Session", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("Sessions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Speed", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Speeds") + .HasForeignKey("AgentId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Speeds") + .HasForeignKey("TaskId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.SupertaskPretask", b => + { + b.HasOne("HashSlinger.Shared.Models.PreconfiguredTask", "PreconfiguredTask") + .WithMany("SupertaskPretasks") + .HasForeignKey("PreconfiguredTaskId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Supertask", "Supertask") + .WithMany("SupertaskPretasks") + .HasForeignKey("SupertaskId") + .IsRequired(); + + b.Navigation("PreconfiguredTask"); + + b.Navigation("Supertask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinary", "CrackerBinary") + .WithMany("Tasks") + .HasForeignKey("CrackerBinaryId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("Tasks") + .HasForeignKey("CrackerBinaryTypeId"); + + b.HasOne("HashSlinger.Shared.Models.Preprocessor", "Preprocessor") + .WithMany("Tasks") + .HasForeignKey("PreprocessorId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.TaskWrapper", "TaskWrapper") + .WithMany("Tasks") + .HasForeignKey("TaskWrapperId") + .OnDelete(DeleteBehavior.SetNull) + .IsRequired(); + + b.Navigation("CrackerBinary"); + + b.Navigation("CrackerBinaryType"); + + b.Navigation("Preprocessor"); + + b.Navigation("TaskWrapper"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskDebugOutput", b => + { + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("TaskDebugOutputs") + .HasForeignKey("TaskId") + .IsRequired(); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("TaskWrappers") + .HasForeignKey("AccessGroupId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("TaskWrappers") + .HasForeignKey("HashlistId") + .IsRequired(); + + b.Navigation("AccessGroup"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Zap", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Zaps") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("Zaps") + .HasForeignKey("HashlistId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("CrackerBinaries") + .HasForeignKey("CrackerBinaryTypeId") + .IsRequired(); + + b.Navigation("CrackerBinaryType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.BinaryHash", b => + { + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("BinaryHashes") + .HasForeignKey("ChunkId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("BinaryHashes") + .HasForeignKey("HashlistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Chunk"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hash", b => + { + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("Hashes") + .HasForeignKey("ChunkId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("Hashes") + .HasForeignKey("HashlistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Chunk"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AccessGroup", b => + { + b.Navigation("Files"); + + b.Navigation("Hashlists"); + + b.Navigation("RegistrationVouchers"); + + b.Navigation("TaskWrappers"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.Navigation("Assignments"); + + b.Navigation("Chunks"); + + b.Navigation("Errors"); + + b.Navigation("HealthCheckAgents"); + + b.Navigation("Speeds"); + + b.Navigation("Stats"); + + b.Navigation("Zaps"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiGroup", b => + { + b.Navigation("ApiKeys"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.Navigation("BinaryHashes"); + + b.Navigation("Errors"); + + b.Navigation("Hashes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinaryType", b => + { + b.Navigation("CrackerBinaries"); + + b.Navigation("Pretasks"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.Navigation("FileDownloads"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashType", b => + { + b.Navigation("Hashlists"); + + b.Navigation("HealthChecks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.Navigation("BinaryHashes"); + + b.Navigation("Hashes"); + + b.Navigation("TaskWrappers"); + + b.Navigation("Zaps"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.Navigation("HealthCheckAgents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.Navigation("SupertaskPretasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Supertask", b => + { + b.Navigation("SupertaskPretasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.Navigation("AgentErrors"); + + b.Navigation("Assignments"); + + b.Navigation("Chunks"); + + b.Navigation("Speeds"); + + b.Navigation("TaskDebugOutputs"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.User", b => + { + b.Navigation("Agents"); + + b.Navigation("ApiKeys"); + + b.Navigation("NotificationSettings"); + + b.Navigation("Sessions"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.Navigation("HealthChecks"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Preprocessor", b => + { + b.Navigation("Tasks"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/HashSlinger/Migrations/20230629001850_ModifiedTasksAndChunks.cs b/HashSlinger/Migrations/20230629001850_ModifiedTasksAndChunks.cs new file mode 100644 index 0000000..ac51f08 --- /dev/null +++ b/HashSlinger/Migrations/20230629001850_ModifiedTasksAndChunks.cs @@ -0,0 +1,52 @@ +#nullable disable + +namespace HashSlinger.Api.Migrations +{ + using Microsoft.EntityFrameworkCore.Migrations; + + /// + public partial class ModifiedTasksAndChunks : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Keyspace", + table: "Tasks", + type: "bigint", + nullable: false, + oldClrType: typeof(decimal), + oldType: "numeric(20,0)"); + + migrationBuilder.AlterColumn( + name: "Progress", + table: "Chunk", + type: "real", + nullable: true, + oldClrType: typeof(int), + oldType: "integer", + oldNullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Keyspace", + table: "Tasks", + type: "numeric(20,0)", + nullable: false, + oldClrType: typeof(long), + oldType: "bigint"); + + migrationBuilder.AlterColumn( + name: "Progress", + table: "Chunk", + type: "integer", + nullable: true, + oldClrType: typeof(float), + oldType: "real", + oldNullable: true); + } + } +} diff --git a/HashSlinger/Migrations/20230701163527_ExposedChunks.Designer.cs b/HashSlinger/Migrations/20230701163527_ExposedChunks.Designer.cs new file mode 100644 index 0000000..dca3b2c --- /dev/null +++ b/HashSlinger/Migrations/20230701163527_ExposedChunks.Designer.cs @@ -0,0 +1,1911 @@ +// + +#nullable disable + +namespace HashSlinger.Api.Migrations +{ + using System.Net; + using Data; + using Microsoft.EntityFrameworkCore; + using Microsoft.EntityFrameworkCore.Infrastructure; + using Microsoft.EntityFrameworkCore.Migrations; + + [DbContext(typeof(HashSlingerContext))] + [Migration("20230701163527_ExposedChunks")] + partial class ExposedChunks + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("AccessGroupAgent", b => + { + b.Property("AccessGroupsId") + .HasColumnType("integer"); + + b.Property("AgentsId") + .HasColumnType("integer"); + + b.HasKey("AccessGroupsId", "AgentsId"); + + b.HasIndex("AgentsId"); + + b.ToTable("AccessGroupAgent"); + }); + + modelBuilder.Entity("AccessGroupUser", b => + { + b.Property("AccessGroupsId") + .HasColumnType("integer"); + + b.Property("UsersId") + .HasColumnType("integer"); + + b.HasKey("AccessGroupsId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("AccessGroupUser"); + }); + + modelBuilder.Entity("FilePreconfiguredTask", b => + { + b.Property("FilesId") + .HasColumnType("integer"); + + b.Property("PreconfiguredTasksId") + .HasColumnType("integer"); + + b.HasKey("FilesId", "PreconfiguredTasksId"); + + b.HasIndex("PreconfiguredTasksId"); + + b.ToTable("FilePreconfiguredTask"); + }); + + modelBuilder.Entity("FileTask", b => + { + b.Property("FilesId") + .HasColumnType("integer"); + + b.Property("TasksId") + .HasColumnType("integer"); + + b.HasKey("FilesId", "TasksId"); + + b.HasIndex("TasksId"); + + b.ToTable("FileTask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AccessGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("AccessGroups"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClientSignature") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("CommandParameters") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CpuOnly") + .HasColumnType("boolean"); + + b.Property>("Devices") + .HasColumnType("text[]"); + + b.Property("IgnoreErrors") + .HasColumnType("boolean"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("IsTrusted") + .HasColumnType("boolean"); + + b.Property("LastAction") + .HasColumnType("integer"); + + b.Property("LastSeenIpAddress") + .HasColumnType("inet"); + + b.Property("LastSeenTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("OperatingSystem") + .HasColumnType("integer"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.Property("Uid") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("Token"); + + b.HasIndex("Uid"); + + b.HasIndex("UserId"); + + b.ToTable("Agents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentError", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("ChunkId") + .HasColumnType("integer"); + + b.Property("Error") + .IsRequired() + .HasColumnType("text"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("ChunkId"); + + b.HasIndex("TaskId"); + + b.ToTable("AgentError"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentStat", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("StatType") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.ToTable("AgentStat"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Permissions") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("ApiGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessCount") + .HasColumnType("integer"); + + b.Property("AccessKey") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ApiGroupId") + .HasColumnType("integer"); + + b.Property("EndValid") + .HasColumnType("timestamp with time zone"); + + b.Property("StartValid") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ApiGroupId"); + + b.HasIndex("UserId"); + + b.ToTable("ApiKey"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Assignment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Benchmark") + .IsRequired() + .HasColumnType("text"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Assignment"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Checkpoint") + .HasColumnType("numeric(20,0)"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("DispatchTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Length") + .HasColumnType("numeric(20,0)"); + + b.Property("Progress") + .HasColumnType("real"); + + b.Property("Skip") + .HasColumnType("numeric(20,0)"); + + b.Property("SolveTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Speed") + .HasColumnType("numeric(20,0)"); + + b.Property("State") + .HasColumnType("integer"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Chunks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinaryType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IsChunkingAvailable") + .HasColumnType("boolean"); + + b.Property("TypeName") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.HasKey("Id"); + + b.ToTable("CrackerBinaryTypes"); + + b.HasData( + new + { + Id = 1, + IsChunkingAvailable = true, + TypeName = "hashcat" + }); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.DownloadableBinary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("text"); + + b.Property("DownloadUrl") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("Executable") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("FileId") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property>("OperatingSystems") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("Version") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.ToTable("DownloadableBinaries"); + + b.HasDiscriminator("Discriminator").HasValue("DownloadableBinary"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("FileGuid") + .HasColumnType("uuid"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("FileType") + .HasColumnType("integer"); + + b.Property("IsSecret") + .HasColumnType("boolean"); + + b.Property("LineCount") + .HasColumnType("bigint"); + + b.Property("Size") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.ToTable("Files"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDelete", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("FileDeletes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDownload", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FileId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.ToTable("FileDownload"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashBase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ChunkId") + .HasColumnType("integer"); + + b.Property("CrackPos") + .HasColumnType("numeric(20,0)"); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("IsCracked") + .HasColumnType("boolean"); + + b.Property("Plaintext") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("TimeCracked") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("HashBase"); + + b.HasDiscriminator("Discriminator").HasValue("HashBase"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("HashcatId") + .HasColumnType("integer"); + + b.Property("IsSalted") + .HasColumnType("boolean"); + + b.Property("IsSlowHash") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("HashcatId") + .IsUnique(); + + b.ToTable("HashTypes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("BrainFeatures") + .HasColumnType("smallint"); + + b.Property("BrainId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("Format") + .HasColumnType("integer"); + + b.Property("HashCount") + .HasColumnType("integer"); + + b.Property("HashTypeId") + .HasColumnType("uuid"); + + b.Property("HexSalt") + .HasColumnType("boolean"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("IsSalted") + .HasColumnType("boolean"); + + b.Property("IsSecret") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("text"); + + b.Property("SaltSeparator") + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("HashTypeId"); + + b.HasIndex("IsSecret"); + + b.ToTable("Hashlists"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCmd") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CheckType") + .HasColumnType("integer"); + + b.Property("CrackerBinaryId") + .HasColumnType("integer"); + + b.Property("ExpectedCracks") + .HasColumnType("integer"); + + b.Property("HashListAlias") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashTypeId") + .HasColumnType("uuid"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property>("TestHashes") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryId"); + + b.HasIndex("HashTypeId"); + + b.ToTable("HealthChecks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheckAgent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("End") + .HasColumnType("numeric(20,0)"); + + b.Property>("Errors") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("HealthCheckId") + .HasColumnType("integer"); + + b.Property("NumGpus") + .HasColumnType("integer"); + + b.Property("Start") + .HasColumnType("numeric(20,0)"); + + b.Property("Status") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("HealthCheckId"); + + b.ToTable("HealthCheckAgents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.LogEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Issuer") + .IsRequired() + .HasColumnType("text"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("LogEntries"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.NotificationSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("Notification") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("ObjectId") + .HasColumnType("integer"); + + b.Property("Receiver") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationSetting"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCommand") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ChunkTime") + .HasColumnType("integer"); + + b.Property("Color") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.Property("IsCpuTask") + .HasColumnType("boolean"); + + b.Property("IsMaskImport") + .HasColumnType("boolean"); + + b.Property("IsSmall") + .HasColumnType("boolean"); + + b.Property("MaxAgents") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("StatusTimer") + .HasColumnType("integer"); + + b.Property("UseNewBench") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.ToTable("PreconfiguredTask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.RegistrationVoucher", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("Expiration") + .HasColumnType("timestamp with time zone"); + + b.Property("Voucher") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("Voucher") + .IsUnique(); + + b.ToTable("RegistrationVouchers"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Session", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IsOpen") + .HasColumnType("boolean"); + + b.Property("LastActionDate") + .HasColumnType("timestamp with time zone"); + + b.Property("SessionKey") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("SessionLifetime") + .HasColumnType("integer"); + + b.Property("SessionStartDate") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Session"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Speed", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("SpeedValue") + .HasColumnType("numeric(20,0)"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Speed"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Supertask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("Supertask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.SupertaskPretask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("PreconfiguredTaskId") + .HasColumnType("integer"); + + b.Property("PretaskId") + .HasColumnType("integer"); + + b.Property("SupertaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("PreconfiguredTaskId"); + + b.HasIndex("SupertaskId"); + + b.ToTable("SupertaskPretask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCommand") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ChunkSize") + .HasColumnType("integer"); + + b.Property("ChunkTime") + .HasColumnType("integer"); + + b.Property("Color") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CrackerBinaryId") + .HasColumnType("integer"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.Property("EnforcePipe") + .HasColumnType("boolean"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("IsCpuTask") + .HasColumnType("boolean"); + + b.Property("IsSmall") + .HasColumnType("boolean"); + + b.Property("Keyspace") + .HasColumnType("bigint"); + + b.Property("KeyspaceProgress") + .HasColumnType("numeric(20,0)"); + + b.Property("MaxAgents") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("text"); + + b.Property("PreprocessorCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PreprocessorId") + .HasColumnType("integer"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("SkipKeyspace") + .HasColumnType("numeric(20,0)"); + + b.Property("StaticChunks") + .HasColumnType("integer"); + + b.Property("StatusTimer") + .HasColumnType("integer"); + + b.Property("TaskWrapperId") + .HasColumnType("integer"); + + b.Property("UseNewBenchmark") + .HasColumnType("boolean"); + + b.Property("UsePreprocessor") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryId"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.HasIndex("PreprocessorId"); + + b.HasIndex("TaskWrapperId"); + + b.ToTable("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskDebugOutput", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Output") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("TaskId"); + + b.ToTable("TaskDebugOutput"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("TaskType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("HashlistId"); + + b.ToTable("TaskWrapper"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Email") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("IsValid") + .HasColumnType("boolean"); + + b.Property("LastLoginDate") + .HasColumnType("timestamp with time zone"); + + b.Property("PasswordHash") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordSalt") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("RegisteredSince") + .HasColumnType("timestamp with time zone"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Zap", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Hash") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("SolveTime") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("HashlistId"); + + b.ToTable("Zap"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentBinary", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("UpdateAvailable") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("UpdateTrack") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.HasIndex("Type"); + + b.HasDiscriminator().HasValue("AgentBinary"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.HasDiscriminator().HasValue("CrackerBinary"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Preprocessor", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("KeyspaceCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("LimitCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("SkipCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasDiscriminator().HasValue("Preprocessor"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.BinaryHash", b => + { + b.HasBaseType("HashSlinger.Shared.Models.HashBase"); + + b.Property("Essid") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashBytes") + .IsRequired() + .HasColumnType("bytea"); + + b.HasIndex("ChunkId"); + + b.HasIndex("HashlistId"); + + b.HasIndex("IsCracked"); + + b.HasDiscriminator().HasValue("BinaryHash"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hash", b => + { + b.HasBaseType("HashSlinger.Shared.Models.HashBase"); + + b.Property("HashValue") + .IsRequired() + .HasColumnType("text"); + + b.Property("Salt") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasIndex("ChunkId"); + + b.HasIndex("HashlistId"); + + b.HasIndex("IsCracked"); + + b.HasDiscriminator().HasValue("Hash"); + }); + + modelBuilder.Entity("AccessGroupAgent", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", null) + .WithMany() + .HasForeignKey("AccessGroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Agent", null) + .WithMany() + .HasForeignKey("AgentsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AccessGroupUser", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", null) + .WithMany() + .HasForeignKey("AccessGroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("FilePreconfiguredTask", b => + { + b.HasOne("HashSlinger.Shared.Models.File", null) + .WithMany() + .HasForeignKey("FilesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.PreconfiguredTask", null) + .WithMany() + .HasForeignKey("PreconfiguredTasksId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("FileTask", b => + { + b.HasOne("HashSlinger.Shared.Models.File", null) + .WithMany() + .HasForeignKey("FilesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", null) + .WithMany() + .HasForeignKey("TasksId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("Agents") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentError", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Errors") + .HasForeignKey("AgentId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("Errors") + .HasForeignKey("ChunkId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("AgentErrors") + .HasForeignKey("TaskId"); + + b.Navigation("Agent"); + + b.Navigation("Chunk"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentStat", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Stats") + .HasForeignKey("AgentId") + .IsRequired(); + + b.Navigation("Agent"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiKey", b => + { + b.HasOne("HashSlinger.Shared.Models.ApiGroup", "ApiGroup") + .WithMany("ApiKeys") + .HasForeignKey("ApiGroupId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("ApiKeys") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ApiGroup"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Assignment", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Assignments") + .HasForeignKey("AgentId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Assignments") + .HasForeignKey("TaskId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Chunks") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Chunks") + .HasForeignKey("TaskId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.DownloadableBinary", b => + { + b.HasOne("HashSlinger.Shared.Models.File", "File") + .WithMany() + .HasForeignKey("FileId"); + + b.Navigation("File"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("Files") + .HasForeignKey("AccessGroupId") + .IsRequired(); + + b.Navigation("AccessGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDownload", b => + { + b.HasOne("HashSlinger.Shared.Models.File", "File") + .WithMany("FileDownloads") + .HasForeignKey("FileId") + .IsRequired(); + + b.Navigation("File"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("Hashlists") + .HasForeignKey("AccessGroupId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HashType", "HashType") + .WithMany("Hashlists") + .HasForeignKey("HashTypeId") + .IsRequired(); + + b.Navigation("AccessGroup"); + + b.Navigation("HashType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinary", "CrackerBinary") + .WithMany("HealthChecks") + .HasForeignKey("CrackerBinaryId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HashType", "HashType") + .WithMany("HealthChecks") + .HasForeignKey("HashTypeId") + .IsRequired(); + + b.Navigation("CrackerBinary"); + + b.Navigation("HashType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheckAgent", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("HealthCheckAgents") + .HasForeignKey("AgentId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HealthCheck", "HealthCheck") + .WithMany("HealthCheckAgents") + .HasForeignKey("HealthCheckId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("HealthCheck"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.NotificationSetting", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("NotificationSettings") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("Pretasks") + .HasForeignKey("CrackerBinaryTypeId") + .IsRequired(); + + b.Navigation("CrackerBinaryType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.RegistrationVoucher", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("RegistrationVouchers") + .HasForeignKey("AccessGroupId"); + + b.Navigation("AccessGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Session", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("Sessions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Speed", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Speeds") + .HasForeignKey("AgentId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Speeds") + .HasForeignKey("TaskId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.SupertaskPretask", b => + { + b.HasOne("HashSlinger.Shared.Models.PreconfiguredTask", "PreconfiguredTask") + .WithMany("SupertaskPretasks") + .HasForeignKey("PreconfiguredTaskId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Supertask", "Supertask") + .WithMany("SupertaskPretasks") + .HasForeignKey("SupertaskId") + .IsRequired(); + + b.Navigation("PreconfiguredTask"); + + b.Navigation("Supertask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinary", "CrackerBinary") + .WithMany("Tasks") + .HasForeignKey("CrackerBinaryId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("Tasks") + .HasForeignKey("CrackerBinaryTypeId"); + + b.HasOne("HashSlinger.Shared.Models.Preprocessor", "Preprocessor") + .WithMany("Tasks") + .HasForeignKey("PreprocessorId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.TaskWrapper", "TaskWrapper") + .WithMany("Tasks") + .HasForeignKey("TaskWrapperId") + .OnDelete(DeleteBehavior.SetNull) + .IsRequired(); + + b.Navigation("CrackerBinary"); + + b.Navigation("CrackerBinaryType"); + + b.Navigation("Preprocessor"); + + b.Navigation("TaskWrapper"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskDebugOutput", b => + { + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("TaskDebugOutputs") + .HasForeignKey("TaskId") + .IsRequired(); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("TaskWrappers") + .HasForeignKey("AccessGroupId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("TaskWrappers") + .HasForeignKey("HashlistId") + .IsRequired(); + + b.Navigation("AccessGroup"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Zap", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Zaps") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("Zaps") + .HasForeignKey("HashlistId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("CrackerBinaries") + .HasForeignKey("CrackerBinaryTypeId") + .IsRequired(); + + b.Navigation("CrackerBinaryType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.BinaryHash", b => + { + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("BinaryHashes") + .HasForeignKey("ChunkId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("BinaryHashes") + .HasForeignKey("HashlistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Chunk"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hash", b => + { + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("Hashes") + .HasForeignKey("ChunkId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("Hashes") + .HasForeignKey("HashlistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Chunk"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AccessGroup", b => + { + b.Navigation("Files"); + + b.Navigation("Hashlists"); + + b.Navigation("RegistrationVouchers"); + + b.Navigation("TaskWrappers"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.Navigation("Assignments"); + + b.Navigation("Chunks"); + + b.Navigation("Errors"); + + b.Navigation("HealthCheckAgents"); + + b.Navigation("Speeds"); + + b.Navigation("Stats"); + + b.Navigation("Zaps"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiGroup", b => + { + b.Navigation("ApiKeys"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.Navigation("BinaryHashes"); + + b.Navigation("Errors"); + + b.Navigation("Hashes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinaryType", b => + { + b.Navigation("CrackerBinaries"); + + b.Navigation("Pretasks"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.Navigation("FileDownloads"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashType", b => + { + b.Navigation("Hashlists"); + + b.Navigation("HealthChecks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.Navigation("BinaryHashes"); + + b.Navigation("Hashes"); + + b.Navigation("TaskWrappers"); + + b.Navigation("Zaps"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.Navigation("HealthCheckAgents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.Navigation("SupertaskPretasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Supertask", b => + { + b.Navigation("SupertaskPretasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.Navigation("AgentErrors"); + + b.Navigation("Assignments"); + + b.Navigation("Chunks"); + + b.Navigation("Speeds"); + + b.Navigation("TaskDebugOutputs"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.User", b => + { + b.Navigation("Agents"); + + b.Navigation("ApiKeys"); + + b.Navigation("NotificationSettings"); + + b.Navigation("Sessions"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.Navigation("HealthChecks"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Preprocessor", b => + { + b.Navigation("Tasks"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/HashSlinger/Migrations/20230701163527_ExposedChunks.cs b/HashSlinger/Migrations/20230701163527_ExposedChunks.cs new file mode 100644 index 0000000..1879f16 --- /dev/null +++ b/HashSlinger/Migrations/20230701163527_ExposedChunks.cs @@ -0,0 +1,156 @@ +#nullable disable + +namespace HashSlinger.Api.Migrations +{ + using Microsoft.EntityFrameworkCore.Migrations; + + /// + public partial class ExposedChunks : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_AgentError_Chunk_ChunkId", + table: "AgentError"); + + migrationBuilder.DropForeignKey( + name: "FK_Chunk_Agents_AgentId", + table: "Chunk"); + + migrationBuilder.DropForeignKey( + name: "FK_Chunk_Tasks_TaskId", + table: "Chunk"); + + migrationBuilder.DropForeignKey( + name: "FK_HashBase_Chunk_ChunkId", + table: "HashBase"); + + migrationBuilder.DropPrimaryKey( + name: "PK_Chunk", + table: "Chunk"); + + migrationBuilder.RenameTable( + name: "Chunk", + newName: "Chunks"); + + migrationBuilder.RenameIndex( + name: "IX_Chunk_TaskId", + table: "Chunks", + newName: "IX_Chunks_TaskId"); + + migrationBuilder.RenameIndex( + name: "IX_Chunk_AgentId", + table: "Chunks", + newName: "IX_Chunks_AgentId"); + + migrationBuilder.AddPrimaryKey( + name: "PK_Chunks", + table: "Chunks", + column: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_AgentError_Chunks_ChunkId", + table: "AgentError", + column: "ChunkId", + principalTable: "Chunks", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_Chunks_Agents_AgentId", + table: "Chunks", + column: "AgentId", + principalTable: "Agents", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_Chunks_Tasks_TaskId", + table: "Chunks", + column: "TaskId", + principalTable: "Tasks", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_HashBase_Chunks_ChunkId", + table: "HashBase", + column: "ChunkId", + principalTable: "Chunks", + principalColumn: "Id"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_AgentError_Chunks_ChunkId", + table: "AgentError"); + + migrationBuilder.DropForeignKey( + name: "FK_Chunks_Agents_AgentId", + table: "Chunks"); + + migrationBuilder.DropForeignKey( + name: "FK_Chunks_Tasks_TaskId", + table: "Chunks"); + + migrationBuilder.DropForeignKey( + name: "FK_HashBase_Chunks_ChunkId", + table: "HashBase"); + + migrationBuilder.DropPrimaryKey( + name: "PK_Chunks", + table: "Chunks"); + + migrationBuilder.RenameTable( + name: "Chunks", + newName: "Chunk"); + + migrationBuilder.RenameIndex( + name: "IX_Chunks_TaskId", + table: "Chunk", + newName: "IX_Chunk_TaskId"); + + migrationBuilder.RenameIndex( + name: "IX_Chunks_AgentId", + table: "Chunk", + newName: "IX_Chunk_AgentId"); + + migrationBuilder.AddPrimaryKey( + name: "PK_Chunk", + table: "Chunk", + column: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_AgentError_Chunk_ChunkId", + table: "AgentError", + column: "ChunkId", + principalTable: "Chunk", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_Chunk_Agents_AgentId", + table: "Chunk", + column: "AgentId", + principalTable: "Agents", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_Chunk_Tasks_TaskId", + table: "Chunk", + column: "TaskId", + principalTable: "Tasks", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_HashBase_Chunk_ChunkId", + table: "HashBase", + column: "ChunkId", + principalTable: "Chunk", + principalColumn: "Id"); + } + } +} diff --git a/HashSlinger/Migrations/20230701175137_changes.Designer.cs b/HashSlinger/Migrations/20230701175137_changes.Designer.cs new file mode 100644 index 0000000..ac14741 --- /dev/null +++ b/HashSlinger/Migrations/20230701175137_changes.Designer.cs @@ -0,0 +1,1913 @@ +// + +#nullable disable + +namespace HashSlinger.Api.Migrations +{ + using System.Net; + using Data; + using Microsoft.EntityFrameworkCore; + using Microsoft.EntityFrameworkCore.Infrastructure; + using Microsoft.EntityFrameworkCore.Migrations; + + [DbContext(typeof(HashSlingerContext))] + [Migration("20230701175137_changes")] + partial class changes + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("AccessGroupAgent", b => + { + b.Property("AccessGroupsId") + .HasColumnType("integer"); + + b.Property("AgentsId") + .HasColumnType("integer"); + + b.HasKey("AccessGroupsId", "AgentsId"); + + b.HasIndex("AgentsId"); + + b.ToTable("AccessGroupAgent"); + }); + + modelBuilder.Entity("AccessGroupUser", b => + { + b.Property("AccessGroupsId") + .HasColumnType("integer"); + + b.Property("UsersId") + .HasColumnType("integer"); + + b.HasKey("AccessGroupsId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("AccessGroupUser"); + }); + + modelBuilder.Entity("FilePreconfiguredTask", b => + { + b.Property("FilesId") + .HasColumnType("integer"); + + b.Property("PreconfiguredTasksId") + .HasColumnType("integer"); + + b.HasKey("FilesId", "PreconfiguredTasksId"); + + b.HasIndex("PreconfiguredTasksId"); + + b.ToTable("FilePreconfiguredTask"); + }); + + modelBuilder.Entity("FileTask", b => + { + b.Property("FilesId") + .HasColumnType("integer"); + + b.Property("TasksId") + .HasColumnType("integer"); + + b.HasKey("FilesId", "TasksId"); + + b.HasIndex("TasksId"); + + b.ToTable("FileTask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AccessGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("AccessGroups"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClientSignature") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("CommandParameters") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CpuOnly") + .HasColumnType("boolean"); + + b.Property>("Devices") + .HasColumnType("text[]"); + + b.Property("IgnoreErrors") + .HasColumnType("boolean"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("IsTrusted") + .HasColumnType("boolean"); + + b.Property("LastAction") + .HasColumnType("integer"); + + b.Property("LastSeenIpAddress") + .HasColumnType("inet"); + + b.Property("LastSeenTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("OperatingSystem") + .HasColumnType("integer"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.Property("Uid") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("Token"); + + b.HasIndex("Uid"); + + b.HasIndex("UserId"); + + b.ToTable("Agents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentError", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("ChunkId") + .HasColumnType("integer"); + + b.Property("Error") + .IsRequired() + .HasColumnType("text"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("ChunkId"); + + b.HasIndex("TaskId"); + + b.ToTable("AgentError"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentStat", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("StatType") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.ToTable("AgentStat"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Permissions") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("ApiGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessCount") + .HasColumnType("integer"); + + b.Property("AccessKey") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ApiGroupId") + .HasColumnType("integer"); + + b.Property("EndValid") + .HasColumnType("timestamp with time zone"); + + b.Property("StartValid") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ApiGroupId"); + + b.HasIndex("UserId"); + + b.ToTable("ApiKey"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Assignment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Benchmark") + .IsRequired() + .HasColumnType("text"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Assignment"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Checkpoint") + .HasColumnType("numeric(20,0)"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("DispatchTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Length") + .HasColumnType("numeric(20,0)"); + + b.Property("Progress") + .HasColumnType("real"); + + b.Property("Skip") + .HasColumnType("numeric(20,0)"); + + b.Property("SolveTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Speed") + .HasColumnType("numeric(20,0)"); + + b.Property("State") + .HasColumnType("integer"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Chunks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinaryType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IsChunkingAvailable") + .HasColumnType("boolean"); + + b.Property("TypeName") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.HasKey("Id"); + + b.ToTable("CrackerBinaryTypes"); + + b.HasData( + new + { + Id = 1, + IsChunkingAvailable = true, + TypeName = "hashcat" + }); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.DownloadableBinary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("text"); + + b.Property("DownloadUrl") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("Executable") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("FileId") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property>("OperatingSystems") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("Version") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.ToTable("DownloadableBinaries"); + + b.HasDiscriminator("Discriminator").HasValue("DownloadableBinary"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("FileGuid") + .HasColumnType("uuid"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("FileType") + .HasColumnType("integer"); + + b.Property("IsSecret") + .HasColumnType("boolean"); + + b.Property("LineCount") + .HasColumnType("bigint"); + + b.Property("Size") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.ToTable("Files"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDelete", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("FileDeletes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDownload", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FileId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.ToTable("FileDownload"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashBase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ChunkId") + .HasColumnType("integer"); + + b.Property("CrackPos") + .HasColumnType("numeric(20,0)"); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("IsCracked") + .HasColumnType("boolean"); + + b.Property("Plaintext") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("TimeCracked") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("HashBase"); + + b.HasDiscriminator("Discriminator").HasValue("HashBase"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("HashcatId") + .HasColumnType("integer"); + + b.Property("IsSalted") + .HasColumnType("boolean"); + + b.Property("IsSlowHash") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("HashcatId") + .IsUnique(); + + b.ToTable("HashTypes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("BrainFeatures") + .HasColumnType("smallint"); + + b.Property("BrainId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("Format") + .HasColumnType("integer"); + + b.Property("HashCount") + .HasColumnType("integer"); + + b.Property("HashTypeId") + .HasColumnType("uuid"); + + b.Property("HexSalt") + .HasColumnType("boolean"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("IsSalted") + .HasColumnType("boolean"); + + b.Property("IsSecret") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("text"); + + b.Property("SaltSeparator") + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("HashTypeId"); + + b.HasIndex("IsSecret"); + + b.ToTable("Hashlists"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCmd") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CheckType") + .HasColumnType("integer"); + + b.Property("CrackerBinaryId") + .HasColumnType("integer"); + + b.Property("ExpectedCracks") + .HasColumnType("integer"); + + b.Property("HashListAlias") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashTypeId") + .HasColumnType("uuid"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property>("TestHashes") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryId"); + + b.HasIndex("HashTypeId"); + + b.ToTable("HealthChecks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheckAgent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("End") + .HasColumnType("numeric(20,0)"); + + b.Property>("Errors") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("HealthCheckId") + .HasColumnType("integer"); + + b.Property("NumGpus") + .HasColumnType("integer"); + + b.Property("Start") + .HasColumnType("numeric(20,0)"); + + b.Property("Status") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("HealthCheckId"); + + b.ToTable("HealthCheckAgents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.LogEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Issuer") + .IsRequired() + .HasColumnType("text"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("LogEntries"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.NotificationSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("Notification") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("ObjectId") + .HasColumnType("integer"); + + b.Property("Receiver") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationSetting"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCommand") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ChunkTime") + .HasColumnType("integer"); + + b.Property("Color") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.Property("IsCpuTask") + .HasColumnType("boolean"); + + b.Property("IsMaskImport") + .HasColumnType("boolean"); + + b.Property("IsSmall") + .HasColumnType("boolean"); + + b.Property("MaxAgents") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("StatusTimer") + .HasColumnType("integer"); + + b.Property("UseNewBench") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.ToTable("PreconfiguredTask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.RegistrationVoucher", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("Expiration") + .HasColumnType("timestamp with time zone"); + + b.Property("Voucher") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("Voucher") + .IsUnique(); + + b.ToTable("RegistrationVouchers"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Session", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IsOpen") + .HasColumnType("boolean"); + + b.Property("LastActionDate") + .HasColumnType("timestamp with time zone"); + + b.Property("SessionKey") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("SessionLifetime") + .HasColumnType("integer"); + + b.Property("SessionStartDate") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Session"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Speed", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("SpeedValue") + .HasColumnType("numeric(20,0)"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Speed"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Supertask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("Supertask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.SupertaskPretask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("PreconfiguredTaskId") + .HasColumnType("integer"); + + b.Property("PretaskId") + .HasColumnType("integer"); + + b.Property("SupertaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("PreconfiguredTaskId"); + + b.HasIndex("SupertaskId"); + + b.ToTable("SupertaskPretask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCommand") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ChunkSize") + .HasColumnType("integer"); + + b.Property("ChunkTime") + .HasColumnType("integer"); + + b.Property("Color") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CrackerBinaryId") + .HasColumnType("integer"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.Property("EnforcePipe") + .HasColumnType("boolean"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("IsCpuTask") + .HasColumnType("boolean"); + + b.Property("IsSmall") + .HasColumnType("boolean"); + + b.Property("Keyspace") + .HasColumnType("bigint"); + + b.Property("KeyspaceProgress") + .HasColumnType("numeric(20,0)"); + + b.Property("MaxAgents") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("text"); + + b.Property("PreprocessorCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PreprocessorId") + .HasColumnType("integer"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("SkipKeyspace") + .HasColumnType("numeric(20,0)"); + + b.Property("StaticChunks") + .HasColumnType("integer"); + + b.Property("StatusTimer") + .HasColumnType("integer"); + + b.Property("TaskWrapperId") + .HasColumnType("integer"); + + b.Property("UseNewBenchmark") + .HasColumnType("boolean"); + + b.Property("UsePreprocessor") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryId"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.HasIndex("PreprocessorId"); + + b.HasIndex("TaskWrapperId"); + + b.ToTable("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskDebugOutput", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Output") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("TaskId"); + + b.ToTable("TaskDebugOutput"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("TaskType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("HashlistId"); + + b.ToTable("TaskWrapper"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Email") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("IsValid") + .HasColumnType("boolean"); + + b.Property("LastLoginDate") + .HasColumnType("timestamp with time zone"); + + b.Property("PasswordHash") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordSalt") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("RegisteredSince") + .HasColumnType("timestamp with time zone"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Zap", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Hash") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("SolveTime") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("HashlistId"); + + b.ToTable("Zap"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentBinary", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("UpdateAvailable") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("UpdateTrack") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.HasIndex("Type"); + + b.HasDiscriminator().HasValue("AgentBinary"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.HasDiscriminator().HasValue("CrackerBinary"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Preprocessor", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("KeyspaceCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("LimitCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("SkipCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasDiscriminator().HasValue("Preprocessor"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.BinaryHash", b => + { + b.HasBaseType("HashSlinger.Shared.Models.HashBase"); + + b.Property("Essid") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashBytes") + .IsRequired() + .HasColumnType("bytea"); + + b.HasIndex("ChunkId"); + + b.HasIndex("HashlistId"); + + b.HasIndex("IsCracked"); + + b.HasDiscriminator().HasValue("BinaryHash"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hash", b => + { + b.HasBaseType("HashSlinger.Shared.Models.HashBase"); + + b.Property("HashValue") + .IsRequired() + .HasColumnType("text"); + + b.Property("Salt") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasIndex("ChunkId"); + + b.HasIndex("HashlistId"); + + b.HasIndex("IsCracked"); + + b.HasDiscriminator().HasValue("Hash"); + }); + + modelBuilder.Entity("AccessGroupAgent", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", null) + .WithMany() + .HasForeignKey("AccessGroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Agent", null) + .WithMany() + .HasForeignKey("AgentsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AccessGroupUser", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", null) + .WithMany() + .HasForeignKey("AccessGroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("FilePreconfiguredTask", b => + { + b.HasOne("HashSlinger.Shared.Models.File", null) + .WithMany() + .HasForeignKey("FilesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.PreconfiguredTask", null) + .WithMany() + .HasForeignKey("PreconfiguredTasksId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("FileTask", b => + { + b.HasOne("HashSlinger.Shared.Models.File", null) + .WithMany() + .HasForeignKey("FilesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", null) + .WithMany() + .HasForeignKey("TasksId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("Agents") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentError", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Errors") + .HasForeignKey("AgentId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("Errors") + .HasForeignKey("ChunkId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("AgentErrors") + .HasForeignKey("TaskId"); + + b.Navigation("Agent"); + + b.Navigation("Chunk"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentStat", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Stats") + .HasForeignKey("AgentId") + .IsRequired(); + + b.Navigation("Agent"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiKey", b => + { + b.HasOne("HashSlinger.Shared.Models.ApiGroup", "ApiGroup") + .WithMany("ApiKeys") + .HasForeignKey("ApiGroupId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("ApiKeys") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ApiGroup"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Assignment", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Assignments") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Assignments") + .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Chunks") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Chunks") + .HasForeignKey("TaskId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.DownloadableBinary", b => + { + b.HasOne("HashSlinger.Shared.Models.File", "File") + .WithMany() + .HasForeignKey("FileId"); + + b.Navigation("File"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("Files") + .HasForeignKey("AccessGroupId") + .IsRequired(); + + b.Navigation("AccessGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDownload", b => + { + b.HasOne("HashSlinger.Shared.Models.File", "File") + .WithMany("FileDownloads") + .HasForeignKey("FileId") + .IsRequired(); + + b.Navigation("File"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("Hashlists") + .HasForeignKey("AccessGroupId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HashType", "HashType") + .WithMany("Hashlists") + .HasForeignKey("HashTypeId") + .IsRequired(); + + b.Navigation("AccessGroup"); + + b.Navigation("HashType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinary", "CrackerBinary") + .WithMany("HealthChecks") + .HasForeignKey("CrackerBinaryId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HashType", "HashType") + .WithMany("HealthChecks") + .HasForeignKey("HashTypeId") + .IsRequired(); + + b.Navigation("CrackerBinary"); + + b.Navigation("HashType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheckAgent", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("HealthCheckAgents") + .HasForeignKey("AgentId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HealthCheck", "HealthCheck") + .WithMany("HealthCheckAgents") + .HasForeignKey("HealthCheckId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("HealthCheck"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.NotificationSetting", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("NotificationSettings") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("Pretasks") + .HasForeignKey("CrackerBinaryTypeId") + .IsRequired(); + + b.Navigation("CrackerBinaryType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.RegistrationVoucher", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("RegistrationVouchers") + .HasForeignKey("AccessGroupId"); + + b.Navigation("AccessGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Session", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("Sessions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Speed", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Speeds") + .HasForeignKey("AgentId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Speeds") + .HasForeignKey("TaskId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.SupertaskPretask", b => + { + b.HasOne("HashSlinger.Shared.Models.PreconfiguredTask", "PreconfiguredTask") + .WithMany("SupertaskPretasks") + .HasForeignKey("PreconfiguredTaskId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Supertask", "Supertask") + .WithMany("SupertaskPretasks") + .HasForeignKey("SupertaskId") + .IsRequired(); + + b.Navigation("PreconfiguredTask"); + + b.Navigation("Supertask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinary", "CrackerBinary") + .WithMany("Tasks") + .HasForeignKey("CrackerBinaryId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("Tasks") + .HasForeignKey("CrackerBinaryTypeId"); + + b.HasOne("HashSlinger.Shared.Models.Preprocessor", "Preprocessor") + .WithMany("Tasks") + .HasForeignKey("PreprocessorId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.TaskWrapper", "TaskWrapper") + .WithMany("Tasks") + .HasForeignKey("TaskWrapperId") + .OnDelete(DeleteBehavior.SetNull) + .IsRequired(); + + b.Navigation("CrackerBinary"); + + b.Navigation("CrackerBinaryType"); + + b.Navigation("Preprocessor"); + + b.Navigation("TaskWrapper"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskDebugOutput", b => + { + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("TaskDebugOutputs") + .HasForeignKey("TaskId") + .IsRequired(); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("TaskWrappers") + .HasForeignKey("AccessGroupId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("TaskWrappers") + .HasForeignKey("HashlistId") + .IsRequired(); + + b.Navigation("AccessGroup"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Zap", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Zaps") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("Zaps") + .HasForeignKey("HashlistId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("CrackerBinaries") + .HasForeignKey("CrackerBinaryTypeId") + .IsRequired(); + + b.Navigation("CrackerBinaryType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.BinaryHash", b => + { + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("BinaryHashes") + .HasForeignKey("ChunkId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("BinaryHashes") + .HasForeignKey("HashlistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Chunk"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hash", b => + { + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("Hashes") + .HasForeignKey("ChunkId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("Hashes") + .HasForeignKey("HashlistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Chunk"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AccessGroup", b => + { + b.Navigation("Files"); + + b.Navigation("Hashlists"); + + b.Navigation("RegistrationVouchers"); + + b.Navigation("TaskWrappers"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.Navigation("Assignments"); + + b.Navigation("Chunks"); + + b.Navigation("Errors"); + + b.Navigation("HealthCheckAgents"); + + b.Navigation("Speeds"); + + b.Navigation("Stats"); + + b.Navigation("Zaps"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiGroup", b => + { + b.Navigation("ApiKeys"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.Navigation("BinaryHashes"); + + b.Navigation("Errors"); + + b.Navigation("Hashes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinaryType", b => + { + b.Navigation("CrackerBinaries"); + + b.Navigation("Pretasks"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.Navigation("FileDownloads"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashType", b => + { + b.Navigation("Hashlists"); + + b.Navigation("HealthChecks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.Navigation("BinaryHashes"); + + b.Navigation("Hashes"); + + b.Navigation("TaskWrappers"); + + b.Navigation("Zaps"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.Navigation("HealthCheckAgents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.Navigation("SupertaskPretasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Supertask", b => + { + b.Navigation("SupertaskPretasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.Navigation("AgentErrors"); + + b.Navigation("Assignments"); + + b.Navigation("Chunks"); + + b.Navigation("Speeds"); + + b.Navigation("TaskDebugOutputs"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.User", b => + { + b.Navigation("Agents"); + + b.Navigation("ApiKeys"); + + b.Navigation("NotificationSettings"); + + b.Navigation("Sessions"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.Navigation("HealthChecks"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Preprocessor", b => + { + b.Navigation("Tasks"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/HashSlinger/Migrations/20230701175137_changes.cs b/HashSlinger/Migrations/20230701175137_changes.cs new file mode 100644 index 0000000..ab7a50c --- /dev/null +++ b/HashSlinger/Migrations/20230701175137_changes.cs @@ -0,0 +1,64 @@ +#nullable disable + +namespace HashSlinger.Api.Migrations +{ + using Microsoft.EntityFrameworkCore.Migrations; + + /// + public partial class changes : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Assignment_Agents_AgentId", + table: "Assignment"); + + migrationBuilder.DropForeignKey( + name: "FK_Assignment_Tasks_TaskId", + table: "Assignment"); + + migrationBuilder.AddForeignKey( + name: "FK_Assignment_Agents_AgentId", + table: "Assignment", + column: "AgentId", + principalTable: "Agents", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_Assignment_Tasks_TaskId", + table: "Assignment", + column: "TaskId", + principalTable: "Tasks", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Assignment_Agents_AgentId", + table: "Assignment"); + + migrationBuilder.DropForeignKey( + name: "FK_Assignment_Tasks_TaskId", + table: "Assignment"); + + migrationBuilder.AddForeignKey( + name: "FK_Assignment_Agents_AgentId", + table: "Assignment", + column: "AgentId", + principalTable: "Agents", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Assignment_Tasks_TaskId", + table: "Assignment", + column: "TaskId", + principalTable: "Tasks", + principalColumn: "Id"); + } + } +} diff --git a/HashSlinger/Migrations/20230701175709_MoreOnDeleteChanges.Designer.cs b/HashSlinger/Migrations/20230701175709_MoreOnDeleteChanges.Designer.cs new file mode 100644 index 0000000..78e0d4d --- /dev/null +++ b/HashSlinger/Migrations/20230701175709_MoreOnDeleteChanges.Designer.cs @@ -0,0 +1,1919 @@ +// + +#nullable disable + +namespace HashSlinger.Api.Migrations +{ + using System.Net; + using Data; + using Microsoft.EntityFrameworkCore; + using Microsoft.EntityFrameworkCore.Infrastructure; + using Microsoft.EntityFrameworkCore.Migrations; + + [DbContext(typeof(HashSlingerContext))] + [Migration("20230701175709_MoreOnDeleteChanges")] + partial class MoreOnDeleteChanges + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("AccessGroupAgent", b => + { + b.Property("AccessGroupsId") + .HasColumnType("integer"); + + b.Property("AgentsId") + .HasColumnType("integer"); + + b.HasKey("AccessGroupsId", "AgentsId"); + + b.HasIndex("AgentsId"); + + b.ToTable("AccessGroupAgent"); + }); + + modelBuilder.Entity("AccessGroupUser", b => + { + b.Property("AccessGroupsId") + .HasColumnType("integer"); + + b.Property("UsersId") + .HasColumnType("integer"); + + b.HasKey("AccessGroupsId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("AccessGroupUser"); + }); + + modelBuilder.Entity("FilePreconfiguredTask", b => + { + b.Property("FilesId") + .HasColumnType("integer"); + + b.Property("PreconfiguredTasksId") + .HasColumnType("integer"); + + b.HasKey("FilesId", "PreconfiguredTasksId"); + + b.HasIndex("PreconfiguredTasksId"); + + b.ToTable("FilePreconfiguredTask"); + }); + + modelBuilder.Entity("FileTask", b => + { + b.Property("FilesId") + .HasColumnType("integer"); + + b.Property("TasksId") + .HasColumnType("integer"); + + b.HasKey("FilesId", "TasksId"); + + b.HasIndex("TasksId"); + + b.ToTable("FileTask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AccessGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("AccessGroups"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClientSignature") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("CommandParameters") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CpuOnly") + .HasColumnType("boolean"); + + b.Property>("Devices") + .HasColumnType("text[]"); + + b.Property("IgnoreErrors") + .HasColumnType("boolean"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("IsTrusted") + .HasColumnType("boolean"); + + b.Property("LastAction") + .HasColumnType("integer"); + + b.Property("LastSeenIpAddress") + .HasColumnType("inet"); + + b.Property("LastSeenTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("OperatingSystem") + .HasColumnType("integer"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.Property("Uid") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("Token"); + + b.HasIndex("Uid"); + + b.HasIndex("UserId"); + + b.ToTable("Agents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentError", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("ChunkId") + .HasColumnType("integer"); + + b.Property("Error") + .IsRequired() + .HasColumnType("text"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("ChunkId"); + + b.HasIndex("TaskId"); + + b.ToTable("AgentError"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentStat", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("StatType") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.ToTable("AgentStat"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Permissions") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("ApiGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessCount") + .HasColumnType("integer"); + + b.Property("AccessKey") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ApiGroupId") + .HasColumnType("integer"); + + b.Property("EndValid") + .HasColumnType("timestamp with time zone"); + + b.Property("StartValid") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ApiGroupId"); + + b.HasIndex("UserId"); + + b.ToTable("ApiKey"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Assignment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Benchmark") + .IsRequired() + .HasColumnType("text"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Assignment"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Checkpoint") + .HasColumnType("numeric(20,0)"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("DispatchTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Length") + .HasColumnType("numeric(20,0)"); + + b.Property("Progress") + .HasColumnType("real"); + + b.Property("Skip") + .HasColumnType("numeric(20,0)"); + + b.Property("SolveTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Speed") + .HasColumnType("numeric(20,0)"); + + b.Property("State") + .HasColumnType("integer"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Chunks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinaryType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IsChunkingAvailable") + .HasColumnType("boolean"); + + b.Property("TypeName") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.HasKey("Id"); + + b.ToTable("CrackerBinaryTypes"); + + b.HasData( + new + { + Id = 1, + IsChunkingAvailable = true, + TypeName = "hashcat" + }); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.DownloadableBinary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("text"); + + b.Property("DownloadUrl") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("Executable") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("FileId") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property>("OperatingSystems") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("Version") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.ToTable("DownloadableBinaries"); + + b.HasDiscriminator("Discriminator").HasValue("DownloadableBinary"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("FileGuid") + .HasColumnType("uuid"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("FileType") + .HasColumnType("integer"); + + b.Property("IsSecret") + .HasColumnType("boolean"); + + b.Property("LineCount") + .HasColumnType("bigint"); + + b.Property("Size") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.ToTable("Files"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDelete", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("FileDeletes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDownload", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FileId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.ToTable("FileDownload"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashBase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ChunkId") + .HasColumnType("integer"); + + b.Property("CrackPos") + .HasColumnType("numeric(20,0)"); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("IsCracked") + .HasColumnType("boolean"); + + b.Property("Plaintext") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("TimeCracked") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("HashBase"); + + b.HasDiscriminator("Discriminator").HasValue("HashBase"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("HashcatId") + .HasColumnType("integer"); + + b.Property("IsSalted") + .HasColumnType("boolean"); + + b.Property("IsSlowHash") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("HashcatId") + .IsUnique(); + + b.ToTable("HashTypes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("BrainFeatures") + .HasColumnType("smallint"); + + b.Property("BrainId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("Format") + .HasColumnType("integer"); + + b.Property("HashCount") + .HasColumnType("integer"); + + b.Property("HashTypeId") + .HasColumnType("uuid"); + + b.Property("HexSalt") + .HasColumnType("boolean"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("IsSalted") + .HasColumnType("boolean"); + + b.Property("IsSecret") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("text"); + + b.Property("SaltSeparator") + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("HashTypeId"); + + b.HasIndex("IsSecret"); + + b.ToTable("Hashlists"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCmd") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CheckType") + .HasColumnType("integer"); + + b.Property("CrackerBinaryId") + .HasColumnType("integer"); + + b.Property("ExpectedCracks") + .HasColumnType("integer"); + + b.Property("HashListAlias") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashTypeId") + .HasColumnType("uuid"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property>("TestHashes") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryId"); + + b.HasIndex("HashTypeId"); + + b.ToTable("HealthChecks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheckAgent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("End") + .HasColumnType("numeric(20,0)"); + + b.Property>("Errors") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("HealthCheckId") + .HasColumnType("integer"); + + b.Property("NumGpus") + .HasColumnType("integer"); + + b.Property("Start") + .HasColumnType("numeric(20,0)"); + + b.Property("Status") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("HealthCheckId"); + + b.ToTable("HealthCheckAgents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.LogEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Issuer") + .IsRequired() + .HasColumnType("text"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("LogEntries"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.NotificationSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("Notification") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("ObjectId") + .HasColumnType("integer"); + + b.Property("Receiver") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationSetting"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCommand") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ChunkTime") + .HasColumnType("integer"); + + b.Property("Color") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.Property("IsCpuTask") + .HasColumnType("boolean"); + + b.Property("IsMaskImport") + .HasColumnType("boolean"); + + b.Property("IsSmall") + .HasColumnType("boolean"); + + b.Property("MaxAgents") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("StatusTimer") + .HasColumnType("integer"); + + b.Property("UseNewBench") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.ToTable("PreconfiguredTask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.RegistrationVoucher", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("Expiration") + .HasColumnType("timestamp with time zone"); + + b.Property("Voucher") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("Voucher") + .IsUnique(); + + b.ToTable("RegistrationVouchers"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Session", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IsOpen") + .HasColumnType("boolean"); + + b.Property("LastActionDate") + .HasColumnType("timestamp with time zone"); + + b.Property("SessionKey") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("SessionLifetime") + .HasColumnType("integer"); + + b.Property("SessionStartDate") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Session"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Speed", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("SpeedValue") + .HasColumnType("numeric(20,0)"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Speed"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Supertask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("Supertask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.SupertaskPretask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("PreconfiguredTaskId") + .HasColumnType("integer"); + + b.Property("PretaskId") + .HasColumnType("integer"); + + b.Property("SupertaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("PreconfiguredTaskId"); + + b.HasIndex("SupertaskId"); + + b.ToTable("SupertaskPretask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCommand") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ChunkSize") + .HasColumnType("integer"); + + b.Property("ChunkTime") + .HasColumnType("integer"); + + b.Property("Color") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CrackerBinaryId") + .HasColumnType("integer"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.Property("EnforcePipe") + .HasColumnType("boolean"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("IsCpuTask") + .HasColumnType("boolean"); + + b.Property("IsSmall") + .HasColumnType("boolean"); + + b.Property("Keyspace") + .HasColumnType("bigint"); + + b.Property("KeyspaceProgress") + .HasColumnType("numeric(20,0)"); + + b.Property("MaxAgents") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("text"); + + b.Property("PreprocessorCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PreprocessorId") + .HasColumnType("integer"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("SkipKeyspace") + .HasColumnType("numeric(20,0)"); + + b.Property("StaticChunks") + .HasColumnType("integer"); + + b.Property("StatusTimer") + .HasColumnType("integer"); + + b.Property("TaskWrapperId") + .HasColumnType("integer"); + + b.Property("UseNewBenchmark") + .HasColumnType("boolean"); + + b.Property("UsePreprocessor") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryId"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.HasIndex("PreprocessorId"); + + b.HasIndex("TaskWrapperId"); + + b.ToTable("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskDebugOutput", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Output") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("TaskId"); + + b.ToTable("TaskDebugOutput"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("TaskType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("HashlistId"); + + b.ToTable("TaskWrapper"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Email") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("IsValid") + .HasColumnType("boolean"); + + b.Property("LastLoginDate") + .HasColumnType("timestamp with time zone"); + + b.Property("PasswordHash") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordSalt") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("RegisteredSince") + .HasColumnType("timestamp with time zone"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Zap", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Hash") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("SolveTime") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("HashlistId"); + + b.ToTable("Zap"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentBinary", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("UpdateAvailable") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("UpdateTrack") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.HasIndex("Type"); + + b.HasDiscriminator().HasValue("AgentBinary"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.HasDiscriminator().HasValue("CrackerBinary"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Preprocessor", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("KeyspaceCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("LimitCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("SkipCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasDiscriminator().HasValue("Preprocessor"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.BinaryHash", b => + { + b.HasBaseType("HashSlinger.Shared.Models.HashBase"); + + b.Property("Essid") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashBytes") + .IsRequired() + .HasColumnType("bytea"); + + b.HasIndex("ChunkId"); + + b.HasIndex("HashlistId"); + + b.HasIndex("IsCracked"); + + b.HasDiscriminator().HasValue("BinaryHash"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hash", b => + { + b.HasBaseType("HashSlinger.Shared.Models.HashBase"); + + b.Property("HashValue") + .IsRequired() + .HasColumnType("text"); + + b.Property("Salt") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasIndex("ChunkId"); + + b.HasIndex("HashlistId"); + + b.HasIndex("IsCracked"); + + b.HasDiscriminator().HasValue("Hash"); + }); + + modelBuilder.Entity("AccessGroupAgent", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", null) + .WithMany() + .HasForeignKey("AccessGroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Agent", null) + .WithMany() + .HasForeignKey("AgentsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AccessGroupUser", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", null) + .WithMany() + .HasForeignKey("AccessGroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("FilePreconfiguredTask", b => + { + b.HasOne("HashSlinger.Shared.Models.File", null) + .WithMany() + .HasForeignKey("FilesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.PreconfiguredTask", null) + .WithMany() + .HasForeignKey("PreconfiguredTasksId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("FileTask", b => + { + b.HasOne("HashSlinger.Shared.Models.File", null) + .WithMany() + .HasForeignKey("FilesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", null) + .WithMany() + .HasForeignKey("TasksId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("Agents") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentError", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Errors") + .HasForeignKey("AgentId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("Errors") + .HasForeignKey("ChunkId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("AgentErrors") + .HasForeignKey("TaskId"); + + b.Navigation("Agent"); + + b.Navigation("Chunk"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentStat", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Stats") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiKey", b => + { + b.HasOne("HashSlinger.Shared.Models.ApiGroup", "ApiGroup") + .WithMany("ApiKeys") + .HasForeignKey("ApiGroupId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("ApiKeys") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ApiGroup"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Assignment", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Assignments") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Assignments") + .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Chunks") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Chunks") + .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.DownloadableBinary", b => + { + b.HasOne("HashSlinger.Shared.Models.File", "File") + .WithMany() + .HasForeignKey("FileId"); + + b.Navigation("File"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("Files") + .HasForeignKey("AccessGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AccessGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDownload", b => + { + b.HasOne("HashSlinger.Shared.Models.File", "File") + .WithMany("FileDownloads") + .HasForeignKey("FileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("File"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("Hashlists") + .HasForeignKey("AccessGroupId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HashType", "HashType") + .WithMany("Hashlists") + .HasForeignKey("HashTypeId") + .IsRequired(); + + b.Navigation("AccessGroup"); + + b.Navigation("HashType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinary", "CrackerBinary") + .WithMany("HealthChecks") + .HasForeignKey("CrackerBinaryId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HashType", "HashType") + .WithMany("HealthChecks") + .HasForeignKey("HashTypeId") + .IsRequired(); + + b.Navigation("CrackerBinary"); + + b.Navigation("HashType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheckAgent", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("HealthCheckAgents") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HealthCheck", "HealthCheck") + .WithMany("HealthCheckAgents") + .HasForeignKey("HealthCheckId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("HealthCheck"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.NotificationSetting", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("NotificationSettings") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("Pretasks") + .HasForeignKey("CrackerBinaryTypeId") + .IsRequired(); + + b.Navigation("CrackerBinaryType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.RegistrationVoucher", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("RegistrationVouchers") + .HasForeignKey("AccessGroupId"); + + b.Navigation("AccessGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Session", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("Sessions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Speed", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Speeds") + .HasForeignKey("AgentId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Speeds") + .HasForeignKey("TaskId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.SupertaskPretask", b => + { + b.HasOne("HashSlinger.Shared.Models.PreconfiguredTask", "PreconfiguredTask") + .WithMany("SupertaskPretasks") + .HasForeignKey("PreconfiguredTaskId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Supertask", "Supertask") + .WithMany("SupertaskPretasks") + .HasForeignKey("SupertaskId") + .IsRequired(); + + b.Navigation("PreconfiguredTask"); + + b.Navigation("Supertask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinary", "CrackerBinary") + .WithMany("Tasks") + .HasForeignKey("CrackerBinaryId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("Tasks") + .HasForeignKey("CrackerBinaryTypeId"); + + b.HasOne("HashSlinger.Shared.Models.Preprocessor", "Preprocessor") + .WithMany("Tasks") + .HasForeignKey("PreprocessorId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.TaskWrapper", "TaskWrapper") + .WithMany("Tasks") + .HasForeignKey("TaskWrapperId") + .OnDelete(DeleteBehavior.SetNull) + .IsRequired(); + + b.Navigation("CrackerBinary"); + + b.Navigation("CrackerBinaryType"); + + b.Navigation("Preprocessor"); + + b.Navigation("TaskWrapper"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskDebugOutput", b => + { + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("TaskDebugOutputs") + .HasForeignKey("TaskId") + .IsRequired(); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("TaskWrappers") + .HasForeignKey("AccessGroupId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("TaskWrappers") + .HasForeignKey("HashlistId") + .IsRequired(); + + b.Navigation("AccessGroup"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Zap", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Zaps") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("Zaps") + .HasForeignKey("HashlistId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("CrackerBinaries") + .HasForeignKey("CrackerBinaryTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CrackerBinaryType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.BinaryHash", b => + { + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("BinaryHashes") + .HasForeignKey("ChunkId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("BinaryHashes") + .HasForeignKey("HashlistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Chunk"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hash", b => + { + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("Hashes") + .HasForeignKey("ChunkId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("Hashes") + .HasForeignKey("HashlistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Chunk"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AccessGroup", b => + { + b.Navigation("Files"); + + b.Navigation("Hashlists"); + + b.Navigation("RegistrationVouchers"); + + b.Navigation("TaskWrappers"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.Navigation("Assignments"); + + b.Navigation("Chunks"); + + b.Navigation("Errors"); + + b.Navigation("HealthCheckAgents"); + + b.Navigation("Speeds"); + + b.Navigation("Stats"); + + b.Navigation("Zaps"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiGroup", b => + { + b.Navigation("ApiKeys"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.Navigation("BinaryHashes"); + + b.Navigation("Errors"); + + b.Navigation("Hashes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinaryType", b => + { + b.Navigation("CrackerBinaries"); + + b.Navigation("Pretasks"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.Navigation("FileDownloads"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashType", b => + { + b.Navigation("Hashlists"); + + b.Navigation("HealthChecks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.Navigation("BinaryHashes"); + + b.Navigation("Hashes"); + + b.Navigation("TaskWrappers"); + + b.Navigation("Zaps"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.Navigation("HealthCheckAgents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.Navigation("SupertaskPretasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Supertask", b => + { + b.Navigation("SupertaskPretasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.Navigation("AgentErrors"); + + b.Navigation("Assignments"); + + b.Navigation("Chunks"); + + b.Navigation("Speeds"); + + b.Navigation("TaskDebugOutputs"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.User", b => + { + b.Navigation("Agents"); + + b.Navigation("ApiKeys"); + + b.Navigation("NotificationSettings"); + + b.Navigation("Sessions"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.Navigation("HealthChecks"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Preprocessor", b => + { + b.Navigation("Tasks"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/HashSlinger/Migrations/20230701175709_MoreOnDeleteChanges.cs b/HashSlinger/Migrations/20230701175709_MoreOnDeleteChanges.cs new file mode 100644 index 0000000..b14253a --- /dev/null +++ b/HashSlinger/Migrations/20230701175709_MoreOnDeleteChanges.cs @@ -0,0 +1,156 @@ +#nullable disable + +namespace HashSlinger.Api.Migrations +{ + using Microsoft.EntityFrameworkCore.Migrations; + + /// + public partial class MoreOnDeleteChanges : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_AgentStat_Agents_AgentId", + table: "AgentStat"); + + migrationBuilder.DropForeignKey( + name: "FK_Chunks_Tasks_TaskId", + table: "Chunks"); + + migrationBuilder.DropForeignKey( + name: "FK_DownloadableBinaries_CrackerBinaryTypes_CrackerBinaryTypeId", + table: "DownloadableBinaries"); + + migrationBuilder.DropForeignKey( + name: "FK_FileDownload_Files_FileId", + table: "FileDownload"); + + migrationBuilder.DropForeignKey( + name: "FK_Files_AccessGroups_AccessGroupId", + table: "Files"); + + migrationBuilder.DropForeignKey( + name: "FK_HealthCheckAgents_Agents_AgentId", + table: "HealthCheckAgents"); + + migrationBuilder.AddForeignKey( + name: "FK_AgentStat_Agents_AgentId", + table: "AgentStat", + column: "AgentId", + principalTable: "Agents", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_Chunks_Tasks_TaskId", + table: "Chunks", + column: "TaskId", + principalTable: "Tasks", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_DownloadableBinaries_CrackerBinaryTypes_CrackerBinaryTypeId", + table: "DownloadableBinaries", + column: "CrackerBinaryTypeId", + principalTable: "CrackerBinaryTypes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_FileDownload_Files_FileId", + table: "FileDownload", + column: "FileId", + principalTable: "Files", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_Files_AccessGroups_AccessGroupId", + table: "Files", + column: "AccessGroupId", + principalTable: "AccessGroups", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_HealthCheckAgents_Agents_AgentId", + table: "HealthCheckAgents", + column: "AgentId", + principalTable: "Agents", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_AgentStat_Agents_AgentId", + table: "AgentStat"); + + migrationBuilder.DropForeignKey( + name: "FK_Chunks_Tasks_TaskId", + table: "Chunks"); + + migrationBuilder.DropForeignKey( + name: "FK_DownloadableBinaries_CrackerBinaryTypes_CrackerBinaryTypeId", + table: "DownloadableBinaries"); + + migrationBuilder.DropForeignKey( + name: "FK_FileDownload_Files_FileId", + table: "FileDownload"); + + migrationBuilder.DropForeignKey( + name: "FK_Files_AccessGroups_AccessGroupId", + table: "Files"); + + migrationBuilder.DropForeignKey( + name: "FK_HealthCheckAgents_Agents_AgentId", + table: "HealthCheckAgents"); + + migrationBuilder.AddForeignKey( + name: "FK_AgentStat_Agents_AgentId", + table: "AgentStat", + column: "AgentId", + principalTable: "Agents", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Chunks_Tasks_TaskId", + table: "Chunks", + column: "TaskId", + principalTable: "Tasks", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_DownloadableBinaries_CrackerBinaryTypes_CrackerBinaryTypeId", + table: "DownloadableBinaries", + column: "CrackerBinaryTypeId", + principalTable: "CrackerBinaryTypes", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_FileDownload_Files_FileId", + table: "FileDownload", + column: "FileId", + principalTable: "Files", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Files_AccessGroups_AccessGroupId", + table: "Files", + column: "AccessGroupId", + principalTable: "AccessGroups", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_HealthCheckAgents_Agents_AgentId", + table: "HealthCheckAgents", + column: "AgentId", + principalTable: "Agents", + principalColumn: "Id"); + } + } +} diff --git a/HashSlinger/Migrations/20230701175923_EvenMoreOnDeleteChanges.Designer.cs b/HashSlinger/Migrations/20230701175923_EvenMoreOnDeleteChanges.Designer.cs new file mode 100644 index 0000000..a9a20fb --- /dev/null +++ b/HashSlinger/Migrations/20230701175923_EvenMoreOnDeleteChanges.Designer.cs @@ -0,0 +1,1922 @@ +// + +#nullable disable + +namespace HashSlinger.Api.Migrations +{ + using System.Net; + using Data; + using Microsoft.EntityFrameworkCore; + using Microsoft.EntityFrameworkCore.Infrastructure; + using Microsoft.EntityFrameworkCore.Migrations; + + [DbContext(typeof(HashSlingerContext))] + [Migration("20230701175923_EvenMoreOnDeleteChanges")] + partial class EvenMoreOnDeleteChanges + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("AccessGroupAgent", b => + { + b.Property("AccessGroupsId") + .HasColumnType("integer"); + + b.Property("AgentsId") + .HasColumnType("integer"); + + b.HasKey("AccessGroupsId", "AgentsId"); + + b.HasIndex("AgentsId"); + + b.ToTable("AccessGroupAgent"); + }); + + modelBuilder.Entity("AccessGroupUser", b => + { + b.Property("AccessGroupsId") + .HasColumnType("integer"); + + b.Property("UsersId") + .HasColumnType("integer"); + + b.HasKey("AccessGroupsId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("AccessGroupUser"); + }); + + modelBuilder.Entity("FilePreconfiguredTask", b => + { + b.Property("FilesId") + .HasColumnType("integer"); + + b.Property("PreconfiguredTasksId") + .HasColumnType("integer"); + + b.HasKey("FilesId", "PreconfiguredTasksId"); + + b.HasIndex("PreconfiguredTasksId"); + + b.ToTable("FilePreconfiguredTask"); + }); + + modelBuilder.Entity("FileTask", b => + { + b.Property("FilesId") + .HasColumnType("integer"); + + b.Property("TasksId") + .HasColumnType("integer"); + + b.HasKey("FilesId", "TasksId"); + + b.HasIndex("TasksId"); + + b.ToTable("FileTask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AccessGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("AccessGroups"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClientSignature") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("CommandParameters") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CpuOnly") + .HasColumnType("boolean"); + + b.Property>("Devices") + .HasColumnType("text[]"); + + b.Property("IgnoreErrors") + .HasColumnType("boolean"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("IsTrusted") + .HasColumnType("boolean"); + + b.Property("LastAction") + .HasColumnType("integer"); + + b.Property("LastSeenIpAddress") + .HasColumnType("inet"); + + b.Property("LastSeenTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("OperatingSystem") + .HasColumnType("integer"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.Property("Uid") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("Token"); + + b.HasIndex("Uid"); + + b.HasIndex("UserId"); + + b.ToTable("Agents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentError", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("ChunkId") + .HasColumnType("integer"); + + b.Property("Error") + .IsRequired() + .HasColumnType("text"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("ChunkId"); + + b.HasIndex("TaskId"); + + b.ToTable("AgentError"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentStat", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("StatType") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.ToTable("AgentStat"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Permissions") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("ApiGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessCount") + .HasColumnType("integer"); + + b.Property("AccessKey") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ApiGroupId") + .HasColumnType("integer"); + + b.Property("EndValid") + .HasColumnType("timestamp with time zone"); + + b.Property("StartValid") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ApiGroupId"); + + b.HasIndex("UserId"); + + b.ToTable("ApiKey"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Assignment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Benchmark") + .IsRequired() + .HasColumnType("text"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Assignment"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Checkpoint") + .HasColumnType("numeric(20,0)"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("DispatchTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Length") + .HasColumnType("numeric(20,0)"); + + b.Property("Progress") + .HasColumnType("real"); + + b.Property("Skip") + .HasColumnType("numeric(20,0)"); + + b.Property("SolveTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Speed") + .HasColumnType("numeric(20,0)"); + + b.Property("State") + .HasColumnType("integer"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Chunks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinaryType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IsChunkingAvailable") + .HasColumnType("boolean"); + + b.Property("TypeName") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.HasKey("Id"); + + b.ToTable("CrackerBinaryTypes"); + + b.HasData( + new + { + Id = 1, + IsChunkingAvailable = true, + TypeName = "hashcat" + }); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.DownloadableBinary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("text"); + + b.Property("DownloadUrl") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("Executable") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("FileId") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property>("OperatingSystems") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("Version") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.ToTable("DownloadableBinaries"); + + b.HasDiscriminator("Discriminator").HasValue("DownloadableBinary"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("FileGuid") + .HasColumnType("uuid"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("FileType") + .HasColumnType("integer"); + + b.Property("IsSecret") + .HasColumnType("boolean"); + + b.Property("LineCount") + .HasColumnType("bigint"); + + b.Property("Size") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.ToTable("Files"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDelete", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("FileDeletes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDownload", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FileId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.ToTable("FileDownload"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashBase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ChunkId") + .HasColumnType("integer"); + + b.Property("CrackPos") + .HasColumnType("numeric(20,0)"); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("IsCracked") + .HasColumnType("boolean"); + + b.Property("Plaintext") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("TimeCracked") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("HashBase"); + + b.HasDiscriminator("Discriminator").HasValue("HashBase"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("HashcatId") + .HasColumnType("integer"); + + b.Property("IsSalted") + .HasColumnType("boolean"); + + b.Property("IsSlowHash") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("HashcatId") + .IsUnique(); + + b.ToTable("HashTypes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("BrainFeatures") + .HasColumnType("smallint"); + + b.Property("BrainId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("Format") + .HasColumnType("integer"); + + b.Property("HashCount") + .HasColumnType("integer"); + + b.Property("HashTypeId") + .HasColumnType("uuid"); + + b.Property("HexSalt") + .HasColumnType("boolean"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("IsSalted") + .HasColumnType("boolean"); + + b.Property("IsSecret") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("text"); + + b.Property("SaltSeparator") + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("HashTypeId"); + + b.HasIndex("IsSecret"); + + b.ToTable("Hashlists"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCmd") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CheckType") + .HasColumnType("integer"); + + b.Property("CrackerBinaryId") + .HasColumnType("integer"); + + b.Property("ExpectedCracks") + .HasColumnType("integer"); + + b.Property("HashListAlias") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashTypeId") + .HasColumnType("uuid"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property>("TestHashes") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryId"); + + b.HasIndex("HashTypeId"); + + b.ToTable("HealthChecks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheckAgent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("End") + .HasColumnType("numeric(20,0)"); + + b.Property>("Errors") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("HealthCheckId") + .HasColumnType("integer"); + + b.Property("NumGpus") + .HasColumnType("integer"); + + b.Property("Start") + .HasColumnType("numeric(20,0)"); + + b.Property("Status") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("HealthCheckId"); + + b.ToTable("HealthCheckAgents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.LogEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Issuer") + .IsRequired() + .HasColumnType("text"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("LogEntries"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.NotificationSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("Notification") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("ObjectId") + .HasColumnType("integer"); + + b.Property("Receiver") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationSetting"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCommand") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ChunkTime") + .HasColumnType("integer"); + + b.Property("Color") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.Property("IsCpuTask") + .HasColumnType("boolean"); + + b.Property("IsMaskImport") + .HasColumnType("boolean"); + + b.Property("IsSmall") + .HasColumnType("boolean"); + + b.Property("MaxAgents") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("StatusTimer") + .HasColumnType("integer"); + + b.Property("UseNewBench") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.ToTable("PreconfiguredTask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.RegistrationVoucher", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("Expiration") + .HasColumnType("timestamp with time zone"); + + b.Property("Voucher") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("Voucher") + .IsUnique(); + + b.ToTable("RegistrationVouchers"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Session", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IsOpen") + .HasColumnType("boolean"); + + b.Property("LastActionDate") + .HasColumnType("timestamp with time zone"); + + b.Property("SessionKey") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("SessionLifetime") + .HasColumnType("integer"); + + b.Property("SessionStartDate") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Session"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Speed", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("SpeedValue") + .HasColumnType("numeric(20,0)"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Speed"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Supertask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("Supertask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.SupertaskPretask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("PreconfiguredTaskId") + .HasColumnType("integer"); + + b.Property("PretaskId") + .HasColumnType("integer"); + + b.Property("SupertaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("PreconfiguredTaskId"); + + b.HasIndex("SupertaskId"); + + b.ToTable("SupertaskPretask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCommand") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ChunkSize") + .HasColumnType("integer"); + + b.Property("ChunkTime") + .HasColumnType("integer"); + + b.Property("Color") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CrackerBinaryId") + .HasColumnType("integer"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.Property("EnforcePipe") + .HasColumnType("boolean"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("IsCpuTask") + .HasColumnType("boolean"); + + b.Property("IsSmall") + .HasColumnType("boolean"); + + b.Property("Keyspace") + .HasColumnType("bigint"); + + b.Property("KeyspaceProgress") + .HasColumnType("numeric(20,0)"); + + b.Property("MaxAgents") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("text"); + + b.Property("PreprocessorCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PreprocessorId") + .HasColumnType("integer"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("SkipKeyspace") + .HasColumnType("numeric(20,0)"); + + b.Property("StaticChunks") + .HasColumnType("integer"); + + b.Property("StatusTimer") + .HasColumnType("integer"); + + b.Property("TaskWrapperId") + .HasColumnType("integer"); + + b.Property("UseNewBenchmark") + .HasColumnType("boolean"); + + b.Property("UsePreprocessor") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryId"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.HasIndex("PreprocessorId"); + + b.HasIndex("TaskWrapperId"); + + b.ToTable("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskDebugOutput", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Output") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("TaskId"); + + b.ToTable("TaskDebugOutput"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("TaskType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("HashlistId"); + + b.ToTable("TaskWrapper"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Email") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("IsValid") + .HasColumnType("boolean"); + + b.Property("LastLoginDate") + .HasColumnType("timestamp with time zone"); + + b.Property("PasswordHash") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordSalt") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("RegisteredSince") + .HasColumnType("timestamp with time zone"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Zap", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Hash") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("SolveTime") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("HashlistId"); + + b.ToTable("Zap"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentBinary", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("UpdateAvailable") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("UpdateTrack") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.HasIndex("Type"); + + b.HasDiscriminator().HasValue("AgentBinary"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.HasDiscriminator().HasValue("CrackerBinary"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Preprocessor", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("KeyspaceCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("LimitCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("SkipCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasDiscriminator().HasValue("Preprocessor"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.BinaryHash", b => + { + b.HasBaseType("HashSlinger.Shared.Models.HashBase"); + + b.Property("Essid") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashBytes") + .IsRequired() + .HasColumnType("bytea"); + + b.HasIndex("ChunkId"); + + b.HasIndex("HashlistId"); + + b.HasIndex("IsCracked"); + + b.HasDiscriminator().HasValue("BinaryHash"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hash", b => + { + b.HasBaseType("HashSlinger.Shared.Models.HashBase"); + + b.Property("HashValue") + .IsRequired() + .HasColumnType("text"); + + b.Property("Salt") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasIndex("ChunkId"); + + b.HasIndex("HashlistId"); + + b.HasIndex("IsCracked"); + + b.HasDiscriminator().HasValue("Hash"); + }); + + modelBuilder.Entity("AccessGroupAgent", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", null) + .WithMany() + .HasForeignKey("AccessGroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Agent", null) + .WithMany() + .HasForeignKey("AgentsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AccessGroupUser", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", null) + .WithMany() + .HasForeignKey("AccessGroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("FilePreconfiguredTask", b => + { + b.HasOne("HashSlinger.Shared.Models.File", null) + .WithMany() + .HasForeignKey("FilesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.PreconfiguredTask", null) + .WithMany() + .HasForeignKey("PreconfiguredTasksId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("FileTask", b => + { + b.HasOne("HashSlinger.Shared.Models.File", null) + .WithMany() + .HasForeignKey("FilesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", null) + .WithMany() + .HasForeignKey("TasksId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("Agents") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentError", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Errors") + .HasForeignKey("AgentId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("Errors") + .HasForeignKey("ChunkId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("AgentErrors") + .HasForeignKey("TaskId"); + + b.Navigation("Agent"); + + b.Navigation("Chunk"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentStat", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Stats") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiKey", b => + { + b.HasOne("HashSlinger.Shared.Models.ApiGroup", "ApiGroup") + .WithMany("ApiKeys") + .HasForeignKey("ApiGroupId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("ApiKeys") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ApiGroup"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Assignment", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Assignments") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Assignments") + .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Chunks") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Chunks") + .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.DownloadableBinary", b => + { + b.HasOne("HashSlinger.Shared.Models.File", "File") + .WithMany() + .HasForeignKey("FileId"); + + b.Navigation("File"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("Files") + .HasForeignKey("AccessGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AccessGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDownload", b => + { + b.HasOne("HashSlinger.Shared.Models.File", "File") + .WithMany("FileDownloads") + .HasForeignKey("FileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("File"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("Hashlists") + .HasForeignKey("AccessGroupId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HashType", "HashType") + .WithMany("Hashlists") + .HasForeignKey("HashTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AccessGroup"); + + b.Navigation("HashType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinary", "CrackerBinary") + .WithMany("HealthChecks") + .HasForeignKey("CrackerBinaryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HashType", "HashType") + .WithMany("HealthChecks") + .HasForeignKey("HashTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CrackerBinary"); + + b.Navigation("HashType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheckAgent", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("HealthCheckAgents") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HealthCheck", "HealthCheck") + .WithMany("HealthCheckAgents") + .HasForeignKey("HealthCheckId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("HealthCheck"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.NotificationSetting", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("NotificationSettings") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("Pretasks") + .HasForeignKey("CrackerBinaryTypeId") + .IsRequired(); + + b.Navigation("CrackerBinaryType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.RegistrationVoucher", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("RegistrationVouchers") + .HasForeignKey("AccessGroupId"); + + b.Navigation("AccessGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Session", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("Sessions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Speed", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Speeds") + .HasForeignKey("AgentId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Speeds") + .HasForeignKey("TaskId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.SupertaskPretask", b => + { + b.HasOne("HashSlinger.Shared.Models.PreconfiguredTask", "PreconfiguredTask") + .WithMany("SupertaskPretasks") + .HasForeignKey("PreconfiguredTaskId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Supertask", "Supertask") + .WithMany("SupertaskPretasks") + .HasForeignKey("SupertaskId") + .IsRequired(); + + b.Navigation("PreconfiguredTask"); + + b.Navigation("Supertask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinary", "CrackerBinary") + .WithMany("Tasks") + .HasForeignKey("CrackerBinaryId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("Tasks") + .HasForeignKey("CrackerBinaryTypeId"); + + b.HasOne("HashSlinger.Shared.Models.Preprocessor", "Preprocessor") + .WithMany("Tasks") + .HasForeignKey("PreprocessorId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.TaskWrapper", "TaskWrapper") + .WithMany("Tasks") + .HasForeignKey("TaskWrapperId") + .OnDelete(DeleteBehavior.SetNull) + .IsRequired(); + + b.Navigation("CrackerBinary"); + + b.Navigation("CrackerBinaryType"); + + b.Navigation("Preprocessor"); + + b.Navigation("TaskWrapper"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskDebugOutput", b => + { + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("TaskDebugOutputs") + .HasForeignKey("TaskId") + .IsRequired(); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("TaskWrappers") + .HasForeignKey("AccessGroupId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("TaskWrappers") + .HasForeignKey("HashlistId") + .IsRequired(); + + b.Navigation("AccessGroup"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Zap", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Zaps") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("Zaps") + .HasForeignKey("HashlistId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("CrackerBinaries") + .HasForeignKey("CrackerBinaryTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CrackerBinaryType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.BinaryHash", b => + { + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("BinaryHashes") + .HasForeignKey("ChunkId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("BinaryHashes") + .HasForeignKey("HashlistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Chunk"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hash", b => + { + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("Hashes") + .HasForeignKey("ChunkId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("Hashes") + .HasForeignKey("HashlistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Chunk"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AccessGroup", b => + { + b.Navigation("Files"); + + b.Navigation("Hashlists"); + + b.Navigation("RegistrationVouchers"); + + b.Navigation("TaskWrappers"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.Navigation("Assignments"); + + b.Navigation("Chunks"); + + b.Navigation("Errors"); + + b.Navigation("HealthCheckAgents"); + + b.Navigation("Speeds"); + + b.Navigation("Stats"); + + b.Navigation("Zaps"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiGroup", b => + { + b.Navigation("ApiKeys"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.Navigation("BinaryHashes"); + + b.Navigation("Errors"); + + b.Navigation("Hashes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinaryType", b => + { + b.Navigation("CrackerBinaries"); + + b.Navigation("Pretasks"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.Navigation("FileDownloads"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashType", b => + { + b.Navigation("Hashlists"); + + b.Navigation("HealthChecks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.Navigation("BinaryHashes"); + + b.Navigation("Hashes"); + + b.Navigation("TaskWrappers"); + + b.Navigation("Zaps"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.Navigation("HealthCheckAgents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.Navigation("SupertaskPretasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Supertask", b => + { + b.Navigation("SupertaskPretasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.Navigation("AgentErrors"); + + b.Navigation("Assignments"); + + b.Navigation("Chunks"); + + b.Navigation("Speeds"); + + b.Navigation("TaskDebugOutputs"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.User", b => + { + b.Navigation("Agents"); + + b.Navigation("ApiKeys"); + + b.Navigation("NotificationSettings"); + + b.Navigation("Sessions"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.Navigation("HealthChecks"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Preprocessor", b => + { + b.Navigation("Tasks"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/HashSlinger/Migrations/20230701175923_EvenMoreOnDeleteChanges.cs b/HashSlinger/Migrations/20230701175923_EvenMoreOnDeleteChanges.cs new file mode 100644 index 0000000..cda27bd --- /dev/null +++ b/HashSlinger/Migrations/20230701175923_EvenMoreOnDeleteChanges.cs @@ -0,0 +1,87 @@ +#nullable disable + +namespace HashSlinger.Api.Migrations +{ + using Microsoft.EntityFrameworkCore.Migrations; + + /// + public partial class EvenMoreOnDeleteChanges : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Hashlists_HashTypes_HashTypeId", + table: "Hashlists"); + + migrationBuilder.DropForeignKey( + name: "FK_HealthChecks_DownloadableBinaries_CrackerBinaryId", + table: "HealthChecks"); + + migrationBuilder.DropForeignKey( + name: "FK_HealthChecks_HashTypes_HashTypeId", + table: "HealthChecks"); + + migrationBuilder.AddForeignKey( + name: "FK_Hashlists_HashTypes_HashTypeId", + table: "Hashlists", + column: "HashTypeId", + principalTable: "HashTypes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_HealthChecks_DownloadableBinaries_CrackerBinaryId", + table: "HealthChecks", + column: "CrackerBinaryId", + principalTable: "DownloadableBinaries", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + + migrationBuilder.AddForeignKey( + name: "FK_HealthChecks_HashTypes_HashTypeId", + table: "HealthChecks", + column: "HashTypeId", + principalTable: "HashTypes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Hashlists_HashTypes_HashTypeId", + table: "Hashlists"); + + migrationBuilder.DropForeignKey( + name: "FK_HealthChecks_DownloadableBinaries_CrackerBinaryId", + table: "HealthChecks"); + + migrationBuilder.DropForeignKey( + name: "FK_HealthChecks_HashTypes_HashTypeId", + table: "HealthChecks"); + + migrationBuilder.AddForeignKey( + name: "FK_Hashlists_HashTypes_HashTypeId", + table: "Hashlists", + column: "HashTypeId", + principalTable: "HashTypes", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_HealthChecks_DownloadableBinaries_CrackerBinaryId", + table: "HealthChecks", + column: "CrackerBinaryId", + principalTable: "DownloadableBinaries", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_HealthChecks_HashTypes_HashTypeId", + table: "HealthChecks", + column: "HashTypeId", + principalTable: "HashTypes", + principalColumn: "Id"); + } + } +} diff --git a/HashSlinger/Migrations/20230701180247_EvenMoreOnDeleteChanges2.Designer.cs b/HashSlinger/Migrations/20230701180247_EvenMoreOnDeleteChanges2.Designer.cs new file mode 100644 index 0000000..d758f94 --- /dev/null +++ b/HashSlinger/Migrations/20230701180247_EvenMoreOnDeleteChanges2.Designer.cs @@ -0,0 +1,1923 @@ +// + +#nullable disable + +namespace HashSlinger.Api.Migrations +{ + using System.Net; + using Data; + using Microsoft.EntityFrameworkCore; + using Microsoft.EntityFrameworkCore.Infrastructure; + using Microsoft.EntityFrameworkCore.Migrations; + + [DbContext(typeof(HashSlingerContext))] + [Migration("20230701180247_EvenMoreOnDeleteChanges2")] + partial class EvenMoreOnDeleteChanges2 + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("AccessGroupAgent", b => + { + b.Property("AccessGroupsId") + .HasColumnType("integer"); + + b.Property("AgentsId") + .HasColumnType("integer"); + + b.HasKey("AccessGroupsId", "AgentsId"); + + b.HasIndex("AgentsId"); + + b.ToTable("AccessGroupAgent"); + }); + + modelBuilder.Entity("AccessGroupUser", b => + { + b.Property("AccessGroupsId") + .HasColumnType("integer"); + + b.Property("UsersId") + .HasColumnType("integer"); + + b.HasKey("AccessGroupsId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("AccessGroupUser"); + }); + + modelBuilder.Entity("FilePreconfiguredTask", b => + { + b.Property("FilesId") + .HasColumnType("integer"); + + b.Property("PreconfiguredTasksId") + .HasColumnType("integer"); + + b.HasKey("FilesId", "PreconfiguredTasksId"); + + b.HasIndex("PreconfiguredTasksId"); + + b.ToTable("FilePreconfiguredTask"); + }); + + modelBuilder.Entity("FileTask", b => + { + b.Property("FilesId") + .HasColumnType("integer"); + + b.Property("TasksId") + .HasColumnType("integer"); + + b.HasKey("FilesId", "TasksId"); + + b.HasIndex("TasksId"); + + b.ToTable("FileTask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AccessGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("AccessGroups"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClientSignature") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("CommandParameters") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CpuOnly") + .HasColumnType("boolean"); + + b.Property>("Devices") + .HasColumnType("text[]"); + + b.Property("IgnoreErrors") + .HasColumnType("boolean"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("IsTrusted") + .HasColumnType("boolean"); + + b.Property("LastAction") + .HasColumnType("integer"); + + b.Property("LastSeenIpAddress") + .HasColumnType("inet"); + + b.Property("LastSeenTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("OperatingSystem") + .HasColumnType("integer"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.Property("Uid") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("Token"); + + b.HasIndex("Uid"); + + b.HasIndex("UserId"); + + b.ToTable("Agents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentError", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("ChunkId") + .HasColumnType("integer"); + + b.Property("Error") + .IsRequired() + .HasColumnType("text"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("ChunkId"); + + b.HasIndex("TaskId"); + + b.ToTable("AgentError"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentStat", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("StatType") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.ToTable("AgentStat"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Permissions") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("ApiGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessCount") + .HasColumnType("integer"); + + b.Property("AccessKey") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ApiGroupId") + .HasColumnType("integer"); + + b.Property("EndValid") + .HasColumnType("timestamp with time zone"); + + b.Property("StartValid") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ApiGroupId"); + + b.HasIndex("UserId"); + + b.ToTable("ApiKey"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Assignment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Benchmark") + .IsRequired() + .HasColumnType("text"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Assignment"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Checkpoint") + .HasColumnType("numeric(20,0)"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("DispatchTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Length") + .HasColumnType("numeric(20,0)"); + + b.Property("Progress") + .HasColumnType("real"); + + b.Property("Skip") + .HasColumnType("numeric(20,0)"); + + b.Property("SolveTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Speed") + .HasColumnType("numeric(20,0)"); + + b.Property("State") + .HasColumnType("integer"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Chunks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinaryType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IsChunkingAvailable") + .HasColumnType("boolean"); + + b.Property("TypeName") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.HasKey("Id"); + + b.ToTable("CrackerBinaryTypes"); + + b.HasData( + new + { + Id = 1, + IsChunkingAvailable = true, + TypeName = "hashcat" + }); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.DownloadableBinary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("text"); + + b.Property("DownloadUrl") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("Executable") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("FileId") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property>("OperatingSystems") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("Version") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.ToTable("DownloadableBinaries"); + + b.HasDiscriminator("Discriminator").HasValue("DownloadableBinary"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("FileGuid") + .HasColumnType("uuid"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("FileType") + .HasColumnType("integer"); + + b.Property("IsSecret") + .HasColumnType("boolean"); + + b.Property("LineCount") + .HasColumnType("bigint"); + + b.Property("Size") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.ToTable("Files"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDelete", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("FileDeletes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDownload", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FileId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.ToTable("FileDownload"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashBase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ChunkId") + .HasColumnType("integer"); + + b.Property("CrackPos") + .HasColumnType("numeric(20,0)"); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("IsCracked") + .HasColumnType("boolean"); + + b.Property("Plaintext") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("TimeCracked") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("HashBase"); + + b.HasDiscriminator("Discriminator").HasValue("HashBase"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("HashcatId") + .HasColumnType("integer"); + + b.Property("IsSalted") + .HasColumnType("boolean"); + + b.Property("IsSlowHash") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("HashcatId") + .IsUnique(); + + b.ToTable("HashTypes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("BrainFeatures") + .HasColumnType("smallint"); + + b.Property("BrainId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("Format") + .HasColumnType("integer"); + + b.Property("HashCount") + .HasColumnType("integer"); + + b.Property("HashTypeId") + .HasColumnType("uuid"); + + b.Property("HexSalt") + .HasColumnType("boolean"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("IsSalted") + .HasColumnType("boolean"); + + b.Property("IsSecret") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("text"); + + b.Property("SaltSeparator") + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("HashTypeId"); + + b.HasIndex("IsSecret"); + + b.ToTable("Hashlists"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCmd") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CheckType") + .HasColumnType("integer"); + + b.Property("CrackerBinaryId") + .HasColumnType("integer"); + + b.Property("ExpectedCracks") + .HasColumnType("integer"); + + b.Property("HashListAlias") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashTypeId") + .HasColumnType("uuid"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property>("TestHashes") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryId"); + + b.HasIndex("HashTypeId"); + + b.ToTable("HealthChecks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheckAgent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("End") + .HasColumnType("numeric(20,0)"); + + b.Property>("Errors") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("HealthCheckId") + .HasColumnType("integer"); + + b.Property("NumGpus") + .HasColumnType("integer"); + + b.Property("Start") + .HasColumnType("numeric(20,0)"); + + b.Property("Status") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("HealthCheckId"); + + b.ToTable("HealthCheckAgents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.LogEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Issuer") + .IsRequired() + .HasColumnType("text"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("LogEntries"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.NotificationSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("Notification") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("ObjectId") + .HasColumnType("integer"); + + b.Property("Receiver") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationSetting"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCommand") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ChunkTime") + .HasColumnType("integer"); + + b.Property("Color") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.Property("IsCpuTask") + .HasColumnType("boolean"); + + b.Property("IsMaskImport") + .HasColumnType("boolean"); + + b.Property("IsSmall") + .HasColumnType("boolean"); + + b.Property("MaxAgents") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("StatusTimer") + .HasColumnType("integer"); + + b.Property("UseNewBench") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.ToTable("PreconfiguredTask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.RegistrationVoucher", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("Expiration") + .HasColumnType("timestamp with time zone"); + + b.Property("Voucher") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("Voucher") + .IsUnique(); + + b.ToTable("RegistrationVouchers"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Session", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IsOpen") + .HasColumnType("boolean"); + + b.Property("LastActionDate") + .HasColumnType("timestamp with time zone"); + + b.Property("SessionKey") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("SessionLifetime") + .HasColumnType("integer"); + + b.Property("SessionStartDate") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Session"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Speed", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("SpeedValue") + .HasColumnType("numeric(20,0)"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Speed"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Supertask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("Supertask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.SupertaskPretask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("PreconfiguredTaskId") + .HasColumnType("integer"); + + b.Property("PretaskId") + .HasColumnType("integer"); + + b.Property("SupertaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("PreconfiguredTaskId"); + + b.HasIndex("SupertaskId"); + + b.ToTable("SupertaskPretask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCommand") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ChunkSize") + .HasColumnType("integer"); + + b.Property("ChunkTime") + .HasColumnType("integer"); + + b.Property("Color") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CrackerBinaryId") + .HasColumnType("integer"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.Property("EnforcePipe") + .HasColumnType("boolean"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("IsCpuTask") + .HasColumnType("boolean"); + + b.Property("IsSmall") + .HasColumnType("boolean"); + + b.Property("Keyspace") + .HasColumnType("bigint"); + + b.Property("KeyspaceProgress") + .HasColumnType("numeric(20,0)"); + + b.Property("MaxAgents") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("text"); + + b.Property("PreprocessorCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PreprocessorId") + .HasColumnType("integer"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("SkipKeyspace") + .HasColumnType("numeric(20,0)"); + + b.Property("StaticChunks") + .HasColumnType("integer"); + + b.Property("StatusTimer") + .HasColumnType("integer"); + + b.Property("TaskWrapperId") + .HasColumnType("integer"); + + b.Property("UseNewBenchmark") + .HasColumnType("boolean"); + + b.Property("UsePreprocessor") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryId"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.HasIndex("PreprocessorId"); + + b.HasIndex("TaskWrapperId"); + + b.ToTable("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskDebugOutput", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Output") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("TaskId"); + + b.ToTable("TaskDebugOutput"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("TaskType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("HashlistId"); + + b.ToTable("TaskWrapper"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Email") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("IsValid") + .HasColumnType("boolean"); + + b.Property("LastLoginDate") + .HasColumnType("timestamp with time zone"); + + b.Property("PasswordHash") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordSalt") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("RegisteredSince") + .HasColumnType("timestamp with time zone"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Zap", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Hash") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("SolveTime") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("HashlistId"); + + b.ToTable("Zap"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentBinary", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("UpdateAvailable") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("UpdateTrack") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.HasIndex("Type"); + + b.HasDiscriminator().HasValue("AgentBinary"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.HasDiscriminator().HasValue("CrackerBinary"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Preprocessor", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("KeyspaceCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("LimitCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("SkipCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasDiscriminator().HasValue("Preprocessor"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.BinaryHash", b => + { + b.HasBaseType("HashSlinger.Shared.Models.HashBase"); + + b.Property("Essid") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashBytes") + .IsRequired() + .HasColumnType("bytea"); + + b.HasIndex("ChunkId"); + + b.HasIndex("HashlistId"); + + b.HasIndex("IsCracked"); + + b.HasDiscriminator().HasValue("BinaryHash"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hash", b => + { + b.HasBaseType("HashSlinger.Shared.Models.HashBase"); + + b.Property("HashValue") + .IsRequired() + .HasColumnType("text"); + + b.Property("Salt") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasIndex("ChunkId"); + + b.HasIndex("HashlistId"); + + b.HasIndex("IsCracked"); + + b.HasDiscriminator().HasValue("Hash"); + }); + + modelBuilder.Entity("AccessGroupAgent", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", null) + .WithMany() + .HasForeignKey("AccessGroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Agent", null) + .WithMany() + .HasForeignKey("AgentsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AccessGroupUser", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", null) + .WithMany() + .HasForeignKey("AccessGroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("FilePreconfiguredTask", b => + { + b.HasOne("HashSlinger.Shared.Models.File", null) + .WithMany() + .HasForeignKey("FilesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.PreconfiguredTask", null) + .WithMany() + .HasForeignKey("PreconfiguredTasksId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("FileTask", b => + { + b.HasOne("HashSlinger.Shared.Models.File", null) + .WithMany() + .HasForeignKey("FilesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", null) + .WithMany() + .HasForeignKey("TasksId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("Agents") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentError", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Errors") + .HasForeignKey("AgentId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("Errors") + .HasForeignKey("ChunkId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("AgentErrors") + .HasForeignKey("TaskId"); + + b.Navigation("Agent"); + + b.Navigation("Chunk"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentStat", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Stats") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiKey", b => + { + b.HasOne("HashSlinger.Shared.Models.ApiGroup", "ApiGroup") + .WithMany("ApiKeys") + .HasForeignKey("ApiGroupId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("ApiKeys") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ApiGroup"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Assignment", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Assignments") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Assignments") + .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Chunks") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Chunks") + .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.DownloadableBinary", b => + { + b.HasOne("HashSlinger.Shared.Models.File", "File") + .WithMany() + .HasForeignKey("FileId"); + + b.Navigation("File"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("Files") + .HasForeignKey("AccessGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AccessGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDownload", b => + { + b.HasOne("HashSlinger.Shared.Models.File", "File") + .WithMany("FileDownloads") + .HasForeignKey("FileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("File"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("Hashlists") + .HasForeignKey("AccessGroupId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HashType", "HashType") + .WithMany("Hashlists") + .HasForeignKey("HashTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AccessGroup"); + + b.Navigation("HashType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinary", "CrackerBinary") + .WithMany("HealthChecks") + .HasForeignKey("CrackerBinaryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HashType", "HashType") + .WithMany("HealthChecks") + .HasForeignKey("HashTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CrackerBinary"); + + b.Navigation("HashType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheckAgent", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("HealthCheckAgents") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HealthCheck", "HealthCheck") + .WithMany("HealthCheckAgents") + .HasForeignKey("HealthCheckId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("HealthCheck"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.NotificationSetting", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("NotificationSettings") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("Pretasks") + .HasForeignKey("CrackerBinaryTypeId") + .IsRequired(); + + b.Navigation("CrackerBinaryType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.RegistrationVoucher", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("RegistrationVouchers") + .HasForeignKey("AccessGroupId"); + + b.Navigation("AccessGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Session", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("Sessions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Speed", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Speeds") + .HasForeignKey("AgentId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Speeds") + .HasForeignKey("TaskId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.SupertaskPretask", b => + { + b.HasOne("HashSlinger.Shared.Models.PreconfiguredTask", "PreconfiguredTask") + .WithMany("SupertaskPretasks") + .HasForeignKey("PreconfiguredTaskId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Supertask", "Supertask") + .WithMany("SupertaskPretasks") + .HasForeignKey("SupertaskId") + .IsRequired(); + + b.Navigation("PreconfiguredTask"); + + b.Navigation("Supertask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinary", "CrackerBinary") + .WithMany("Tasks") + .HasForeignKey("CrackerBinaryId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("Tasks") + .HasForeignKey("CrackerBinaryTypeId"); + + b.HasOne("HashSlinger.Shared.Models.Preprocessor", "Preprocessor") + .WithMany("Tasks") + .HasForeignKey("PreprocessorId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.TaskWrapper", "TaskWrapper") + .WithMany("Tasks") + .HasForeignKey("TaskWrapperId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CrackerBinary"); + + b.Navigation("CrackerBinaryType"); + + b.Navigation("Preprocessor"); + + b.Navigation("TaskWrapper"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskDebugOutput", b => + { + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("TaskDebugOutputs") + .HasForeignKey("TaskId") + .IsRequired(); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("TaskWrappers") + .HasForeignKey("AccessGroupId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("TaskWrappers") + .HasForeignKey("HashlistId") + .IsRequired(); + + b.Navigation("AccessGroup"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Zap", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Zaps") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("Zaps") + .HasForeignKey("HashlistId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("CrackerBinaries") + .HasForeignKey("CrackerBinaryTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CrackerBinaryType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.BinaryHash", b => + { + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("BinaryHashes") + .HasForeignKey("ChunkId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("BinaryHashes") + .HasForeignKey("HashlistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Chunk"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hash", b => + { + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("Hashes") + .HasForeignKey("ChunkId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("Hashes") + .HasForeignKey("HashlistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Chunk"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AccessGroup", b => + { + b.Navigation("Files"); + + b.Navigation("Hashlists"); + + b.Navigation("RegistrationVouchers"); + + b.Navigation("TaskWrappers"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.Navigation("Assignments"); + + b.Navigation("Chunks"); + + b.Navigation("Errors"); + + b.Navigation("HealthCheckAgents"); + + b.Navigation("Speeds"); + + b.Navigation("Stats"); + + b.Navigation("Zaps"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiGroup", b => + { + b.Navigation("ApiKeys"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.Navigation("BinaryHashes"); + + b.Navigation("Errors"); + + b.Navigation("Hashes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinaryType", b => + { + b.Navigation("CrackerBinaries"); + + b.Navigation("Pretasks"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.Navigation("FileDownloads"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashType", b => + { + b.Navigation("Hashlists"); + + b.Navigation("HealthChecks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.Navigation("BinaryHashes"); + + b.Navigation("Hashes"); + + b.Navigation("TaskWrappers"); + + b.Navigation("Zaps"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.Navigation("HealthCheckAgents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.Navigation("SupertaskPretasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Supertask", b => + { + b.Navigation("SupertaskPretasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.Navigation("AgentErrors"); + + b.Navigation("Assignments"); + + b.Navigation("Chunks"); + + b.Navigation("Speeds"); + + b.Navigation("TaskDebugOutputs"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.User", b => + { + b.Navigation("Agents"); + + b.Navigation("ApiKeys"); + + b.Navigation("NotificationSettings"); + + b.Navigation("Sessions"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.Navigation("HealthChecks"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Preprocessor", b => + { + b.Navigation("Tasks"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/HashSlinger/Migrations/20230701180247_EvenMoreOnDeleteChanges2.cs b/HashSlinger/Migrations/20230701180247_EvenMoreOnDeleteChanges2.cs new file mode 100644 index 0000000..0a5344f --- /dev/null +++ b/HashSlinger/Migrations/20230701180247_EvenMoreOnDeleteChanges2.cs @@ -0,0 +1,65 @@ +#nullable disable + +namespace HashSlinger.Api.Migrations +{ + using Microsoft.EntityFrameworkCore.Migrations; + + /// + public partial class EvenMoreOnDeleteChanges2 : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Agents_Users_UserId", + table: "Agents"); + + migrationBuilder.DropForeignKey( + name: "FK_Tasks_TaskWrapper_TaskWrapperId", + table: "Tasks"); + + migrationBuilder.AddForeignKey( + name: "FK_Agents_Users_UserId", + table: "Agents", + column: "UserId", + principalTable: "Users", + principalColumn: "Id", + onDelete: ReferentialAction.SetNull); + + migrationBuilder.AddForeignKey( + name: "FK_Tasks_TaskWrapper_TaskWrapperId", + table: "Tasks", + column: "TaskWrapperId", + principalTable: "TaskWrapper", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_Agents_Users_UserId", + table: "Agents"); + + migrationBuilder.DropForeignKey( + name: "FK_Tasks_TaskWrapper_TaskWrapperId", + table: "Tasks"); + + migrationBuilder.AddForeignKey( + name: "FK_Agents_Users_UserId", + table: "Agents", + column: "UserId", + principalTable: "Users", + principalColumn: "Id"); + + migrationBuilder.AddForeignKey( + name: "FK_Tasks_TaskWrapper_TaskWrapperId", + table: "Tasks", + column: "TaskWrapperId", + principalTable: "TaskWrapper", + principalColumn: "Id", + onDelete: ReferentialAction.SetNull); + } + } +} diff --git a/HashSlinger/Migrations/20230712212853_UpdateDelete.Designer.cs b/HashSlinger/Migrations/20230712212853_UpdateDelete.Designer.cs new file mode 100644 index 0000000..6a07b85 --- /dev/null +++ b/HashSlinger/Migrations/20230712212853_UpdateDelete.Designer.cs @@ -0,0 +1,1924 @@ +// + +#nullable disable + +namespace HashSlinger.Api.Migrations +{ + using System.Net; + using Data; + using Microsoft.EntityFrameworkCore; + using Microsoft.EntityFrameworkCore.Infrastructure; + using Microsoft.EntityFrameworkCore.Migrations; + + [DbContext(typeof(HashSlingerContext))] + [Migration("20230712212853_UpdateDelete")] + partial class UpdateDelete + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("AccessGroupAgent", b => + { + b.Property("AccessGroupsId") + .HasColumnType("integer"); + + b.Property("AgentsId") + .HasColumnType("integer"); + + b.HasKey("AccessGroupsId", "AgentsId"); + + b.HasIndex("AgentsId"); + + b.ToTable("AccessGroupAgent"); + }); + + modelBuilder.Entity("AccessGroupUser", b => + { + b.Property("AccessGroupsId") + .HasColumnType("integer"); + + b.Property("UsersId") + .HasColumnType("integer"); + + b.HasKey("AccessGroupsId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("AccessGroupUser"); + }); + + modelBuilder.Entity("FilePreconfiguredTask", b => + { + b.Property("FilesId") + .HasColumnType("integer"); + + b.Property("PreconfiguredTasksId") + .HasColumnType("integer"); + + b.HasKey("FilesId", "PreconfiguredTasksId"); + + b.HasIndex("PreconfiguredTasksId"); + + b.ToTable("FilePreconfiguredTask"); + }); + + modelBuilder.Entity("FileTask", b => + { + b.Property("FilesId") + .HasColumnType("integer"); + + b.Property("TasksId") + .HasColumnType("integer"); + + b.HasKey("FilesId", "TasksId"); + + b.HasIndex("TasksId"); + + b.ToTable("FileTask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AccessGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("AccessGroups"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClientSignature") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("CommandParameters") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CpuOnly") + .HasColumnType("boolean"); + + b.Property>("Devices") + .HasColumnType("text[]"); + + b.Property("IgnoreErrors") + .HasColumnType("boolean"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("IsTrusted") + .HasColumnType("boolean"); + + b.Property("LastAction") + .HasColumnType("integer"); + + b.Property("LastSeenIpAddress") + .HasColumnType("inet"); + + b.Property("LastSeenTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("OperatingSystem") + .HasColumnType("integer"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.Property("Uid") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("Token"); + + b.HasIndex("Uid"); + + b.HasIndex("UserId"); + + b.ToTable("Agents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentError", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("ChunkId") + .HasColumnType("integer"); + + b.Property("Error") + .IsRequired() + .HasColumnType("text"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("ChunkId"); + + b.HasIndex("TaskId"); + + b.ToTable("AgentError"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentStat", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("StatType") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.ToTable("AgentStat"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Permissions") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("ApiGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessCount") + .HasColumnType("integer"); + + b.Property("AccessKey") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ApiGroupId") + .HasColumnType("integer"); + + b.Property("EndValid") + .HasColumnType("timestamp with time zone"); + + b.Property("StartValid") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ApiGroupId"); + + b.HasIndex("UserId"); + + b.ToTable("ApiKey"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Assignment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Benchmark") + .IsRequired() + .HasColumnType("text"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Assignment"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Checkpoint") + .HasColumnType("numeric(20,0)"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("DispatchTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Length") + .HasColumnType("numeric(20,0)"); + + b.Property("Progress") + .HasColumnType("real"); + + b.Property("Skip") + .HasColumnType("numeric(20,0)"); + + b.Property("SolveTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Speed") + .HasColumnType("numeric(20,0)"); + + b.Property("State") + .HasColumnType("integer"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Chunks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinaryType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IsChunkingAvailable") + .HasColumnType("boolean"); + + b.Property("TypeName") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.HasKey("Id"); + + b.ToTable("CrackerBinaryTypes"); + + b.HasData( + new + { + Id = 1, + IsChunkingAvailable = true, + TypeName = "hashcat" + }); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.DownloadableBinary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("text"); + + b.Property("DownloadUrl") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("Executable") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("FileId") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property>("OperatingSystems") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("Version") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.ToTable("DownloadableBinaries"); + + b.HasDiscriminator("Discriminator").HasValue("DownloadableBinary"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("FileGuid") + .HasColumnType("uuid"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("FileType") + .HasColumnType("integer"); + + b.Property("IsSecret") + .HasColumnType("boolean"); + + b.Property("LineCount") + .HasColumnType("bigint"); + + b.Property("Size") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.ToTable("Files"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDelete", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("FileDeletes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDownload", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FileId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.ToTable("FileDownload"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashBase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ChunkId") + .HasColumnType("integer"); + + b.Property("CrackPos") + .HasColumnType("numeric(20,0)"); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("IsCracked") + .HasColumnType("boolean"); + + b.Property("Plaintext") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("TimeCracked") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("HashBase"); + + b.HasDiscriminator("Discriminator").HasValue("HashBase"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("HashcatId") + .HasColumnType("integer"); + + b.Property("IsSalted") + .HasColumnType("boolean"); + + b.Property("IsSlowHash") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("HashcatId") + .IsUnique(); + + b.ToTable("HashTypes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("BrainFeatures") + .HasColumnType("smallint"); + + b.Property("BrainId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("Format") + .HasColumnType("integer"); + + b.Property("HashCount") + .HasColumnType("integer"); + + b.Property("HashTypeId") + .HasColumnType("uuid"); + + b.Property("HexSalt") + .HasColumnType("boolean"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("IsSalted") + .HasColumnType("boolean"); + + b.Property("IsSecret") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("text"); + + b.Property("SaltSeparator") + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("HashTypeId"); + + b.HasIndex("IsSecret"); + + b.ToTable("Hashlists"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCmd") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CheckType") + .HasColumnType("integer"); + + b.Property("CrackerBinaryId") + .HasColumnType("integer"); + + b.Property("ExpectedCracks") + .HasColumnType("integer"); + + b.Property("HashListAlias") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashTypeId") + .HasColumnType("uuid"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property>("TestHashes") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryId"); + + b.HasIndex("HashTypeId"); + + b.ToTable("HealthChecks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheckAgent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("End") + .HasColumnType("numeric(20,0)"); + + b.Property>("Errors") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("HealthCheckId") + .HasColumnType("integer"); + + b.Property("NumGpus") + .HasColumnType("integer"); + + b.Property("Start") + .HasColumnType("numeric(20,0)"); + + b.Property("Status") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("HealthCheckId"); + + b.ToTable("HealthCheckAgents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.LogEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Issuer") + .IsRequired() + .HasColumnType("text"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("LogEntries"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.NotificationSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("Notification") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("ObjectId") + .HasColumnType("integer"); + + b.Property("Receiver") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationSetting"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCommand") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ChunkTime") + .HasColumnType("integer"); + + b.Property("Color") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.Property("IsCpuTask") + .HasColumnType("boolean"); + + b.Property("IsMaskImport") + .HasColumnType("boolean"); + + b.Property("IsSmall") + .HasColumnType("boolean"); + + b.Property("MaxAgents") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("StatusTimer") + .HasColumnType("integer"); + + b.Property("UseNewBench") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.ToTable("PreconfiguredTask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.RegistrationVoucher", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("Expiration") + .HasColumnType("timestamp with time zone"); + + b.Property("Voucher") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("Voucher") + .IsUnique(); + + b.ToTable("RegistrationVouchers"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Session", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IsOpen") + .HasColumnType("boolean"); + + b.Property("LastActionDate") + .HasColumnType("timestamp with time zone"); + + b.Property("SessionKey") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("SessionLifetime") + .HasColumnType("integer"); + + b.Property("SessionStartDate") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Session"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Speed", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("SpeedValue") + .HasColumnType("numeric(20,0)"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Speed"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Supertask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("Supertask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.SupertaskPretask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("PreconfiguredTaskId") + .HasColumnType("integer"); + + b.Property("PretaskId") + .HasColumnType("integer"); + + b.Property("SupertaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("PreconfiguredTaskId"); + + b.HasIndex("SupertaskId"); + + b.ToTable("SupertaskPretask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCommand") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ChunkSize") + .HasColumnType("integer"); + + b.Property("ChunkTime") + .HasColumnType("integer"); + + b.Property("Color") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CrackerBinaryId") + .HasColumnType("integer"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.Property("EnforcePipe") + .HasColumnType("boolean"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("IsCpuTask") + .HasColumnType("boolean"); + + b.Property("IsSmall") + .HasColumnType("boolean"); + + b.Property("Keyspace") + .HasColumnType("bigint"); + + b.Property("KeyspaceProgress") + .HasColumnType("numeric(20,0)"); + + b.Property("MaxAgents") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("text"); + + b.Property("PreprocessorCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PreprocessorId") + .HasColumnType("integer"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("SkipKeyspace") + .HasColumnType("numeric(20,0)"); + + b.Property("StaticChunks") + .HasColumnType("integer"); + + b.Property("StatusTimer") + .HasColumnType("integer"); + + b.Property("TaskWrapperId") + .HasColumnType("integer"); + + b.Property("UseNewBenchmark") + .HasColumnType("boolean"); + + b.Property("UsePreprocessor") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryId"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.HasIndex("PreprocessorId"); + + b.HasIndex("TaskWrapperId"); + + b.ToTable("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskDebugOutput", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Output") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("TaskId"); + + b.ToTable("TaskDebugOutput"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("TaskType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("HashlistId"); + + b.ToTable("TaskWrapper"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Email") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("IsValid") + .HasColumnType("boolean"); + + b.Property("LastLoginDate") + .HasColumnType("timestamp with time zone"); + + b.Property("PasswordHash") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordSalt") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("RegisteredSince") + .HasColumnType("timestamp with time zone"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Zap", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Hash") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("SolveTime") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("HashlistId"); + + b.ToTable("Zap"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentBinary", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("UpdateAvailable") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("UpdateTrack") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.HasIndex("Type"); + + b.HasDiscriminator().HasValue("AgentBinary"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.HasDiscriminator().HasValue("CrackerBinary"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Preprocessor", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("KeyspaceCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("LimitCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("SkipCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasDiscriminator().HasValue("Preprocessor"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.BinaryHash", b => + { + b.HasBaseType("HashSlinger.Shared.Models.HashBase"); + + b.Property("Essid") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashBytes") + .IsRequired() + .HasColumnType("bytea"); + + b.HasIndex("ChunkId"); + + b.HasIndex("HashlistId"); + + b.HasIndex("IsCracked"); + + b.HasDiscriminator().HasValue("BinaryHash"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hash", b => + { + b.HasBaseType("HashSlinger.Shared.Models.HashBase"); + + b.Property("HashValue") + .IsRequired() + .HasColumnType("text"); + + b.Property("Salt") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasIndex("ChunkId"); + + b.HasIndex("HashlistId"); + + b.HasIndex("IsCracked"); + + b.HasDiscriminator().HasValue("Hash"); + }); + + modelBuilder.Entity("AccessGroupAgent", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", null) + .WithMany() + .HasForeignKey("AccessGroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Agent", null) + .WithMany() + .HasForeignKey("AgentsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AccessGroupUser", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", null) + .WithMany() + .HasForeignKey("AccessGroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("FilePreconfiguredTask", b => + { + b.HasOne("HashSlinger.Shared.Models.File", null) + .WithMany() + .HasForeignKey("FilesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.PreconfiguredTask", null) + .WithMany() + .HasForeignKey("PreconfiguredTasksId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("FileTask", b => + { + b.HasOne("HashSlinger.Shared.Models.File", null) + .WithMany() + .HasForeignKey("FilesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", null) + .WithMany() + .HasForeignKey("TasksId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("Agents") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentError", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Errors") + .HasForeignKey("AgentId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("Errors") + .HasForeignKey("ChunkId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("AgentErrors") + .HasForeignKey("TaskId"); + + b.Navigation("Agent"); + + b.Navigation("Chunk"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentStat", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Stats") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiKey", b => + { + b.HasOne("HashSlinger.Shared.Models.ApiGroup", "ApiGroup") + .WithMany("ApiKeys") + .HasForeignKey("ApiGroupId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("ApiKeys") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ApiGroup"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Assignment", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Assignments") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Assignments") + .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Chunks") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Chunks") + .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.DownloadableBinary", b => + { + b.HasOne("HashSlinger.Shared.Models.File", "File") + .WithMany() + .HasForeignKey("FileId"); + + b.Navigation("File"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("Files") + .HasForeignKey("AccessGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AccessGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDownload", b => + { + b.HasOne("HashSlinger.Shared.Models.File", "File") + .WithMany("FileDownloads") + .HasForeignKey("FileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("File"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("Hashlists") + .HasForeignKey("AccessGroupId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HashType", "HashType") + .WithMany("Hashlists") + .HasForeignKey("HashTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AccessGroup"); + + b.Navigation("HashType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinary", "CrackerBinary") + .WithMany("HealthChecks") + .HasForeignKey("CrackerBinaryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HashType", "HashType") + .WithMany("HealthChecks") + .HasForeignKey("HashTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CrackerBinary"); + + b.Navigation("HashType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheckAgent", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("HealthCheckAgents") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HealthCheck", "HealthCheck") + .WithMany("HealthCheckAgents") + .HasForeignKey("HealthCheckId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("HealthCheck"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.NotificationSetting", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("NotificationSettings") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("Pretasks") + .HasForeignKey("CrackerBinaryTypeId") + .IsRequired(); + + b.Navigation("CrackerBinaryType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.RegistrationVoucher", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("RegistrationVouchers") + .HasForeignKey("AccessGroupId"); + + b.Navigation("AccessGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Session", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("Sessions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Speed", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Speeds") + .HasForeignKey("AgentId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Speeds") + .HasForeignKey("TaskId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.SupertaskPretask", b => + { + b.HasOne("HashSlinger.Shared.Models.PreconfiguredTask", "PreconfiguredTask") + .WithMany("SupertaskPretasks") + .HasForeignKey("PreconfiguredTaskId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Supertask", "Supertask") + .WithMany("SupertaskPretasks") + .HasForeignKey("SupertaskId") + .IsRequired(); + + b.Navigation("PreconfiguredTask"); + + b.Navigation("Supertask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinary", "CrackerBinary") + .WithMany("Tasks") + .HasForeignKey("CrackerBinaryId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("Tasks") + .HasForeignKey("CrackerBinaryTypeId"); + + b.HasOne("HashSlinger.Shared.Models.Preprocessor", "Preprocessor") + .WithMany("Tasks") + .HasForeignKey("PreprocessorId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.TaskWrapper", "TaskWrapper") + .WithMany("Tasks") + .HasForeignKey("TaskWrapperId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CrackerBinary"); + + b.Navigation("CrackerBinaryType"); + + b.Navigation("Preprocessor"); + + b.Navigation("TaskWrapper"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskDebugOutput", b => + { + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("TaskDebugOutputs") + .HasForeignKey("TaskId") + .IsRequired(); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("TaskWrappers") + .HasForeignKey("AccessGroupId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("TaskWrappers") + .HasForeignKey("HashlistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AccessGroup"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Zap", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Zaps") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("Zaps") + .HasForeignKey("HashlistId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("CrackerBinaries") + .HasForeignKey("CrackerBinaryTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CrackerBinaryType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.BinaryHash", b => + { + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("BinaryHashes") + .HasForeignKey("ChunkId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("BinaryHashes") + .HasForeignKey("HashlistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Chunk"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hash", b => + { + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("Hashes") + .HasForeignKey("ChunkId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("Hashes") + .HasForeignKey("HashlistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Chunk"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AccessGroup", b => + { + b.Navigation("Files"); + + b.Navigation("Hashlists"); + + b.Navigation("RegistrationVouchers"); + + b.Navigation("TaskWrappers"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.Navigation("Assignments"); + + b.Navigation("Chunks"); + + b.Navigation("Errors"); + + b.Navigation("HealthCheckAgents"); + + b.Navigation("Speeds"); + + b.Navigation("Stats"); + + b.Navigation("Zaps"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiGroup", b => + { + b.Navigation("ApiKeys"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.Navigation("BinaryHashes"); + + b.Navigation("Errors"); + + b.Navigation("Hashes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinaryType", b => + { + b.Navigation("CrackerBinaries"); + + b.Navigation("Pretasks"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.Navigation("FileDownloads"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashType", b => + { + b.Navigation("Hashlists"); + + b.Navigation("HealthChecks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.Navigation("BinaryHashes"); + + b.Navigation("Hashes"); + + b.Navigation("TaskWrappers"); + + b.Navigation("Zaps"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.Navigation("HealthCheckAgents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.Navigation("SupertaskPretasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Supertask", b => + { + b.Navigation("SupertaskPretasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.Navigation("AgentErrors"); + + b.Navigation("Assignments"); + + b.Navigation("Chunks"); + + b.Navigation("Speeds"); + + b.Navigation("TaskDebugOutputs"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.User", b => + { + b.Navigation("Agents"); + + b.Navigation("ApiKeys"); + + b.Navigation("NotificationSettings"); + + b.Navigation("Sessions"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.Navigation("HealthChecks"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Preprocessor", b => + { + b.Navigation("Tasks"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/HashSlinger/Migrations/20230712212853_UpdateDelete.cs b/HashSlinger/Migrations/20230712212853_UpdateDelete.cs new file mode 100644 index 0000000..b2767c5 --- /dev/null +++ b/HashSlinger/Migrations/20230712212853_UpdateDelete.cs @@ -0,0 +1,41 @@ +#nullable disable + +namespace HashSlinger.Api.Migrations +{ + using Microsoft.EntityFrameworkCore.Migrations; + + /// + public partial class UpdateDelete : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_TaskWrapper_Hashlists_HashlistId", + table: "TaskWrapper"); + + migrationBuilder.AddForeignKey( + name: "FK_TaskWrapper_Hashlists_HashlistId", + table: "TaskWrapper", + column: "HashlistId", + principalTable: "Hashlists", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_TaskWrapper_Hashlists_HashlistId", + table: "TaskWrapper"); + + migrationBuilder.AddForeignKey( + name: "FK_TaskWrapper_Hashlists_HashlistId", + table: "TaskWrapper", + column: "HashlistId", + principalTable: "Hashlists", + principalColumn: "Id"); + } + } +} diff --git a/HashSlinger/Migrations/20230712222549_CleanedUpFiles.Designer.cs b/HashSlinger/Migrations/20230712222549_CleanedUpFiles.Designer.cs new file mode 100644 index 0000000..62409f7 --- /dev/null +++ b/HashSlinger/Migrations/20230712222549_CleanedUpFiles.Designer.cs @@ -0,0 +1,1924 @@ +// + +#nullable disable + +namespace HashSlinger.Api.Migrations +{ + using System.Net; + using Data; + using Microsoft.EntityFrameworkCore; + using Microsoft.EntityFrameworkCore.Infrastructure; + using Microsoft.EntityFrameworkCore.Migrations; + + [DbContext(typeof(HashSlingerContext))] + [Migration("20230712222549_CleanedUpFiles")] + partial class CleanedUpFiles + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.7") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("AccessGroupAgent", b => + { + b.Property("AccessGroupsId") + .HasColumnType("integer"); + + b.Property("AgentsId") + .HasColumnType("integer"); + + b.HasKey("AccessGroupsId", "AgentsId"); + + b.HasIndex("AgentsId"); + + b.ToTable("AccessGroupAgent"); + }); + + modelBuilder.Entity("AccessGroupUser", b => + { + b.Property("AccessGroupsId") + .HasColumnType("integer"); + + b.Property("UsersId") + .HasColumnType("integer"); + + b.HasKey("AccessGroupsId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("AccessGroupUser"); + }); + + modelBuilder.Entity("FilePreconfiguredTask", b => + { + b.Property("FilesId") + .HasColumnType("integer"); + + b.Property("PreconfiguredTasksId") + .HasColumnType("integer"); + + b.HasKey("FilesId", "PreconfiguredTasksId"); + + b.HasIndex("PreconfiguredTasksId"); + + b.ToTable("FilePreconfiguredTask"); + }); + + modelBuilder.Entity("FileTask", b => + { + b.Property("FilesId") + .HasColumnType("integer"); + + b.Property("TasksId") + .HasColumnType("integer"); + + b.HasKey("FilesId", "TasksId"); + + b.HasIndex("TasksId"); + + b.ToTable("FileTask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AccessGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("AccessGroups"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClientSignature") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("CommandParameters") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CpuOnly") + .HasColumnType("boolean"); + + b.Property>("Devices") + .HasColumnType("text[]"); + + b.Property("IgnoreErrors") + .HasColumnType("boolean"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("IsTrusted") + .HasColumnType("boolean"); + + b.Property("LastAction") + .HasColumnType("integer"); + + b.Property("LastSeenIpAddress") + .HasColumnType("inet"); + + b.Property("LastSeenTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("OperatingSystem") + .HasColumnType("integer"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.Property("Uid") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("Token"); + + b.HasIndex("Uid"); + + b.HasIndex("UserId"); + + b.ToTable("Agents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentError", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("ChunkId") + .HasColumnType("integer"); + + b.Property("Error") + .IsRequired() + .HasColumnType("text"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("ChunkId"); + + b.HasIndex("TaskId"); + + b.ToTable("AgentError"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentStat", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("StatType") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.ToTable("AgentStat"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Permissions") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("ApiGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessCount") + .HasColumnType("integer"); + + b.Property("AccessKey") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ApiGroupId") + .HasColumnType("integer"); + + b.Property("EndValid") + .HasColumnType("timestamp with time zone"); + + b.Property("StartValid") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ApiGroupId"); + + b.HasIndex("UserId"); + + b.ToTable("ApiKey"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Assignment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Benchmark") + .IsRequired() + .HasColumnType("text"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Assignment"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Checkpoint") + .HasColumnType("numeric(20,0)"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("DispatchTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Length") + .HasColumnType("numeric(20,0)"); + + b.Property("Progress") + .HasColumnType("real"); + + b.Property("Skip") + .HasColumnType("numeric(20,0)"); + + b.Property("SolveTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Speed") + .HasColumnType("numeric(20,0)"); + + b.Property("State") + .HasColumnType("integer"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Chunks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinaryType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IsChunkingAvailable") + .HasColumnType("boolean"); + + b.Property("TypeName") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.HasKey("Id"); + + b.ToTable("CrackerBinaryTypes"); + + b.HasData( + new + { + Id = 1, + IsChunkingAvailable = true, + TypeName = "hashcat" + }); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.DownloadableBinary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("text"); + + b.Property("DownloadUrl") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("Executable") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("FileId") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property>("OperatingSystems") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("Version") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.ToTable("DownloadableBinaries"); + + b.HasDiscriminator("Discriminator").HasValue("DownloadableBinary"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("FileGuid") + .HasColumnType("uuid"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("FileType") + .HasColumnType("integer"); + + b.Property("IsSecret") + .HasColumnType("boolean"); + + b.Property("LineCount") + .HasColumnType("integer"); + + b.Property("Size") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.ToTable("Files"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDelete", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("FileDeletes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDownload", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FileId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.ToTable("FileDownload"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashBase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ChunkId") + .HasColumnType("integer"); + + b.Property("CrackPos") + .HasColumnType("numeric(20,0)"); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("IsCracked") + .HasColumnType("boolean"); + + b.Property("Plaintext") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("TimeCracked") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("HashBase"); + + b.HasDiscriminator("Discriminator").HasValue("HashBase"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("HashcatId") + .HasColumnType("integer"); + + b.Property("IsSalted") + .HasColumnType("boolean"); + + b.Property("IsSlowHash") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("HashcatId") + .IsUnique(); + + b.ToTable("HashTypes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("BrainFeatures") + .HasColumnType("smallint"); + + b.Property("BrainId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("Format") + .HasColumnType("integer"); + + b.Property("HashCount") + .HasColumnType("integer"); + + b.Property("HashTypeId") + .HasColumnType("uuid"); + + b.Property("HexSalt") + .HasColumnType("boolean"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("IsSalted") + .HasColumnType("boolean"); + + b.Property("IsSecret") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("text"); + + b.Property("SaltSeparator") + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("HashTypeId"); + + b.HasIndex("IsSecret"); + + b.ToTable("Hashlists"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCmd") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CheckType") + .HasColumnType("integer"); + + b.Property("CrackerBinaryId") + .HasColumnType("integer"); + + b.Property("ExpectedCracks") + .HasColumnType("integer"); + + b.Property("HashListAlias") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashTypeId") + .HasColumnType("uuid"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property>("TestHashes") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryId"); + + b.HasIndex("HashTypeId"); + + b.ToTable("HealthChecks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheckAgent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("End") + .HasColumnType("numeric(20,0)"); + + b.Property>("Errors") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("HealthCheckId") + .HasColumnType("integer"); + + b.Property("NumGpus") + .HasColumnType("integer"); + + b.Property("Start") + .HasColumnType("numeric(20,0)"); + + b.Property("Status") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("HealthCheckId"); + + b.ToTable("HealthCheckAgents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.LogEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Issuer") + .IsRequired() + .HasColumnType("text"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("LogEntries"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.NotificationSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("Notification") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("ObjectId") + .HasColumnType("integer"); + + b.Property("Receiver") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationSetting"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCommand") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ChunkTime") + .HasColumnType("integer"); + + b.Property("Color") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.Property("IsCpuTask") + .HasColumnType("boolean"); + + b.Property("IsMaskImport") + .HasColumnType("boolean"); + + b.Property("IsSmall") + .HasColumnType("boolean"); + + b.Property("MaxAgents") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("StatusTimer") + .HasColumnType("integer"); + + b.Property("UseNewBench") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.ToTable("PreconfiguredTask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.RegistrationVoucher", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("Expiration") + .HasColumnType("timestamp with time zone"); + + b.Property("Voucher") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("Voucher") + .IsUnique(); + + b.ToTable("RegistrationVouchers"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Session", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IsOpen") + .HasColumnType("boolean"); + + b.Property("LastActionDate") + .HasColumnType("timestamp with time zone"); + + b.Property("SessionKey") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("SessionLifetime") + .HasColumnType("integer"); + + b.Property("SessionStartDate") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Session"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Speed", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("SpeedValue") + .HasColumnType("numeric(20,0)"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Speed"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Supertask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("Supertask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.SupertaskPretask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("PreconfiguredTaskId") + .HasColumnType("integer"); + + b.Property("PretaskId") + .HasColumnType("integer"); + + b.Property("SupertaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("PreconfiguredTaskId"); + + b.HasIndex("SupertaskId"); + + b.ToTable("SupertaskPretask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCommand") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ChunkSize") + .HasColumnType("integer"); + + b.Property("ChunkTime") + .HasColumnType("integer"); + + b.Property("Color") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CrackerBinaryId") + .HasColumnType("integer"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.Property("EnforcePipe") + .HasColumnType("boolean"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("IsCpuTask") + .HasColumnType("boolean"); + + b.Property("IsSmall") + .HasColumnType("boolean"); + + b.Property("Keyspace") + .HasColumnType("bigint"); + + b.Property("KeyspaceProgress") + .HasColumnType("numeric(20,0)"); + + b.Property("MaxAgents") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("text"); + + b.Property("PreprocessorCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PreprocessorId") + .HasColumnType("integer"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("SkipKeyspace") + .HasColumnType("numeric(20,0)"); + + b.Property("StaticChunks") + .HasColumnType("integer"); + + b.Property("StatusTimer") + .HasColumnType("integer"); + + b.Property("TaskWrapperId") + .HasColumnType("integer"); + + b.Property("UseNewBenchmark") + .HasColumnType("boolean"); + + b.Property("UsePreprocessor") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryId"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.HasIndex("PreprocessorId"); + + b.HasIndex("TaskWrapperId"); + + b.ToTable("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskDebugOutput", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Output") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("TaskId"); + + b.ToTable("TaskDebugOutput"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("TaskType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("HashlistId"); + + b.ToTable("TaskWrapper"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Email") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("IsValid") + .HasColumnType("boolean"); + + b.Property("LastLoginDate") + .HasColumnType("timestamp with time zone"); + + b.Property("PasswordHash") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordSalt") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("RegisteredSince") + .HasColumnType("timestamp with time zone"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Zap", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Hash") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("SolveTime") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("HashlistId"); + + b.ToTable("Zap"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentBinary", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("UpdateAvailable") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("UpdateTrack") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.HasIndex("Type"); + + b.HasDiscriminator().HasValue("AgentBinary"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.HasDiscriminator().HasValue("CrackerBinary"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Preprocessor", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("KeyspaceCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("LimitCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("SkipCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasDiscriminator().HasValue("Preprocessor"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.BinaryHash", b => + { + b.HasBaseType("HashSlinger.Shared.Models.HashBase"); + + b.Property("Essid") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashBytes") + .IsRequired() + .HasColumnType("bytea"); + + b.HasIndex("ChunkId"); + + b.HasIndex("HashlistId"); + + b.HasIndex("IsCracked"); + + b.HasDiscriminator().HasValue("BinaryHash"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hash", b => + { + b.HasBaseType("HashSlinger.Shared.Models.HashBase"); + + b.Property("HashValue") + .IsRequired() + .HasColumnType("text"); + + b.Property("Salt") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasIndex("ChunkId"); + + b.HasIndex("HashlistId"); + + b.HasIndex("IsCracked"); + + b.HasDiscriminator().HasValue("Hash"); + }); + + modelBuilder.Entity("AccessGroupAgent", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", null) + .WithMany() + .HasForeignKey("AccessGroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Agent", null) + .WithMany() + .HasForeignKey("AgentsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AccessGroupUser", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", null) + .WithMany() + .HasForeignKey("AccessGroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("FilePreconfiguredTask", b => + { + b.HasOne("HashSlinger.Shared.Models.File", null) + .WithMany() + .HasForeignKey("FilesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.PreconfiguredTask", null) + .WithMany() + .HasForeignKey("PreconfiguredTasksId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("FileTask", b => + { + b.HasOne("HashSlinger.Shared.Models.File", null) + .WithMany() + .HasForeignKey("FilesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", null) + .WithMany() + .HasForeignKey("TasksId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("Agents") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentError", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Errors") + .HasForeignKey("AgentId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("Errors") + .HasForeignKey("ChunkId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("AgentErrors") + .HasForeignKey("TaskId"); + + b.Navigation("Agent"); + + b.Navigation("Chunk"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentStat", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Stats") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiKey", b => + { + b.HasOne("HashSlinger.Shared.Models.ApiGroup", "ApiGroup") + .WithMany("ApiKeys") + .HasForeignKey("ApiGroupId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("ApiKeys") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ApiGroup"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Assignment", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Assignments") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Assignments") + .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Chunks") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Chunks") + .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.DownloadableBinary", b => + { + b.HasOne("HashSlinger.Shared.Models.File", "File") + .WithMany() + .HasForeignKey("FileId"); + + b.Navigation("File"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("Files") + .HasForeignKey("AccessGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AccessGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDownload", b => + { + b.HasOne("HashSlinger.Shared.Models.File", "File") + .WithMany("FileDownloads") + .HasForeignKey("FileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("File"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("Hashlists") + .HasForeignKey("AccessGroupId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HashType", "HashType") + .WithMany("Hashlists") + .HasForeignKey("HashTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AccessGroup"); + + b.Navigation("HashType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinary", "CrackerBinary") + .WithMany("HealthChecks") + .HasForeignKey("CrackerBinaryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HashType", "HashType") + .WithMany("HealthChecks") + .HasForeignKey("HashTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CrackerBinary"); + + b.Navigation("HashType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheckAgent", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("HealthCheckAgents") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HealthCheck", "HealthCheck") + .WithMany("HealthCheckAgents") + .HasForeignKey("HealthCheckId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("HealthCheck"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.NotificationSetting", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("NotificationSettings") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("Pretasks") + .HasForeignKey("CrackerBinaryTypeId") + .IsRequired(); + + b.Navigation("CrackerBinaryType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.RegistrationVoucher", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("RegistrationVouchers") + .HasForeignKey("AccessGroupId"); + + b.Navigation("AccessGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Session", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("Sessions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Speed", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Speeds") + .HasForeignKey("AgentId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Speeds") + .HasForeignKey("TaskId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.SupertaskPretask", b => + { + b.HasOne("HashSlinger.Shared.Models.PreconfiguredTask", "PreconfiguredTask") + .WithMany("SupertaskPretasks") + .HasForeignKey("PreconfiguredTaskId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Supertask", "Supertask") + .WithMany("SupertaskPretasks") + .HasForeignKey("SupertaskId") + .IsRequired(); + + b.Navigation("PreconfiguredTask"); + + b.Navigation("Supertask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinary", "CrackerBinary") + .WithMany("Tasks") + .HasForeignKey("CrackerBinaryId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("Tasks") + .HasForeignKey("CrackerBinaryTypeId"); + + b.HasOne("HashSlinger.Shared.Models.Preprocessor", "Preprocessor") + .WithMany("Tasks") + .HasForeignKey("PreprocessorId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.TaskWrapper", "TaskWrapper") + .WithMany("Tasks") + .HasForeignKey("TaskWrapperId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CrackerBinary"); + + b.Navigation("CrackerBinaryType"); + + b.Navigation("Preprocessor"); + + b.Navigation("TaskWrapper"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskDebugOutput", b => + { + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("TaskDebugOutputs") + .HasForeignKey("TaskId") + .IsRequired(); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("TaskWrappers") + .HasForeignKey("AccessGroupId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("TaskWrappers") + .HasForeignKey("HashlistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AccessGroup"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Zap", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Zaps") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("Zaps") + .HasForeignKey("HashlistId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("CrackerBinaries") + .HasForeignKey("CrackerBinaryTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CrackerBinaryType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.BinaryHash", b => + { + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("BinaryHashes") + .HasForeignKey("ChunkId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("BinaryHashes") + .HasForeignKey("HashlistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Chunk"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hash", b => + { + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("Hashes") + .HasForeignKey("ChunkId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("Hashes") + .HasForeignKey("HashlistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Chunk"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AccessGroup", b => + { + b.Navigation("Files"); + + b.Navigation("Hashlists"); + + b.Navigation("RegistrationVouchers"); + + b.Navigation("TaskWrappers"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.Navigation("Assignments"); + + b.Navigation("Chunks"); + + b.Navigation("Errors"); + + b.Navigation("HealthCheckAgents"); + + b.Navigation("Speeds"); + + b.Navigation("Stats"); + + b.Navigation("Zaps"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiGroup", b => + { + b.Navigation("ApiKeys"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.Navigation("BinaryHashes"); + + b.Navigation("Errors"); + + b.Navigation("Hashes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinaryType", b => + { + b.Navigation("CrackerBinaries"); + + b.Navigation("Pretasks"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.Navigation("FileDownloads"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashType", b => + { + b.Navigation("Hashlists"); + + b.Navigation("HealthChecks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.Navigation("BinaryHashes"); + + b.Navigation("Hashes"); + + b.Navigation("TaskWrappers"); + + b.Navigation("Zaps"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.Navigation("HealthCheckAgents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.Navigation("SupertaskPretasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Supertask", b => + { + b.Navigation("SupertaskPretasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.Navigation("AgentErrors"); + + b.Navigation("Assignments"); + + b.Navigation("Chunks"); + + b.Navigation("Speeds"); + + b.Navigation("TaskDebugOutputs"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.User", b => + { + b.Navigation("Agents"); + + b.Navigation("ApiKeys"); + + b.Navigation("NotificationSettings"); + + b.Navigation("Sessions"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.Navigation("HealthChecks"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Preprocessor", b => + { + b.Navigation("Tasks"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/HashSlinger/Migrations/20230712222549_CleanedUpFiles.cs b/HashSlinger/Migrations/20230712222549_CleanedUpFiles.cs new file mode 100644 index 0000000..1a6b474 --- /dev/null +++ b/HashSlinger/Migrations/20230712222549_CleanedUpFiles.cs @@ -0,0 +1,52 @@ +#nullable disable + +namespace HashSlinger.Api.Migrations +{ + using Microsoft.EntityFrameworkCore.Migrations; + + /// + public partial class CleanedUpFiles : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Size", + table: "Files", + type: "integer", + nullable: false, + oldClrType: typeof(long), + oldType: "bigint"); + + migrationBuilder.AlterColumn( + name: "LineCount", + table: "Files", + type: "integer", + nullable: true, + oldClrType: typeof(long), + oldType: "bigint", + oldNullable: true); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Size", + table: "Files", + type: "bigint", + nullable: false, + oldClrType: typeof(int), + oldType: "integer"); + + migrationBuilder.AlterColumn( + name: "LineCount", + table: "Files", + type: "bigint", + nullable: true, + oldClrType: typeof(int), + oldType: "integer", + oldNullable: true); + } + } +} diff --git a/HashSlinger/Migrations/20230712230755_AddedIndexesToFiles.Designer.cs b/HashSlinger/Migrations/20230712230755_AddedIndexesToFiles.Designer.cs new file mode 100644 index 0000000..4631b91 --- /dev/null +++ b/HashSlinger/Migrations/20230712230755_AddedIndexesToFiles.Designer.cs @@ -0,0 +1,1928 @@ +// + +#nullable disable + +namespace HashSlinger.Api.Migrations +{ + using System.Net; + using Data; + using Microsoft.EntityFrameworkCore; + using Microsoft.EntityFrameworkCore.Infrastructure; + using Microsoft.EntityFrameworkCore.Migrations; + + [DbContext(typeof(HashSlingerContext))] + [Migration("20230712230755_AddedIndexesToFiles")] + partial class AddedIndexesToFiles + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.9") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("AccessGroupAgent", b => + { + b.Property("AccessGroupsId") + .HasColumnType("integer"); + + b.Property("AgentsId") + .HasColumnType("integer"); + + b.HasKey("AccessGroupsId", "AgentsId"); + + b.HasIndex("AgentsId"); + + b.ToTable("AccessGroupAgent"); + }); + + modelBuilder.Entity("AccessGroupUser", b => + { + b.Property("AccessGroupsId") + .HasColumnType("integer"); + + b.Property("UsersId") + .HasColumnType("integer"); + + b.HasKey("AccessGroupsId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("AccessGroupUser"); + }); + + modelBuilder.Entity("FilePreconfiguredTask", b => + { + b.Property("FilesId") + .HasColumnType("integer"); + + b.Property("PreconfiguredTasksId") + .HasColumnType("integer"); + + b.HasKey("FilesId", "PreconfiguredTasksId"); + + b.HasIndex("PreconfiguredTasksId"); + + b.ToTable("FilePreconfiguredTask"); + }); + + modelBuilder.Entity("FileTask", b => + { + b.Property("FilesId") + .HasColumnType("integer"); + + b.Property("TasksId") + .HasColumnType("integer"); + + b.HasKey("FilesId", "TasksId"); + + b.HasIndex("TasksId"); + + b.ToTable("FileTask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AccessGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("AccessGroups"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClientSignature") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("CommandParameters") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CpuOnly") + .HasColumnType("boolean"); + + b.Property>("Devices") + .HasColumnType("text[]"); + + b.Property("IgnoreErrors") + .HasColumnType("boolean"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("IsTrusted") + .HasColumnType("boolean"); + + b.Property("LastAction") + .HasColumnType("integer"); + + b.Property("LastSeenIpAddress") + .HasColumnType("inet"); + + b.Property("LastSeenTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("OperatingSystem") + .HasColumnType("integer"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.Property("Uid") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("Token"); + + b.HasIndex("Uid"); + + b.HasIndex("UserId"); + + b.ToTable("Agents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentError", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("ChunkId") + .HasColumnType("integer"); + + b.Property("Error") + .IsRequired() + .HasColumnType("text"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("ChunkId"); + + b.HasIndex("TaskId"); + + b.ToTable("AgentError"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentStat", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("StatType") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.ToTable("AgentStat"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Permissions") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("ApiGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessCount") + .HasColumnType("integer"); + + b.Property("AccessKey") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ApiGroupId") + .HasColumnType("integer"); + + b.Property("EndValid") + .HasColumnType("timestamp with time zone"); + + b.Property("StartValid") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ApiGroupId"); + + b.HasIndex("UserId"); + + b.ToTable("ApiKey"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Assignment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Benchmark") + .IsRequired() + .HasColumnType("text"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Assignment"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Checkpoint") + .HasColumnType("numeric(20,0)"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("DispatchTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Length") + .HasColumnType("numeric(20,0)"); + + b.Property("Progress") + .HasColumnType("real"); + + b.Property("Skip") + .HasColumnType("numeric(20,0)"); + + b.Property("SolveTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Speed") + .HasColumnType("numeric(20,0)"); + + b.Property("State") + .HasColumnType("integer"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Chunks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinaryType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IsChunkingAvailable") + .HasColumnType("boolean"); + + b.Property("TypeName") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.HasKey("Id"); + + b.ToTable("CrackerBinaryTypes"); + + b.HasData( + new + { + Id = 1, + IsChunkingAvailable = true, + TypeName = "hashcat" + }); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.DownloadableBinary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("text"); + + b.Property("DownloadUrl") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("Executable") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("FileId") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property>("OperatingSystems") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("Version") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.ToTable("DownloadableBinaries"); + + b.HasDiscriminator("Discriminator").HasValue("DownloadableBinary"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("FileGuid") + .HasColumnType("uuid"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("FileType") + .HasColumnType("integer"); + + b.Property("IsSecret") + .HasColumnType("boolean"); + + b.Property("LineCount") + .HasColumnType("integer"); + + b.Property("Size") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("FileGuid"); + + b.HasIndex("FileName"); + + b.ToTable("Files"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDelete", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("FileDeletes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDownload", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FileId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.ToTable("FileDownload"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashBase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ChunkId") + .HasColumnType("integer"); + + b.Property("CrackPos") + .HasColumnType("numeric(20,0)"); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("IsCracked") + .HasColumnType("boolean"); + + b.Property("Plaintext") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("TimeCracked") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("HashBase"); + + b.HasDiscriminator("Discriminator").HasValue("HashBase"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("HashcatId") + .HasColumnType("integer"); + + b.Property("IsSalted") + .HasColumnType("boolean"); + + b.Property("IsSlowHash") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("HashcatId") + .IsUnique(); + + b.ToTable("HashTypes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("BrainFeatures") + .HasColumnType("smallint"); + + b.Property("BrainId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("Format") + .HasColumnType("integer"); + + b.Property("HashCount") + .HasColumnType("integer"); + + b.Property("HashTypeId") + .HasColumnType("uuid"); + + b.Property("HexSalt") + .HasColumnType("boolean"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("IsSalted") + .HasColumnType("boolean"); + + b.Property("IsSecret") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("text"); + + b.Property("SaltSeparator") + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("HashTypeId"); + + b.HasIndex("IsSecret"); + + b.ToTable("Hashlists"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCmd") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CheckType") + .HasColumnType("integer"); + + b.Property("CrackerBinaryId") + .HasColumnType("integer"); + + b.Property("ExpectedCracks") + .HasColumnType("integer"); + + b.Property("HashListAlias") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashTypeId") + .HasColumnType("uuid"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property>("TestHashes") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryId"); + + b.HasIndex("HashTypeId"); + + b.ToTable("HealthChecks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheckAgent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("End") + .HasColumnType("numeric(20,0)"); + + b.Property>("Errors") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("HealthCheckId") + .HasColumnType("integer"); + + b.Property("NumGpus") + .HasColumnType("integer"); + + b.Property("Start") + .HasColumnType("numeric(20,0)"); + + b.Property("Status") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("HealthCheckId"); + + b.ToTable("HealthCheckAgents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.LogEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Issuer") + .IsRequired() + .HasColumnType("text"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("LogEntries"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.NotificationSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("Notification") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("ObjectId") + .HasColumnType("integer"); + + b.Property("Receiver") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationSetting"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCommand") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ChunkTime") + .HasColumnType("integer"); + + b.Property("Color") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.Property("IsCpuTask") + .HasColumnType("boolean"); + + b.Property("IsMaskImport") + .HasColumnType("boolean"); + + b.Property("IsSmall") + .HasColumnType("boolean"); + + b.Property("MaxAgents") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("StatusTimer") + .HasColumnType("integer"); + + b.Property("UseNewBench") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.ToTable("PreconfiguredTask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.RegistrationVoucher", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("Expiration") + .HasColumnType("timestamp with time zone"); + + b.Property("Voucher") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("Voucher") + .IsUnique(); + + b.ToTable("RegistrationVouchers"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Session", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IsOpen") + .HasColumnType("boolean"); + + b.Property("LastActionDate") + .HasColumnType("timestamp with time zone"); + + b.Property("SessionKey") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("SessionLifetime") + .HasColumnType("integer"); + + b.Property("SessionStartDate") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Session"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Speed", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("SpeedValue") + .HasColumnType("numeric(20,0)"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Speed"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Supertask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("Supertask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.SupertaskPretask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("PreconfiguredTaskId") + .HasColumnType("integer"); + + b.Property("PretaskId") + .HasColumnType("integer"); + + b.Property("SupertaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("PreconfiguredTaskId"); + + b.HasIndex("SupertaskId"); + + b.ToTable("SupertaskPretask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCommand") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ChunkSize") + .HasColumnType("integer"); + + b.Property("ChunkTime") + .HasColumnType("integer"); + + b.Property("Color") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CrackerBinaryId") + .HasColumnType("integer"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.Property("EnforcePipe") + .HasColumnType("boolean"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("IsCpuTask") + .HasColumnType("boolean"); + + b.Property("IsSmall") + .HasColumnType("boolean"); + + b.Property("Keyspace") + .HasColumnType("bigint"); + + b.Property("KeyspaceProgress") + .HasColumnType("numeric(20,0)"); + + b.Property("MaxAgents") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("text"); + + b.Property("PreprocessorCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PreprocessorId") + .HasColumnType("integer"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("SkipKeyspace") + .HasColumnType("numeric(20,0)"); + + b.Property("StaticChunks") + .HasColumnType("integer"); + + b.Property("StatusTimer") + .HasColumnType("integer"); + + b.Property("TaskWrapperId") + .HasColumnType("integer"); + + b.Property("UseNewBenchmark") + .HasColumnType("boolean"); + + b.Property("UsePreprocessor") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryId"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.HasIndex("PreprocessorId"); + + b.HasIndex("TaskWrapperId"); + + b.ToTable("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskDebugOutput", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Output") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("TaskId"); + + b.ToTable("TaskDebugOutput"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("TaskType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("HashlistId"); + + b.ToTable("TaskWrapper"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Email") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("IsValid") + .HasColumnType("boolean"); + + b.Property("LastLoginDate") + .HasColumnType("timestamp with time zone"); + + b.Property("PasswordHash") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordSalt") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("RegisteredSince") + .HasColumnType("timestamp with time zone"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Zap", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Hash") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("SolveTime") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("HashlistId"); + + b.ToTable("Zap"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentBinary", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("UpdateAvailable") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("UpdateTrack") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.HasIndex("Type"); + + b.HasDiscriminator().HasValue("AgentBinary"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.HasDiscriminator().HasValue("CrackerBinary"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Preprocessor", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("KeyspaceCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("LimitCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("SkipCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasDiscriminator().HasValue("Preprocessor"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.BinaryHash", b => + { + b.HasBaseType("HashSlinger.Shared.Models.HashBase"); + + b.Property("Essid") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashBytes") + .IsRequired() + .HasColumnType("bytea"); + + b.HasIndex("ChunkId"); + + b.HasIndex("HashlistId"); + + b.HasIndex("IsCracked"); + + b.HasDiscriminator().HasValue("BinaryHash"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hash", b => + { + b.HasBaseType("HashSlinger.Shared.Models.HashBase"); + + b.Property("HashValue") + .IsRequired() + .HasColumnType("text"); + + b.Property("Salt") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasIndex("ChunkId"); + + b.HasIndex("HashlistId"); + + b.HasIndex("IsCracked"); + + b.HasDiscriminator().HasValue("Hash"); + }); + + modelBuilder.Entity("AccessGroupAgent", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", null) + .WithMany() + .HasForeignKey("AccessGroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Agent", null) + .WithMany() + .HasForeignKey("AgentsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AccessGroupUser", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", null) + .WithMany() + .HasForeignKey("AccessGroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("FilePreconfiguredTask", b => + { + b.HasOne("HashSlinger.Shared.Models.File", null) + .WithMany() + .HasForeignKey("FilesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.PreconfiguredTask", null) + .WithMany() + .HasForeignKey("PreconfiguredTasksId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("FileTask", b => + { + b.HasOne("HashSlinger.Shared.Models.File", null) + .WithMany() + .HasForeignKey("FilesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", null) + .WithMany() + .HasForeignKey("TasksId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("Agents") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentError", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Errors") + .HasForeignKey("AgentId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("Errors") + .HasForeignKey("ChunkId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("AgentErrors") + .HasForeignKey("TaskId"); + + b.Navigation("Agent"); + + b.Navigation("Chunk"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentStat", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Stats") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiKey", b => + { + b.HasOne("HashSlinger.Shared.Models.ApiGroup", "ApiGroup") + .WithMany("ApiKeys") + .HasForeignKey("ApiGroupId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("ApiKeys") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ApiGroup"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Assignment", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Assignments") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Assignments") + .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Chunks") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Chunks") + .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.DownloadableBinary", b => + { + b.HasOne("HashSlinger.Shared.Models.File", "File") + .WithMany() + .HasForeignKey("FileId"); + + b.Navigation("File"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("Files") + .HasForeignKey("AccessGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AccessGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDownload", b => + { + b.HasOne("HashSlinger.Shared.Models.File", "File") + .WithMany("FileDownloads") + .HasForeignKey("FileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("File"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("Hashlists") + .HasForeignKey("AccessGroupId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HashType", "HashType") + .WithMany("Hashlists") + .HasForeignKey("HashTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AccessGroup"); + + b.Navigation("HashType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinary", "CrackerBinary") + .WithMany("HealthChecks") + .HasForeignKey("CrackerBinaryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HashType", "HashType") + .WithMany("HealthChecks") + .HasForeignKey("HashTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CrackerBinary"); + + b.Navigation("HashType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheckAgent", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("HealthCheckAgents") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HealthCheck", "HealthCheck") + .WithMany("HealthCheckAgents") + .HasForeignKey("HealthCheckId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("HealthCheck"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.NotificationSetting", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("NotificationSettings") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("Pretasks") + .HasForeignKey("CrackerBinaryTypeId") + .IsRequired(); + + b.Navigation("CrackerBinaryType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.RegistrationVoucher", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("RegistrationVouchers") + .HasForeignKey("AccessGroupId"); + + b.Navigation("AccessGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Session", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("Sessions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Speed", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Speeds") + .HasForeignKey("AgentId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Speeds") + .HasForeignKey("TaskId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.SupertaskPretask", b => + { + b.HasOne("HashSlinger.Shared.Models.PreconfiguredTask", "PreconfiguredTask") + .WithMany("SupertaskPretasks") + .HasForeignKey("PreconfiguredTaskId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Supertask", "Supertask") + .WithMany("SupertaskPretasks") + .HasForeignKey("SupertaskId") + .IsRequired(); + + b.Navigation("PreconfiguredTask"); + + b.Navigation("Supertask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinary", "CrackerBinary") + .WithMany("Tasks") + .HasForeignKey("CrackerBinaryId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("Tasks") + .HasForeignKey("CrackerBinaryTypeId"); + + b.HasOne("HashSlinger.Shared.Models.Preprocessor", "Preprocessor") + .WithMany("Tasks") + .HasForeignKey("PreprocessorId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.TaskWrapper", "TaskWrapper") + .WithMany("Tasks") + .HasForeignKey("TaskWrapperId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CrackerBinary"); + + b.Navigation("CrackerBinaryType"); + + b.Navigation("Preprocessor"); + + b.Navigation("TaskWrapper"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskDebugOutput", b => + { + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("TaskDebugOutputs") + .HasForeignKey("TaskId") + .IsRequired(); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("TaskWrappers") + .HasForeignKey("AccessGroupId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("TaskWrappers") + .HasForeignKey("HashlistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AccessGroup"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Zap", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Zaps") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("Zaps") + .HasForeignKey("HashlistId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("CrackerBinaries") + .HasForeignKey("CrackerBinaryTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CrackerBinaryType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.BinaryHash", b => + { + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("BinaryHashes") + .HasForeignKey("ChunkId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("BinaryHashes") + .HasForeignKey("HashlistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Chunk"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hash", b => + { + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("Hashes") + .HasForeignKey("ChunkId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("Hashes") + .HasForeignKey("HashlistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Chunk"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AccessGroup", b => + { + b.Navigation("Files"); + + b.Navigation("Hashlists"); + + b.Navigation("RegistrationVouchers"); + + b.Navigation("TaskWrappers"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.Navigation("Assignments"); + + b.Navigation("Chunks"); + + b.Navigation("Errors"); + + b.Navigation("HealthCheckAgents"); + + b.Navigation("Speeds"); + + b.Navigation("Stats"); + + b.Navigation("Zaps"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiGroup", b => + { + b.Navigation("ApiKeys"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.Navigation("BinaryHashes"); + + b.Navigation("Errors"); + + b.Navigation("Hashes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinaryType", b => + { + b.Navigation("CrackerBinaries"); + + b.Navigation("Pretasks"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.Navigation("FileDownloads"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashType", b => + { + b.Navigation("Hashlists"); + + b.Navigation("HealthChecks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.Navigation("BinaryHashes"); + + b.Navigation("Hashes"); + + b.Navigation("TaskWrappers"); + + b.Navigation("Zaps"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.Navigation("HealthCheckAgents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.Navigation("SupertaskPretasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Supertask", b => + { + b.Navigation("SupertaskPretasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.Navigation("AgentErrors"); + + b.Navigation("Assignments"); + + b.Navigation("Chunks"); + + b.Navigation("Speeds"); + + b.Navigation("TaskDebugOutputs"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.User", b => + { + b.Navigation("Agents"); + + b.Navigation("ApiKeys"); + + b.Navigation("NotificationSettings"); + + b.Navigation("Sessions"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.Navigation("HealthChecks"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Preprocessor", b => + { + b.Navigation("Tasks"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/HashSlinger/Migrations/20230712230755_AddedIndexesToFiles.cs b/HashSlinger/Migrations/20230712230755_AddedIndexesToFiles.cs new file mode 100644 index 0000000..027cf9f --- /dev/null +++ b/HashSlinger/Migrations/20230712230755_AddedIndexesToFiles.cs @@ -0,0 +1,36 @@ +#nullable disable + +namespace HashSlinger.Api.Migrations +{ + using Microsoft.EntityFrameworkCore.Migrations; + + /// + public partial class AddedIndexesToFiles : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateIndex( + name: "IX_Files_FileGuid", + table: "Files", + column: "FileGuid"); + + migrationBuilder.CreateIndex( + name: "IX_Files_FileName", + table: "Files", + column: "FileName"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_Files_FileGuid", + table: "Files"); + + migrationBuilder.DropIndex( + name: "IX_Files_FileName", + table: "Files"); + } + } +} diff --git a/HashSlinger/Migrations/20230725215305_ExpandKeyspace.Designer.cs b/HashSlinger/Migrations/20230725215305_ExpandKeyspace.Designer.cs new file mode 100644 index 0000000..55cc71d --- /dev/null +++ b/HashSlinger/Migrations/20230725215305_ExpandKeyspace.Designer.cs @@ -0,0 +1,1931 @@ +// +using System; +using System.Collections.Generic; +using System.Net; +using HashSlinger.Api.Data; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace HashSlinger.Api.Migrations +{ + [DbContext(typeof(HashSlingerContext))] + [Migration("20230725215305_ExpandKeyspace")] + partial class ExpandKeyspace + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.9") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("AccessGroupAgent", b => + { + b.Property("AccessGroupsId") + .HasColumnType("integer"); + + b.Property("AgentsId") + .HasColumnType("integer"); + + b.HasKey("AccessGroupsId", "AgentsId"); + + b.HasIndex("AgentsId"); + + b.ToTable("AccessGroupAgent"); + }); + + modelBuilder.Entity("AccessGroupUser", b => + { + b.Property("AccessGroupsId") + .HasColumnType("integer"); + + b.Property("UsersId") + .HasColumnType("integer"); + + b.HasKey("AccessGroupsId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("AccessGroupUser"); + }); + + modelBuilder.Entity("FilePreconfiguredTask", b => + { + b.Property("FilesId") + .HasColumnType("integer"); + + b.Property("PreconfiguredTasksId") + .HasColumnType("integer"); + + b.HasKey("FilesId", "PreconfiguredTasksId"); + + b.HasIndex("PreconfiguredTasksId"); + + b.ToTable("FilePreconfiguredTask"); + }); + + modelBuilder.Entity("FileTask", b => + { + b.Property("FilesId") + .HasColumnType("integer"); + + b.Property("TasksId") + .HasColumnType("integer"); + + b.HasKey("FilesId", "TasksId"); + + b.HasIndex("TasksId"); + + b.ToTable("FileTask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AccessGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("AccessGroups"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClientSignature") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("CommandParameters") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CpuOnly") + .HasColumnType("boolean"); + + b.Property>("Devices") + .HasColumnType("text[]"); + + b.Property("IgnoreErrors") + .HasColumnType("boolean"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("IsTrusted") + .HasColumnType("boolean"); + + b.Property("LastAction") + .HasColumnType("integer"); + + b.Property("LastSeenIpAddress") + .HasColumnType("inet"); + + b.Property("LastSeenTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("OperatingSystem") + .HasColumnType("integer"); + + b.Property("Token") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.Property("Uid") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("Token"); + + b.HasIndex("Uid"); + + b.HasIndex("UserId"); + + b.ToTable("Agents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentError", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("ChunkId") + .HasColumnType("integer"); + + b.Property("Error") + .IsRequired() + .HasColumnType("text"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("ChunkId"); + + b.HasIndex("TaskId"); + + b.ToTable("AgentError"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentStat", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("StatType") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.ToTable("AgentStat"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiGroup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Permissions") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("ApiGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiKey", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessCount") + .HasColumnType("integer"); + + b.Property("AccessKey") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ApiGroupId") + .HasColumnType("integer"); + + b.Property("EndValid") + .HasColumnType("timestamp with time zone"); + + b.Property("StartValid") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ApiGroupId"); + + b.HasIndex("UserId"); + + b.ToTable("ApiKey"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Assignment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Benchmark") + .IsRequired() + .HasColumnType("text"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Assignment"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Checkpoint") + .HasColumnType("numeric(20,0)"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("DispatchTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Length") + .HasColumnType("numeric(20,0)"); + + b.Property("Progress") + .HasColumnType("real"); + + b.Property("Skip") + .HasColumnType("numeric(20,0)"); + + b.Property("SolveTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Speed") + .HasColumnType("numeric(20,0)"); + + b.Property("State") + .HasColumnType("integer"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Chunks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinaryType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IsChunkingAvailable") + .HasColumnType("boolean"); + + b.Property("TypeName") + .IsRequired() + .HasMaxLength(30) + .HasColumnType("character varying(30)"); + + b.HasKey("Id"); + + b.ToTable("CrackerBinaryTypes"); + + b.HasData( + new + { + Id = 1, + IsChunkingAvailable = true, + TypeName = "hashcat" + }); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.DownloadableBinary", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("text"); + + b.Property("DownloadUrl") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("Executable") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("FileId") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property>("OperatingSystems") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("Version") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.ToTable("DownloadableBinaries"); + + b.HasDiscriminator("Discriminator").HasValue("DownloadableBinary"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("FileGuid") + .HasColumnType("uuid"); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("FileType") + .HasColumnType("integer"); + + b.Property("IsSecret") + .HasColumnType("boolean"); + + b.Property("LineCount") + .HasColumnType("integer"); + + b.Property("Size") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("FileGuid"); + + b.HasIndex("FileName"); + + b.ToTable("Files"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDelete", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FileName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("FileDeletes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDownload", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FileId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("FileId"); + + b.ToTable("FileDownload"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashBase", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ChunkId") + .HasColumnType("integer"); + + b.Property("CrackPos") + .HasColumnType("numeric(20,0)"); + + b.Property("Discriminator") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("IsCracked") + .HasColumnType("boolean"); + + b.Property("Plaintext") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("TimeCracked") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("HashBase"); + + b.HasDiscriminator("Discriminator").HasValue("HashBase"); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Description") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("HashcatId") + .HasColumnType("integer"); + + b.Property("IsSalted") + .HasColumnType("boolean"); + + b.Property("IsSlowHash") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("HashcatId") + .IsUnique(); + + b.ToTable("HashTypes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("BrainFeatures") + .HasColumnType("smallint"); + + b.Property("BrainId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("Format") + .HasColumnType("integer"); + + b.Property("HashCount") + .HasColumnType("integer"); + + b.Property("HashTypeId") + .HasColumnType("uuid"); + + b.Property("HexSalt") + .HasColumnType("boolean"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("IsSalted") + .HasColumnType("boolean"); + + b.Property("IsSecret") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("text"); + + b.Property("SaltSeparator") + .HasMaxLength(10) + .HasColumnType("character varying(10)"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("HashTypeId"); + + b.HasIndex("IsSecret"); + + b.ToTable("Hashlists"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCmd") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("CheckType") + .HasColumnType("integer"); + + b.Property("CrackerBinaryId") + .HasColumnType("integer"); + + b.Property("ExpectedCracks") + .HasColumnType("integer"); + + b.Property("HashListAlias") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashTypeId") + .HasColumnType("uuid"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property>("TestHashes") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryId"); + + b.HasIndex("HashTypeId"); + + b.ToTable("HealthChecks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheckAgent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("End") + .HasColumnType("numeric(20,0)"); + + b.Property>("Errors") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("HealthCheckId") + .HasColumnType("integer"); + + b.Property("NumGpus") + .HasColumnType("integer"); + + b.Property("Start") + .HasColumnType("numeric(20,0)"); + + b.Property("Status") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("HealthCheckId"); + + b.ToTable("HealthCheckAgents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.LogEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Issuer") + .IsRequired() + .HasColumnType("text"); + + b.Property("Level") + .HasColumnType("integer"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.ToTable("LogEntries"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.NotificationSetting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Action") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("IsActive") + .HasColumnType("boolean"); + + b.Property("Notification") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("ObjectId") + .HasColumnType("integer"); + + b.Property("Receiver") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationSetting"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCommand") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ChunkTime") + .HasColumnType("integer"); + + b.Property("Color") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.Property("IsCpuTask") + .HasColumnType("boolean"); + + b.Property("IsMaskImport") + .HasColumnType("boolean"); + + b.Property("IsSmall") + .HasColumnType("boolean"); + + b.Property("MaxAgents") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("StatusTimer") + .HasColumnType("integer"); + + b.Property("UseNewBench") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.ToTable("PreconfiguredTask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.RegistrationVoucher", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("Expiration") + .HasColumnType("timestamp with time zone"); + + b.Property("Voucher") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("Voucher") + .IsUnique(); + + b.ToTable("RegistrationVouchers"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Session", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("IsOpen") + .HasColumnType("boolean"); + + b.Property("LastActionDate") + .HasColumnType("timestamp with time zone"); + + b.Property("SessionKey") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("SessionLifetime") + .HasColumnType("integer"); + + b.Property("SessionStartDate") + .HasColumnType("timestamp with time zone"); + + b.Property("UserId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Session"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Speed", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("SpeedValue") + .HasColumnType("numeric(20,0)"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("TaskId"); + + b.ToTable("Speed"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Supertask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.HasKey("Id"); + + b.ToTable("Supertask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.SupertaskPretask", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("PreconfiguredTaskId") + .HasColumnType("integer"); + + b.Property("PretaskId") + .HasColumnType("integer"); + + b.Property("SupertaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("PreconfiguredTaskId"); + + b.HasIndex("SupertaskId"); + + b.ToTable("SupertaskPretask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AttackCommand") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("ChunkSize") + .HasColumnType("integer"); + + b.Property("ChunkTime") + .HasColumnType("integer"); + + b.Property("Color") + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("CrackerBinaryId") + .HasColumnType("integer"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.Property("EnforcePipe") + .HasColumnType("boolean"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("IsCpuTask") + .HasColumnType("boolean"); + + b.Property("IsSmall") + .HasColumnType("boolean"); + + b.Property("Keyspace") + .HasColumnType("numeric(20,0)"); + + b.Property("KeyspaceProgress") + .HasColumnType("numeric(20,0)"); + + b.Property("MaxAgents") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Notes") + .IsRequired() + .HasColumnType("text"); + + b.Property("PreprocessorCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PreprocessorId") + .HasColumnType("integer"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("SkipKeyspace") + .HasColumnType("numeric(20,0)"); + + b.Property("StaticChunks") + .HasColumnType("integer"); + + b.Property("StatusTimer") + .HasColumnType("integer"); + + b.Property("TaskWrapperId") + .HasColumnType("integer"); + + b.Property("UseNewBenchmark") + .HasColumnType("boolean"); + + b.Property("UsePreprocessor") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("CrackerBinaryId"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.HasIndex("PreprocessorId"); + + b.HasIndex("TaskWrapperId"); + + b.ToTable("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskDebugOutput", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Output") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("TaskId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("TaskId"); + + b.ToTable("TaskDebugOutput"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccessGroupId") + .HasColumnType("integer"); + + b.Property("Cracked") + .HasColumnType("integer"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("IsArchived") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("TaskType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AccessGroupId"); + + b.HasIndex("HashlistId"); + + b.ToTable("TaskWrapper"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Email") + .IsRequired() + .HasMaxLength(150) + .HasColumnType("character varying(150)"); + + b.Property("IsValid") + .HasColumnType("boolean"); + + b.Property("LastLoginDate") + .HasColumnType("timestamp with time zone"); + + b.Property("PasswordHash") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordSalt") + .IsRequired() + .HasColumnType("bytea"); + + b.Property("RegisteredSince") + .HasColumnType("timestamp with time zone"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Zap", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AgentId") + .HasColumnType("integer"); + + b.Property("Hash") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashlistId") + .HasColumnType("integer"); + + b.Property("SolveTime") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("AgentId"); + + b.HasIndex("HashlistId"); + + b.ToTable("Zap"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentBinary", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("Type") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("UpdateAvailable") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.Property("UpdateTrack") + .IsRequired() + .HasMaxLength(20) + .HasColumnType("character varying(20)"); + + b.HasIndex("Type"); + + b.HasDiscriminator().HasValue("AgentBinary"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("CrackerBinaryTypeId") + .HasColumnType("integer"); + + b.HasIndex("CrackerBinaryTypeId"); + + b.HasDiscriminator().HasValue("CrackerBinary"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Preprocessor", b => + { + b.HasBaseType("HashSlinger.Shared.Models.DownloadableBinary"); + + b.Property("KeyspaceCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("LimitCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("SkipCommand") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasDiscriminator().HasValue("Preprocessor"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.BinaryHash", b => + { + b.HasBaseType("HashSlinger.Shared.Models.HashBase"); + + b.Property("Essid") + .IsRequired() + .HasColumnType("text"); + + b.Property("HashBytes") + .IsRequired() + .HasColumnType("bytea"); + + b.HasIndex("ChunkId"); + + b.HasIndex("HashlistId"); + + b.HasIndex("IsCracked"); + + b.HasDiscriminator().HasValue("BinaryHash"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hash", b => + { + b.HasBaseType("HashSlinger.Shared.Models.HashBase"); + + b.Property("HashValue") + .IsRequired() + .HasColumnType("text"); + + b.Property("Salt") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasIndex("ChunkId"); + + b.HasIndex("HashlistId"); + + b.HasIndex("IsCracked"); + + b.HasDiscriminator().HasValue("Hash"); + }); + + modelBuilder.Entity("AccessGroupAgent", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", null) + .WithMany() + .HasForeignKey("AccessGroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Agent", null) + .WithMany() + .HasForeignKey("AgentsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("AccessGroupUser", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", null) + .WithMany() + .HasForeignKey("AccessGroupsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("FilePreconfiguredTask", b => + { + b.HasOne("HashSlinger.Shared.Models.File", null) + .WithMany() + .HasForeignKey("FilesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.PreconfiguredTask", null) + .WithMany() + .HasForeignKey("PreconfiguredTasksId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("FileTask", b => + { + b.HasOne("HashSlinger.Shared.Models.File", null) + .WithMany() + .HasForeignKey("FilesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", null) + .WithMany() + .HasForeignKey("TasksId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("Agents") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.SetNull); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentError", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Errors") + .HasForeignKey("AgentId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("Errors") + .HasForeignKey("ChunkId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("AgentErrors") + .HasForeignKey("TaskId"); + + b.Navigation("Agent"); + + b.Navigation("Chunk"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AgentStat", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Stats") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiKey", b => + { + b.HasOne("HashSlinger.Shared.Models.ApiGroup", "ApiGroup") + .WithMany("ApiKeys") + .HasForeignKey("ApiGroupId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("ApiKeys") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ApiGroup"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Assignment", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Assignments") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Assignments") + .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Chunks") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Chunks") + .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.DownloadableBinary", b => + { + b.HasOne("HashSlinger.Shared.Models.File", "File") + .WithMany() + .HasForeignKey("FileId"); + + b.Navigation("File"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("Files") + .HasForeignKey("AccessGroupId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AccessGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.FileDownload", b => + { + b.HasOne("HashSlinger.Shared.Models.File", "File") + .WithMany("FileDownloads") + .HasForeignKey("FileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("File"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("Hashlists") + .HasForeignKey("AccessGroupId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HashType", "HashType") + .WithMany("Hashlists") + .HasForeignKey("HashTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AccessGroup"); + + b.Navigation("HashType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinary", "CrackerBinary") + .WithMany("HealthChecks") + .HasForeignKey("CrackerBinaryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HashType", "HashType") + .WithMany("HealthChecks") + .HasForeignKey("HashTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CrackerBinary"); + + b.Navigation("HashType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheckAgent", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("HealthCheckAgents") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.HealthCheck", "HealthCheck") + .WithMany("HealthCheckAgents") + .HasForeignKey("HealthCheckId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("HealthCheck"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.NotificationSetting", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("NotificationSettings") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("Pretasks") + .HasForeignKey("CrackerBinaryTypeId") + .IsRequired(); + + b.Navigation("CrackerBinaryType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.RegistrationVoucher", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("RegistrationVouchers") + .HasForeignKey("AccessGroupId"); + + b.Navigation("AccessGroup"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Session", b => + { + b.HasOne("HashSlinger.Shared.Models.User", "User") + .WithMany("Sessions") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("User"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Speed", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Speeds") + .HasForeignKey("AgentId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("Speeds") + .HasForeignKey("TaskId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.SupertaskPretask", b => + { + b.HasOne("HashSlinger.Shared.Models.PreconfiguredTask", "PreconfiguredTask") + .WithMany("SupertaskPretasks") + .HasForeignKey("PreconfiguredTaskId") + .IsRequired(); + + b.HasOne("HashSlinger.Shared.Models.Supertask", "Supertask") + .WithMany("SupertaskPretasks") + .HasForeignKey("SupertaskId") + .IsRequired(); + + b.Navigation("PreconfiguredTask"); + + b.Navigation("Supertask"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinary", "CrackerBinary") + .WithMany("Tasks") + .HasForeignKey("CrackerBinaryId") + .OnDelete(DeleteBehavior.SetNull); + + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("Tasks") + .HasForeignKey("CrackerBinaryTypeId"); + + b.HasOne("HashSlinger.Shared.Models.Preprocessor", "Preprocessor") + .WithMany("Tasks") + .HasForeignKey("PreprocessorId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.TaskWrapper", "TaskWrapper") + .WithMany("Tasks") + .HasForeignKey("TaskWrapperId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CrackerBinary"); + + b.Navigation("CrackerBinaryType"); + + b.Navigation("Preprocessor"); + + b.Navigation("TaskWrapper"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskDebugOutput", b => + { + b.HasOne("HashSlinger.Shared.Models.Task", "Task") + .WithMany("TaskDebugOutputs") + .HasForeignKey("TaskId") + .IsRequired(); + + b.Navigation("Task"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") + .WithMany("TaskWrappers") + .HasForeignKey("AccessGroupId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("TaskWrappers") + .HasForeignKey("HashlistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("AccessGroup"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Zap", b => + { + b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") + .WithMany("Zaps") + .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("Zaps") + .HasForeignKey("HashlistId") + .IsRequired(); + + b.Navigation("Agent"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") + .WithMany("CrackerBinaries") + .HasForeignKey("CrackerBinaryTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("CrackerBinaryType"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.BinaryHash", b => + { + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("BinaryHashes") + .HasForeignKey("ChunkId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("BinaryHashes") + .HasForeignKey("HashlistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Chunk"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hash", b => + { + b.HasOne("HashSlinger.Shared.Models.Chunk", "Chunk") + .WithMany("Hashes") + .HasForeignKey("ChunkId"); + + b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") + .WithMany("Hashes") + .HasForeignKey("HashlistId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Chunk"); + + b.Navigation("Hashlist"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.AccessGroup", b => + { + b.Navigation("Files"); + + b.Navigation("Hashlists"); + + b.Navigation("RegistrationVouchers"); + + b.Navigation("TaskWrappers"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Agent", b => + { + b.Navigation("Assignments"); + + b.Navigation("Chunks"); + + b.Navigation("Errors"); + + b.Navigation("HealthCheckAgents"); + + b.Navigation("Speeds"); + + b.Navigation("Stats"); + + b.Navigation("Zaps"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.ApiGroup", b => + { + b.Navigation("ApiKeys"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Chunk", b => + { + b.Navigation("BinaryHashes"); + + b.Navigation("Errors"); + + b.Navigation("Hashes"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinaryType", b => + { + b.Navigation("CrackerBinaries"); + + b.Navigation("Pretasks"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.File", b => + { + b.Navigation("FileDownloads"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HashType", b => + { + b.Navigation("Hashlists"); + + b.Navigation("HealthChecks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Hashlist", b => + { + b.Navigation("BinaryHashes"); + + b.Navigation("Hashes"); + + b.Navigation("TaskWrappers"); + + b.Navigation("Zaps"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.HealthCheck", b => + { + b.Navigation("HealthCheckAgents"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.PreconfiguredTask", b => + { + b.Navigation("SupertaskPretasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Supertask", b => + { + b.Navigation("SupertaskPretasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Task", b => + { + b.Navigation("AgentErrors"); + + b.Navigation("Assignments"); + + b.Navigation("Chunks"); + + b.Navigation("Speeds"); + + b.Navigation("TaskDebugOutputs"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.TaskWrapper", b => + { + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.User", b => + { + b.Navigation("Agents"); + + b.Navigation("ApiKeys"); + + b.Navigation("NotificationSettings"); + + b.Navigation("Sessions"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinary", b => + { + b.Navigation("HealthChecks"); + + b.Navigation("Tasks"); + }); + + modelBuilder.Entity("HashSlinger.Shared.Models.Preprocessor", b => + { + b.Navigation("Tasks"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/HashSlinger/Migrations/20230725215305_ExpandKeyspace.cs b/HashSlinger/Migrations/20230725215305_ExpandKeyspace.cs new file mode 100644 index 0000000..b9a2372 --- /dev/null +++ b/HashSlinger/Migrations/20230725215305_ExpandKeyspace.cs @@ -0,0 +1,34 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace HashSlinger.Api.Migrations +{ + /// + public partial class ExpandKeyspace : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Keyspace", + table: "Tasks", + type: "numeric(20,0)", + nullable: false, + oldClrType: typeof(long), + oldType: "bigint"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "Keyspace", + table: "Tasks", + type: "bigint", + nullable: false, + oldClrType: typeof(decimal), + oldType: "numeric(20,0)"); + } + } +} diff --git a/HashSlinger/Migrations/HashSlingerContextModelSnapshot.cs b/HashSlinger/Migrations/HashSlingerContextModelSnapshot.cs index 28c70da..879d2ad 100644 --- a/HashSlinger/Migrations/HashSlingerContextModelSnapshot.cs +++ b/HashSlinger/Migrations/HashSlingerContextModelSnapshot.cs @@ -19,7 +19,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "7.0.7") + .HasAnnotation("ProductVersion", "7.0.9") .HasAnnotation("Relational:MaxIdentifierLength", 63); NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); @@ -349,8 +349,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("Length") .HasColumnType("numeric(20,0)"); - b.Property("Progress") - .HasColumnType("integer"); + b.Property("Progress") + .HasColumnType("real"); b.Property("Skip") .HasColumnType("numeric(20,0)"); @@ -373,7 +373,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("TaskId"); - b.ToTable("Chunk"); + b.ToTable("Chunks"); }); modelBuilder.Entity("HashSlinger.Shared.Models.CrackerBinaryType", b => @@ -480,16 +480,20 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("IsSecret") .HasColumnType("boolean"); - b.Property("LineCount") - .HasColumnType("bigint"); + b.Property("LineCount") + .HasColumnType("integer"); - b.Property("Size") - .HasColumnType("bigint"); + b.Property("Size") + .HasColumnType("integer"); b.HasKey("Id"); b.HasIndex("AccessGroupId"); + b.HasIndex("FileGuid"); + + b.HasIndex("FileName"); + b.ToTable("Files"); }); @@ -1413,7 +1417,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) { b.HasOne("HashSlinger.Shared.Models.User", "User") .WithMany("Agents") - .HasForeignKey("UserId"); + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.SetNull); b.Navigation("User"); }); @@ -1446,6 +1451,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") .WithMany("Stats") .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) .IsRequired(); b.Navigation("Agent"); @@ -1474,11 +1480,13 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") .WithMany("Assignments") .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) .IsRequired(); b.HasOne("HashSlinger.Shared.Models.Task", "Task") .WithMany("Assignments") .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade) .IsRequired(); b.Navigation("Agent"); @@ -1496,6 +1504,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasOne("HashSlinger.Shared.Models.Task", "Task") .WithMany("Chunks") .HasForeignKey("TaskId") + .OnDelete(DeleteBehavior.Cascade) .IsRequired(); b.Navigation("Agent"); @@ -1517,6 +1526,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasOne("HashSlinger.Shared.Models.AccessGroup", "AccessGroup") .WithMany("Files") .HasForeignKey("AccessGroupId") + .OnDelete(DeleteBehavior.Cascade) .IsRequired(); b.Navigation("AccessGroup"); @@ -1527,6 +1537,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasOne("HashSlinger.Shared.Models.File", "File") .WithMany("FileDownloads") .HasForeignKey("FileId") + .OnDelete(DeleteBehavior.Cascade) .IsRequired(); b.Navigation("File"); @@ -1542,6 +1553,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasOne("HashSlinger.Shared.Models.HashType", "HashType") .WithMany("Hashlists") .HasForeignKey("HashTypeId") + .OnDelete(DeleteBehavior.Cascade) .IsRequired(); b.Navigation("AccessGroup"); @@ -1554,11 +1566,13 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasOne("HashSlinger.Shared.Models.CrackerBinary", "CrackerBinary") .WithMany("HealthChecks") .HasForeignKey("CrackerBinaryId") + .OnDelete(DeleteBehavior.Cascade) .IsRequired(); b.HasOne("HashSlinger.Shared.Models.HashType", "HashType") .WithMany("HealthChecks") .HasForeignKey("HashTypeId") + .OnDelete(DeleteBehavior.Cascade) .IsRequired(); b.Navigation("CrackerBinary"); @@ -1571,6 +1585,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasOne("HashSlinger.Shared.Models.Agent", "Agent") .WithMany("HealthCheckAgents") .HasForeignKey("AgentId") + .OnDelete(DeleteBehavior.Cascade) .IsRequired(); b.HasOne("HashSlinger.Shared.Models.HealthCheck", "HealthCheck") @@ -1677,7 +1692,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasOne("HashSlinger.Shared.Models.TaskWrapper", "TaskWrapper") .WithMany("Tasks") .HasForeignKey("TaskWrapperId") - .OnDelete(DeleteBehavior.SetNull) + .OnDelete(DeleteBehavior.Cascade) .IsRequired(); b.Navigation("CrackerBinary"); @@ -1708,6 +1723,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasOne("HashSlinger.Shared.Models.Hashlist", "Hashlist") .WithMany("TaskWrappers") .HasForeignKey("HashlistId") + .OnDelete(DeleteBehavior.Cascade) .IsRequired(); b.Navigation("AccessGroup"); @@ -1737,6 +1753,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasOne("HashSlinger.Shared.Models.CrackerBinaryType", "CrackerBinaryType") .WithMany("CrackerBinaries") .HasForeignKey("CrackerBinaryTypeId") + .OnDelete(DeleteBehavior.Cascade) .IsRequired(); b.Navigation("CrackerBinaryType"); diff --git a/HashSlinger/Program.cs b/HashSlinger/Program.cs index 65771ab..be75ae8 100644 --- a/HashSlinger/Program.cs +++ b/HashSlinger/Program.cs @@ -1,6 +1,5 @@ using System.Text.Json.Serialization; using HashSlinger.Api.Data; -using HashSlinger.Api.Endpoints.ClientApiV1; using HashSlinger.Api.Endpoints.HashtopolisApiV2; using HashSlinger.Api.Endpoints.UserApiV1; using HashSlinger.Api.Services; @@ -15,9 +14,9 @@ TypeAdapterConfig.GlobalSettings.Default.MaxDepth(2); Log.Logger = new LoggerConfiguration().WriteTo.Console(LogEventLevel.Information) - .MinimumLevel.Debug() - .WriteTo.File("Log/log-.txt", rollingInterval: RollingInterval.Day) - .CreateLogger(); + .MinimumLevel.Debug() + .WriteTo.File("Log/log-.txt", rollingInterval: RollingInterval.Day) + .CreateLogger(); WebApplicationBuilder builder = WebApplication.CreateBuilder(args); builder.Host.UseSerilog(); @@ -52,11 +51,9 @@ app.MapHashtopolisEndpoints(); app.MapUserApiEndpoints(); -app.MapFileEndpoints(); - await using (AsyncServiceScope scope = app.Services.CreateAsyncScope()) { - HashSlingerContext dbContext = scope.ServiceProvider.GetRequiredService(); + var dbContext = scope.ServiceProvider.GetRequiredService(); await dbContext.Database.EnsureCreatedAsync().ConfigureAwait(true); } diff --git a/HashSlinger/Services/LocalFileStorageService.cs b/HashSlinger/Services/LocalFileStorageService.cs index bf7921b..566ac04 100644 --- a/HashSlinger/Services/LocalFileStorageService.cs +++ b/HashSlinger/Services/LocalFileStorageService.cs @@ -15,7 +15,7 @@ public string LocalStoragePath get => _localStoragePath; set { - LocalFileStorageService.EnsureDirectoryExists(value); + EnsureDirectoryExists(value); _localStoragePath = value; } } @@ -32,7 +32,7 @@ public string LocalStoragePath /// public async Task StoreFileAsync(string name, string bucket, Stream fileStream) { - var filePath = Path.Combine(GetBucketPath(bucket), LocalFileStorageService.SanitizePath(name)); + var filePath = Path.Combine(GetBucketPath(bucket), SanitizePath(name)); EnsureBucketExists(bucket); await using (FileStream stream = File.Create(filePath)) { @@ -47,7 +47,7 @@ public async Task StoreFileAsync(string name, string bucket, Stream fileSt /// public Task FileExistsAsync(string name, string bucket) { - var filePath = Path.Combine(GetBucketPath(bucket), LocalFileStorageService.SanitizePath(name)); + var filePath = Path.Combine(GetBucketPath(bucket), SanitizePath(name)); return Task.FromResult(File.Exists(filePath)); } @@ -67,11 +67,11 @@ private static string SanitizePath(string path) private void EnsureBucketExists(string bucket) { var bucketPath = GetBucketPath(bucket); - LocalFileStorageService.EnsureDirectoryExists(bucketPath); + EnsureDirectoryExists(bucketPath); } private string GetBucketPath(string bucket) { - return Path.Combine(LocalStoragePath, LocalFileStorageService.SanitizePath(bucket)); + return Path.Combine(LocalStoragePath, SanitizePath(bucket)); } }