committed by
GitHub
29 changed files with 320 additions and 98 deletions
@ -0,0 +1,36 @@ |
|||||
|
using LINGYUN.Abp.WeChat.Work.Authorize; |
||||
|
using LINGYUN.Abp.WeChat.Work.Security.Claims; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using System; |
||||
|
using System.Linq; |
||||
|
using System.Security.Claims; |
||||
|
using System.Security.Principal; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Security.Claims; |
||||
|
|
||||
|
namespace LINGYUN.Abp.Identity.WeChat.Work; |
||||
|
public class AbpWeChatWorkClaimsPrincipalContributor : IAbpClaimsPrincipalContributor, ITransientDependency |
||||
|
{ |
||||
|
public async virtual Task ContributeAsync(AbpClaimsPrincipalContributorContext context) |
||||
|
{ |
||||
|
var claimsIdentity = context.ClaimsPrincipal.Identities.First(); |
||||
|
if (claimsIdentity.HasClaim(x => x.Type == AbpWeChatWorkClaimTypes.UserId)) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
var userId = claimsIdentity.FindUserId(); |
||||
|
if (userId.HasValue) |
||||
|
{ |
||||
|
var userClaimProvider = context.ServiceProvider.GetService<IWeChatWorkUserClaimProvider>(); |
||||
|
|
||||
|
var weChatWorkUserId = await userClaimProvider?.FindUserIdentifierAsync(userId.Value); |
||||
|
if (!weChatWorkUserId.IsNullOrWhiteSpace()) |
||||
|
{ |
||||
|
claimsIdentity.AddOrReplace(new Claim(AbpWeChatWorkClaimTypes.UserId, weChatWorkUserId)); |
||||
|
|
||||
|
context.ClaimsPrincipal.AddIdentityIfNotContains(claimsIdentity); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,12 +0,0 @@ |
|||||
using System.Collections.Generic; |
|
||||
|
|
||||
namespace LINGYUN.Abp.WeChat.Common.Messages; |
|
||||
public class AbpWeChatMessageResolveOptions |
|
||||
{ |
|
||||
public List<IMessageResolveContributor> MessageResolvers { get; } |
|
||||
|
|
||||
public AbpWeChatMessageResolveOptions() |
|
||||
{ |
|
||||
MessageResolvers = new List<IMessageResolveContributor>(); |
|
||||
} |
|
||||
} |
|
||||
@ -1,7 +0,0 @@ |
|||||
using System.Threading.Tasks; |
|
||||
|
|
||||
namespace LINGYUN.Abp.WeChat.Common.Messages; |
|
||||
public interface IMessageResolver |
|
||||
{ |
|
||||
Task<MessageResolveResult> ResolveMessageAsync(MessageResolveData messageData); |
|
||||
} |
|
||||
@ -0,0 +1,16 @@ |
|||||
|
using LINGYUN.Abp.WeChat.Common.Messages; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WeChat.Official.Messages; |
||||
|
/// <summary>
|
||||
|
/// 微信公众号消息解析器
|
||||
|
/// </summary>
|
||||
|
public interface IWeChatOfficialMessageResolver |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 解析微信公众号消息
|
||||
|
/// </summary>
|
||||
|
/// <param name="messageData">公众号消息</param>
|
||||
|
/// <returns></returns>
|
||||
|
Task<MessageResolveResult> ResolveAsync(MessageResolveData messageData); |
||||
|
} |
||||
@ -0,0 +1,39 @@ |
|||||
|
using LINGYUN.Abp.WeChat.Common.Crypto; |
||||
|
using LINGYUN.Abp.WeChat.Common.Messages; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WeChat.Official.Messages; |
||||
|
public class WeChatOfficialMessageResolver : MessageResolverBase, IWeChatOfficialMessageResolver |
||||
|
{ |
||||
|
private readonly AbpWeChatOfficialMessageResolveOptions _options; |
||||
|
public WeChatOfficialMessageResolver( |
||||
|
IWeChatCryptoService cryptoService, |
||||
|
IServiceProvider serviceProvider, |
||||
|
IOptions<AbpWeChatOfficialMessageResolveOptions> options) |
||||
|
: base(cryptoService, serviceProvider) |
||||
|
{ |
||||
|
_options = options.Value; |
||||
|
} |
||||
|
|
||||
|
protected async override Task<MessageResolveResult> ResolveMessageAsync(MessageResolveContext context) |
||||
|
{ |
||||
|
var result = new MessageResolveResult(context.Origin); |
||||
|
|
||||
|
foreach (var messageResolver in _options.MessageResolvers) |
||||
|
{ |
||||
|
await messageResolver.ResolveAsync(context); |
||||
|
|
||||
|
result.AppliedResolvers.Add(messageResolver.Name); |
||||
|
|
||||
|
if (context.HasResolvedMessage()) |
||||
|
{ |
||||
|
result.Message = context.Message; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
using LINGYUN.Abp.WeChat.Common.Messages; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WeChat.Work.Common.Messages; |
||||
|
/// <summary>
|
||||
|
/// 企业微信消息解析器
|
||||
|
/// </summary>
|
||||
|
public interface IWeChatWorkMessageResolver |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 解析企业微信消息
|
||||
|
/// </summary>
|
||||
|
/// <param name="messageData">企业微信消息</param>
|
||||
|
/// <returns></returns>
|
||||
|
Task<MessageResolveResult> ResolveAsync(MessageResolveData messageData); |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
using LINGYUN.Abp.WeChat.Common.Messages; |
||||
|
using System.Xml.Serialization; |
||||
|
using Volo.Abp.EventBus; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WeChat.Work.Common.Messages.Models; |
||||
|
/// <summary>
|
||||
|
/// 会议室预定事件
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// 当用户在企业微信预定会议室时,会触发该事件回调给会议室系统应用。
|
||||
|
/// </remarks>
|
||||
|
[EventName("book_meeting_room")] |
||||
|
public class BookMeetingRoomEvent : WeChatWorkEventMessage |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 会议室id
|
||||
|
/// </summary>
|
||||
|
[XmlElement("MeetingRoomId")] |
||||
|
public int MeetingRoomId { get; set; } |
||||
|
/// <summary>
|
||||
|
/// 预定id,可根据该ID查询具体的会议预定情况
|
||||
|
/// </summary>
|
||||
|
[XmlElement("BookingId")] |
||||
|
public string BookingId { get; set; } |
||||
|
|
||||
|
public override WeChatMessageEto ToEto() |
||||
|
{ |
||||
|
return new WeChatWorkEventMessageEto<BookMeetingRoomEvent>(this); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
using LINGYUN.Abp.WeChat.Common.Messages; |
||||
|
using System.Xml.Serialization; |
||||
|
using Volo.Abp.EventBus; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WeChat.Work.Common.Messages.Models; |
||||
|
/// <summary>
|
||||
|
/// 会议室取消事件
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// 当用户在企业微信取消预定会议室时,会触发该事件回调给会议室系统应用;如果该会议室由自建应用预定,除了会议室系统应用外,也会回调给对应的自建应用。
|
||||
|
/// </remarks>
|
||||
|
[EventName("cancel_meeting_room")] |
||||
|
public class CancelMeetingRoomEvent : WeChatWorkEventMessage |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 会议室id
|
||||
|
/// </summary>
|
||||
|
[XmlElement("MeetingRoomId")] |
||||
|
public int MeetingRoomId { get; set; } |
||||
|
/// <summary>
|
||||
|
/// 预定id,可根据该ID查询具体的会议预定情况
|
||||
|
/// </summary>
|
||||
|
[XmlElement("BookingId")] |
||||
|
public string BookingId { get; set; } |
||||
|
|
||||
|
public override WeChatMessageEto ToEto() |
||||
|
{ |
||||
|
return new WeChatWorkEventMessageEto<CancelMeetingRoomEvent>(this); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,39 @@ |
|||||
|
using LINGYUN.Abp.WeChat.Common.Crypto; |
||||
|
using LINGYUN.Abp.WeChat.Common.Messages; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WeChat.Work.Common.Messages; |
||||
|
public class WeChatWorkMessageResolver : MessageResolverBase, IWeChatWorkMessageResolver |
||||
|
{ |
||||
|
private readonly AbpWeChatWorkMessageResolveOptions _options; |
||||
|
public WeChatWorkMessageResolver( |
||||
|
IWeChatCryptoService cryptoService, |
||||
|
IServiceProvider serviceProvider, |
||||
|
IOptions<AbpWeChatWorkMessageResolveOptions> options) |
||||
|
: base(cryptoService, serviceProvider) |
||||
|
{ |
||||
|
_options = options.Value; |
||||
|
} |
||||
|
|
||||
|
protected async override Task<MessageResolveResult> ResolveMessageAsync(MessageResolveContext context) |
||||
|
{ |
||||
|
var result = new MessageResolveResult(context.Origin); |
||||
|
|
||||
|
foreach (var messageResolver in _options.MessageResolvers) |
||||
|
{ |
||||
|
await messageResolver.ResolveAsync(context); |
||||
|
|
||||
|
result.AppliedResolvers.Add(messageResolver.Name); |
||||
|
|
||||
|
if (context.HasResolvedMessage()) |
||||
|
{ |
||||
|
result.Message = context.Message; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,61 @@ |
|||||
|
using LINGYUN.Abp.WeChat.Work; |
||||
|
using System; |
||||
|
using System.Net.Http; |
||||
|
|
||||
|
namespace Microsoft.Extensions.DependencyInjection; |
||||
|
public static class IHttpClientFactoryWeChatWorkExtensions |
||||
|
{ |
||||
|
internal static IServiceCollection AddApiClient(this IServiceCollection services, Action<HttpClient> configureClient = null) |
||||
|
{ |
||||
|
services.AddHttpClient(AbpWeChatWorkGlobalConsts.ApiClient, |
||||
|
options => |
||||
|
{ |
||||
|
options.BaseAddress = new Uri("https://qyapi.weixin.qq.com"); |
||||
|
|
||||
|
configureClient?.Invoke(options); |
||||
|
}); |
||||
|
|
||||
|
return services; |
||||
|
} |
||||
|
|
||||
|
public static HttpClient CreateWeChatWorkApiClient(this IHttpClientFactory httpClientFactory) |
||||
|
{ |
||||
|
return httpClientFactory.CreateClient(AbpWeChatWorkGlobalConsts.ApiClient); |
||||
|
} |
||||
|
|
||||
|
internal static IServiceCollection AddOAuthClient(this IServiceCollection services, Action<HttpClient> configureClient = null) |
||||
|
{ |
||||
|
services.AddHttpClient(AbpWeChatWorkGlobalConsts.OAuthClient, |
||||
|
options => |
||||
|
{ |
||||
|
options.BaseAddress = new Uri("https://open.weixin.qq.com"); |
||||
|
|
||||
|
configureClient?.Invoke(options); |
||||
|
}); |
||||
|
|
||||
|
return services; |
||||
|
} |
||||
|
|
||||
|
public static HttpClient CreateWeChatWorkOAuthClient(this IHttpClientFactory httpClientFactory) |
||||
|
{ |
||||
|
return httpClientFactory.CreateClient(AbpWeChatWorkGlobalConsts.OAuthClient); |
||||
|
} |
||||
|
|
||||
|
internal static IServiceCollection AddLoginClient(this IServiceCollection services, Action<HttpClient> configureClient = null) |
||||
|
{ |
||||
|
services.AddHttpClient(AbpWeChatWorkGlobalConsts.LoginClient, |
||||
|
options => |
||||
|
{ |
||||
|
options.BaseAddress = new Uri("https://login.work.weixin.qq.com"); |
||||
|
|
||||
|
configureClient?.Invoke(options); |
||||
|
}); |
||||
|
|
||||
|
return services; |
||||
|
} |
||||
|
|
||||
|
public static HttpClient CreateWeChatWorkLoginClient(this IHttpClientFactory httpClientFactory) |
||||
|
{ |
||||
|
return httpClientFactory.CreateClient(AbpWeChatWorkGlobalConsts.LoginClient); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue