Merge branch 'develop' into feature/inifinite-scroll
This commit is contained in:
commit
bd9ffb1450
14
build/Jenkinsfile
vendored
14
build/Jenkinsfile
vendored
@ -43,20 +43,20 @@ pipeline {
|
||||
stages {
|
||||
stage('Components') {
|
||||
steps {
|
||||
sh "yarn install --frozen-lockfile && yarn build && cd ${env.WORKSPACE}/packages/asc-web-components && yarn test:coverage --ci --reporters=default --reporters=jest-junit || true"
|
||||
sh "yarn install --frozen-lockfile && yarn build && cd ${env.WORKSPACE}/packages/components && yarn test:coverage --ci --reporters=default --reporters=jest-junit || true"
|
||||
}
|
||||
post {
|
||||
success {
|
||||
junit 'packages/asc-web-components/junit.xml'
|
||||
junit 'packages/components/junit.xml'
|
||||
publishHTML target: [
|
||||
allowMissing : false,
|
||||
alwaysLinkToLastBuild: false,
|
||||
keepAll : true,
|
||||
reportDir : 'packages/asc-web-components/coverage/lcov-report',
|
||||
reportDir : 'packages/components/coverage/lcov-report',
|
||||
reportFiles : 'index.html',
|
||||
reportName : 'Unix Test Report'
|
||||
]
|
||||
publishCoverage adapters: [coberturaAdapter('packages/asc-web-components/coverage/cobertura-coverage.xml')]
|
||||
publishCoverage adapters: [coberturaAdapter('packages/components/coverage/cobertura-coverage.xml')]
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -72,16 +72,16 @@ pipeline {
|
||||
stages {
|
||||
stage('Components') {
|
||||
steps {
|
||||
bat "yarn install --frozen-lockfile && yarn build && cd ${env.WORKSPACE}\\packages\\asc-web-components && yarn test:coverage --ci --reporters=default --reporters=jest-junit || true"
|
||||
bat "yarn install --frozen-lockfile && yarn build && cd ${env.WORKSPACE}\\packages\\components && yarn test:coverage --ci --reporters=default --reporters=jest-junit || true"
|
||||
}
|
||||
post {
|
||||
success {
|
||||
junit 'packages\\asc-web-components\\junit.xml'
|
||||
junit 'packages\\components\\junit.xml'
|
||||
publishHTML target: [
|
||||
allowMissing : false,
|
||||
alwaysLinkToLastBuild: false,
|
||||
keepAll : true,
|
||||
reportDir : 'packages\\asc-web-components\\coverage\\lcov-report',
|
||||
reportDir : 'packages\\components\\coverage\\lcov-report',
|
||||
reportFiles : 'index.html',
|
||||
reportName : 'Windows Test Report'
|
||||
]
|
||||
|
@ -1,5 +1,6 @@
|
||||
@echo "MIGRATIONS"
|
||||
@echo off
|
||||
|
||||
PUSHD %~dp0..\common\Tools\Migration.Creator
|
||||
dotnet run --project Migration.Creator.csproj
|
||||
PUSHD %~dp0..\common\Tools\ASC.Migration.Creator
|
||||
dotnet run --project ASC.Migration.Creator.csproj
|
||||
pause
|
@ -24,8 +24,6 @@
|
||||
// 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
|
||||
|
||||
global using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
global using System.Collections.Concurrent;
|
||||
global using System.ComponentModel;
|
||||
global using System.Globalization;
|
||||
global using System.Linq.Expressions;
|
||||
@ -36,6 +34,7 @@ global using System.Runtime.Serialization;
|
||||
global using System.Security;
|
||||
global using System.Security.Authentication;
|
||||
global using System.Security.Claims;
|
||||
global using System.Text;
|
||||
global using System.Text.Encodings.Web;
|
||||
global using System.Text.Json;
|
||||
global using System.Text.Json.Serialization;
|
||||
@ -56,8 +55,8 @@ global using ASC.AuditTrail.Types;
|
||||
global using ASC.Common;
|
||||
global using ASC.Common.Caching;
|
||||
global using ASC.Common.DependencyInjection;
|
||||
global using ASC.Common.Log;
|
||||
global using ASC.Common.Logging;
|
||||
global using ASC.Common.Mapping;
|
||||
global using ASC.Common.Notify.Engine;
|
||||
global using ASC.Common.Threading;
|
||||
global using ASC.Common.Utils;
|
||||
@ -119,6 +118,7 @@ global using Microsoft.AspNetCore.WebUtilities;
|
||||
global using Microsoft.EntityFrameworkCore;
|
||||
global using Microsoft.Extensions.Configuration;
|
||||
global using Microsoft.Extensions.DependencyInjection;
|
||||
global using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
global using Microsoft.Extensions.Diagnostics.HealthChecks;
|
||||
global using Microsoft.Extensions.Hosting;
|
||||
global using Microsoft.Extensions.Logging;
|
||||
|
@ -24,8 +24,6 @@
|
||||
// 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 System.Text;
|
||||
|
||||
namespace ASC.Api.Core.Middleware;
|
||||
|
||||
[Scope]
|
||||
@ -34,12 +32,14 @@ public class WebhooksGlobalFilterAttribute : ResultFilterAttribute, IDisposable
|
||||
private readonly MemoryStream _stream;
|
||||
private Stream _bodyStream;
|
||||
private readonly IWebhookPublisher _webhookPublisher;
|
||||
private readonly ILogger<WebhooksGlobalFilterAttribute> _logger;
|
||||
private static readonly List<string> _methodList = new List<string> { "POST", "UPDATE", "DELETE" };
|
||||
|
||||
public WebhooksGlobalFilterAttribute(IWebhookPublisher webhookPublisher)
|
||||
public WebhooksGlobalFilterAttribute(IWebhookPublisher webhookPublisher, ILogger<WebhooksGlobalFilterAttribute> logger)
|
||||
{
|
||||
_stream = new MemoryStream();
|
||||
_webhookPublisher = webhookPublisher;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
public override void OnResultExecuting(ResultExecutingContext context)
|
||||
@ -68,11 +68,18 @@ public class WebhooksGlobalFilterAttribute : ResultFilterAttribute, IDisposable
|
||||
await _stream.CopyToAsync(_bodyStream);
|
||||
context.HttpContext.Response.Body = _bodyStream;
|
||||
|
||||
var (method, routePattern) = GetData(context.HttpContext);
|
||||
try
|
||||
{
|
||||
var (method, routePattern) = GetData(context.HttpContext);
|
||||
|
||||
var resultContent = Encoding.UTF8.GetString(_stream.ToArray());
|
||||
var eventName = $"method: {method}, route: {routePattern}";
|
||||
_webhookPublisher.Publish(eventName, resultContent);
|
||||
var resultContent = Encoding.UTF8.GetString(_stream.ToArray());
|
||||
|
||||
await _webhookPublisher.PublishAsync(method, routePattern, resultContent);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_logger.ErrorWithException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<T> Entity<T>() where T : class
|
||||
{
|
||||
return ModelBuilder.Entity<T>();
|
||||
}
|
||||
|
||||
public void AddDbFunction()
|
||||
{
|
||||
ModelBuilder
|
||||
|
@ -30,117 +30,186 @@ namespace ASC.Webhooks.Core;
|
||||
public class DbWorker
|
||||
{
|
||||
private readonly IDbContextFactory<WebhooksDbContext> _dbContextFactory;
|
||||
private readonly TenantManager _tenantManager;
|
||||
public DbWorker(IDbContextFactory<WebhooksDbContext> dbContextFactory, TenantManager tenantManager)
|
||||
private readonly TenantManager _tenantManager;
|
||||
private readonly AuthContext _authContext;
|
||||
|
||||
private int Tenant
|
||||
{
|
||||
get
|
||||
{
|
||||
return _tenantManager.GetCurrentTenant().Id;
|
||||
}
|
||||
}
|
||||
|
||||
public DbWorker(IDbContextFactory<WebhooksDbContext> dbContextFactory, TenantManager tenantManager, AuthContext authContext)
|
||||
{
|
||||
_dbContextFactory = dbContextFactory;
|
||||
_tenantManager = tenantManager;
|
||||
}
|
||||
public void AddWebhookConfig(WebhooksConfig webhooksConfig)
|
||||
{
|
||||
webhooksConfig.TenantId = _tenantManager.GetCurrentTenant().Id;
|
||||
|
||||
using var webhooksDbContext = _dbContextFactory.CreateDbContext();
|
||||
_tenantManager = tenantManager;
|
||||
_authContext = authContext;
|
||||
}
|
||||
|
||||
var addObj = webhooksDbContext.WebhooksConfigs.Where(it =>
|
||||
it.SecretKey == webhooksConfig.SecretKey &&
|
||||
it.TenantId == webhooksConfig.TenantId &&
|
||||
it.Uri == webhooksConfig.Uri).FirstOrDefault();
|
||||
|
||||
if (addObj != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
webhooksDbContext.WebhooksConfigs.Add(webhooksConfig);
|
||||
webhooksDbContext.SaveChanges();
|
||||
}
|
||||
|
||||
public int ConfigsNumber()
|
||||
public async Task<WebhooksConfig> AddWebhookConfig(string name, string uri, string secretKey)
|
||||
{
|
||||
using var webhooksDbContext = _dbContextFactory.CreateDbContext();
|
||||
return webhooksDbContext.WebhooksConfigs.Count();
|
||||
|
||||
var toAdd = new WebhooksConfig { TenantId = Tenant, Uri = uri, SecretKey = secretKey, Name = name };
|
||||
toAdd = await webhooksDbContext.AddOrUpdateAsync(r => r.WebhooksConfigs, toAdd);
|
||||
await webhooksDbContext.SaveChangesAsync();
|
||||
|
||||
return toAdd;
|
||||
}
|
||||
|
||||
public List<WebhooksLog> GetTenantWebhooks()
|
||||
public async IAsyncEnumerable<WebhooksConfig> GetTenantWebhooks()
|
||||
{
|
||||
using var webhooksDbContext = _dbContextFactory.CreateDbContext();
|
||||
|
||||
var q = webhooksDbContext.WebhooksConfigs
|
||||
.AsNoTracking()
|
||||
.Where(it => it.TenantId == Tenant)
|
||||
.AsAsyncEnumerable();
|
||||
|
||||
await foreach (var webhook in q)
|
||||
{
|
||||
yield return webhook;
|
||||
}
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<WebhooksConfig> GetWebhookConfigs()
|
||||
{
|
||||
var webhooksDbContext = _dbContextFactory.CreateDbContext();
|
||||
|
||||
return webhooksDbContext.WebhooksConfigs
|
||||
.Where(t => t.TenantId == Tenant)
|
||||
.AsAsyncEnumerable();
|
||||
}
|
||||
|
||||
public async Task<WebhooksConfig> UpdateWebhookConfig(int id, string name, string uri, string key, bool? enabled)
|
||||
{
|
||||
using var webhooksDbContext = _dbContextFactory.CreateDbContext();
|
||||
|
||||
var updateObj = await webhooksDbContext.WebhooksConfigs
|
||||
.Where(it => it.TenantId == Tenant && it.Id == id)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
if (updateObj != null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(uri))
|
||||
{
|
||||
updateObj.Uri = uri;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(name))
|
||||
{
|
||||
updateObj.Name = name;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(key))
|
||||
{
|
||||
updateObj.SecretKey = key;
|
||||
}
|
||||
|
||||
if (enabled.HasValue)
|
||||
{
|
||||
updateObj.Enabled = enabled.Value;
|
||||
}
|
||||
|
||||
webhooksDbContext.WebhooksConfigs.Update(updateObj);
|
||||
await webhooksDbContext.SaveChangesAsync();
|
||||
}
|
||||
|
||||
return updateObj;
|
||||
}
|
||||
|
||||
public async Task<WebhooksConfig> RemoveWebhookConfig(int id)
|
||||
{
|
||||
var tenant = _tenantManager.GetCurrentTenant().Id;
|
||||
|
||||
using var webhooksDbContext = _dbContextFactory.CreateDbContext();
|
||||
return webhooksDbContext.WebhooksLogs.Where(it => it.TenantId == tenant)
|
||||
.Select(t => new WebhooksLog
|
||||
{
|
||||
Uid = t.Uid,
|
||||
CreationTime = t.CreationTime,
|
||||
RequestPayload = t.RequestPayload,
|
||||
RequestHeaders = t.RequestHeaders,
|
||||
ResponsePayload = t.ResponsePayload,
|
||||
ResponseHeaders = t.ResponseHeaders,
|
||||
Status = t.Status
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
public List<WebhooksConfig> GetWebhookConfigs(int tenant)
|
||||
{
|
||||
using var webhooksDbContext = _dbContextFactory.CreateDbContext();
|
||||
return webhooksDbContext.WebhooksConfigs.Where(t => t.TenantId == tenant).ToList();
|
||||
}
|
||||
|
||||
public WebhookEntry ReadFromJournal(int id)
|
||||
{
|
||||
using var webhooksDbContext = _dbContextFactory.CreateDbContext();
|
||||
return webhooksDbContext.WebhooksLogs
|
||||
.Where(it => it.Id == id)
|
||||
.Join(webhooksDbContext.WebhooksConfigs, t => t.ConfigId, t => t.ConfigId, (payload, config) => new { payload, config })
|
||||
.Select(t => new WebhookEntry { Id = t.payload.Id, Payload = t.payload.RequestPayload, SecretKey = t.config.SecretKey, Uri = t.config.Uri })
|
||||
.OrderBy(t => t.Id).FirstOrDefault();
|
||||
}
|
||||
|
||||
public void RemoveWebhookConfig(WebhooksConfig webhooksConfig)
|
||||
{
|
||||
webhooksConfig.TenantId = _tenantManager.GetCurrentTenant().Id;
|
||||
using var webhooksDbContext = _dbContextFactory.CreateDbContext();
|
||||
|
||||
using var webhooksDbContext = _dbContextFactory.CreateDbContext();
|
||||
var removeObj = webhooksDbContext.WebhooksConfigs.Where(it =>
|
||||
it.SecretKey == webhooksConfig.SecretKey &&
|
||||
it.TenantId == webhooksConfig.TenantId &&
|
||||
it.Uri == webhooksConfig.Uri).FirstOrDefault();
|
||||
var removeObj = await webhooksDbContext.WebhooksConfigs
|
||||
.Where(it => it.TenantId == tenant && it.Id == id)
|
||||
.FirstOrDefaultAsync();
|
||||
|
||||
webhooksDbContext.WebhooksConfigs.Remove(removeObj);
|
||||
webhooksDbContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void UpdateWebhookConfig(WebhooksConfig webhooksConfig)
|
||||
{
|
||||
webhooksConfig.TenantId = _tenantManager.GetCurrentTenant().Id;
|
||||
await webhooksDbContext.SaveChangesAsync();
|
||||
|
||||
using var webhooksDbContext = _dbContextFactory.CreateDbContext();
|
||||
var updateObj = webhooksDbContext.WebhooksConfigs.Where(it =>
|
||||
it.SecretKey == webhooksConfig.SecretKey &&
|
||||
it.TenantId == webhooksConfig.TenantId &&
|
||||
it.Uri == webhooksConfig.Uri).FirstOrDefault();
|
||||
|
||||
webhooksDbContext.WebhooksConfigs.Update(updateObj);
|
||||
webhooksDbContext.SaveChanges();
|
||||
}
|
||||
|
||||
public void UpdateWebhookJournal(int id, ProcessStatus status, string responsePayload, string responseHeaders, string requestHeaders)
|
||||
return removeObj;
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<WebhooksLog> ReadJournal(int startIndex, int limit, DateTime? delivery, string hookname, string route)
|
||||
{
|
||||
using var webhooksDbContext = _dbContextFactory.CreateDbContext();
|
||||
var webhook = webhooksDbContext.WebhooksLogs.Where(t => t.Id == id).FirstOrDefault();
|
||||
var webhooksDbContext = _dbContextFactory.CreateDbContext();
|
||||
|
||||
var q = webhooksDbContext.WebhooksLogs
|
||||
.AsNoTracking()
|
||||
.Where(r => r.TenantId == Tenant);
|
||||
|
||||
if (delivery.HasValue)
|
||||
{
|
||||
var date = delivery.Value;
|
||||
q = q.Where(r => r.Delivery == date);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(hookname))
|
||||
{
|
||||
q = q.Where(r => r.Config.Name == hookname);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(route))
|
||||
{
|
||||
q = q.Where(r => r.Route == route);
|
||||
}
|
||||
|
||||
if (startIndex != 0)
|
||||
{
|
||||
q = q.Skip(startIndex);
|
||||
}
|
||||
|
||||
if (limit != 0)
|
||||
{
|
||||
q = q.Take(limit);
|
||||
}
|
||||
|
||||
return q.OrderByDescending(t => t.Id).AsAsyncEnumerable();
|
||||
}
|
||||
|
||||
public async Task<WebhooksLog> ReadJournal(int id)
|
||||
{
|
||||
using var webhooksDbContext = _dbContextFactory.CreateDbContext();
|
||||
|
||||
return await webhooksDbContext.WebhooksLogs
|
||||
.AsNoTracking()
|
||||
.Where(it => it.Id == id)
|
||||
.FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public async Task<WebhooksLog> WriteToJournal(WebhooksLog webhook)
|
||||
{
|
||||
webhook.TenantId = _tenantManager.GetCurrentTenant().Id;
|
||||
webhook.Uid = _authContext.CurrentAccount.ID;
|
||||
|
||||
using var webhooksDbContext = _dbContextFactory.CreateDbContext();
|
||||
|
||||
var entity = await webhooksDbContext.WebhooksLogs.AddAsync(webhook);
|
||||
await webhooksDbContext.SaveChangesAsync();
|
||||
|
||||
return entity.Entity;
|
||||
}
|
||||
|
||||
public async Task<WebhooksLog> UpdateWebhookJournal(int id, int status, DateTime delivery, string requestHeaders, string responsePayload, string responseHeaders)
|
||||
{
|
||||
using var webhooksDbContext = _dbContextFactory.CreateDbContext();
|
||||
|
||||
var webhook = await webhooksDbContext.WebhooksLogs.Where(t => t.Id == id).FirstOrDefaultAsync();
|
||||
webhook.Status = status;
|
||||
webhook.RequestHeaders = requestHeaders;
|
||||
webhook.ResponsePayload = responsePayload;
|
||||
webhook.ResponseHeaders = responseHeaders;
|
||||
webhook.RequestHeaders = requestHeaders;
|
||||
webhooksDbContext.WebhooksLogs.Update(webhook);
|
||||
webhooksDbContext.SaveChanges();
|
||||
}
|
||||
webhook.ResponseHeaders = responseHeaders;
|
||||
webhook.Delivery = delivery;
|
||||
|
||||
public int WriteToJournal(WebhooksLog webhook)
|
||||
{
|
||||
using var webhooksDbContext = _dbContextFactory.CreateDbContext();
|
||||
var entity = webhooksDbContext.WebhooksLogs.Add(webhook);
|
||||
webhooksDbContext.SaveChanges();
|
||||
return entity.Entity.Id;
|
||||
webhooksDbContext.WebhooksLogs.Update(webhook);
|
||||
await webhooksDbContext.SaveChangesAsync();
|
||||
|
||||
return webhook;
|
||||
}
|
||||
}
|
@ -28,8 +28,8 @@ namespace ASC.Webhooks.Core.EF.Context;
|
||||
|
||||
public class WebhooksDbContext : DbContext
|
||||
{
|
||||
public virtual DbSet<WebhooksConfig> WebhooksConfigs { get; set; }
|
||||
public virtual DbSet<WebhooksLog> WebhooksLogs { get; set; }
|
||||
public DbSet<WebhooksConfig> WebhooksConfigs { get; set; }
|
||||
public DbSet<WebhooksLog> WebhooksLogs { get; set; }
|
||||
|
||||
public WebhooksDbContext(DbContextOptions<WebhooksDbContext> options) : base(options) { }
|
||||
|
||||
|
@ -25,12 +25,20 @@
|
||||
// International. See the License terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode
|
||||
|
||||
namespace ASC.Webhooks.Core.EF.Model;
|
||||
public partial class WebhooksConfig
|
||||
|
||||
public class WebhooksConfig : BaseEntity
|
||||
{
|
||||
public int ConfigId { get; set; }
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string SecretKey { get; set; }
|
||||
public int TenantId { get; set; }
|
||||
public string Uri { get; set; }
|
||||
public string Uri { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
|
||||
public override object[] GetKeys()
|
||||
{
|
||||
return new object[] { Id };
|
||||
}
|
||||
}
|
||||
|
||||
public static class WebhooksConfigExtension
|
||||
@ -46,15 +54,18 @@ public static class WebhooksConfigExtension
|
||||
{
|
||||
modelBuilder.Entity<WebhooksConfig>(entity =>
|
||||
{
|
||||
entity.HasKey(e => new { e.ConfigId })
|
||||
.HasName("PRIMARY");
|
||||
entity.HasKey(e => new { e.Id })
|
||||
.HasName("PRIMARY");
|
||||
|
||||
entity.HasIndex(e => e.TenantId)
|
||||
.HasDatabaseName("tenant_id");
|
||||
|
||||
entity.ToTable("webhooks_config")
|
||||
.HasCharSet("utf8");
|
||||
|
||||
entity.Property(e => e.ConfigId)
|
||||
entity.Property(e => e.Id)
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("config_id");
|
||||
.HasColumnName("id");
|
||||
|
||||
entity.Property(e => e.TenantId)
|
||||
.HasColumnName("tenant_id")
|
||||
@ -68,7 +79,17 @@ public static class WebhooksConfigExtension
|
||||
entity.Property(e => e.SecretKey)
|
||||
.HasMaxLength(50)
|
||||
.HasColumnName("secret_key")
|
||||
.HasDefaultValueSql("''");
|
||||
.HasDefaultValueSql("''");
|
||||
|
||||
entity.Property(e => e.Name)
|
||||
.HasMaxLength(50)
|
||||
.HasColumnName("name")
|
||||
.IsRequired();
|
||||
|
||||
entity.Property(e => e.Enabled)
|
||||
.HasColumnName("enabled")
|
||||
.HasDefaultValueSql("'1'")
|
||||
.HasColumnType("tinyint(1)");
|
||||
});
|
||||
}
|
||||
|
||||
@ -76,14 +97,17 @@ public static class WebhooksConfigExtension
|
||||
{
|
||||
modelBuilder.Entity<WebhooksConfig>(entity =>
|
||||
{
|
||||
entity.HasKey(e => new { e.ConfigId })
|
||||
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.ConfigId)
|
||||
entity.Property(e => e.Id)
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("config_id");
|
||||
.HasColumnName("id");
|
||||
|
||||
entity.Property(e => e.TenantId)
|
||||
.HasColumnName("tenant_id")
|
||||
@ -97,7 +121,16 @@ public static class WebhooksConfigExtension
|
||||
entity.Property(e => e.SecretKey)
|
||||
.HasMaxLength(50)
|
||||
.HasColumnName("secret_key")
|
||||
.HasDefaultValueSql("''");
|
||||
.HasDefaultValueSql("''");
|
||||
|
||||
entity.Property(e => e.Name)
|
||||
.HasMaxLength(50)
|
||||
.HasColumnName("name")
|
||||
.IsRequired();
|
||||
|
||||
entity.Property(e => e.Enabled)
|
||||
.HasColumnName("enabled")
|
||||
.HasDefaultValueSql("true");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -26,25 +26,31 @@
|
||||
|
||||
namespace ASC.Webhooks.Core.EF.Model;
|
||||
|
||||
public partial class WebhooksLog
|
||||
public class WebhooksLog
|
||||
{
|
||||
public int ConfigId { get; set; }
|
||||
public DateTime CreationTime { get; set; }
|
||||
public string Event { get; set; }
|
||||
public int Id { get; set; }
|
||||
public int Id { get; set; }
|
||||
public string Method { get; set; }
|
||||
public string Route { get; set; }
|
||||
public string RequestHeaders { get; set; }
|
||||
public string RequestPayload { get; set; }
|
||||
public string ResponseHeaders { get; set; }
|
||||
public string ResponsePayload { get; set; }
|
||||
public ProcessStatus Status { get; set; }
|
||||
public int Status { get; set; }
|
||||
public int TenantId { get; set; }
|
||||
public string Uid { get; set; }
|
||||
public Guid Uid { 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<WebhooksLog>().Navigation(e => e.Config).AutoInclude();
|
||||
|
||||
modelBuilder
|
||||
.Add(MySqlAddWebhooksLog, Provider.MySql)
|
||||
.Add(PgSqlAddWebhooksLog, Provider.PostgreSql);
|
||||
@ -60,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")
|
||||
@ -72,9 +81,10 @@ public static class WebhooksPayloadExtension
|
||||
.HasColumnName("config_id");
|
||||
|
||||
entity.Property(e => e.Uid)
|
||||
.HasColumnType("varchar")
|
||||
.HasColumnName("uid")
|
||||
.HasMaxLength(50);
|
||||
.HasColumnName("uid")
|
||||
.HasColumnType("varchar(36)")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.TenantId)
|
||||
.HasColumnName("tenant_id")
|
||||
@ -83,7 +93,9 @@ public static class WebhooksPayloadExtension
|
||||
entity.Property(e => e.RequestPayload)
|
||||
.IsRequired()
|
||||
.HasColumnName("request_payload")
|
||||
.HasColumnType("json");
|
||||
.HasColumnType("text")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.RequestHeaders)
|
||||
.HasColumnName("request_headers")
|
||||
@ -91,25 +103,35 @@ public static class WebhooksPayloadExtension
|
||||
|
||||
entity.Property(e => e.ResponsePayload)
|
||||
.HasColumnName("response_payload")
|
||||
.HasColumnType("json");
|
||||
.HasColumnType("text")
|
||||
.HasCharSet("utf8")
|
||||
.UseCollation("utf8_general_ci");
|
||||
|
||||
entity.Property(e => e.ResponseHeaders)
|
||||
.HasColumnName("response_headers")
|
||||
.HasColumnType("json");
|
||||
|
||||
entity.Property(e => e.Event)
|
||||
entity.Property(e => e.Method)
|
||||
.HasColumnType("varchar")
|
||||
.HasColumnName("event")
|
||||
.HasColumnName("method")
|
||||
.HasMaxLength(100);
|
||||
|
||||
entity.Property(e => e.Route)
|
||||
.HasColumnType("varchar")
|
||||
.HasColumnName("route")
|
||||
.HasMaxLength(100);
|
||||
|
||||
entity.Property(e => e.CreationTime)
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("creation_time");
|
||||
|
||||
entity.Property(e => e.Delivery)
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("delivery");
|
||||
|
||||
entity.Property(e => e.Status)
|
||||
.HasColumnType("varchar")
|
||||
.HasColumnName("status")
|
||||
.HasMaxLength(50);
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("status");
|
||||
});
|
||||
}
|
||||
|
||||
@ -120,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")
|
||||
@ -142,34 +167,40 @@ public static class WebhooksPayloadExtension
|
||||
|
||||
entity.Property(e => e.RequestPayload)
|
||||
.IsRequired()
|
||||
.HasColumnName("request_payload")
|
||||
.HasColumnType("json");
|
||||
.HasColumnName("request_payload");
|
||||
|
||||
entity.Property(e => e.RequestHeaders)
|
||||
.HasColumnName("request_headers")
|
||||
.HasColumnType("json");
|
||||
|
||||
entity.Property(e => e.ResponsePayload)
|
||||
.HasColumnName("response_payload")
|
||||
.HasColumnType("json");
|
||||
.HasColumnName("response_payload");
|
||||
|
||||
entity.Property(e => e.ResponseHeaders)
|
||||
.HasColumnName("response_headers")
|
||||
.HasColumnType("json");
|
||||
|
||||
entity.Property(e => e.Event)
|
||||
entity.Property(e => e.Method)
|
||||
.HasColumnType("varchar")
|
||||
.HasColumnName("event")
|
||||
.HasColumnName("method")
|
||||
.HasMaxLength(100);
|
||||
|
||||
entity.Property(e => e.Route)
|
||||
.HasColumnType("varchar")
|
||||
.HasColumnName("route")
|
||||
.HasMaxLength(100);
|
||||
|
||||
entity.Property(e => e.CreationTime)
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("creation_time");
|
||||
.HasColumnName("creation_time");
|
||||
|
||||
entity.Property(e => e.Delivery)
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("delivery");
|
||||
|
||||
entity.Property(e => e.Status)
|
||||
.HasColumnType("varchar")
|
||||
.HasColumnName("status")
|
||||
.HasMaxLength(50);
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("status");
|
||||
});
|
||||
}
|
||||
}
|
@ -29,5 +29,6 @@ namespace ASC.Webhooks.Core;
|
||||
[Scope]
|
||||
public interface IWebhookPublisher
|
||||
{
|
||||
public void Publish(string eventName, string requestPayload);
|
||||
public Task PublishAsync(string method, string route, string requestPayload);
|
||||
public Task<WebhooksLog> PublishAsync(string method, string route, string requestPayload, int configId);
|
||||
}
|
@ -30,51 +30,56 @@ namespace ASC.Webhooks.Core;
|
||||
public class WebhookPublisher : IWebhookPublisher
|
||||
{
|
||||
private readonly DbWorker _dbWorker;
|
||||
private readonly TenantManager _tenantManager;
|
||||
private readonly ICacheNotify<WebhookRequest> _webhookNotify;
|
||||
|
||||
|
||||
public WebhookPublisher(
|
||||
DbWorker dbWorker,
|
||||
TenantManager tenantManager,
|
||||
ICacheNotify<WebhookRequest> webhookNotify)
|
||||
{
|
||||
_dbWorker = dbWorker;
|
||||
_tenantManager = tenantManager;
|
||||
_webhookNotify = webhookNotify;
|
||||
}
|
||||
|
||||
public void Publish(string eventName, string requestPayload)
|
||||
public async Task PublishAsync(string method, string route, string requestPayload)
|
||||
{
|
||||
var tenantId = _tenantManager.GetCurrentTenant().Id;
|
||||
var webhookConfigs = _dbWorker.GetWebhookConfigs(tenantId);
|
||||
|
||||
foreach (var config in webhookConfigs)
|
||||
if (string.IsNullOrEmpty(requestPayload))
|
||||
{
|
||||
var webhooksLog = new WebhooksLog
|
||||
{
|
||||
Uid = Guid.NewGuid().ToString(),
|
||||
TenantId = tenantId,
|
||||
Event = eventName,
|
||||
CreationTime = DateTime.UtcNow,
|
||||
RequestPayload = requestPayload,
|
||||
Status = ProcessStatus.InProcess,
|
||||
ConfigId = config.ConfigId
|
||||
};
|
||||
var DbId = _dbWorker.WriteToJournal(webhooksLog);
|
||||
return;
|
||||
}
|
||||
|
||||
var webhookConfigs = _dbWorker.GetWebhookConfigs();
|
||||
|
||||
var request = new WebhookRequest()
|
||||
{
|
||||
Id = DbId
|
||||
};
|
||||
|
||||
_webhookNotify.Publish(request, CacheNotifyAction.Update);
|
||||
await foreach (var config in webhookConfigs.Where(r => r.Enabled))
|
||||
{
|
||||
_ = await PublishAsync(method, route, requestPayload, config.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum ProcessStatus
|
||||
{
|
||||
InProcess,
|
||||
Success,
|
||||
Failed
|
||||
public async Task<WebhooksLog> PublishAsync(string method, string route, string requestPayload, int configId)
|
||||
{
|
||||
if (string.IsNullOrEmpty(requestPayload))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var webhooksLog = new WebhooksLog
|
||||
{
|
||||
Method = method,
|
||||
Route = route,
|
||||
CreationTime = DateTime.UtcNow,
|
||||
RequestPayload = requestPayload,
|
||||
ConfigId = configId
|
||||
};
|
||||
|
||||
var webhook = await _dbWorker.WriteToJournal(webhooksLog);
|
||||
|
||||
var request = new WebhookRequest
|
||||
{
|
||||
Id = webhook.Id
|
||||
};
|
||||
|
||||
_webhookNotify.Publish(request, CacheNotifyAction.Update);
|
||||
|
||||
return webhook;
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,10 @@
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="6.0.8" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\ASC.Api.Core\ASC.Api.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
@ -37,9 +37,13 @@ global using ASC.Common.Log;
|
||||
global using ASC.Common.Utils;
|
||||
global using ASC.Web.Webhooks;
|
||||
global using ASC.Webhooks.Core;
|
||||
global using ASC.Webhooks.Service;
|
||||
global using ASC.Webhooks.Service.Log;
|
||||
global using ASC.Webhooks.Service.Services;
|
||||
|
||||
global using Microsoft.AspNetCore.Builder;
|
||||
global using Microsoft.Extensions.Hosting.WindowsServices;
|
||||
global using Microsoft.Extensions.Logging;
|
||||
global using Microsoft.Extensions.Logging;
|
||||
|
||||
global using Polly;
|
||||
global using Polly.Extensions.Http;
|
@ -41,11 +41,20 @@ builder.Host.ConfigureDefault(args, (hostContext, config, env, path) =>
|
||||
|
||||
diHelper.TryAdd<DbWorker>();
|
||||
|
||||
services.AddHostedService<BuildQueueService>();
|
||||
diHelper.TryAdd<BuildQueueService>();
|
||||
|
||||
services.AddHostedService<WorkerService>();
|
||||
diHelper.TryAdd<WorkerService>();
|
||||
diHelper.TryAdd<WorkerService>();
|
||||
|
||||
services.AddHttpClient("webhook")
|
||||
.SetHandlerLifetime(TimeSpan.FromMinutes(5))
|
||||
.AddPolicyHandler((s, request) =>
|
||||
{
|
||||
var settings = s.GetRequiredService<Settings>();
|
||||
|
||||
return HttpPolicyExtensions
|
||||
.HandleTransientHttpError()
|
||||
.OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
|
||||
.WaitAndRetryAsync(settings.RepeatCount.HasValue ? settings.RepeatCount.Value : 5, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
|
||||
});
|
||||
});
|
||||
|
||||
builder.WebHost.ConfigureDefaultKestrel();
|
||||
|
@ -29,26 +29,36 @@ namespace ASC.Webhooks.Service.Services;
|
||||
[Singletone]
|
||||
public class WorkerService : BackgroundService
|
||||
{
|
||||
private readonly ILogger<WorkerService> _logger;
|
||||
private readonly ConcurrentQueue<WebhookRequest> _queue;
|
||||
private readonly ILogger<WorkerService> _logger;
|
||||
private readonly int? _threadCount = 10;
|
||||
private readonly WebhookSender _webhookSender;
|
||||
private readonly TimeSpan _waitingPeriod;
|
||||
private readonly TimeSpan _waitingPeriod;
|
||||
private readonly ConcurrentQueue<WebhookRequest> _queue;
|
||||
private readonly ICacheNotify<WebhookRequest> _webhookNotify;
|
||||
|
||||
public WorkerService(WebhookSender webhookSender,
|
||||
public WorkerService(
|
||||
ICacheNotify<WebhookRequest> webhookNotify,
|
||||
WebhookSender webhookSender,
|
||||
ILogger<WorkerService> logger,
|
||||
BuildQueueService buildQueueService,
|
||||
Settings settings)
|
||||
{
|
||||
_logger = logger;
|
||||
{
|
||||
_webhookNotify = webhookNotify;
|
||||
_queue = new ConcurrentQueue<WebhookRequest>();
|
||||
_logger = logger;
|
||||
_webhookSender = webhookSender;
|
||||
_queue = buildQueueService.Queue;
|
||||
_threadCount = settings.ThreadCount;
|
||||
_waitingPeriod = TimeSpan.FromSeconds(5);
|
||||
}
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
{
|
||||
_webhookNotify.Subscribe(_queue.Enqueue, CacheNotifyAction.Update);
|
||||
|
||||
stoppingToken.Register(() =>
|
||||
{
|
||||
_webhookNotify.Unsubscribe(CacheNotifyAction.Update);
|
||||
});
|
||||
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
var queueSize = _queue.Count;
|
||||
@ -62,7 +72,7 @@ public class WorkerService : BackgroundService
|
||||
continue;
|
||||
}
|
||||
|
||||
var tasks = new List<Task>();
|
||||
var tasks = new List<Task>(queueSize);
|
||||
var counter = 0;
|
||||
|
||||
for (var i = 0; i < queueSize; i++)
|
||||
@ -82,13 +92,13 @@ public class WorkerService : BackgroundService
|
||||
|
||||
if (counter >= _threadCount)
|
||||
{
|
||||
Task.WaitAll(tasks.ToArray());
|
||||
await Task.WhenAll(tasks);
|
||||
tasks.Clear();
|
||||
counter = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Task.WaitAll(tasks.ToArray());
|
||||
}
|
||||
|
||||
await Task.WhenAll(tasks);
|
||||
_logger.DebugProcedureFinish();
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ public class Settings
|
||||
{
|
||||
var cfg = configuration.GetSetting<Settings>("webhooks");
|
||||
RepeatCount = cfg.RepeatCount ?? 5;
|
||||
ThreadCount = cfg.ThreadCount ?? 1;
|
||||
ThreadCount = cfg.ThreadCount ?? 10;
|
||||
}
|
||||
public int? RepeatCount { get; }
|
||||
public int? ThreadCount { get; }
|
||||
|
@ -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 System.Text.Json.Serialization;
|
||||
|
||||
namespace ASC.Webhooks.Service;
|
||||
|
||||
[Singletone]
|
||||
@ -31,15 +33,19 @@ public class WebhookSender
|
||||
{
|
||||
private readonly IHttpClientFactory _clientFactory;
|
||||
private readonly ILogger _log;
|
||||
public int? RepeatCount { get; init; }
|
||||
private readonly IServiceScopeFactory _scopeFactory;
|
||||
private readonly IServiceScopeFactory _scopeFactory;
|
||||
private readonly JsonSerializerOptions _jsonSerializerOptions;
|
||||
|
||||
public WebhookSender(ILoggerProvider options, IServiceScopeFactory scopeFactory, Settings settings, IHttpClientFactory clientFactory)
|
||||
public WebhookSender(ILoggerProvider options, IServiceScopeFactory scopeFactory, IHttpClientFactory clientFactory)
|
||||
{
|
||||
_log = options.CreateLogger("ASC.Webhooks.Core");
|
||||
_scopeFactory = scopeFactory;
|
||||
RepeatCount = settings.RepeatCount;
|
||||
_clientFactory = clientFactory;
|
||||
_clientFactory = clientFactory;
|
||||
_jsonSerializerOptions = new JsonSerializerOptions
|
||||
{
|
||||
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
|
||||
IgnoreReadOnlyProperties = true
|
||||
};
|
||||
}
|
||||
|
||||
public async Task Send(WebhookRequest webhookRequest, CancellationToken cancellationToken)
|
||||
@ -47,82 +53,65 @@ public class WebhookSender
|
||||
using var scope = _scopeFactory.CreateScope();
|
||||
var dbWorker = scope.ServiceProvider.GetRequiredService<DbWorker>();
|
||||
|
||||
var entry = dbWorker.ReadFromJournal(webhookRequest.Id);
|
||||
var id = entry.Id;
|
||||
var requestURI = entry.Uri;
|
||||
var secretKey = entry.SecretKey;
|
||||
var data = entry.Payload;
|
||||
|
||||
var response = new HttpResponseMessage();
|
||||
var request = new HttpRequestMessage();
|
||||
|
||||
for (var i = 0; i < RepeatCount; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
request = new HttpRequestMessage(HttpMethod.Post, requestURI);
|
||||
request.Headers.Add("Accept", "*/*");
|
||||
request.Headers.Add("Secret", "SHA256=" + GetSecretHash(secretKey, data));
|
||||
|
||||
request.Content = new StringContent(
|
||||
data,
|
||||
Encoding.UTF8,
|
||||
"application/json");
|
||||
|
||||
var httpClient = _clientFactory.CreateClient();
|
||||
response = await httpClient.SendAsync(request, cancellationToken);
|
||||
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
UpdateDb(dbWorker, id, response, request, ProcessStatus.Success);
|
||||
_log.DebugResponse(response);
|
||||
break;
|
||||
}
|
||||
else if (i == RepeatCount - 1)
|
||||
{
|
||||
UpdateDb(dbWorker, id, response, request, ProcessStatus.Failed);
|
||||
_log.DebugResponse(response);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (i == RepeatCount - 1)
|
||||
{
|
||||
UpdateDb(dbWorker, id, response, request, ProcessStatus.Failed);
|
||||
}
|
||||
|
||||
_log.ErrorWithException(ex);
|
||||
continue;
|
||||
}
|
||||
var entry = await dbWorker.ReadJournal(webhookRequest.Id);
|
||||
|
||||
var status = 0;
|
||||
string responsePayload = null;
|
||||
string responseHeaders = null;
|
||||
string requestHeaders = null;
|
||||
var delivery = DateTime.MinValue;
|
||||
|
||||
try
|
||||
{
|
||||
var httpClient = _clientFactory.CreateClient("webhook");
|
||||
var request = new HttpRequestMessage(HttpMethod.Post, entry.Config.Uri)
|
||||
{
|
||||
Content = new StringContent(entry.RequestPayload, Encoding.UTF8, "application/json")
|
||||
};
|
||||
|
||||
request.Headers.Add("Accept", "*/*");
|
||||
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);
|
||||
|
||||
status = (int)response.StatusCode;
|
||||
responseHeaders = JsonSerializer.Serialize(response.Headers.ToDictionary(r => r.Key, v => v.Value), _jsonSerializerOptions);
|
||||
responsePayload = await response.Content.ReadAsStringAsync();
|
||||
delivery = DateTime.UtcNow;
|
||||
|
||||
_log.DebugResponse(response);
|
||||
}
|
||||
catch (HttpRequestException e)
|
||||
{
|
||||
if (e.StatusCode.HasValue)
|
||||
{
|
||||
status = (int)e.StatusCode.Value;
|
||||
}
|
||||
responsePayload = e.Message;
|
||||
delivery = DateTime.UtcNow;
|
||||
|
||||
_log.ErrorWithException(e);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
_log.ErrorWithException(e);
|
||||
}
|
||||
|
||||
if (delivery != DateTime.MinValue)
|
||||
{
|
||||
await dbWorker.UpdateWebhookJournal(entry.Id, status, delivery, requestHeaders, responsePayload, responseHeaders);
|
||||
}
|
||||
}
|
||||
|
||||
private string GetSecretHash(string secretKey, string body)
|
||||
{
|
||||
string computedSignature;
|
||||
{
|
||||
var secretBytes = Encoding.UTF8.GetBytes(secretKey);
|
||||
|
||||
using (var hasher = new HMACSHA256(secretBytes))
|
||||
{
|
||||
var data = Encoding.UTF8.GetBytes(body);
|
||||
computedSignature = BitConverter.ToString(hasher.ComputeHash(data));
|
||||
return BitConverter.ToString(hasher.ComputeHash(data));
|
||||
}
|
||||
|
||||
return computedSignature;
|
||||
}
|
||||
|
||||
private void UpdateDb(DbWorker dbWorker, int id, HttpResponseMessage response, HttpRequestMessage request, ProcessStatus status)
|
||||
{
|
||||
var responseHeaders = JsonSerializer.Serialize(response.Headers.ToDictionary(r => r.Key, v => v.Value));
|
||||
var requestHeaders = JsonSerializer.Serialize(request.Headers.ToDictionary(r => r.Key, v => v.Value));
|
||||
string responsePayload;
|
||||
|
||||
using (var streamReader = new StreamReader(response.Content.ReadAsStream()))
|
||||
{
|
||||
var responseContent = streamReader.ReadToEnd();
|
||||
responsePayload = JsonSerializer.Serialize(responseContent);
|
||||
}
|
||||
|
||||
dbWorker.UpdateWebhookJournal(id, status, responsePayload, responseHeaders, requestHeaders);
|
||||
}
|
||||
}
|
@ -53,7 +53,7 @@
|
||||
"enabled": "true"
|
||||
},
|
||||
"version": {
|
||||
"number": "11.5.0",
|
||||
"number": "1.0.0",
|
||||
"release": {
|
||||
"date": "",
|
||||
"sign": ""
|
||||
|
163
migrations/mysql/WebhooksDbContext/20220818144209_WebhooksDbContext_Upgrade1.Designer.cs
generated
Normal file
163
migrations/mysql/WebhooksDbContext/20220818144209_WebhooksDbContext_Upgrade1.Designer.cs
generated
Normal file
@ -0,0 +1,163 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using ASC.Webhooks.Core.EF.Context;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ASC.Migrations.MySql.Migrations.WebhooksDb
|
||||
{
|
||||
[DbContext(typeof(WebhooksDbContext))]
|
||||
[Migration("20220818144209_WebhooksDbContext_Upgrade1")]
|
||||
partial class WebhooksDbContext_Upgrade1
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "6.0.7")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||
|
||||
modelBuilder.Entity("ASC.Webhooks.Core.EF.Model.WebhooksConfig", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("enabled")
|
||||
.HasDefaultValueSql("'1'");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("name");
|
||||
|
||||
b.Property<string>("SecretKey")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("secret_key")
|
||||
.HasDefaultValueSql("''");
|
||||
|
||||
b.Property<uint>("TenantId")
|
||||
.HasColumnType("int unsigned")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<string>("Uri")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("uri")
|
||||
.HasDefaultValueSql("''");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.HasIndex("TenantId")
|
||||
.HasDatabaseName("tenant_id");
|
||||
|
||||
b.ToTable("webhooks_config", (string)null);
|
||||
|
||||
b.HasAnnotation("MySql:CharSet", "utf8");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Webhooks.Core.EF.Model.WebhooksLog", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<int>("ConfigId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("config_id");
|
||||
|
||||
b.Property<DateTime>("CreationTime")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("creation_time");
|
||||
|
||||
b.Property<DateTime?>("Delivery")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("delivery");
|
||||
|
||||
b.Property<string>("Method")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("varchar(100)")
|
||||
.HasColumnName("method");
|
||||
|
||||
b.Property<string>("RequestHeaders")
|
||||
.HasColumnType("json")
|
||||
.HasColumnName("request_headers");
|
||||
|
||||
b.Property<string>("RequestPayload")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("request_payload")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("ResponseHeaders")
|
||||
.HasColumnType("json")
|
||||
.HasColumnName("response_headers");
|
||||
|
||||
b.Property<string>("ResponsePayload")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("response_payload")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Route")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("varchar(100)")
|
||||
.HasColumnName("route");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("status");
|
||||
|
||||
b.Property<uint>("TenantId")
|
||||
.HasColumnType("int unsigned")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<string>("Uid")
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(36)")
|
||||
.HasColumnName("uid")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,151 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ASC.Migrations.MySql.Migrations.WebhooksDb
|
||||
{
|
||||
public partial class WebhooksDbContext_Upgrade1 : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "config_id",
|
||||
table: "webhooks_config",
|
||||
newName: "id");
|
||||
|
||||
migrationBuilder.UpdateData(
|
||||
table: "webhooks_logs",
|
||||
keyColumn: "uid",
|
||||
keyValue: null,
|
||||
column: "uid",
|
||||
value: "");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "uid",
|
||||
table: "webhooks_logs",
|
||||
type: "varchar(36)",
|
||||
nullable: false,
|
||||
collation: "utf8_general_ci",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true)
|
||||
.Annotation("MySql:CharSet", "utf8")
|
||||
.OldAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "status",
|
||||
table: "webhooks_logs",
|
||||
type: "int",
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(50)",
|
||||
oldMaxLength: 50)
|
||||
.OldAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "delivery",
|
||||
table: "webhooks_logs",
|
||||
type: "datetime",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "enabled",
|
||||
table: "webhooks_config",
|
||||
type: "tinyint(1)",
|
||||
nullable: false,
|
||||
defaultValueSql: "'1'");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "name",
|
||||
table: "webhooks_config",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
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");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "enabled",
|
||||
table: "webhooks_config");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "name",
|
||||
table: "webhooks_config");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "id",
|
||||
table: "webhooks_config",
|
||||
newName: "config_id");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "uid",
|
||||
table: "webhooks_logs",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar(36)",
|
||||
oldCollation: "utf8_general_ci")
|
||||
.Annotation("MySql:CharSet", "utf8")
|
||||
.OldAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "status",
|
||||
table: "webhooks_logs",
|
||||
type: "varchar(50)",
|
||||
maxLength: 50,
|
||||
nullable: false,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "int")
|
||||
.Annotation("MySql:CharSet", "utf8");
|
||||
}
|
||||
}
|
||||
}
|
@ -16,15 +16,27 @@ namespace ASC.Migrations.MySql.Migrations
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "6.0.4")
|
||||
.HasAnnotation("ProductVersion", "6.0.7")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 64);
|
||||
|
||||
modelBuilder.Entity("ASC.Webhooks.Core.EF.Model.WebhooksConfig", b =>
|
||||
{
|
||||
b.Property<int>("ConfigId")
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("config_id");
|
||||
.HasColumnName("id");
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("tinyint(1)")
|
||||
.HasColumnName("enabled")
|
||||
.HasDefaultValueSql("'1'");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("name");
|
||||
|
||||
b.Property<string>("SecretKey")
|
||||
.ValueGeneratedOnAdd()
|
||||
@ -44,9 +56,12 @@ namespace ASC.Migrations.MySql.Migrations
|
||||
.HasColumnName("uri")
|
||||
.HasDefaultValueSql("''");
|
||||
|
||||
b.HasKey("ConfigId")
|
||||
b.HasKey("Id")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.HasIndex("TenantId")
|
||||
.HasDatabaseName("tenant_id");
|
||||
|
||||
b.ToTable("webhooks_config", (string)null);
|
||||
|
||||
b.HasAnnotation("MySql:CharSet", "utf8");
|
||||
@ -67,10 +82,14 @@ namespace ASC.Migrations.MySql.Migrations
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("creation_time");
|
||||
|
||||
b.Property<string>("Event")
|
||||
b.Property<DateTime?>("Delivery")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("delivery");
|
||||
|
||||
b.Property<string>("Method")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("varchar(100)")
|
||||
.HasColumnName("event");
|
||||
.HasColumnName("method");
|
||||
|
||||
b.Property<string>("RequestHeaders")
|
||||
.HasColumnType("json")
|
||||
@ -78,21 +97,28 @@ namespace ASC.Migrations.MySql.Migrations
|
||||
|
||||
b.Property<string>("RequestPayload")
|
||||
.IsRequired()
|
||||
.HasColumnType("json")
|
||||
.HasColumnName("request_payload");
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("request_payload")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("ResponseHeaders")
|
||||
.HasColumnType("json")
|
||||
.HasColumnName("response_headers");
|
||||
|
||||
b.Property<string>("ResponsePayload")
|
||||
.HasColumnType("json")
|
||||
.HasColumnName("response_payload");
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("response_payload")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
b.Property<string>("Status")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
b.Property<string>("Route")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("varchar(100)")
|
||||
.HasColumnName("route");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("status");
|
||||
|
||||
b.Property<uint>("TenantId")
|
||||
@ -100,17 +126,35 @@ namespace ASC.Migrations.MySql.Migrations
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<string>("Uid")
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar(50)")
|
||||
.HasColumnName("uid");
|
||||
.IsRequired()
|
||||
.HasColumnType("varchar(36)")
|
||||
.HasColumnName("uid")
|
||||
.UseCollation("utf8_general_ci")
|
||||
.HasAnnotation("MySql:CharSet", "utf8");
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
158
migrations/postgre/WebhooksDbContext/20220818144209_WebhooksDbContext_Upgrade1.Designer.cs
generated
Normal file
158
migrations/postgre/WebhooksDbContext/20220818144209_WebhooksDbContext_Upgrade1.Designer.cs
generated
Normal file
@ -0,0 +1,158 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using ASC.Webhooks.Core.EF.Context;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ASC.Migrations.PostgreSql.Migrations.WebhooksDb
|
||||
{
|
||||
[DbContext(typeof(WebhooksDbContext))]
|
||||
[Migration("20220818144209_WebhooksDbContext_Upgrade1")]
|
||||
partial class WebhooksDbContext_Upgrade1
|
||||
{
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
|
||||
.HasAnnotation("ProductVersion", "6.0.7")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
modelBuilder.Entity("ASC.Webhooks.Core.EF.Model.WebhooksConfig", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id")
|
||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("boolean")
|
||||
.HasColumnName("enabled")
|
||||
.HasDefaultValueSql("true");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)")
|
||||
.HasColumnName("name");
|
||||
|
||||
b.Property<string>("SecretKey")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)")
|
||||
.HasColumnName("secret_key")
|
||||
.HasDefaultValueSql("''");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int unsigned")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<string>("Uri")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)")
|
||||
.HasColumnName("uri")
|
||||
.HasDefaultValueSql("''");
|
||||
|
||||
b.HasKey("Id")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.HasIndex("TenantId")
|
||||
.HasDatabaseName("tenant_id");
|
||||
|
||||
b.ToTable("webhooks_config", (string)null);
|
||||
});
|
||||
|
||||
modelBuilder.Entity("ASC.Webhooks.Core.EF.Model.WebhooksLog", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("id")
|
||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||
|
||||
b.Property<int>("ConfigId")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("config_id");
|
||||
|
||||
b.Property<DateTime>("CreationTime")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("creation_time");
|
||||
|
||||
b.Property<DateTime?>("Delivery")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("delivery");
|
||||
|
||||
b.Property<string>("Method")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("varchar")
|
||||
.HasColumnName("method");
|
||||
|
||||
b.Property<string>("RequestHeaders")
|
||||
.HasColumnType("json")
|
||||
.HasColumnName("request_headers");
|
||||
|
||||
b.Property<string>("RequestPayload")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("request_payload");
|
||||
|
||||
b.Property<string>("ResponseHeaders")
|
||||
.HasColumnType("json")
|
||||
.HasColumnName("response_headers");
|
||||
|
||||
b.Property<string>("ResponsePayload")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("response_payload");
|
||||
|
||||
b.Property<string>("Route")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("varchar")
|
||||
.HasColumnName("route");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("status");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
.HasColumnType("int unsigned")
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<string>("Uid")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar")
|
||||
.HasColumnName("uid");
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,138 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace ASC.Migrations.PostgreSql.Migrations.WebhooksDb
|
||||
{
|
||||
public partial class WebhooksDbContext_Upgrade1 : Migration
|
||||
{
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "config_id",
|
||||
table: "webhooks_config",
|
||||
newName: "id");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "uid",
|
||||
table: "webhooks_logs",
|
||||
type: "varchar",
|
||||
maxLength: 50,
|
||||
nullable: false,
|
||||
defaultValue: "",
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar",
|
||||
oldMaxLength: 50,
|
||||
oldNullable: true);
|
||||
|
||||
migrationBuilder.AlterColumn<int>(
|
||||
name: "status",
|
||||
table: "webhooks_logs",
|
||||
type: "int",
|
||||
nullable: false,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar",
|
||||
oldMaxLength: 50);
|
||||
|
||||
migrationBuilder.AddColumn<DateTime>(
|
||||
name: "delivery",
|
||||
table: "webhooks_logs",
|
||||
type: "datetime",
|
||||
nullable: true);
|
||||
|
||||
migrationBuilder.AddColumn<bool>(
|
||||
name: "enabled",
|
||||
table: "webhooks_config",
|
||||
type: "boolean",
|
||||
nullable: false,
|
||||
defaultValueSql: "true");
|
||||
|
||||
migrationBuilder.AddColumn<string>(
|
||||
name: "name",
|
||||
table: "webhooks_config",
|
||||
type: "character varying(50)",
|
||||
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");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "enabled",
|
||||
table: "webhooks_config");
|
||||
|
||||
migrationBuilder.DropColumn(
|
||||
name: "name",
|
||||
table: "webhooks_config");
|
||||
|
||||
migrationBuilder.RenameColumn(
|
||||
name: "id",
|
||||
table: "webhooks_config",
|
||||
newName: "config_id");
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "uid",
|
||||
table: "webhooks_logs",
|
||||
type: "varchar",
|
||||
maxLength: 50,
|
||||
nullable: true,
|
||||
oldClrType: typeof(string),
|
||||
oldType: "varchar",
|
||||
oldMaxLength: 50);
|
||||
|
||||
migrationBuilder.AlterColumn<string>(
|
||||
name: "status",
|
||||
table: "webhooks_logs",
|
||||
type: "varchar",
|
||||
maxLength: 50,
|
||||
nullable: false,
|
||||
oldClrType: typeof(int),
|
||||
oldType: "int");
|
||||
}
|
||||
}
|
||||
}
|
@ -18,17 +18,29 @@ namespace ASC.Migrations.PostgreSql.Migrations
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn)
|
||||
.HasAnnotation("ProductVersion", "6.0.4")
|
||||
.HasAnnotation("ProductVersion", "6.0.7")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
modelBuilder.Entity("ASC.Webhooks.Core.EF.Model.WebhooksConfig", b =>
|
||||
{
|
||||
b.Property<int>("ConfigId")
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("config_id")
|
||||
.HasColumnName("id")
|
||||
.HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
|
||||
|
||||
b.Property<bool>("Enabled")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("boolean")
|
||||
.HasColumnName("enabled")
|
||||
.HasDefaultValueSql("true");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("character varying(50)")
|
||||
.HasColumnName("name");
|
||||
|
||||
b.Property<string>("SecretKey")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasMaxLength(50)
|
||||
@ -47,9 +59,12 @@ namespace ASC.Migrations.PostgreSql.Migrations
|
||||
.HasColumnName("uri")
|
||||
.HasDefaultValueSql("''");
|
||||
|
||||
b.HasKey("ConfigId")
|
||||
b.HasKey("Id")
|
||||
.HasName("PRIMARY");
|
||||
|
||||
b.HasIndex("TenantId")
|
||||
.HasDatabaseName("tenant_id");
|
||||
|
||||
b.ToTable("webhooks_config", (string)null);
|
||||
});
|
||||
|
||||
@ -69,10 +84,14 @@ namespace ASC.Migrations.PostgreSql.Migrations
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("creation_time");
|
||||
|
||||
b.Property<string>("Event")
|
||||
b.Property<DateTime?>("Delivery")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("delivery");
|
||||
|
||||
b.Property<string>("Method")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("varchar")
|
||||
.HasColumnName("event");
|
||||
.HasColumnName("method");
|
||||
|
||||
b.Property<string>("RequestHeaders")
|
||||
.HasColumnType("json")
|
||||
@ -80,7 +99,7 @@ namespace ASC.Migrations.PostgreSql.Migrations
|
||||
|
||||
b.Property<string>("RequestPayload")
|
||||
.IsRequired()
|
||||
.HasColumnType("json")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("request_payload");
|
||||
|
||||
b.Property<string>("ResponseHeaders")
|
||||
@ -88,13 +107,16 @@ namespace ASC.Migrations.PostgreSql.Migrations
|
||||
.HasColumnName("response_headers");
|
||||
|
||||
b.Property<string>("ResponsePayload")
|
||||
.HasColumnType("json")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("response_payload");
|
||||
|
||||
b.Property<string>("Status")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
b.Property<string>("Route")
|
||||
.HasMaxLength(100)
|
||||
.HasColumnType("varchar")
|
||||
.HasColumnName("route");
|
||||
|
||||
b.Property<int>("Status")
|
||||
.HasColumnType("int")
|
||||
.HasColumnName("status");
|
||||
|
||||
b.Property<int>("TenantId")
|
||||
@ -102,6 +124,7 @@ namespace ASC.Migrations.PostgreSql.Migrations
|
||||
.HasColumnName("tenant_id");
|
||||
|
||||
b.Property<string>("Uid")
|
||||
.IsRequired()
|
||||
.HasMaxLength(50)
|
||||
.HasColumnType("varchar")
|
||||
.HasColumnName("uid");
|
||||
@ -109,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
|
||||
}
|
||||
}
|
||||
|
@ -238,8 +238,21 @@ public class FileStorageService<T> //: IFileStorageService
|
||||
}));
|
||||
}
|
||||
|
||||
public async Task<DataWrapper<T>> GetFolderItemsAsync(T parentId, int from, int count, FilterType filterType, bool subjectGroup, string subject, string searchText,
|
||||
bool searchInContent, bool withSubfolders, OrderBy orderBy, SearchArea searchArea = SearchArea.Active, bool withoutTags = false, IEnumerable<string> tagNames = null, bool withoutMe = false)
|
||||
public async Task<DataWrapper<T>> GetFolderItemsAsync(
|
||||
T parentId,
|
||||
int from,
|
||||
int count,
|
||||
FilterType filterType,
|
||||
bool subjectGroup,
|
||||
string subject,
|
||||
string searchText,
|
||||
bool searchInContent,
|
||||
bool withSubfolders,
|
||||
OrderBy orderBy,
|
||||
SearchArea searchArea = SearchArea.Active,
|
||||
bool withoutTags = false,
|
||||
IEnumerable<string> tagNames = null,
|
||||
bool withoutMe = false)
|
||||
{
|
||||
var subjectId = string.IsNullOrEmpty(subject) ? Guid.Empty : new Guid(subject);
|
||||
|
||||
|
@ -122,7 +122,7 @@ public abstract class FoldersController<T> : ApiControllerBase
|
||||
/// <param name="filterType" optional="true" remark="Allowed values: None (0), FilesOnly (1), FoldersOnly (2), DocumentsOnly (3), PresentationsOnly (4), SpreadsheetsOnly (5) or ImagesOnly (7)">Filter type</param>
|
||||
/// <returns>Folder contents</returns>
|
||||
[HttpGet("{folderId}", Order = 1)]
|
||||
public async Task<FolderContentDto<T>> GetFolderAsync(T folderId, Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withsubfolders)
|
||||
public async Task<FolderContentDto<T>> GetFolderAsync(T folderId, Guid? userIdOrGroupId, FilterType? filterType, bool? searchInContent, bool? withsubfolders)
|
||||
{
|
||||
var folder = await _foldersControllerHelper.GetFolderAsync(folderId, userIdOrGroupId, filterType, searchInContent, withsubfolders);
|
||||
|
||||
@ -223,7 +223,7 @@ public class FoldersControllerCommon : ApiControllerBase
|
||||
/// <category>Folders</category>
|
||||
/// <returns>Common folder contents</returns>
|
||||
[HttpGet("@common")]
|
||||
public async Task<FolderContentDto<int>> GetCommonFolderAsync(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withsubfolders)
|
||||
public async Task<FolderContentDto<int>> GetCommonFolderAsync(Guid? userIdOrGroupId, FilterType? filterType, bool? searchInContent, bool? withsubfolders)
|
||||
{
|
||||
return await _foldersControllerHelperInt.GetFolderAsync(await _globalFolderHelper.FolderCommonAsync, userIdOrGroupId, filterType, searchInContent, withsubfolders);
|
||||
}
|
||||
@ -235,7 +235,7 @@ public class FoldersControllerCommon : ApiControllerBase
|
||||
/// <category>Folders</category>
|
||||
/// <returns>Favorites contents</returns>
|
||||
[HttpGet("@favorites")]
|
||||
public async Task<FolderContentDto<int>> GetFavoritesFolderAsync(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withsubfolders)
|
||||
public async Task<FolderContentDto<int>> GetFavoritesFolderAsync(Guid? userIdOrGroupId, FilterType? filterType, bool? searchInContent, bool? withsubfolders)
|
||||
{
|
||||
return await _foldersControllerHelperInt.GetFolderAsync(await _globalFolderHelper.FolderFavoritesAsync, userIdOrGroupId, filterType, searchInContent, withsubfolders);
|
||||
}
|
||||
@ -249,13 +249,13 @@ public class FoldersControllerCommon : ApiControllerBase
|
||||
/// <category>Folders</category>
|
||||
/// <returns>My folder contents</returns>
|
||||
[HttpGet("@my")]
|
||||
public Task<FolderContentDto<int>> GetMyFolderAsync(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withsubfolders)
|
||||
public Task<FolderContentDto<int>> GetMyFolderAsync(Guid? userIdOrGroupId, FilterType? filterType, bool? searchInContent, bool? withsubfolders)
|
||||
{
|
||||
return _foldersControllerHelperInt.GetFolderAsync(_globalFolderHelper.FolderMy, userIdOrGroupId, filterType, searchInContent, withsubfolders);
|
||||
}
|
||||
|
||||
[HttpGet("@privacy")]
|
||||
public async Task<FolderContentDto<int>> GetPrivacyFolderAsync(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withsubfolders)
|
||||
public async Task<FolderContentDto<int>> GetPrivacyFolderAsync(Guid? userIdOrGroupId, FilterType? filterType, bool? searchInContent, bool? withsubfolders)
|
||||
{
|
||||
if (PrivacyRoomSettings.IsAvailable())
|
||||
{
|
||||
@ -274,7 +274,7 @@ public class FoldersControllerCommon : ApiControllerBase
|
||||
/// <category>Folders</category>
|
||||
/// <returns>Projects folder contents</returns>
|
||||
[HttpGet("@projects")]
|
||||
public async Task<FolderContentDto<string>> GetProjectsFolderAsync(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withsubfolders)
|
||||
public async Task<FolderContentDto<string>> GetProjectsFolderAsync(Guid? userIdOrGroupId, FilterType? filterType, bool? searchInContent, bool? withsubfolders)
|
||||
{
|
||||
return await _foldersControllerHelperString.GetFolderAsync(await _globalFolderHelper.GetFolderProjectsAsync<string>(), userIdOrGroupId, filterType, searchInContent, withsubfolders);
|
||||
}
|
||||
@ -286,15 +286,15 @@ public class FoldersControllerCommon : ApiControllerBase
|
||||
/// <category>Folders</category>
|
||||
/// <returns>Recent contents</returns>
|
||||
[HttpGet("@recent")]
|
||||
public async Task<FolderContentDto<int>> GetRecentFolderAsync(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withsubfolders)
|
||||
public async Task<FolderContentDto<int>> GetRecentFolderAsync(Guid? userIdOrGroupId, FilterType? filterType, bool? searchInContent, bool? withsubfolders)
|
||||
{
|
||||
return await _foldersControllerHelperInt.GetFolderAsync(await _globalFolderHelper.FolderRecentAsync, userIdOrGroupId, filterType, searchInContent, withsubfolders);
|
||||
}
|
||||
|
||||
[HttpGet("@root")]
|
||||
public async IAsyncEnumerable<FolderContentDto<int>> GetRootFoldersAsync(Guid userIdOrGroupId, FilterType filterType, bool withsubfolders, bool withoutTrash, bool searchInContent, bool withoutAdditionalFolder)
|
||||
public async IAsyncEnumerable<FolderContentDto<int>> GetRootFoldersAsync(Guid? userIdOrGroupId, FilterType? filterType, bool? withsubfolders, bool? withoutTrash, bool? searchInContent, bool? withoutAdditionalFolder)
|
||||
{
|
||||
var foldersIds = _foldersControllerHelperInt.GetRootFoldersIdsAsync(withoutTrash, withoutAdditionalFolder);
|
||||
var foldersIds = _foldersControllerHelperInt.GetRootFoldersIdsAsync(withoutTrash ?? false, withoutAdditionalFolder ?? false);
|
||||
|
||||
await foreach (var folder in foldersIds)
|
||||
{
|
||||
@ -311,7 +311,7 @@ public class FoldersControllerCommon : ApiControllerBase
|
||||
/// <category>Folders</category>
|
||||
/// <returns>Shared folder contents</returns>
|
||||
[HttpGet("@share")]
|
||||
public async Task<FolderContentDto<int>> GetShareFolderAsync(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withsubfolders)
|
||||
public async Task<FolderContentDto<int>> GetShareFolderAsync(Guid? userIdOrGroupId, FilterType? filterType, bool? searchInContent, bool? withsubfolders)
|
||||
{
|
||||
return await _foldersControllerHelperInt.GetFolderAsync(await _globalFolderHelper.FolderShareAsync, userIdOrGroupId, filterType, searchInContent, withsubfolders);
|
||||
}
|
||||
@ -323,7 +323,7 @@ public class FoldersControllerCommon : ApiControllerBase
|
||||
/// <category>Folders</category>
|
||||
/// <returns>Templates contents</returns>
|
||||
[HttpGet("@templates")]
|
||||
public async Task<FolderContentDto<int>> GetTemplatesFolderAsync(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withsubfolders)
|
||||
public async Task<FolderContentDto<int>> GetTemplatesFolderAsync(Guid? userIdOrGroupId, FilterType? filterType, bool? searchInContent, bool? withsubfolders)
|
||||
{
|
||||
return await _foldersControllerHelperInt.GetFolderAsync(await _globalFolderHelper.FolderTemplatesAsync, userIdOrGroupId, filterType, searchInContent, withsubfolders);
|
||||
}
|
||||
@ -337,7 +337,7 @@ public class FoldersControllerCommon : ApiControllerBase
|
||||
/// <category>Folders</category>
|
||||
/// <returns>Trash folder contents</returns>
|
||||
[HttpGet("@trash")]
|
||||
public Task<FolderContentDto<int>> GetTrashFolderAsync(Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withsubfolders)
|
||||
public Task<FolderContentDto<int>> GetTrashFolderAsync(Guid? userIdOrGroupId, FilterType? filterType, bool? searchInContent, bool? withsubfolders)
|
||||
{
|
||||
return _foldersControllerHelperInt.GetFolderAsync(Convert.ToInt32(_globalFolderHelper.FolderTrash), userIdOrGroupId, filterType, searchInContent, withsubfolders);
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ public abstract class VirtualRoomsController<T> : ApiControllerBase
|
||||
/// Room content
|
||||
/// </returns>
|
||||
[HttpGet("rooms/{id}")]
|
||||
public async Task<FolderContentDto<T>> GetRoomAsync(T id, Guid userOrGroupId, FilterType filterType, bool searchInContent, bool withSubFolders)
|
||||
public async Task<FolderContentDto<T>> GetRoomAsync(T id, Guid? userOrGroupId, FilterType? filterType, bool? searchInContent, bool? withSubFolders)
|
||||
{
|
||||
ErrorIfNotDocSpace();
|
||||
|
||||
@ -669,8 +669,7 @@ public class VirtualRoomsCommonController : ApiControllerBase
|
||||
/// Virtual Rooms content
|
||||
/// </returns>
|
||||
[HttpGet("rooms")]
|
||||
public async Task<FolderContentDto<int>> GetRoomsFolderAsync(RoomType type, string subjectId, bool searchInContent, bool withSubfolders, SearchArea searchArea, bool withoutTags, string tags,
|
||||
bool withoutMe)
|
||||
public async Task<FolderContentDto<int>> GetRoomsFolderAsync(RoomType? type, string subjectId, bool? searchInContent, bool? withSubfolders, SearchArea? searchArea, bool? withoutTags, string tags, bool? withoutMe)
|
||||
{
|
||||
ErrorIfNotDocSpace();
|
||||
|
||||
@ -700,7 +699,7 @@ public class VirtualRoomsCommonController : ApiControllerBase
|
||||
var filterValue = _apiContext.FilterValue;
|
||||
|
||||
var content = await _fileStorageService.GetFolderItemsAsync(parentId, startIndex, count, filterType, false, subjectId, filterValue,
|
||||
searchInContent, withSubfolders, orderBy, searchArea, withoutTags, tagNames, withoutMe);
|
||||
searchInContent ?? false, withSubfolders ?? false, orderBy, searchArea ?? SearchArea.Active, withoutTags ?? false, tagNames, withoutMe ?? false);
|
||||
|
||||
var dto = await _folderContentDtoHelper.GetAsync(content, startIndex);
|
||||
|
||||
|
@ -77,9 +77,9 @@ public class FoldersControllerHelper<T> : FilesHelperBase<T>
|
||||
return await _folderDtoHelper.GetAsync(folder);
|
||||
}
|
||||
|
||||
public async Task<FolderContentDto<T>> GetFolderAsync(T folderId, Guid userIdOrGroupId, FilterType filterType, bool searchInContent, bool withSubFolders)
|
||||
public async Task<FolderContentDto<T>> GetFolderAsync(T folderId, Guid? userIdOrGroupId, FilterType? filterType, bool? searchInContent, bool? withSubFolders)
|
||||
{
|
||||
var folderContentWrapper = await ToFolderContentWrapperAsync(folderId, userIdOrGroupId, filterType, searchInContent, withSubFolders);
|
||||
var folderContentWrapper = await ToFolderContentWrapperAsync(folderId, userIdOrGroupId ?? Guid.Empty, filterType ?? FilterType.None, searchInContent ?? false, withSubFolders ?? false);
|
||||
|
||||
return folderContentWrapper.NotFoundIfNull();
|
||||
}
|
||||
@ -175,8 +175,7 @@ public class FoldersControllerHelper<T> : FilesHelperBase<T>
|
||||
}
|
||||
|
||||
var startIndex = Convert.ToInt32(_apiContext.StartIndex);
|
||||
var items = await _fileStorageService.GetFolderItemsAsync(folderId, startIndex, Convert.ToInt32(_apiContext.Count), filterType,
|
||||
filterType == FilterType.ByUser, userIdOrGroupId.ToString(), _apiContext.FilterValue, searchInContent, withSubFolders, orderBy);
|
||||
var items = await _fileStorageService.GetFolderItemsAsync(folderId, startIndex, Convert.ToInt32(_apiContext.Count), filterType, filterType == FilterType.ByUser, userIdOrGroupId.ToString(), _apiContext.FilterValue, searchInContent, withSubFolders, orderBy);
|
||||
|
||||
return await _folderContentDtoHelper.GetAsync(items, startIndex);
|
||||
}
|
||||
|
@ -51,9 +51,9 @@ public class VersionController : BaseSettingsController
|
||||
[AllowAnonymous]
|
||||
[AllowNotPayment]
|
||||
[HttpGet("version/build")]
|
||||
public Task<BuildVersion> GetBuildVersionsAsync()
|
||||
public async Task<BuildVersion> GetBuildVersionsAsync()
|
||||
{
|
||||
return _buildVersion.GetCurrentBuildVersionAsync();
|
||||
return await _buildVersion.GetCurrentBuildVersionAsync();
|
||||
}
|
||||
|
||||
[HttpGet("version")]
|
||||
|
@ -27,82 +27,136 @@
|
||||
namespace ASC.Web.Api.Controllers.Settings;
|
||||
|
||||
public class WebhooksController : BaseSettingsController
|
||||
{
|
||||
private readonly DbWorker _webhookDbWorker;
|
||||
|
||||
public WebhooksController(
|
||||
{
|
||||
private readonly ApiContext _context;
|
||||
private readonly PermissionContext _permissionContext;
|
||||
private readonly DbWorker _webhookDbWorker;
|
||||
private readonly IMapper _mapper;
|
||||
private readonly WebhookPublisher _webhookPublisher;
|
||||
|
||||
public WebhooksController(
|
||||
ApiContext context,
|
||||
PermissionContext permissionContext,
|
||||
ApiContext apiContext,
|
||||
WebItemManager webItemManager,
|
||||
IMemoryCache memoryCache,
|
||||
DbWorker dbWorker,
|
||||
IHttpContextAccessor httpContextAccessor) : base(apiContext, memoryCache, webItemManager, httpContextAccessor)
|
||||
{
|
||||
_webhookDbWorker = dbWorker;
|
||||
}
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
IMapper mapper,
|
||||
WebhookPublisher webhookPublisher)
|
||||
: base(apiContext, memoryCache, webItemManager, httpContextAccessor)
|
||||
{
|
||||
_context = context;
|
||||
_permissionContext = permissionContext;
|
||||
_webhookDbWorker = dbWorker;
|
||||
_mapper = mapper;
|
||||
_webhookPublisher = webhookPublisher;
|
||||
}
|
||||
|
||||
[HttpGet("webhook")]
|
||||
public async IAsyncEnumerable<WebhooksConfigDto> GetTenantWebhooks()
|
||||
{
|
||||
_permissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
|
||||
|
||||
await foreach (var w in _webhookDbWorker.GetTenantWebhooks())
|
||||
{
|
||||
yield return _mapper.Map<WebhooksConfig, WebhooksConfigDto>(w);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add new config for webhooks
|
||||
/// </summary>
|
||||
[HttpPost("webhook")]
|
||||
public void CreateWebhook(WebhooksConfig model)
|
||||
{
|
||||
if (model.Uri == null)
|
||||
{
|
||||
throw new ArgumentNullException("Uri");
|
||||
}
|
||||
public async Task<WebhooksConfigDto> CreateWebhook(WebhooksConfigRequestsDto model)
|
||||
{
|
||||
_permissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
|
||||
|
||||
ArgumentNullException.ThrowIfNull(model.Uri);
|
||||
ArgumentNullException.ThrowIfNull(model.SecretKey);
|
||||
|
||||
if (model.SecretKey == null)
|
||||
{
|
||||
throw new ArgumentNullException("SecretKey");
|
||||
}
|
||||
|
||||
_webhookDbWorker.AddWebhookConfig(model);
|
||||
var webhook = await _webhookDbWorker.AddWebhookConfig(model.Name, model.Uri, model.SecretKey);
|
||||
|
||||
return _mapper.Map<WebhooksConfig, WebhooksConfigDto>(webhook);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Update config for webhooks
|
||||
/// </summary>
|
||||
[HttpPut("webhook")]
|
||||
public void UpdateWebhook(WebhooksConfig model)
|
||||
{
|
||||
if (model.Uri == null)
|
||||
{
|
||||
throw new ArgumentNullException("Uri");
|
||||
}
|
||||
public async Task<WebhooksConfigDto> UpdateWebhook(WebhooksConfigRequestsDto model)
|
||||
{
|
||||
_permissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
|
||||
|
||||
ArgumentNullException.ThrowIfNull(model.Uri);
|
||||
ArgumentNullException.ThrowIfNull(model.SecretKey);
|
||||
|
||||
if (model.SecretKey == null)
|
||||
{
|
||||
throw new ArgumentNullException("SecretKey");
|
||||
}
|
||||
|
||||
_webhookDbWorker.UpdateWebhookConfig(model);
|
||||
var webhook = await _webhookDbWorker.UpdateWebhookConfig(model.Id, model.Name, model.Uri, model.SecretKey, model.Enabled);
|
||||
|
||||
return _mapper.Map<WebhooksConfig, WebhooksConfigDto>(webhook);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove config for webhooks
|
||||
/// </summary>
|
||||
[HttpDelete("webhook")]
|
||||
public void RemoveWebhook(WebhooksConfig model)
|
||||
{
|
||||
if (model.Uri == null)
|
||||
{
|
||||
throw new ArgumentNullException("Uri");
|
||||
}
|
||||
public async Task<WebhooksConfigDto> RemoveWebhook(int id)
|
||||
{
|
||||
_permissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
|
||||
|
||||
if (model.SecretKey == null)
|
||||
{
|
||||
throw new ArgumentNullException("SecretKey");
|
||||
}
|
||||
|
||||
_webhookDbWorker.RemoveWebhookConfig(model);
|
||||
var webhook = await _webhookDbWorker.RemoveWebhookConfig(id);
|
||||
|
||||
return _mapper.Map<WebhooksConfig, WebhooksConfigDto>(webhook);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read Webhooks history for actual tenant
|
||||
/// </summary>
|
||||
[HttpGet("webhooks")]
|
||||
public List<WebhooksLog> TenantWebhooks()
|
||||
{
|
||||
return _webhookDbWorker.GetTenantWebhooks();
|
||||
[HttpGet("webhooks/log")]
|
||||
public async IAsyncEnumerable<WebhooksLogDto> GetJournal(DateTime? delivery, string hookname, string route)
|
||||
{
|
||||
_permissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
|
||||
var startIndex = Convert.ToInt32(_context.StartIndex);
|
||||
var count = Convert.ToInt32(_context.Count);
|
||||
|
||||
await foreach (var j in _webhookDbWorker.ReadJournal(startIndex, count, delivery, hookname, route))
|
||||
{
|
||||
yield return _mapper.Map<WebhooksLog, WebhooksLogDto>(j);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut("webhook/{id}/retry")]
|
||||
public async Task<WebhooksLogDto> RetryWebhook(int id)
|
||||
{
|
||||
_permissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
|
||||
|
||||
if (id == 0)
|
||||
{
|
||||
throw new ArgumentException(nameof(id));
|
||||
}
|
||||
|
||||
var item = await _webhookDbWorker.ReadJournal(id);
|
||||
|
||||
if (item == null)
|
||||
{
|
||||
throw new ItemNotFoundException();
|
||||
}
|
||||
|
||||
if (item.Status >= 200 && item.Status <= 299 || item.Status == 0)
|
||||
{
|
||||
throw new HttpException(HttpStatusCode.Forbidden);
|
||||
}
|
||||
|
||||
var result = await _webhookPublisher.PublishAsync(item.Method, item.Route, item.RequestPayload, item.ConfigId);
|
||||
|
||||
return _mapper.Map<WebhooksLog, WebhooksLogDto>(result);
|
||||
}
|
||||
|
||||
[HttpPut("webhook/retry")]
|
||||
public async IAsyncEnumerable<WebhooksLogDto> RetryWebhooks(WebhookRetryRequestsDto model)
|
||||
{
|
||||
_permissionContext.DemandPermissions(SecutiryConstants.EditPortalSettings);
|
||||
|
||||
foreach (var id in model.Ids)
|
||||
{
|
||||
var item = await _webhookDbWorker.ReadJournal(id);
|
||||
|
||||
if (item == null || item.Status >= 200 && item.Status <= 299 || item.Status == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var result = await _webhookPublisher.PublishAsync(item.Method, item.Route, item.RequestPayload, item.ConfigId);
|
||||
|
||||
yield return _mapper.Map<WebhooksLog, WebhooksLogDto>(result);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,56 +1,32 @@
|
||||
// (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.Service.Services;
|
||||
|
||||
[Singletone]
|
||||
public class BuildQueueService : BackgroundService
|
||||
{
|
||||
internal readonly ConcurrentQueue<WebhookRequest> Queue;
|
||||
private readonly ICacheNotify<WebhookRequest> _webhookNotify;
|
||||
|
||||
public BuildQueueService(ICacheNotify<WebhookRequest> webhookNotify)
|
||||
{
|
||||
_webhookNotify = webhookNotify;
|
||||
Queue = new ConcurrentQueue<WebhookRequest>();
|
||||
}
|
||||
public void BuildWebhooksQueue(WebhookRequest request)
|
||||
{
|
||||
Queue.Enqueue(request);
|
||||
}
|
||||
|
||||
protected override Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
_webhookNotify.Subscribe(BuildWebhooksQueue, CacheNotifyAction.Update);
|
||||
|
||||
stoppingToken.Register(() =>
|
||||
{
|
||||
_webhookNotify.Unsubscribe(CacheNotifyAction.Update);
|
||||
});
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
// (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.Web.Api.ApiModels.RequestsDto;
|
||||
|
||||
public class WebhookRetryRequestsDto
|
||||
{
|
||||
public List<int> Ids { get; set; }
|
||||
}
|
@ -1,53 +1,36 @@
|
||||
// (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 Payload { get; set; }
|
||||
public string SecretKey { get; set; }
|
||||
public string Uri { get; set; }
|
||||
public override bool Equals(object other)
|
||||
{
|
||||
var toCompareWith = other as WebhookEntry;
|
||||
if (toCompareWith == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Id == toCompareWith.Id &&
|
||||
Payload == toCompareWith.Payload &&
|
||||
Uri == toCompareWith.Uri &&
|
||||
SecretKey == toCompareWith.SecretKey;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Id.GetHashCode();
|
||||
}
|
||||
}
|
||||
// (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.Web.Api.ApiModels.RequestsDto;
|
||||
|
||||
public class WebhooksConfigRequestsDto
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Uri { get; set; }
|
||||
public string SecretKey { get; set; }
|
||||
public bool? Enabled { get; set; }
|
||||
}
|
34
web/ASC.Web.Api/ApiModels/ResponseDto/WebhooksConfigDto.cs
Normal file
34
web/ASC.Web.Api/ApiModels/ResponseDto/WebhooksConfigDto.cs
Normal file
@ -0,0 +1,34 @@
|
||||
// (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.Web.Api.ApiModels.ResponseDto;
|
||||
|
||||
public class WebhooksConfigDto : IMapFrom<WebhooksConfig>
|
||||
{
|
||||
public string Uri { get; set; }
|
||||
public string SecretKey { get; set; }
|
||||
public bool Enabled { get; set; }
|
||||
}
|
42
web/ASC.Web.Api/ApiModels/ResponseDto/WebhooksLogDto.cs
Normal file
42
web/ASC.Web.Api/ApiModels/ResponseDto/WebhooksLogDto.cs
Normal file
@ -0,0 +1,42 @@
|
||||
// (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.Web.Api.ApiModels.ResponseDto;
|
||||
|
||||
public class WebhooksLogDto : IMapFrom<WebhooksLog>
|
||||
{
|
||||
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; }
|
||||
public string RequestPayload { get; set; }
|
||||
public string ResponseHeaders { get; set; }
|
||||
public string ResponsePayload { get; set; }
|
||||
public int Status { get; set; }
|
||||
public DateTime? Delivery { get; set; }
|
||||
}
|
@ -29,7 +29,9 @@ namespace ASC.Api.Settings;
|
||||
[Scope]
|
||||
public class BuildVersion
|
||||
{
|
||||
public string CommunityServer { get; set; }
|
||||
public string DocSpace { get; set; }
|
||||
|
||||
public string CommunityServer { get; set; } //old
|
||||
|
||||
public string DocumentServer { get; set; }
|
||||
|
||||
@ -54,8 +56,10 @@ public class BuildVersion
|
||||
}
|
||||
|
||||
public async Task<BuildVersion> GetCurrentBuildVersionAsync()
|
||||
{
|
||||
CommunityServer = GetCommunityVersion();
|
||||
{
|
||||
CommunityServer = "12.0.0";
|
||||
|
||||
DocSpace = GetDocSpaceVersion();
|
||||
DocumentServer = await GetDocumentVersionAsync();
|
||||
MailServer = GetMailServerVersion();
|
||||
XmppServer = GetXmppServerVersion();
|
||||
@ -63,9 +67,9 @@ public class BuildVersion
|
||||
return this;
|
||||
}
|
||||
|
||||
private string GetCommunityVersion()
|
||||
private string GetDocSpaceVersion()
|
||||
{
|
||||
return _configuration["version:number"] ?? "8.5.0";
|
||||
return _configuration["version:number"] ?? "1.0.0";
|
||||
}
|
||||
|
||||
private Task<string> GetDocumentVersionAsync()
|
||||
|
@ -62,6 +62,7 @@ global using ASC.Common.Radicale.Core;
|
||||
global using ASC.Common.Security.Authorizing;
|
||||
global using ASC.Common.Threading;
|
||||
global using ASC.Common.Utils;
|
||||
global using ASC.Common.Web;
|
||||
global using ASC.Core;
|
||||
global using ASC.Core.Billing;
|
||||
global using ASC.Core.Common.Configuration;
|
||||
|
Loading…
Reference in New Issue
Block a user