Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce IWeChatThirdPartyPlatformEventHandlingService #41

Merged
merged 1 commit into from
Dec 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion common.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Version>1.12.0-preview.5</Version>
<Version>2.0.0-preview.1</Version>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>EasyAbp Team</Authors>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
namespace EasyAbp.Abp.WeChat.Common.Models;

public class WeChatEventHandlingResult
{
public bool Success { get; set; }

public string FailureReason { get; set; }

public WeChatEventHandlingResult()
{
}

public WeChatEventHandlingResult(bool success, string failureReason = null)
{
Success = success;
FailureReason = failureReason;
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using EasyAbp.Abp.WeChat.Common;
using EasyAbp.Abp.WeChat.Common.Infrastructure.Encryption;
using EasyAbp.Abp.WeChat.Common.Models;
using EasyAbp.Abp.WeChat.OpenPlatform.Infrastructure.Models.ThirdPartyPlatform;
using EasyAbp.Abp.WeChat.OpenPlatform.Infrastructure.ThirdPartyPlatform;
using EasyAbp.Abp.WeChat.OpenPlatform.Infrastructure.ThirdPartyPlatform.OptionsResolve;
using EasyAbp.Abp.WeChat.OpenPlatform.Infrastructure.ThirdPartyPlatform.OptionsResolve.Contributors;
using EasyAbp.Abp.WeChat.OpenPlatform.Infrastructure.ThirdPartyPlatform.EventNotification;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.ObjectExtending;

namespace EasyAbp.Abp.WeChat.OpenPlatform.Controllers;

Expand All @@ -24,18 +16,11 @@ namespace EasyAbp.Abp.WeChat.OpenPlatform.Controllers;
[Route("/wechat/third-party-platform")]
public class WeChatThirdPartyPlatformController : AbpControllerBase
{
private readonly IWeChatThirdPartyPlatformAsyncLocal _weChatThirdPartyPlatformAsyncLocal;
private readonly IWeChatNotificationEncryptor _weChatNotificationEncryptor;
private readonly IWeChatThirdPartyPlatformOptionsResolver _optionsResolver;
private readonly IWeChatThirdPartyPlatformEventHandlingService _handlingService;

public WeChatThirdPartyPlatformController(
IWeChatThirdPartyPlatformAsyncLocal weChatThirdPartyPlatformAsyncLocal,
IWeChatNotificationEncryptor weChatNotificationEncryptor,
IWeChatThirdPartyPlatformOptionsResolver optionsResolver)
public WeChatThirdPartyPlatformController(IWeChatThirdPartyPlatformEventHandlingService handlingService)
{
_weChatThirdPartyPlatformAsyncLocal = weChatThirdPartyPlatformAsyncLocal;
_weChatNotificationEncryptor = weChatNotificationEncryptor;
_optionsResolver = optionsResolver;
_handlingService = handlingService;
}

/// <summary>
Expand All @@ -50,32 +35,11 @@ public virtual async Task<ActionResult> NotifyAuthAsync([CanBeNull] string tenan
{
using var changeTenant = CurrentTenant.Change(tenantId.IsNullOrWhiteSpace() ? null : Guid.Parse(tenantId));

var handlers = LazyServiceProvider.LazyGetService<IEnumerable<IWeChatThirdPartyPlatformAuthEventHandler>>();
var result = await _handlingService.NotifyAuthAsync(await CreateRequestModelAsync());

Request.EnableBuffering();
using (var streamReader = new StreamReader(HttpContext.Request.Body))
if (!result.Success)
{
var model = await DecryptMsgAsync<AuthNotificationModel>(await streamReader.ReadToEndAsync());
var context = new WeChatThirdPartyPlatformAuthEventHandlerContext
{
Model = model
};

// 如果你拥有不止一个第三方平台,请务必实现 IHttpApiWeChatThirdPartyOptionsProvider
var options = await ResolveOptionsAsync(model.AppId);
using var changeOptions = _weChatThirdPartyPlatformAsyncLocal.Change(options);

foreach (var handler in handlers.Where(x => x.InfoType == model.InfoType))
{
await handler.HandleAsync(context);

if (!context.IsSuccess)
{
return BadRequest();
}
}

Request.Body.Position = 0;
return BadRequest();
}

return Ok("success");
Expand All @@ -94,65 +58,30 @@ public virtual async Task<ActionResult> NotifyAuthAsync([CanBeNull] string tenan
{
using var changeTenant = CurrentTenant.Change(tenantId.IsNullOrWhiteSpace() ? null : Guid.Parse(tenantId));

// 如果你拥有不止一个第三方平台,请务必实现 IHttpApiWeChatThirdPartyOptionsProvider
var options = await ResolveOptionsAsync(componentAppId);
var result = await _handlingService.NotifyAppAsync(componentAppId, appId, await CreateRequestModelAsync());

using var changeOptions = _weChatThirdPartyPlatformAsyncLocal.Change(options);

var handlers = LazyServiceProvider.LazyGetService<IEnumerable<IWeChatThirdPartyPlatformAppEventHandler>>();

Request.EnableBuffering();
using (var streamReader = new StreamReader(HttpContext.Request.Body))
if (!result.Success)
{
var model = await DecryptMsgAsync<WeChatAppNotificationModel>(await streamReader.ReadToEndAsync());
var context = new WeChatThirdPartyPlatformAppEventHandlerContext
{
ComponentAppId = componentAppId,
AuthorizerAppId = appId,
Model = model
};

foreach (var handler in handlers.Where(x => x.Event == context.Model.Event))
{
await handler.HandleAsync(context);

if (!context.IsSuccess)
{
return BadRequest();
}
}

Request.Body.Position = 0;
return BadRequest();
}

return Ok("success");
}

protected virtual async Task<T> DecryptMsgAsync<T>(string postData) where T : ExtensibleObject, new()
protected virtual async Task<WeChatEventNotificationRequestModel> CreateRequestModelAsync()
{
var options = await _optionsResolver.ResolveAsync();
using var streamReader = new StreamReader(HttpContext.Request.Body);

return await _weChatNotificationEncryptor.DecryptPostDataAsync<T>(
options.Token,
options.EncodingAesKey,
options.AppId,
HttpContext.Request.Query["msg_signature"].FirstOrDefault(),
HttpContext.Request.Query["timestamp"].FirstOrDefault(),
HttpContext.Request.Query["nonce"].FirstOrDefault(),
postData);
}
var postData = await streamReader.ReadToEndAsync();

protected virtual async Task<IWeChatThirdPartyPlatformOptions> ResolveOptionsAsync(string componentAppId)
{
var options = await _optionsResolver.ResolveAsync();
Request.Body.Position = 0;

if (componentAppId.IsNullOrWhiteSpace() || componentAppId == options.AppId)
return new WeChatEventNotificationRequestModel
{
return options;
}

var provider = LazyServiceProvider.LazyGetRequiredService<IHttpApiWeChatThirdPartyPlatformOptionsProvider>();

return await provider.GetAsync(componentAppId);
PostData = postData,
MsgSignature = HttpContext.Request.Query["msg_signature"].FirstOrDefault(),
Timestamp = HttpContext.Request.Query["timestamp"].FirstOrDefault(),
Notice = HttpContext.Request.Query["nonce"].FirstOrDefault()
};
}
}

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace EasyAbp.Abp.WeChat.OpenPlatform.Infrastructure.Models.ThirdPartyPlatform;

public class WeChatEventNotificationRequestModel
{
public string PostData { get; set; }

public string MsgSignature { get; set; }

public string Timestamp { get; set; }

public string Notice { get; set; }
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using System.Threading.Tasks;
using EasyAbp.Abp.WeChat.Common.Models;
using EasyAbp.Abp.WeChat.OpenPlatform.Infrastructure.ThirdPartyPlatform.AccessToken;
using JetBrains.Annotations;

namespace EasyAbp.Abp.WeChat.OpenPlatform.Infrastructure.ThirdPartyPlatform;
namespace EasyAbp.Abp.WeChat.OpenPlatform.Infrastructure.ThirdPartyPlatform.EventNotification;

/// <summary>
/// 微信应用事件通知处理者
Expand All @@ -20,5 +22,6 @@ public interface IWeChatThirdPartyPlatformAppEventHandler
/// 不要设置 AppSecret,此时会自动使用微信第三方平台的 authorizer_access_token
/// 见 <see cref="HybridAccessTokenProvider"/>
/// </summary>
Task HandleAsync(WeChatThirdPartyPlatformAppEventHandlerContext context);
Task<WeChatEventHandlingResult> HandleAsync(
[CanBeNull] string componentAppId, [NotNull] string appId, WeChatAppNotificationModel model);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System.Threading.Tasks;
using EasyAbp.Abp.WeChat.Common.Models;
using EasyAbp.Abp.WeChat.OpenPlatform.Infrastructure.Models.ThirdPartyPlatform;

namespace EasyAbp.Abp.WeChat.OpenPlatform.Infrastructure.ThirdPartyPlatform;
namespace EasyAbp.Abp.WeChat.OpenPlatform.Infrastructure.ThirdPartyPlatform.EventNotification;

/// <summary>
/// 授权事件通知处理者
Expand All @@ -12,5 +14,5 @@ public interface IWeChatThirdPartyPlatformAuthEventHandler
/// </summary>
public string InfoType { get; }

Task HandleAsync(WeChatThirdPartyPlatformAuthEventHandlerContext context);
Task<WeChatEventHandlingResult> HandleAsync(AuthNotificationModel model);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Threading.Tasks;
using EasyAbp.Abp.WeChat.Common.Models;
using EasyAbp.Abp.WeChat.OpenPlatform.Infrastructure.Models.ThirdPartyPlatform;
using JetBrains.Annotations;

namespace EasyAbp.Abp.WeChat.OpenPlatform.Infrastructure.ThirdPartyPlatform.EventNotification;

public interface IWeChatThirdPartyPlatformEventHandlingService
{
Task<WeChatEventHandlingResult> NotifyAuthAsync(WeChatEventNotificationRequestModel request);

Task<WeChatEventHandlingResult> NotifyAppAsync([CanBeNull] string componentAppId, [NotNull] string appId,
WeChatEventNotificationRequestModel request);
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
using System;
using System.Threading.Tasks;
using EasyAbp.Abp.WeChat.OpenPlatform.Infrastructure.ThirdPartyPlatform;
using EasyAbp.Abp.WeChat.Common.Models;
using EasyAbp.Abp.WeChat.OpenPlatform.Infrastructure.Models.ThirdPartyPlatform;
using EasyAbp.Abp.WeChat.OpenPlatform.Infrastructure.ThirdPartyPlatform.VerifyTicket;

namespace EasyAbp.Abp.WeChat.OpenPlatform.Handlers;
namespace EasyAbp.Abp.WeChat.OpenPlatform.Infrastructure.ThirdPartyPlatform.EventNotification;

public class TicketRecordingWeChatThirdPartyPlatformAuthEventHandler : IWeChatThirdPartyPlatformAuthEventHandler
{
Expand All @@ -17,13 +18,15 @@ public class TicketRecordingWeChatThirdPartyPlatformAuthEventHandler : IWeChatTh
_componentVerifyTicketStore = componentVerifyTicketStore;
}

public virtual async Task HandleAsync(WeChatThirdPartyPlatformAuthEventHandlerContext context)
public virtual async Task<WeChatEventHandlingResult> HandleAsync(AuthNotificationModel model)
{
if (context.Model.ComponentVerifyTicket.IsNullOrWhiteSpace())
if (model.ComponentVerifyTicket.IsNullOrWhiteSpace())
{
return;
return new WeChatEventHandlingResult(false, "缺少 ComponentVerifyTicket");
}

await _componentVerifyTicketStore.SetAsync(context.Model.AppId, context.Model.ComponentVerifyTicket);
await _componentVerifyTicketStore.SetAsync(model.AppId, model.ComponentVerifyTicket);

return new WeChatEventHandlingResult(true);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace EasyAbp.Abp.WeChat.OpenPlatform.Infrastructure.ThirdPartyPlatform;
namespace EasyAbp.Abp.WeChat.OpenPlatform.Infrastructure.ThirdPartyPlatform.EventNotification;

public static class WeChatThirdPartyPlatformAuthEventInfoTypes
{
Expand Down