diff --git a/common/ASC.Core.Common/EF/Model/ModelBuilderWrapper.cs b/common/ASC.Core.Common/EF/Model/ModelBuilderWrapper.cs index e7a21b4270..be538f57e4 100644 --- a/common/ASC.Core.Common/EF/Model/ModelBuilderWrapper.cs +++ b/common/ASC.Core.Common/EF/Model/ModelBuilderWrapper.cs @@ -24,6 +24,8 @@ // content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0 // International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode +using Microsoft.EntityFrameworkCore.Metadata.Builders; + namespace ASC.Core.Common.EF.Model; public class ModelBuilderWrapper @@ -75,6 +77,11 @@ public class ModelBuilderWrapper return this; } + public EntityTypeBuilder Entity() where T : class + { + return ModelBuilder.Entity(); + } + public void AddDbFunction() { ModelBuilder diff --git a/common/ASC.Webhooks.Core/DbWorker.cs b/common/ASC.Webhooks.Core/DbWorker.cs index 969b467da9..60ad5c4c2b 100644 --- a/common/ASC.Webhooks.Core/DbWorker.cs +++ b/common/ASC.Webhooks.Core/DbWorker.cs @@ -147,16 +147,13 @@ public class DbWorker .AsAsyncEnumerable(); } - public async Task ReadJournal(int id) + public async Task ReadJournal(int id) { using var webhooksDbContext = _dbContextFactory.CreateDbContext(); return await webhooksDbContext.WebhooksLogs .AsNoTracking() - .Where(it => it.Id == id) - .Join(webhooksDbContext.WebhooksConfigs, t => t.ConfigId, t => t.Id, (payload, config) => new { payload, config }) - .Select(t => new WebhookEntry { Id = t.payload.Id, Name = t.config.Name, Payload = t.payload.RequestPayload, SecretKey = t.config.SecretKey, Uri = t.config.Uri }) - .OrderBy(t => t.Id) + .Where(it => it.Id == id) .FirstOrDefaultAsync(); } diff --git a/common/ASC.Webhooks.Core/EF/Model/WebhookEntry.cs b/common/ASC.Webhooks.Core/EF/Model/WebhookEntry.cs deleted file mode 100644 index 31e3670160..0000000000 --- a/common/ASC.Webhooks.Core/EF/Model/WebhookEntry.cs +++ /dev/null @@ -1,36 +0,0 @@ -// (c) Copyright Ascensio System SIA 2010-2022 -// -// This program is a free software product. -// You can redistribute it and/or modify it under the terms -// of the GNU Affero General Public License (AGPL) version 3 as published by the Free Software -// Foundation. In accordance with Section 7(a) of the GNU AGPL its Section 15 shall be amended -// to the effect that Ascensio System SIA expressly excludes the warranty of non-infringement of -// any third-party rights. -// -// This program is distributed WITHOUT ANY WARRANTY, without even the implied warranty -// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For details, see -// the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html -// -// You can contact Ascensio System SIA at Lubanas st. 125a-25, Riga, Latvia, EU, LV-1021. -// -// The interactive user interfaces in modified source and object code versions of the Program must -// display Appropriate Legal Notices, as required under Section 5 of the GNU AGPL version 3. -// -// Pursuant to Section 7(b) of the License you must retain the original Product logo when -// distributing the program. Pursuant to Section 7(e) we decline to grant you any rights under -// trademark law for use of our trademarks. -// -// All the Product's GUI elements, including illustrations and icon sets, as well as technical writing -// content are licensed under the terms of the Creative Commons Attribution-ShareAlike 4.0 -// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode - -namespace ASC.Webhooks.Core.EF.Model; - -public class WebhookEntry -{ - public int Id { get; set; } - public string Name { get; set; } - public string Payload { get; set; } - public string SecretKey { get; set; } - public string Uri { get; set; } -} diff --git a/common/ASC.Webhooks.Core/EF/Model/WebhooksConfig.cs b/common/ASC.Webhooks.Core/EF/Model/WebhooksConfig.cs index f5d882c408..2232cb3bf9 100644 --- a/common/ASC.Webhooks.Core/EF/Model/WebhooksConfig.cs +++ b/common/ASC.Webhooks.Core/EF/Model/WebhooksConfig.cs @@ -55,7 +55,10 @@ public static class WebhooksConfigExtension modelBuilder.Entity(entity => { entity.HasKey(e => new { e.Id }) - .HasName("PRIMARY"); + .HasName("PRIMARY"); + + entity.HasIndex(e => e.TenantId) + .HasDatabaseName("tenant_id"); entity.ToTable("webhooks_config") .HasCharSet("utf8"); @@ -97,7 +100,10 @@ public static class WebhooksConfigExtension entity.HasKey(e => new { e.Id }) .HasName("PRIMARY"); - entity.ToTable("webhooks_config"); + entity.ToTable("webhooks_config"); + + entity.HasIndex(e => e.TenantId) + .HasDatabaseName("tenant_id"); entity.Property(e => e.Id) .HasColumnType("int") diff --git a/common/ASC.Webhooks.Core/EF/Model/WebhooksLog.cs b/common/ASC.Webhooks.Core/EF/Model/WebhooksLog.cs index 2eb989c415..3daa62b4c1 100644 --- a/common/ASC.Webhooks.Core/EF/Model/WebhooksLog.cs +++ b/common/ASC.Webhooks.Core/EF/Model/WebhooksLog.cs @@ -40,13 +40,17 @@ public class WebhooksLog public int Status { get; set; } public int TenantId { get; set; } public Guid Uid { get; set; } - public DateTime? Delivery { get; set; } + public DateTime? Delivery { get; set; } + + public WebhooksConfig Config { get; set; } } public static class WebhooksPayloadExtension { public static ModelBuilderWrapper AddWebhooksLog(this ModelBuilderWrapper modelBuilder) - { + { + modelBuilder.Entity().Navigation(e => e.Config).AutoInclude(); + modelBuilder .Add(MySqlAddWebhooksLog, Provider.MySql) .Add(PgSqlAddWebhooksLog, Provider.PostgreSql); @@ -62,7 +66,10 @@ public static class WebhooksPayloadExtension .HasName("PRIMARY"); entity.ToTable("webhooks_logs") - .HasCharSet("utf8"); + .HasCharSet("utf8"); + + entity.HasIndex(e => e.TenantId) + .HasDatabaseName("tenant_id"); entity.Property(e => e.Id) .HasColumnType("int") @@ -135,7 +142,10 @@ public static class WebhooksPayloadExtension entity.HasKey(e => new { e.Id }) .HasName("PRIMARY"); - entity.ToTable("webhooks_logs"); + entity.ToTable("webhooks_logs"); + + entity.HasIndex(e => e.TenantId) + .HasDatabaseName("tenant_id"); entity.Property(e => e.Id) .HasColumnType("int") diff --git a/common/services/ASC.Webhooks.Service/WebhookSender.cs b/common/services/ASC.Webhooks.Service/WebhookSender.cs index 11b6bf3ab6..2a0ad3284e 100644 --- a/common/services/ASC.Webhooks.Service/WebhookSender.cs +++ b/common/services/ASC.Webhooks.Service/WebhookSender.cs @@ -53,8 +53,7 @@ public class WebhookSender using var scope = _scopeFactory.CreateScope(); var dbWorker = scope.ServiceProvider.GetRequiredService(); - var entry = await dbWorker.ReadJournal(webhookRequest.Id); - var data = entry.Payload; + var entry = await dbWorker.ReadJournal(webhookRequest.Id); var status = 0; string responsePayload = null; @@ -65,13 +64,13 @@ public class WebhookSender try { var httpClient = _clientFactory.CreateClient("webhook"); - var request = new HttpRequestMessage(HttpMethod.Post, entry.Uri) + var request = new HttpRequestMessage(HttpMethod.Post, entry.Config.Uri) { - Content = new StringContent(data, Encoding.UTF8, "application/json") + Content = new StringContent(entry.RequestPayload, Encoding.UTF8, "application/json") }; request.Headers.Add("Accept", "*/*"); - request.Headers.Add("Secret", "SHA256=" + GetSecretHash(entry.SecretKey, data)); + request.Headers.Add("Secret", "SHA256=" + GetSecretHash(entry.Config.SecretKey, entry.RequestPayload)); requestHeaders = JsonSerializer.Serialize(request.Headers.ToDictionary(r => r.Key, v => v.Value), _jsonSerializerOptions); var response = await httpClient.SendAsync(request, cancellationToken); diff --git a/migrations/mysql/WebhooksDbContext/20220818131736_WebhooksDbContext_Upgrade1.Designer.cs b/migrations/mysql/WebhooksDbContext/20220818144209_WebhooksDbContext_Upgrade1.Designer.cs similarity index 85% rename from migrations/mysql/WebhooksDbContext/20220818131736_WebhooksDbContext_Upgrade1.Designer.cs rename to migrations/mysql/WebhooksDbContext/20220818144209_WebhooksDbContext_Upgrade1.Designer.cs index 5013b9c5ca..518e40c72f 100644 --- a/migrations/mysql/WebhooksDbContext/20220818131736_WebhooksDbContext_Upgrade1.Designer.cs +++ b/migrations/mysql/WebhooksDbContext/20220818144209_WebhooksDbContext_Upgrade1.Designer.cs @@ -11,7 +11,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace ASC.Migrations.MySql.Migrations.WebhooksDb { [DbContext(typeof(WebhooksDbContext))] - [Migration("20220818131736_WebhooksDbContext_Upgrade1")] + [Migration("20220818144209_WebhooksDbContext_Upgrade1")] partial class WebhooksDbContext_Upgrade1 { protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -61,6 +61,9 @@ namespace ASC.Migrations.MySql.Migrations.WebhooksDb b.HasKey("Id") .HasName("PRIMARY"); + b.HasIndex("TenantId") + .HasDatabaseName("tenant_id"); + b.ToTable("webhooks_config", (string)null); b.HasAnnotation("MySql:CharSet", "utf8"); @@ -134,10 +137,26 @@ namespace ASC.Migrations.MySql.Migrations.WebhooksDb b.HasKey("Id") .HasName("PRIMARY"); + b.HasIndex("ConfigId"); + + b.HasIndex("TenantId") + .HasDatabaseName("tenant_id"); + b.ToTable("webhooks_logs", (string)null); b.HasAnnotation("MySql:CharSet", "utf8"); }); + + modelBuilder.Entity("ASC.Webhooks.Core.EF.Model.WebhooksLog", b => + { + b.HasOne("ASC.Webhooks.Core.EF.Model.WebhooksConfig", "Config") + .WithMany() + .HasForeignKey("ConfigId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Config"); + }); #pragma warning restore 612, 618 } } diff --git a/migrations/mysql/WebhooksDbContext/20220818131736_WebhooksDbContext_Upgrade1.cs b/migrations/mysql/WebhooksDbContext/20220818144209_WebhooksDbContext_Upgrade1.cs similarity index 70% rename from migrations/mysql/WebhooksDbContext/20220818131736_WebhooksDbContext_Upgrade1.cs rename to migrations/mysql/WebhooksDbContext/20220818144209_WebhooksDbContext_Upgrade1.cs index aaa1b3bfe2..2cc14406df 100644 --- a/migrations/mysql/WebhooksDbContext/20220818131736_WebhooksDbContext_Upgrade1.cs +++ b/migrations/mysql/WebhooksDbContext/20220818144209_WebhooksDbContext_Upgrade1.cs @@ -65,10 +65,49 @@ namespace ASC.Migrations.MySql.Migrations.WebhooksDb nullable: false, defaultValue: "") .Annotation("MySql:CharSet", "utf8"); + + migrationBuilder.CreateIndex( + name: "IX_webhooks_logs_config_id", + table: "webhooks_logs", + column: "config_id"); + + migrationBuilder.CreateIndex( + name: "tenant_id", + table: "webhooks_logs", + column: "tenant_id"); + + migrationBuilder.CreateIndex( + name: "tenant_id", + table: "webhooks_config", + column: "tenant_id"); + + migrationBuilder.AddForeignKey( + name: "FK_webhooks_logs_webhooks_config_config_id", + table: "webhooks_logs", + column: "config_id", + principalTable: "webhooks_config", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); } protected override void Down(MigrationBuilder migrationBuilder) { + migrationBuilder.DropForeignKey( + name: "FK_webhooks_logs_webhooks_config_config_id", + table: "webhooks_logs"); + + migrationBuilder.DropIndex( + name: "IX_webhooks_logs_config_id", + table: "webhooks_logs"); + + migrationBuilder.DropIndex( + name: "tenant_id", + table: "webhooks_logs"); + + migrationBuilder.DropIndex( + name: "tenant_id", + table: "webhooks_config"); + migrationBuilder.DropColumn( name: "delivery", table: "webhooks_logs"); diff --git a/migrations/mysql/WebhooksDbContext/WebhooksDbContextModelSnapshot.cs b/migrations/mysql/WebhooksDbContext/WebhooksDbContextModelSnapshot.cs index 572a03e3a2..13a232a63a 100644 --- a/migrations/mysql/WebhooksDbContext/WebhooksDbContextModelSnapshot.cs +++ b/migrations/mysql/WebhooksDbContext/WebhooksDbContextModelSnapshot.cs @@ -59,6 +59,9 @@ namespace ASC.Migrations.MySql.Migrations b.HasKey("Id") .HasName("PRIMARY"); + b.HasIndex("TenantId") + .HasDatabaseName("tenant_id"); + b.ToTable("webhooks_config", (string)null); b.HasAnnotation("MySql:CharSet", "utf8"); @@ -132,10 +135,26 @@ namespace ASC.Migrations.MySql.Migrations b.HasKey("Id") .HasName("PRIMARY"); + b.HasIndex("ConfigId"); + + b.HasIndex("TenantId") + .HasDatabaseName("tenant_id"); + b.ToTable("webhooks_logs", (string)null); b.HasAnnotation("MySql:CharSet", "utf8"); }); + + modelBuilder.Entity("ASC.Webhooks.Core.EF.Model.WebhooksLog", b => + { + b.HasOne("ASC.Webhooks.Core.EF.Model.WebhooksConfig", "Config") + .WithMany() + .HasForeignKey("ConfigId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Config"); + }); #pragma warning restore 612, 618 } } diff --git a/migrations/postgre/WebhooksDbContext/20220818131736_WebhooksDbContext_Upgrade1.Designer.cs b/migrations/postgre/WebhooksDbContext/20220818144209_WebhooksDbContext_Upgrade1.Designer.cs similarity index 85% rename from migrations/postgre/WebhooksDbContext/20220818131736_WebhooksDbContext_Upgrade1.Designer.cs rename to migrations/postgre/WebhooksDbContext/20220818144209_WebhooksDbContext_Upgrade1.Designer.cs index 8be4da94a0..c94244b6b9 100644 --- a/migrations/postgre/WebhooksDbContext/20220818131736_WebhooksDbContext_Upgrade1.Designer.cs +++ b/migrations/postgre/WebhooksDbContext/20220818144209_WebhooksDbContext_Upgrade1.Designer.cs @@ -12,7 +12,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; namespace ASC.Migrations.PostgreSql.Migrations.WebhooksDb { [DbContext(typeof(WebhooksDbContext))] - [Migration("20220818131736_WebhooksDbContext_Upgrade1")] + [Migration("20220818144209_WebhooksDbContext_Upgrade1")] partial class WebhooksDbContext_Upgrade1 { protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -64,6 +64,9 @@ namespace ASC.Migrations.PostgreSql.Migrations.WebhooksDb b.HasKey("Id") .HasName("PRIMARY"); + b.HasIndex("TenantId") + .HasDatabaseName("tenant_id"); + b.ToTable("webhooks_config", (string)null); }); @@ -131,8 +134,24 @@ namespace ASC.Migrations.PostgreSql.Migrations.WebhooksDb b.HasKey("Id") .HasName("PRIMARY"); + b.HasIndex("ConfigId"); + + b.HasIndex("TenantId") + .HasDatabaseName("tenant_id"); + b.ToTable("webhooks_logs", (string)null); }); + + modelBuilder.Entity("ASC.Webhooks.Core.EF.Model.WebhooksLog", b => + { + b.HasOne("ASC.Webhooks.Core.EF.Model.WebhooksConfig", "Config") + .WithMany() + .HasForeignKey("ConfigId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Config"); + }); #pragma warning restore 612, 618 } } diff --git a/migrations/postgre/WebhooksDbContext/20220818131736_WebhooksDbContext_Upgrade1.cs b/migrations/postgre/WebhooksDbContext/20220818144209_WebhooksDbContext_Upgrade1.cs similarity index 67% rename from migrations/postgre/WebhooksDbContext/20220818131736_WebhooksDbContext_Upgrade1.cs rename to migrations/postgre/WebhooksDbContext/20220818144209_WebhooksDbContext_Upgrade1.cs index 551e4e04f8..75c35a3790 100644 --- a/migrations/postgre/WebhooksDbContext/20220818131736_WebhooksDbContext_Upgrade1.cs +++ b/migrations/postgre/WebhooksDbContext/20220818144209_WebhooksDbContext_Upgrade1.cs @@ -55,10 +55,49 @@ namespace ASC.Migrations.PostgreSql.Migrations.WebhooksDb maxLength: 50, nullable: false, defaultValue: ""); + + migrationBuilder.CreateIndex( + name: "IX_webhooks_logs_config_id", + table: "webhooks_logs", + column: "config_id"); + + migrationBuilder.CreateIndex( + name: "tenant_id", + table: "webhooks_logs", + column: "tenant_id"); + + migrationBuilder.CreateIndex( + name: "tenant_id", + table: "webhooks_config", + column: "tenant_id"); + + migrationBuilder.AddForeignKey( + name: "FK_webhooks_logs_webhooks_config_config_id", + table: "webhooks_logs", + column: "config_id", + principalTable: "webhooks_config", + principalColumn: "id", + onDelete: ReferentialAction.Cascade); } protected override void Down(MigrationBuilder migrationBuilder) { + migrationBuilder.DropForeignKey( + name: "FK_webhooks_logs_webhooks_config_config_id", + table: "webhooks_logs"); + + migrationBuilder.DropIndex( + name: "IX_webhooks_logs_config_id", + table: "webhooks_logs"); + + migrationBuilder.DropIndex( + name: "tenant_id", + table: "webhooks_logs"); + + migrationBuilder.DropIndex( + name: "tenant_id", + table: "webhooks_config"); + migrationBuilder.DropColumn( name: "delivery", table: "webhooks_logs"); diff --git a/migrations/postgre/WebhooksDbContext/WebhooksDbContextModelSnapshot.cs b/migrations/postgre/WebhooksDbContext/WebhooksDbContextModelSnapshot.cs index 2574b48b25..0c5af441ed 100644 --- a/migrations/postgre/WebhooksDbContext/WebhooksDbContextModelSnapshot.cs +++ b/migrations/postgre/WebhooksDbContext/WebhooksDbContextModelSnapshot.cs @@ -62,6 +62,9 @@ namespace ASC.Migrations.PostgreSql.Migrations b.HasKey("Id") .HasName("PRIMARY"); + b.HasIndex("TenantId") + .HasDatabaseName("tenant_id"); + b.ToTable("webhooks_config", (string)null); }); @@ -129,8 +132,24 @@ namespace ASC.Migrations.PostgreSql.Migrations b.HasKey("Id") .HasName("PRIMARY"); + b.HasIndex("ConfigId"); + + b.HasIndex("TenantId") + .HasDatabaseName("tenant_id"); + b.ToTable("webhooks_logs", (string)null); }); + + modelBuilder.Entity("ASC.Webhooks.Core.EF.Model.WebhooksLog", b => + { + b.HasOne("ASC.Webhooks.Core.EF.Model.WebhooksConfig", "Config") + .WithMany() + .HasForeignKey("ConfigId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Config"); + }); #pragma warning restore 612, 618 } } diff --git a/web/ASC.Web.Api/ApiModels/ResponseDto/WebhooksLogDto.cs b/web/ASC.Web.Api/ApiModels/ResponseDto/WebhooksLogDto.cs index e8589edae7..8c91ad336c 100644 --- a/web/ASC.Web.Api/ApiModels/ResponseDto/WebhooksLogDto.cs +++ b/web/ASC.Web.Api/ApiModels/ResponseDto/WebhooksLogDto.cs @@ -28,9 +28,9 @@ namespace ASC.Web.Api.ApiModels.ResponseDto; public class WebhooksLogDto : IMapFrom { - public string ConfigId { get; set; } - public DateTime CreationTime { get; set; } public int Id { get; set; } + public string ConfigName { get; set; } + public DateTime CreationTime { get; set; } public string Method { get; set; } public string Route { get; set; } public string RequestHeaders { get; set; }