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