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 ICurrentWeChatThirdPartyPlatform #48

Merged
merged 1 commit into from
Dec 18, 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>2.0.0-rc.1</Version>
<Version>2.0.0-rc.2</Version>
<NoWarn>$(NoWarn);CS1591</NoWarn>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>EasyAbp Team</Authors>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public class DefaultAccessTokenProvider : IAccessTokenProvider, ITransientDepend

public virtual async Task<string> GetAsync(string appId, string appSecret)
{
var cacheKey = $"CurrentAccessToken:{appId}";
var cacheKey = await GetCacheKeyAsync(appId);

var token = await _accessTokenCache.GetOrNullAsync(cacheKey);

Expand All @@ -35,6 +35,8 @@ public virtual async Task<string> GetAsync(string appId, string appSecret)
return token;
}

protected virtual Task<string> GetCacheKeyAsync(string appId) => Task.FromResult($"CurrentAccessToken:{appId}");

protected virtual async Task<string> RequestAccessTokenAsync(string appId, string appSecret)
{
var client = _httpClientFactory.CreateClient();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,8 @@ public class DefaultWeChatOfficialApiRequester : IWeChatOfficialApiRequester, IT

#region > Public Methods <

public virtual async Task<string> RequestAsync(string targetUrl,
HttpMethod method,
IOfficialRequest officialRequest = null,
IAbpWeChatOptions abpWeChatOptions = null)
public virtual async Task<string> RequestAsync(string targetUrl, HttpMethod method,
IOfficialRequest officialRequest = null, IAbpWeChatOptions abpWeChatOptions = null)
{
var client = _httpClientFactory.CreateClient();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,20 @@ namespace EasyAbp.Abp.WeChat.Official.ApiRequests
{
public interface IWeChatOfficialApiRequester
{
Task<string> RequestAsync(string targetUrl,
Task<string> RequestAsync(
string targetUrl,
HttpMethod method,
[CanBeNull] IOfficialRequest officialRequest,
[CanBeNull] IAbpWeChatOptions abpWeChatOptions);

Task<TResponse> RequestAsync<TResponse>(string targetUrl,
Task<TResponse> RequestAsync<TResponse>(
string targetUrl,
HttpMethod method,
[CanBeNull] IOfficialRequest officialRequest,
[CanBeNull] IAbpWeChatOptions abpWeChatOptions);

Task<TResponse> RequestFromDataAsync<TResponse>(string targetUrl,
Task<TResponse> RequestFromDataAsync<TResponse>(
string targetUrl,
MultipartFormDataContent formDataContent,
[CanBeNull] IOfficialRequest officialRequest,
[CanBeNull] IAbpWeChatOptions abpWeChatOptions);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using EasyAbp.Abp.WeChat.Common;
using EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;

namespace EasyAbp.Abp.WeChat.OpenPlatform;
Expand All @@ -9,4 +11,9 @@ namespace EasyAbp.Abp.WeChat.OpenPlatform;
)]
public class AbpWeChatOpenPlatformModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddSingleton<ICurrentWeChatThirdPartyPlatformAccessor>(
CurrentWeChatThirdPartyPlatformAccessor.Instance);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public AuthorizerAccessTokenCache(IAccessTokenCache accessTokenCache)
AccessTokenCache = accessTokenCache;
}

public virtual async Task<string> GetAsync(string componentAppId, string authorizerAppId)
public virtual async Task<string> GetOrNullAsync(string componentAppId, string authorizerAppId)
{
return await AccessTokenCache.GetOrNullAsync(await GetCacheKeyAsync(componentAppId, authorizerAppId));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class HybridAccessTokenProvider : IAccessTokenProvider, ITransientDepende
{
private readonly IServiceProvider _serviceProvider;
private readonly IAuthorizerAccessTokenCache _cache;
private readonly ICurrentWeChatThirdPartyPlatform _currentWeChatThirdPartyPlatform;
private readonly IAbpWeChatOptionsProvider<AbpWeChatThirdPartyPlatformOptions> _optionsProvider;
private readonly IAuthorizerRefreshTokenStore _authorizerRefreshTokenStore;
private readonly IComponentAccessTokenProvider _componentAccessTokenProvider;
Expand All @@ -29,13 +30,15 @@ public class HybridAccessTokenProvider : IAccessTokenProvider, ITransientDepende
public HybridAccessTokenProvider(
IServiceProvider serviceProvider,
IAuthorizerAccessTokenCache cache,
ICurrentWeChatThirdPartyPlatform currentWeChatThirdPartyPlatform,
IAbpWeChatOptionsProvider<AbpWeChatThirdPartyPlatformOptions> optionsProvider,
IAuthorizerRefreshTokenStore authorizerRefreshTokenStore,
IComponentAccessTokenProvider componentAccessTokenProvider,
IWeChatThirdPartyPlatformApiRequester weChatThirdPartyPlatformApiRequester)
{
_serviceProvider = serviceProvider;
_cache = cache;
_currentWeChatThirdPartyPlatform = currentWeChatThirdPartyPlatform;
_optionsProvider = optionsProvider;
_authorizerRefreshTokenStore = authorizerRefreshTokenStore;
_componentAccessTokenProvider = componentAccessTokenProvider;
Expand All @@ -46,9 +49,11 @@ public virtual async Task<string> GetAsync(string appId, string appSecret)
{
if (appSecret.IsNullOrWhiteSpace())
{
var options = await _optionsProvider.GetAsync(appId);
var componentAppId = _currentWeChatThirdPartyPlatform.ComponentAppId;

var accessToken = await _cache.GetAsync(options.AppId, appId);
var options = await _optionsProvider.GetAsync(componentAppId);

var accessToken = await _cache.GetOrNullAsync(options.AppId, appId);

if (accessToken.IsNullOrWhiteSpace())
{
Expand Down Expand Up @@ -81,7 +86,7 @@ public virtual async Task<string> GetAsync(string appId, string appSecret)
AuthorizerAppId = appId,
AuthorizerRefreshToken =
await _authorizerRefreshTokenStore.GetOrNullAsync(options.AppId, appId)
});
}, options);

if (response.AuthorizerAccessToken.IsNullOrWhiteSpace())
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.AccessToken;

public interface IAuthorizerAccessTokenCache
{
Task<string> GetAsync([NotNull] string componentAppId, [NotNull] string authorizerAppId);
Task<string> GetOrNullAsync([NotNull] string componentAppId, [NotNull] string authorizerAppId);

Task SetAsync([NotNull] string componentAppId, [NotNull] string authorizerAppId, [NotNull] string accessToken);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using EasyAbp.Abp.WeChat.Common.Infrastructure.Options;
using EasyAbp.Abp.WeChat.OpenPlatform.Shared.Models;
using EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.ComponentAccessToken;
using Newtonsoft.Json;
using Volo.Abp.DependencyInjection;

Expand All @@ -14,21 +16,34 @@ namespace EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.ApiRequests;
public class DefaultWeChatThirdPartyPlatformApiRequester : IWeChatThirdPartyPlatformApiRequester, ITransientDependency
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly IAbpLazyServiceProvider _lazyServiceProvider;

public DefaultWeChatThirdPartyPlatformApiRequester(IHttpClientFactory httpClientFactory)
private IComponentAccessTokenProvider ComponentAccessTokenProvider =>
_lazyServiceProvider.LazyGetRequiredService<IComponentAccessTokenProvider>();

public DefaultWeChatThirdPartyPlatformApiRequester(
IHttpClientFactory httpClientFactory,
IAbpLazyServiceProvider lazyServiceProvider)
{
_httpClientFactory = httpClientFactory;
_lazyServiceProvider = lazyServiceProvider;
}

#region > Public Methods <

public virtual async Task<string> RequestAsync(string targetUrl, HttpMethod method,
IOpenPlatformRequest openPlatformRequest)
IOpenPlatformRequest openPlatformRequest, IAbpWeChatOptions abpWeChatOptions)
{
var client = _httpClientFactory.CreateClient();

targetUrl = targetUrl.EnsureEndsWith('?');

if (abpWeChatOptions is not null)
{
targetUrl +=
$"component_access_token={await ComponentAccessTokenProvider.GetAsync(abpWeChatOptions.AppId, abpWeChatOptions.AppSecret)}";
}

var requestMsg = method == HttpMethod.Get
? BuildHttpGetRequestMessage(targetUrl, openPlatformRequest)
: BuildHttpPostRequestMessage(targetUrl, openPlatformRequest);
Expand All @@ -37,19 +52,26 @@ public DefaultWeChatThirdPartyPlatformApiRequester(IHttpClientFactory httpClient
}

public virtual async Task<TResponse> RequestAsync<TResponse>(string targetUrl, HttpMethod method,
IOpenPlatformRequest openPlatformRequest)
IOpenPlatformRequest openPlatformRequest, IAbpWeChatOptions abpWeChatOptions)
{
var resultStr = await RequestAsync(targetUrl, method, openPlatformRequest);
var resultStr = await RequestAsync(targetUrl, method, openPlatformRequest, abpWeChatOptions);

return JsonConvert.DeserializeObject<TResponse>(resultStr);
}

public virtual async Task<TResponse> RequestFromDataAsync<TResponse>(string targetUrl,
MultipartFormDataContent formDataContent, IOpenPlatformRequest openPlatformRequest)
MultipartFormDataContent formDataContent, IOpenPlatformRequest openPlatformRequest,
IAbpWeChatOptions abpWeChatOptions)
{
var client = _httpClientFactory.CreateClient();
targetUrl = targetUrl.EnsureEndsWith('?');

if (abpWeChatOptions is not null)
{
targetUrl +=
$"component_access_token={await ComponentAccessTokenProvider.GetAsync(abpWeChatOptions.AppId, abpWeChatOptions.AppSecret)}";
}

var requestMsg = BuildHttpGetRequestMessage(targetUrl, openPlatformRequest);
requestMsg.Method = HttpMethod.Post;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,28 @@
using System.Net.Http;
using System.Threading.Tasks;
using EasyAbp.Abp.WeChat.Common.Infrastructure.Options;
using EasyAbp.Abp.WeChat.OpenPlatform.Shared.Models;
using JetBrains.Annotations;

namespace EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.ApiRequests;

public interface IWeChatThirdPartyPlatformApiRequester
{
Task<string> RequestAsync(string targetUrl,
Task<string> RequestAsync(
string targetUrl,
HttpMethod method,
[CanBeNull] IOpenPlatformRequest openPlatformRequest);
[CanBeNull] IOpenPlatformRequest openPlatformRequest,
[CanBeNull] IAbpWeChatOptions abpWeChatOptions);

Task<TResponse> RequestAsync<TResponse>(string targetUrl,
Task<TResponse> RequestAsync<TResponse>(
string targetUrl,
HttpMethod method,
[CanBeNull] IOpenPlatformRequest openPlatformRequest);
[CanBeNull] IOpenPlatformRequest openPlatformRequest,
[CanBeNull] IAbpWeChatOptions abpWeChatOptions);

Task<TResponse> RequestFromDataAsync<TResponse>(string targetUrl,
Task<TResponse> RequestFromDataAsync<TResponse>(
string targetUrl,
MultipartFormDataContent formDataContent,
[CanBeNull] IOpenPlatformRequest openPlatformRequest);
[CanBeNull] IOpenPlatformRequest openPlatformRequest,
[CanBeNull] IAbpWeChatOptions abpWeChatOptions);
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public virtual async Task<string> GetAsync(string componentAppId, string compone
ComponentAppId = componentAppId,
ComponentAppSecret = componentAppSecret,
ComponentVerifyTicket = componentVerifyTicket
});
}, null);

if (response.ComponentAccessToken.IsNullOrWhiteSpace())
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.Models;
using JetBrains.Annotations;
using Volo.Abp;
using Volo.Abp.DependencyInjection;

namespace EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform;

public class CurrentWeChatThirdPartyPlatform : ICurrentWeChatThirdPartyPlatform, ITransientDependency
{
private readonly ICurrentWeChatThirdPartyPlatformAccessor _currentWeChatThirdPartyPlatformAccessor;

public string ComponentAppId => _currentWeChatThirdPartyPlatformAccessor.Current?.ComponentAppId;

public CurrentWeChatThirdPartyPlatform(
ICurrentWeChatThirdPartyPlatformAccessor currentWeChatThirdPartyPlatformAccessor)
{
_currentWeChatThirdPartyPlatformAccessor = currentWeChatThirdPartyPlatformAccessor;
}

public IDisposable Change(string componentAppId) => SetCurrent(componentAppId);

private IDisposable SetCurrent([CanBeNull] string componentAppId)
{
var parentScope = _currentWeChatThirdPartyPlatformAccessor.Current;

_currentWeChatThirdPartyPlatformAccessor.Current = new WeChatThirdPartyPlatformInfo(componentAppId);

return new DisposeAction(() => _currentWeChatThirdPartyPlatformAccessor.Current = parentScope);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System.Threading;
using EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.Models;

namespace EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform;

public class CurrentWeChatThirdPartyPlatformAccessor : ICurrentWeChatThirdPartyPlatformAccessor
{
public static CurrentWeChatThirdPartyPlatformAccessor Instance { get; } = new();

public WeChatThirdPartyPlatformInfo Current
{
get => _currentScope.Value;
set => _currentScope.Value = value;
}

private readonly AsyncLocal<WeChatThirdPartyPlatformInfo> _currentScope;

private CurrentWeChatThirdPartyPlatformAccessor()
{
_currentScope = new AsyncLocal<WeChatThirdPartyPlatformInfo>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;
using JetBrains.Annotations;

namespace EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform;

public interface ICurrentWeChatThirdPartyPlatform
{
[CanBeNull]
string ComponentAppId { get; }

IDisposable Change([CanBeNull] string componentAppId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.Models;

namespace EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform;

public interface ICurrentWeChatThirdPartyPlatformAccessor
{
WeChatThirdPartyPlatformInfo Current { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace EasyAbp.Abp.WeChat.OpenPlatform.ThirdPartyPlatform.Models;

public class WeChatThirdPartyPlatformInfo
{
public string ComponentAppId { get; set; }

public WeChatThirdPartyPlatformInfo(string componentAppId)
{
ComponentAppId = componentAppId;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public virtual async Task<PreAuthCodeResponse> GetPreAuthCodeAsync()
url, HttpMethod.Post, new PreAuthCodeRequest
{
ComponentAppId = Options.AppId
});
}, Options);
}

/// <summary>
Expand All @@ -48,7 +48,7 @@ public virtual async Task<QueryAuthResponse> QueryAuthAsync(string authorization
{
ComponentAppId = Options.AppId,
AuthorizationCode = authorizationCode
});
}, Options);
}

protected virtual async Task<string> AppendComponentAccessTokenAsync(string url)
Expand Down