Added models, DbWorker, publisher, sender.

This commit is contained in:
Vashchuk Nikita 2021-06-29 11:40:20 +03:00
parent bb321da952
commit 5305ad1018
9 changed files with 324 additions and 0 deletions

View File

@ -89,6 +89,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.SsoAuth.Svc", "common\s
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.CRM.BackgroundTasks", "products\ASC.CRM\BackgroundTasks\ASC.CRM.BackgroundTasks.csproj", "{E52C0E35-A05C-437F-8FF2-3E0AC9F81433}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ASC.Webhooks", "common\ASC.Webhooks\ASC.Webhooks.csproj", "{760BFF3A-1A67-43A1-A94C-78D11A4BB1E6}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -251,6 +253,10 @@ Global
{E52C0E35-A05C-437F-8FF2-3E0AC9F81433}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E52C0E35-A05C-437F-8FF2-3E0AC9F81433}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E52C0E35-A05C-437F-8FF2-3E0AC9F81433}.Release|Any CPU.Build.0 = Release|Any CPU
{760BFF3A-1A67-43A1-A94C-78D11A4BB1E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{760BFF3A-1A67-43A1-A94C-78D11A4BB1E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{760BFF3A-1A67-43A1-A94C-78D11A4BB1E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{760BFF3A-1A67-43A1-A94C-78D11A4BB1E6}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<IsPackable>false</IsPackable>
<DefaultItemExcludes>$(DefaultItemExcludes);</DefaultItemExcludes>
<RazorCompileOnBuild>false</RazorCompileOnBuild>
<GenerateMvcApplicationPartsAssemblyAttributes>false</GenerateMvcApplicationPartsAssemblyAttributes>
<OutputType>Library</OutputType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DebugType>none</DebugType>
<DebugSymbols>false</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Autofac.Extensions.DependencyInjection" Version="7.1.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="5.0.7">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.Extensions.Hosting.Systemd" Version="5.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
<PackageReference Include="MySql.Data.EntityFrameworkCore" Version="8.0.21" />
<PackageReference Include="MySql.EntityFrameworkCore" Version="5.0.3.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\common\ASC.Api.Core\ASC.Api.Core.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,10 @@
#nullable disable
namespace ASC.Webhooks.Dao.Models
{
public partial class WebhooksConfig
{
public int TenantId { get; set; }
public string Uri { get; set; }
}
}

View File

@ -0,0 +1,15 @@
using System;
#nullable disable
namespace ASC.Webhooks.Dao.Models
{
public partial class WebhooksPayload
{
public int Id { get; set; }
public int TenantId { get; set; }
public string Data { get; set; }
public DateTime CreationTime { get; set; }
public EventName Event { get; set; }
}
}

View File

@ -0,0 +1,81 @@
using ASC.Core.Common.EF;
using ASC.Webhooks.Dao.Models;
using Microsoft.EntityFrameworkCore;
#nullable disable
namespace ASC.Webhooks.Dao
{
public partial class WebhooksDbContext : BaseDbContext
{
public WebhooksDbContext()
{
}
public WebhooksDbContext(DbContextOptions<WebhooksDbContext> options)
: base(options)
{
}
public virtual DbSet<WebhooksConfig> WebhooksConfigs { get; set; }
public virtual DbSet<WebhooksPayload> WebhooksPayloads { get; set; }
// protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
// {
// if (!optionsBuilder.IsConfigured)
// {
//#warning To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263.
// optionsBuilder.UseMySQL("server=localhost;port=3306;database=onlyoffice;uid=root;password=onlyoffice");
// }
// }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<WebhooksConfig>(entity =>
{
entity.HasKey(e => new { e.TenantId, e.Uri })
.HasName("PRIMARY");
entity.ToTable("webhooks_config");
entity.Property(e => e.TenantId).HasColumnType("int unsigned");
entity.Property(e => e.Uri)
.HasMaxLength(50)
.HasColumnName("URI")
.HasDefaultValueSql("''");
});
modelBuilder.Entity<WebhooksPayload>(entity =>
{
entity.HasKey(e => new { e.Id })
.HasName("PRIMARY");
entity.ToTable("webhooks_payload");
entity.Property(e => e.Id)
.HasColumnType("int")
.HasColumnName("ID")
.ValueGeneratedOnAdd();
entity.Property(e => e.Data)
.IsRequired()
.HasColumnType("json");
entity.Property(e => e.Event)
.HasColumnType("varchar")
.HasColumnName("EventID")
.HasMaxLength(50);
entity.Property(e => e.TenantId)
.HasColumnType("int unsigned")
.HasColumnName("TenantID");
});
OnModelCreatingPartial(modelBuilder);
}
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}
}

View File

@ -0,0 +1,37 @@
using System.Collections.Generic;
using System.Linq;
using ASC.Common;
using ASC.Core.Common.EF;
using ASC.Webhooks.Dao;
using ASC.Webhooks.Dao.Models;
namespace ASC.Webhooks
{
[Scope]
public class DbWorker
{
public WebhooksDbContext webhooksContext { get; }
public DbWorker(DbContextManager<WebhooksDbContext> dbContext)
{
webhooksContext = dbContext.Get("webhooks");
}
public void WriteToJournal(WebhooksPayload webhook)
{
webhooksContext.WebhooksPayloads.Add(webhook);
webhooksContext.SaveChanges();
}
public void AddWebhookConfig(WebhooksConfig webhooksConfig)
{
webhooksContext.WebhooksConfigs.Add(webhooksConfig);
webhooksContext.SaveChanges();
}
public List<string> GetWebhookUri(int tenant)
{
return webhooksContext.WebhooksConfigs.Where(t => t.TenantId == tenant).Select(it => it.Uri).ToList();
}
}
}

View File

@ -0,0 +1,27 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:63599/",
"sslPort": 44357
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"ASC.Webhooks": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:5001;http://localhost:5000"
}
}
}

View File

@ -0,0 +1,49 @@
using System;
using System.Text.Json;
using ASC.Common;
using ASC.Core;
using ASC.Webhooks.Dao.Models;
namespace ASC.Webhooks
{
[Scope]
public class WebhookPublisher
{
private DbWorker DbWorker { get; }
private TenantManager TenantManager { get; }
private WebhookSender WebhookSender { get; }
public WebhookPublisher(DbWorker dbWorker, TenantManager tenantManager, WebhookSender webhookSender)
{
DbWorker = dbWorker;
TenantManager = tenantManager;
WebhookSender = webhookSender;
}
public void Publish(EventName name)
{
var result = WebhookSender.Send(name);
if (result)
{
var tenantId = TenantManager.GetCurrentTenant().TenantId;
var webhooksPayload = new WebhooksPayload
{
TenantId = tenantId,
Event = name,
CreationTime = DateTime.UtcNow,
Data = JsonSerializer.Serialize(name),
};
DbWorker.WriteToJournal(webhooksPayload);
}
}
}
public struct EventName
{
public const string NewUserRegistered = "NewUserRegistered";
public const string TenantDeleted = "TenantDeleted";
}
}

View File

@ -0,0 +1,66 @@
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Text.Json;
using ASC.Common;
using ASC.Core;
namespace ASC.Webhooks
{
[Scope]
public class WebhookSender
{
private DbWorker DbWorker { get; }
private TenantManager TenantManager { get; }
public WebhookSender(DbWorker dbWorker, TenantManager tenantManager)
{
DbWorker = dbWorker;
TenantManager = tenantManager;
}
public bool Send(EventName eventName)
{
var tenantId = TenantManager.GetCurrentTenant().TenantId;
var requestURIList = DbWorker.GetWebhookUri(tenantId);
foreach (var requestUrl in requestURIList)
{
try
{
var webRequest = WebRequest.Create(requestUrl);
webRequest.Method = "POST";
webRequest.ContentType = "application/json";
webRequest.Headers.Add("Secret", GetSecret("secretKey"));
var data = JsonSerializer.Serialize(eventName);
var encoding = new UTF8Encoding();
byte[] bytes = encoding.GetBytes(data);
webRequest.ContentLength = bytes.Length;
using (var writeStream = webRequest.GetRequestStream())
{
writeStream.Write(bytes, 0, bytes.Length);
}
using (var webResponse = webRequest.GetResponse())
using (var reader = new StreamReader(webResponse.GetResponseStream()))
{
string responseFromServer = reader.ReadToEnd();
return true;
}
}
catch (Exception ex)
{
continue;
}
}
return false;
}
private string GetSecret(string secretKey)
{
return "";
}
}
}