17 changed files with 443 additions and 10 deletions
@ -0,0 +1,14 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace LINGYUN.Abp.WebhooksManagement; |
|||
|
|||
public interface IWebhookSubscriptionAppService : |
|||
ICrudAppService< |
|||
WebhookSubscriptionDto, |
|||
Guid, |
|||
WebhookSubscriptionGetListInput, |
|||
WebhookSubscriptionCreateInput, |
|||
WebhookSubscriptionUpdateInput> |
|||
{ |
|||
} |
|||
@ -0,0 +1,32 @@ |
|||
using System.Collections.Generic; |
|||
using System.ComponentModel.DataAnnotations; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LINGYUN.Abp.WebhooksManagement; |
|||
|
|||
public class WebhookSubscriptionCreateInput : WebhookSubscriptionCreateOrUpdateInput |
|||
{ |
|||
|
|||
} |
|||
|
|||
public class WebhookSubscriptionUpdateInput : WebhookSubscriptionCreateOrUpdateInput |
|||
{ |
|||
|
|||
} |
|||
|
|||
public abstract class WebhookSubscriptionCreateOrUpdateInput |
|||
{ |
|||
[Required] |
|||
[DynamicStringLength(typeof(WebhookSubscriptionConsts), nameof(WebhookSubscriptionConsts.MaxWebhookUriLength))] |
|||
public string WebhookUri { get; set; } |
|||
|
|||
[Required] |
|||
[DynamicStringLength(typeof(WebhookSubscriptionConsts), nameof(WebhookSubscriptionConsts.MaxSecretLength))] |
|||
public string Secret { get; set; } |
|||
|
|||
public bool IsActive { get; set; } |
|||
|
|||
public List<string> Webhooks { get; set; } = new List<string>(); |
|||
|
|||
public Dictionary<string, string> Headers { get; set; } = new Dictionary<string, string>(); |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.WebhooksManagement; |
|||
|
|||
public class WebhookSubscriptionDto : CreationAuditedEntityDto<Guid> |
|||
{ |
|||
public Guid? TenantId { get; set; } |
|||
public string WebhookUri { get; set; } |
|||
public string Secret { get; set; } |
|||
public bool IsActive { get; set; } |
|||
public List<string> Webhooks { get; set; } = new List<string>(); |
|||
public IDictionary<string, string> Headers { get; set; } = new Dictionary<string, string>(); |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
using System; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Validation; |
|||
|
|||
namespace LINGYUN.Abp.WebhooksManagement; |
|||
|
|||
public class WebhookSubscriptionGetListInput : PagedAndSortedResultRequestDto |
|||
{ |
|||
public string Filter { get; set; } |
|||
|
|||
public Guid? TenantId { get; set; } |
|||
|
|||
[DynamicStringLength(typeof(WebhookSubscriptionConsts), nameof(WebhookSubscriptionConsts.MaxWebhookUriLength))] |
|||
public string WebhookUri { get; set; } |
|||
|
|||
[DynamicStringLength(typeof(WebhookSubscriptionConsts), nameof(WebhookSubscriptionConsts.MaxSecretLength))] |
|||
public string Secret { get; set; } |
|||
|
|||
public bool? IsActive { get; set; } |
|||
|
|||
public string Webhooks { get; set; } |
|||
|
|||
public DateTime? BeginCreationTime { get; set; } |
|||
|
|||
public DateTime? EndCreationTime { get; set; } |
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
using Newtonsoft.Json; |
|||
using System.Linq; |
|||
|
|||
namespace LINGYUN.Abp.WebhooksManagement.Extensions |
|||
{ |
|||
public static class WebhookSubscriptionExtensions |
|||
{ |
|||
public static WebhookSubscriptionDto ToWebhookSubscriptionDto(this WebhookSubscription webhookSubscription) |
|||
{ |
|||
return new WebhookSubscriptionDto |
|||
{ |
|||
Id = webhookSubscription.Id, |
|||
TenantId = webhookSubscription.TenantId, |
|||
IsActive = webhookSubscription.IsActive, |
|||
Secret = webhookSubscription.Secret, |
|||
WebhookUri = webhookSubscription.WebhookUri, |
|||
Webhooks = webhookSubscription.GetSubscribedWebhooks(), |
|||
Headers = webhookSubscription.GetWebhookHeaders(), |
|||
CreationTime = webhookSubscription.CreationTime, |
|||
CreatorId = webhookSubscription.CreatorId |
|||
}; |
|||
} |
|||
|
|||
public static string ToSubscribedWebhooksString(this WebhookSubscriptionUpdateInput webhookSubscription) |
|||
{ |
|||
if (webhookSubscription.Webhooks.Any()) |
|||
{ |
|||
return JsonConvert.SerializeObject(webhookSubscription.Webhooks); |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
public static string ToWebhookHeadersString(this WebhookSubscriptionUpdateInput webhookSubscription) |
|||
{ |
|||
if (webhookSubscription.Headers.Any()) |
|||
{ |
|||
return JsonConvert.SerializeObject(webhookSubscription.Headers); |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,111 @@ |
|||
using LINGYUN.Abp.WebhooksManagement.Authorization; |
|||
using LINGYUN.Abp.WebhooksManagement.Extensions; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Newtonsoft.Json; |
|||
using System; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.WebhooksManagement; |
|||
|
|||
[Authorize(WebhooksManagementPermissions.WebhookSubscription.Default)] |
|||
public class WebhookSubscriptionAppService : WebhooksManagementAppServiceBase, IWebhookSubscriptionAppService |
|||
{ |
|||
protected IWebhookSubscriptionRepository SubscriptionRepository { get; } |
|||
|
|||
public WebhookSubscriptionAppService( |
|||
IWebhookSubscriptionRepository subscriptionRepository) |
|||
{ |
|||
SubscriptionRepository = subscriptionRepository; |
|||
} |
|||
|
|||
[Authorize(WebhooksManagementPermissions.WebhookSubscription.Create)] |
|||
public async virtual Task<WebhookSubscriptionDto> CreateAsync(WebhookSubscriptionCreateInput input) |
|||
{ |
|||
await CheckSubscribedAsync(input); |
|||
|
|||
var subscription = new WebhookSubscription( |
|||
GuidGenerator.Create(), |
|||
input.WebhookUri, |
|||
input.Secret, |
|||
JsonConvert.SerializeObject(input.Webhooks), |
|||
JsonConvert.SerializeObject(input.Headers), |
|||
CurrentTenant.Id); |
|||
|
|||
await SubscriptionRepository.InsertAsync(subscription); |
|||
|
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
|
|||
return subscription.ToWebhookSubscriptionDto(); |
|||
} |
|||
|
|||
[Authorize(WebhooksManagementPermissions.WebhookSubscription.Delete)] |
|||
public virtual Task DeleteAsync(Guid id) |
|||
{ |
|||
return SubscriptionRepository.DeleteAsync(id); |
|||
} |
|||
|
|||
public async virtual Task<WebhookSubscriptionDto> GetAsync(Guid id) |
|||
{ |
|||
var subscription = await SubscriptionRepository.GetAsync(id); |
|||
|
|||
return subscription.ToWebhookSubscriptionDto(); |
|||
} |
|||
|
|||
public async virtual Task<PagedResultDto<WebhookSubscriptionDto>> GetListAsync(WebhookSubscriptionGetListInput input) |
|||
{ |
|||
var filter = new WebhookSubscriptionFilter |
|||
{ |
|||
Filter = input.Filter, |
|||
BeginCreationTime = input.BeginCreationTime, |
|||
EndCreationTime = input.EndCreationTime, |
|||
IsActive = input.IsActive, |
|||
Secret = input.Secret, |
|||
TenantId = input.TenantId, |
|||
Webhooks = input.Webhooks, |
|||
WebhookUri = input.WebhookUri |
|||
}; |
|||
|
|||
var totalCount = await SubscriptionRepository.GetCountAsync(filter); |
|||
var subscriptions = await SubscriptionRepository.GetListAsync(filter, |
|||
input.Sorting, input.MaxResultCount, input.SkipCount); |
|||
|
|||
return new PagedResultDto<WebhookSubscriptionDto>(totalCount, |
|||
subscriptions.Select(subscription => subscription.ToWebhookSubscriptionDto()).ToList()); |
|||
} |
|||
|
|||
[Authorize(WebhooksManagementPermissions.WebhookSubscription.Update)] |
|||
public async virtual Task<WebhookSubscriptionDto> UpdateAsync(Guid id, WebhookSubscriptionUpdateInput input) |
|||
{ |
|||
var subscription = await SubscriptionRepository.GetAsync(id); |
|||
if (!string.Equals(subscription.WebhookUri, input.WebhookUri)) |
|||
{ |
|||
await CheckSubscribedAsync(input); |
|||
} |
|||
|
|||
subscription.SetWebhookUri(input.WebhookUri); |
|||
subscription.SetWebhooks(input.ToSubscribedWebhooksString()); |
|||
subscription.SetHeaders(input.ToWebhookHeadersString()); |
|||
|
|||
await SubscriptionRepository.UpdateAsync(subscription); |
|||
|
|||
await CurrentUnitOfWork.SaveChangesAsync(); |
|||
|
|||
return subscription.ToWebhookSubscriptionDto(); |
|||
} |
|||
|
|||
protected async virtual Task CheckSubscribedAsync(WebhookSubscriptionCreateOrUpdateInput input) |
|||
{ |
|||
foreach (var webhookName in input.Webhooks) |
|||
{ |
|||
if (await SubscriptionRepository.IsSubscribedAsync(CurrentTenant.Id, input.WebhookUri, webhookName)) |
|||
{ |
|||
throw new BusinessException(WebhooksManagementErrorCodes.WebhookSubscription.DuplicateSubscribed) |
|||
.WithData(nameof(WebhookSubscription.WebhookUri), input.WebhookUri) |
|||
.WithData(nameof(WebhookSubscription.Webhooks), webhookName); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -1,8 +1,27 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Domain.Repositories; |
|||
|
|||
namespace LINGYUN.Abp.WebhooksManagement; |
|||
|
|||
public interface IWebhookSubscriptionRepository : IRepository<WebhookSubscription, Guid> |
|||
{ |
|||
Task<bool> IsSubscribedAsync( |
|||
Guid? tenantId, |
|||
string webhookUri, |
|||
string webhookName, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<int> GetCountAsync( |
|||
WebhookSubscriptionFilter filter, |
|||
CancellationToken cancellationToken = default); |
|||
|
|||
Task<List<WebhookSubscription>> GetListAsync( |
|||
WebhookSubscriptionFilter filter, |
|||
string sorting = $"{nameof(WebhookSubscription.CreationTime)} DESC", |
|||
int maxResultCount = 10, |
|||
int skipCount = 0, |
|||
CancellationToken cancellationToken = default); |
|||
} |
|||
|
|||
@ -0,0 +1,22 @@ |
|||
using System; |
|||
|
|||
namespace LINGYUN.Abp.WebhooksManagement; |
|||
|
|||
public class WebhookSubscriptionFilter |
|||
{ |
|||
public string Filter { get; set; } |
|||
|
|||
public Guid? TenantId { get; set; } |
|||
|
|||
public string WebhookUri { get; set; } |
|||
|
|||
public string Secret { get; set; } |
|||
|
|||
public bool? IsActive { get; set; } |
|||
|
|||
public string Webhooks { get; set; } |
|||
|
|||
public DateTime? BeginCreationTime { get; set; } |
|||
|
|||
public DateTime? EndCreationTime { get; set; } |
|||
} |
|||
@ -0,0 +1,59 @@ |
|||
using LINGYUN.Abp.WebhooksManagement.Authorization; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp; |
|||
using Volo.Abp.Application.Dtos; |
|||
|
|||
namespace LINGYUN.Abp.WebhooksManagement; |
|||
|
|||
[RemoteService(Name = WebhooksManagementRemoteServiceConsts.RemoteServiceName)] |
|||
[Area(WebhooksManagementRemoteServiceConsts.ModuleName)] |
|||
[Authorize(WebhooksManagementPermissions.WebhookSubscription.Default)] |
|||
[Route("api/webhooks/subscriptions")] |
|||
public class WebhookSubscriptionController : WebhooksManagementControllerBase, IWebhookSubscriptionAppService |
|||
{ |
|||
protected IWebhookSubscriptionAppService SubscriptionAppService { get; } |
|||
|
|||
public WebhookSubscriptionController(IWebhookSubscriptionAppService subscriptionAppService) |
|||
{ |
|||
SubscriptionAppService = subscriptionAppService; |
|||
} |
|||
|
|||
[HttpPost] |
|||
[Authorize(WebhooksManagementPermissions.WebhookSubscription.Create)] |
|||
public Task<WebhookSubscriptionDto> CreateAsync(WebhookSubscriptionCreateInput input) |
|||
{ |
|||
return SubscriptionAppService.CreateAsync(input); |
|||
} |
|||
|
|||
[HttpDelete] |
|||
[Route("{id}")] |
|||
[Authorize(WebhooksManagementPermissions.WebhookSubscription.Delete)] |
|||
public Task DeleteAsync(Guid id) |
|||
{ |
|||
return SubscriptionAppService.DeleteAsync(id); |
|||
} |
|||
|
|||
[HttpGet] |
|||
[Route("{id}")] |
|||
public Task<WebhookSubscriptionDto> GetAsync(Guid id) |
|||
{ |
|||
return SubscriptionAppService.GetAsync(id); |
|||
} |
|||
|
|||
[HttpGet] |
|||
public Task<PagedResultDto<WebhookSubscriptionDto>> GetListAsync(WebhookSubscriptionGetListInput input) |
|||
{ |
|||
return SubscriptionAppService.GetListAsync(input); |
|||
} |
|||
|
|||
[HttpPut] |
|||
[Route("{id}")] |
|||
[Authorize(WebhooksManagementPermissions.WebhookSubscription.Update)] |
|||
public Task<WebhookSubscriptionDto> UpdateAsync(Guid id, WebhookSubscriptionUpdateInput input) |
|||
{ |
|||
return SubscriptionAppService.UpdateAsync(id, input); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue