mirror of https://github.com/Squidex/squidex.git
committed by
GitHub
128 changed files with 1901 additions and 789 deletions
@ -0,0 +1,27 @@ |
|||||
|
// ==========================================================================
|
||||
|
// WebhookSchema.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.Webhooks |
||||
|
{ |
||||
|
public sealed class WebhookSchema |
||||
|
{ |
||||
|
public Guid SchemaId { get; set; } |
||||
|
|
||||
|
public bool SendCreate { get; set; } |
||||
|
|
||||
|
public bool SendUpdate { get; set; } |
||||
|
|
||||
|
public bool SendDelete { get; set; } |
||||
|
|
||||
|
public bool SendPublish { get; set; } |
||||
|
|
||||
|
public bool SendUnpublish { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
// ==========================================================================
|
||||
|
// WebhookCreated.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Squidex.Infrastructure; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Events.Webhooks |
||||
|
{ |
||||
|
[TypeName("WebhookCreatedEvent")] |
||||
|
public sealed class WebhookCreated : WebhookEditEvent |
||||
|
{ |
||||
|
public string SharedSecret { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
// ==========================================================================
|
||||
|
// WebhookDeleted.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Squidex.Infrastructure; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Events.Webhooks |
||||
|
{ |
||||
|
[TypeName("WebhookDeletedEventV2")] |
||||
|
public sealed class WebhookDeleted : WebhookEvent |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
// ==========================================================================
|
||||
|
// WebhookEditEvent.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using Squidex.Domain.Apps.Core.Webhooks; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Events.Webhooks |
||||
|
{ |
||||
|
public abstract class WebhookEditEvent : WebhookEvent |
||||
|
{ |
||||
|
public Uri Url { get; set; } |
||||
|
|
||||
|
public List<WebhookSchema> Schemas { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
// ==========================================================================
|
||||
|
// WebhookUpdated.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Squidex.Infrastructure; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Events.Webhooks |
||||
|
{ |
||||
|
[TypeName("WebhookUpdatedEvent")] |
||||
|
public sealed class WebhookUpdated : WebhookEditEvent |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -1,68 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// MongoSchemaWebhookRepository_EventHandling.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System.Threading.Tasks; |
|
||||
using MongoDB.Driver; |
|
||||
using Squidex.Domain.Apps.Events.Schemas; |
|
||||
using Squidex.Infrastructure; |
|
||||
using Squidex.Infrastructure.CQRS.Events; |
|
||||
using Squidex.Infrastructure.Dispatching; |
|
||||
using Squidex.Infrastructure.Reflection; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Read.MongoDb.Schemas |
|
||||
{ |
|
||||
public partial class MongoSchemaWebhookRepository |
|
||||
{ |
|
||||
public string Name |
|
||||
{ |
|
||||
get { return GetType().Name; } |
|
||||
} |
|
||||
|
|
||||
public string EventsFilter |
|
||||
{ |
|
||||
get { return "^schema-"; } |
|
||||
} |
|
||||
|
|
||||
public Task On(Envelope<IEvent> @event) |
|
||||
{ |
|
||||
return this.DispatchActionAsync(@event.Payload, @event.Headers); |
|
||||
} |
|
||||
|
|
||||
protected async Task On(WebhookAdded @event, EnvelopeHeaders headers) |
|
||||
{ |
|
||||
await EnsureWebooksLoadedAsync(); |
|
||||
|
|
||||
var theAppId = @event.AppId.Id; |
|
||||
var theSchemaId = @event.SchemaId.Id; |
|
||||
|
|
||||
var webhook = SimpleMapper.Map(@event, new MongoSchemaWebhookEntity { AppId = theAppId, SchemaId = theSchemaId }); |
|
||||
|
|
||||
inMemoryWebhooks.GetOrAddNew(theAppId).GetOrAddNew(theSchemaId).Add(SimpleMapper.Map(@event, new ShortInfo())); |
|
||||
|
|
||||
await Collection.InsertOneAsync(webhook); |
|
||||
} |
|
||||
|
|
||||
protected async Task On(WebhookDeleted @event, EnvelopeHeaders headers) |
|
||||
{ |
|
||||
await EnsureWebooksLoadedAsync(); |
|
||||
|
|
||||
inMemoryWebhooks.GetOrDefault(@event.AppId.Id)?.Remove(@event.SchemaId.Id); |
|
||||
|
|
||||
await Collection.DeleteManyAsync(x => x.Id == @event.Id); |
|
||||
} |
|
||||
|
|
||||
protected async Task On(SchemaDeleted @event, EnvelopeHeaders headers) |
|
||||
{ |
|
||||
await EnsureWebooksLoadedAsync(); |
|
||||
|
|
||||
inMemoryWebhooks.GetOrDefault(@event.AppId.Id)?.Remove(@event.SchemaId.Id); |
|
||||
|
|
||||
await Collection.DeleteManyAsync(x => x.SchemaId == @event.SchemaId.Id); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,93 @@ |
|||||
|
// ==========================================================================
|
||||
|
// MongoSchemaWebhookRepository_EventHandling.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using MongoDB.Driver; |
||||
|
using Squidex.Domain.Apps.Events.Schemas; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Infrastructure.CQRS.Events; |
||||
|
using Squidex.Infrastructure.Dispatching; |
||||
|
using Squidex.Infrastructure.Reflection; |
||||
|
using Squidex.Domain.Apps.Events.Webhooks; |
||||
|
using Squidex.Domain.Apps.Read.MongoDb.Utils; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Read.MongoDb.Webhooks |
||||
|
{ |
||||
|
public partial class MongoWebhookRepository |
||||
|
{ |
||||
|
public string Name |
||||
|
{ |
||||
|
get { return GetType().Name; } |
||||
|
} |
||||
|
|
||||
|
public string EventsFilter |
||||
|
{ |
||||
|
get { return "(^webhook-)|(^schema-)"; } |
||||
|
} |
||||
|
|
||||
|
public Task On(Envelope<IEvent> @event) |
||||
|
{ |
||||
|
return this.DispatchActionAsync(@event.Payload, @event.Headers); |
||||
|
} |
||||
|
|
||||
|
protected async Task On(WebhookCreated @event, EnvelopeHeaders headers) |
||||
|
{ |
||||
|
await EnsureWebooksLoadedAsync(); |
||||
|
|
||||
|
await Collection.CreateAsync(@event, headers, w => |
||||
|
{ |
||||
|
SimpleMapper.Map(@event, w); |
||||
|
|
||||
|
w.SchemaIds = w.Schemas.Select(x => x.SchemaId).ToList(); |
||||
|
|
||||
|
inMemoryWebhooks.GetOrAddNew(w.AppId).RemoveAll(x => x.Id == w.Id); |
||||
|
inMemoryWebhooks.GetOrAddNew(w.AppId).Add(w); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
protected async Task On(WebhookUpdated @event, EnvelopeHeaders headers) |
||||
|
{ |
||||
|
await EnsureWebooksLoadedAsync(); |
||||
|
|
||||
|
await Collection.UpdateAsync(@event, headers, w => |
||||
|
{ |
||||
|
SimpleMapper.Map(@event, w); |
||||
|
|
||||
|
w.SchemaIds = w.Schemas.Select(x => x.SchemaId).ToList(); |
||||
|
|
||||
|
inMemoryWebhooks.GetOrAddNew(w.AppId).RemoveAll(x => x.Id == w.Id); |
||||
|
inMemoryWebhooks.GetOrAddNew(w.AppId).Add(w); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
protected async Task On(SchemaDeleted @event, EnvelopeHeaders headers) |
||||
|
{ |
||||
|
await EnsureWebooksLoadedAsync(); |
||||
|
|
||||
|
await Collection.UpdateAsync(@event, headers, w => |
||||
|
{ |
||||
|
w.Schemas.RemoveAll(s => s.SchemaId == @event.SchemaId.Id); |
||||
|
|
||||
|
w.SchemaIds = w.Schemas.Select(x => x.SchemaId).ToList(); |
||||
|
|
||||
|
inMemoryWebhooks.GetOrAddNew(w.AppId).RemoveAll(x => x.Id == w.Id); |
||||
|
inMemoryWebhooks.GetOrAddNew(w.AppId).Add(w); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
protected async Task On(WebhookDeleted @event, EnvelopeHeaders headers) |
||||
|
{ |
||||
|
await EnsureWebooksLoadedAsync(); |
||||
|
|
||||
|
inMemoryWebhooks.GetOrAddNew(@event.AppId.Id).RemoveAll(x => x.Id == @event.WebhookId); |
||||
|
|
||||
|
await Collection.DeleteManyAsync(x => x.Id == @event.WebhookId); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,89 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// WebhookSender.cs
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex Group
|
|
||||
// All rights reserved.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System; |
|
||||
using System.Diagnostics; |
|
||||
using System.Net.Http; |
|
||||
using System.Text; |
|
||||
using System.Threading.Tasks; |
|
||||
using Squidex.Infrastructure.Http; |
|
||||
|
|
||||
// ReSharper disable SuggestVarOrType_SimpleTypes
|
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Read.Schemas |
|
||||
{ |
|
||||
public class WebhookSender |
|
||||
{ |
|
||||
private static readonly TimeSpan Timeout = TimeSpan.FromSeconds(2); |
|
||||
|
|
||||
public virtual async Task<(string Dump, WebhookResult Result, TimeSpan Elapsed)> SendAsync(WebhookJob job) |
|
||||
{ |
|
||||
HttpRequestMessage request = BuildRequest(job); |
|
||||
HttpResponseMessage response = null; |
|
||||
|
|
||||
var isTimeout = false; |
|
||||
|
|
||||
var watch = Stopwatch.StartNew(); |
|
||||
|
|
||||
try |
|
||||
{ |
|
||||
using (var client = new HttpClient { Timeout = Timeout }) |
|
||||
{ |
|
||||
response = await client.SendAsync(request); |
|
||||
} |
|
||||
} |
|
||||
catch (TimeoutException) |
|
||||
{ |
|
||||
isTimeout = true; |
|
||||
} |
|
||||
catch (OperationCanceledException) |
|
||||
{ |
|
||||
isTimeout = true; |
|
||||
} |
|
||||
finally |
|
||||
{ |
|
||||
watch.Stop(); |
|
||||
} |
|
||||
|
|
||||
var responseString = string.Empty; |
|
||||
|
|
||||
if (response != null) |
|
||||
{ |
|
||||
responseString = await response.Content.ReadAsStringAsync(); |
|
||||
} |
|
||||
|
|
||||
var dump = DumpFormatter.BuildDump(request, response, job.RequestBody, responseString, watch.Elapsed); |
|
||||
|
|
||||
var result = WebhookResult.Failed; |
|
||||
|
|
||||
if (isTimeout) |
|
||||
{ |
|
||||
result = WebhookResult.Timeout; |
|
||||
} |
|
||||
else if (response?.IsSuccessStatusCode == true) |
|
||||
{ |
|
||||
result = WebhookResult.Success; |
|
||||
} |
|
||||
|
|
||||
return (dump, result, watch.Elapsed); |
|
||||
} |
|
||||
|
|
||||
private static HttpRequestMessage BuildRequest(WebhookJob job) |
|
||||
{ |
|
||||
var request = new HttpRequestMessage(HttpMethod.Post, job.RequestUrl) |
|
||||
{ |
|
||||
Content = new StringContent(job.RequestBody, Encoding.UTF8, "application/json") |
|
||||
}; |
|
||||
|
|
||||
request.Headers.Add("X-Signature", job.RequestSignature); |
|
||||
request.Headers.Add("User-Agent", "Squidex Webhook"); |
|
||||
|
|
||||
return request; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,100 @@ |
|||||
|
// ==========================================================================
|
||||
|
// WebhookSender.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Diagnostics; |
||||
|
using System.Net.Http; |
||||
|
using System.Text; |
||||
|
using System.Threading.Tasks; |
||||
|
using Squidex.Infrastructure.Http; |
||||
|
|
||||
|
// ReSharper disable SuggestVarOrType_SimpleTypes
|
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Read.Webhooks |
||||
|
{ |
||||
|
public class WebhookSender |
||||
|
{ |
||||
|
private static readonly TimeSpan Timeout = TimeSpan.FromSeconds(2); |
||||
|
|
||||
|
public virtual async Task<(string Dump, WebhookResult Result, TimeSpan Elapsed)> SendAsync(WebhookJob job) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
HttpRequestMessage request = BuildRequest(job); |
||||
|
HttpResponseMessage response = null; |
||||
|
|
||||
|
var responseString = string.Empty; |
||||
|
|
||||
|
var isTimeout = false; |
||||
|
|
||||
|
var watch = Stopwatch.StartNew(); |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
using (var client = new HttpClient { Timeout = Timeout }) |
||||
|
{ |
||||
|
response = await client.SendAsync(request); |
||||
|
} |
||||
|
} |
||||
|
catch (TimeoutException) |
||||
|
{ |
||||
|
isTimeout = true; |
||||
|
} |
||||
|
catch (OperationCanceledException) |
||||
|
{ |
||||
|
isTimeout = true; |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
responseString = ex.Message; |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
watch.Stop(); |
||||
|
} |
||||
|
|
||||
|
if (response != null) |
||||
|
{ |
||||
|
responseString = await response.Content.ReadAsStringAsync(); |
||||
|
} |
||||
|
|
||||
|
var dump = DumpFormatter.BuildDump(request, response, job.RequestBody, responseString, watch.Elapsed, isTimeout); |
||||
|
|
||||
|
var result = WebhookResult.Failed; |
||||
|
|
||||
|
if (isTimeout) |
||||
|
{ |
||||
|
result = WebhookResult.Timeout; |
||||
|
} |
||||
|
else if (response?.IsSuccessStatusCode == true) |
||||
|
{ |
||||
|
result = WebhookResult.Success; |
||||
|
} |
||||
|
|
||||
|
return (dump, result, watch.Elapsed); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
return (ex.Message, WebhookResult.Failed, TimeSpan.Zero); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private static HttpRequestMessage BuildRequest(WebhookJob job) |
||||
|
{ |
||||
|
var request = new HttpRequestMessage(HttpMethod.Post, job.RequestUrl) |
||||
|
{ |
||||
|
Content = new StringContent(job.RequestBody, Encoding.UTF8, "application/json") |
||||
|
}; |
||||
|
|
||||
|
request.Headers.Add("X-Signature", job.RequestSignature); |
||||
|
request.Headers.Add("User-Agent", "Squidex Webhook"); |
||||
|
|
||||
|
return request; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
// ==========================================================================
|
||||
|
// CreateWebhook.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using Squidex.Infrastructure; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Write.Webhooks.Commands |
||||
|
{ |
||||
|
public sealed class CreateWebhook : WebhookEditCommand |
||||
|
{ |
||||
|
public string SharedSecret { get; } = RandomHash.New(); |
||||
|
|
||||
|
public CreateWebhook() |
||||
|
{ |
||||
|
WebhookId = Guid.NewGuid(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
// ==========================================================================
|
||||
|
// UpdateWebhook.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Write.Webhooks.Commands |
||||
|
{ |
||||
|
public sealed class UpdateWebhook : WebhookEditCommand |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
// ==========================================================================
|
||||
|
// WebhookAggregateCommand.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using Squidex.Infrastructure.CQRS.Commands; |
||||
|
|
||||
|
// ReSharper disable MemberCanBeProtected.Global
|
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Write.Webhooks.Commands |
||||
|
{ |
||||
|
public abstract class WebhookAggregateCommand : AppCommand, IAggregateCommand |
||||
|
{ |
||||
|
public Guid WebhookId { get; set; } |
||||
|
|
||||
|
Guid IAggregateCommand.AggregateId |
||||
|
{ |
||||
|
get { return WebhookId; } |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,77 @@ |
|||||
|
// ==========================================================================
|
||||
|
// WebhookCommandMiddleware.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Squidex.Domain.Apps.Read.Schemas.Services; |
||||
|
using Squidex.Domain.Apps.Write.Webhooks.Commands; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Infrastructure.CQRS.Commands; |
||||
|
using Squidex.Infrastructure.Dispatching; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Write.Webhooks |
||||
|
{ |
||||
|
public class WebhookCommandMiddleware : ICommandMiddleware |
||||
|
{ |
||||
|
private readonly IAggregateHandler handler; |
||||
|
private readonly ISchemaProvider schemas; |
||||
|
|
||||
|
public WebhookCommandMiddleware(IAggregateHandler handler, ISchemaProvider schemas) |
||||
|
{ |
||||
|
Guard.NotNull(handler, nameof(handler)); |
||||
|
Guard.NotNull(schemas, nameof(schemas)); |
||||
|
|
||||
|
this.handler = handler; |
||||
|
this.schemas = schemas; |
||||
|
} |
||||
|
|
||||
|
protected async Task On(CreateWebhook command, CommandContext context) |
||||
|
{ |
||||
|
await ValidateAsync(command, () => "Failed to create webhook"); |
||||
|
|
||||
|
await handler.CreateAsync<WebhookDomainObject>(context, c => c.Create(command)); |
||||
|
} |
||||
|
|
||||
|
protected async Task On(UpdateWebhook command, CommandContext context) |
||||
|
{ |
||||
|
await ValidateAsync(command, () => "Failed to update content"); |
||||
|
|
||||
|
await handler.UpdateAsync<WebhookDomainObject>(context, c => c.Update(command)); |
||||
|
} |
||||
|
|
||||
|
protected Task On(DeleteWebhook command, CommandContext context) |
||||
|
{ |
||||
|
return handler.UpdateAsync<WebhookDomainObject>(context, c => c.Delete(command)); |
||||
|
} |
||||
|
|
||||
|
public async Task HandleAsync(CommandContext context, Func<Task> next) |
||||
|
{ |
||||
|
if (!await this.DispatchActionAsync(context.Command, context)) |
||||
|
{ |
||||
|
await next(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private async Task ValidateAsync(WebhookEditCommand command, Func<string> message) |
||||
|
{ |
||||
|
var results = await Task.WhenAll( |
||||
|
command.Schemas.Select(async schema => |
||||
|
await schemas.FindSchemaByIdAsync(schema.SchemaId) == null |
||||
|
? new ValidationError($"Schema {schema.SchemaId} does not exist.") |
||||
|
: null)); |
||||
|
|
||||
|
var errors = results.Where(x => x != null).ToArray(); |
||||
|
|
||||
|
if (errors.Length > 0) |
||||
|
{ |
||||
|
throw new ValidationException(message(), errors); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,88 @@ |
|||||
|
// ==========================================================================
|
||||
|
// WebhookDomainObject.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using Squidex.Domain.Apps.Events.Webhooks; |
||||
|
using Squidex.Domain.Apps.Write.Webhooks.Commands; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Infrastructure.CQRS; |
||||
|
using Squidex.Infrastructure.CQRS.Events; |
||||
|
using Squidex.Infrastructure.Dispatching; |
||||
|
using Squidex.Infrastructure.Reflection; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Write.Webhooks |
||||
|
{ |
||||
|
public class WebhookDomainObject : DomainObjectBase |
||||
|
{ |
||||
|
private bool isDeleted; |
||||
|
private bool isCreated; |
||||
|
|
||||
|
public WebhookDomainObject(Guid id, int version) |
||||
|
: base(id, version) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
protected void On(WebhookCreated @event) |
||||
|
{ |
||||
|
isCreated = true; |
||||
|
} |
||||
|
|
||||
|
protected void On(WebhookDeleted @event) |
||||
|
{ |
||||
|
isDeleted = true; |
||||
|
} |
||||
|
|
||||
|
public void Create(CreateWebhook command) |
||||
|
{ |
||||
|
Guard.Valid(command, nameof(command), () => "Cannot create webhook"); |
||||
|
|
||||
|
VerifyNotCreated(); |
||||
|
|
||||
|
RaiseEvent(SimpleMapper.Map(command, new WebhookCreated())); |
||||
|
} |
||||
|
|
||||
|
public void Update(UpdateWebhook command) |
||||
|
{ |
||||
|
Guard.Valid(command, nameof(command), () => "Cannot update webhook"); |
||||
|
|
||||
|
VerifyCreatedAndNotDeleted(); |
||||
|
|
||||
|
RaiseEvent(SimpleMapper.Map(command, new WebhookUpdated())); |
||||
|
} |
||||
|
|
||||
|
public void Delete(DeleteWebhook command) |
||||
|
{ |
||||
|
Guard.NotNull(command, nameof(command)); |
||||
|
|
||||
|
VerifyCreatedAndNotDeleted(); |
||||
|
|
||||
|
RaiseEvent(SimpleMapper.Map(command, new WebhookDeleted())); |
||||
|
} |
||||
|
|
||||
|
private void VerifyNotCreated() |
||||
|
{ |
||||
|
if (isCreated) |
||||
|
{ |
||||
|
throw new DomainException("Webhook has already been created."); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void VerifyCreatedAndNotDeleted() |
||||
|
{ |
||||
|
if (isDeleted || !isCreated) |
||||
|
{ |
||||
|
throw new DomainException("Webhook has already been deleted or not created yet."); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected override void DispatchEvent(Envelope<IEvent> @event) |
||||
|
{ |
||||
|
this.DispatchAction(@event.Payload); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
// ==========================================================================
|
||||
|
// UpdateWebhookDto.cs
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex Group
|
||||
|
// All rights reserved.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.ComponentModel.DataAnnotations; |
||||
|
|
||||
|
namespace Squidex.Controllers.Api.Webhooks.Models |
||||
|
{ |
||||
|
public class UpdateWebhookDto |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// The url of the webhook.
|
||||
|
/// </summary>
|
||||
|
[Required] |
||||
|
public Uri Url { get; set; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The schema settings.
|
||||
|
/// </summary>
|
||||
|
[Required] |
||||
|
public List<WebhookSchemaDto> Schemas { get; set; } |
||||
|
} |
||||
|
} |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue