From c55f45ff6a243980ffe0de53ddaad94a6a00a768 Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Wed, 20 Oct 2021 18:30:58 +0800 Subject: [PATCH] enhance wechat function restrictions --- aspnet-core/LINGYUN.MicroService.All.sln | 7 ++ .../WeChatMiniProgramGrantValidator.cs | 27 +++++++- .../Official/WeChatOfficialGrantValidator.cs | 36 +++++++++-- .../WeChat/WeChatGrantValidator.cs | 14 +++- .../Localization/Resources/en.json | 37 +++++++++++ .../Localization/Resources/zh-Hans.json | 37 +++++++++++ .../LINGYUN.Abp.WeChat.MiniProgram.csproj | 1 + .../MiniProgram/AbpWeChatMiniProgramModule.cs | 6 +- ...hatMiniProgramFeatureDefinitionProvider.cs | 64 +++++++++++++++++++ .../Features/WeChatMiniProgramFeatures.cs | 36 +++++++++++ .../Localization/Resources/en.json | 16 ++++- .../Localization/Resources/zh-Hans.json | 16 ++++- .../MiniProgram/Messages/SubscribeMessager.cs | 18 +++++- ...WeChatOfficialFeatureDefinitionProvider.cs | 39 +++++++++++ .../Features/WeChatOfficialFeatures.cs | 13 ++++ 15 files changed, 352 insertions(+), 15 deletions(-) create mode 100644 aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Localization/Resources/en.json create mode 100644 aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Localization/Resources/zh-Hans.json create mode 100644 aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Features/WeChatMiniProgramFeatureDefinitionProvider.cs create mode 100644 aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Features/WeChatMiniProgramFeatures.cs create mode 100644 aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/Features/WeChatOfficialFeatureDefinitionProvider.cs create mode 100644 aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/Features/WeChatOfficialFeatures.cs diff --git a/aspnet-core/LINGYUN.MicroService.All.sln b/aspnet-core/LINGYUN.MicroService.All.sln index 6703f7ee7..c74f1e080 100644 --- a/aspnet-core/LINGYUN.MicroService.All.sln +++ b/aspnet-core/LINGYUN.MicroService.All.sln @@ -331,6 +331,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.BackgroundWorke EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Hangfire.Dashboard", "modules\common\LINGYUN.Abp.Hangfire.Dashboard\LINGYUN.Abp.Hangfire.Dashboard.csproj", "{340BE5AC-68EC-41A5-9D0D-266037C58F13}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.WeChat", "modules\wechat\LINGYUN.Abp.Identity.WeChat\LINGYUN.Abp.Identity.WeChat.csproj", "{BC518F26-996E-4DF0-BB44-783EB1C275D2}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -865,6 +867,10 @@ Global {340BE5AC-68EC-41A5-9D0D-266037C58F13}.Debug|Any CPU.Build.0 = Debug|Any CPU {340BE5AC-68EC-41A5-9D0D-266037C58F13}.Release|Any CPU.ActiveCfg = Release|Any CPU {340BE5AC-68EC-41A5-9D0D-266037C58F13}.Release|Any CPU.Build.0 = Release|Any CPU + {BC518F26-996E-4DF0-BB44-783EB1C275D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BC518F26-996E-4DF0-BB44-783EB1C275D2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BC518F26-996E-4DF0-BB44-783EB1C275D2}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BC518F26-996E-4DF0-BB44-783EB1C275D2}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1028,6 +1034,7 @@ Global {13219C1C-23E1-4EBA-93FB-86830C93A800} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E} {60D0BEF2-FEAF-4066-8377-6C873CB24858} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E} {340BE5AC-68EC-41A5-9D0D-266037C58F13} = {8AC72641-30D3-4ACF-89FA-808FADC55C2E} + {BC518F26-996E-4DF0-BB44-783EB1C275D2} = {DD9BE9E7-F6BF-4869-BCD2-82F5072BDA21} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C95FDF91-16F2-4A8B-A4BE-0E62D1B66718} diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/MiniProgram/WeChatMiniProgramGrantValidator.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/MiniProgram/WeChatMiniProgramGrantValidator.cs index 7a050e70a..78f81a243 100644 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/MiniProgram/WeChatMiniProgramGrantValidator.cs +++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/MiniProgram/WeChatMiniProgramGrantValidator.cs @@ -1,10 +1,14 @@ -using IdentityServer4.Services; +using IdentityServer4.Models; +using IdentityServer4.Services; +using IdentityServer4.Validation; +using LINGYUN.Abp.WeChat.Localization; using LINGYUN.Abp.WeChat.MiniProgram; +using LINGYUN.Abp.WeChat.MiniProgram.Features; using LINGYUN.Abp.WeChat.OpenId; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Localization; -using Microsoft.Extensions.Options; using System.Threading.Tasks; +using Volo.Abp.Features; using Volo.Abp.Identity; using Volo.Abp.IdentityServer.Localization; using IdentityUser = Volo.Abp.Identity.IdentityUser; @@ -24,6 +28,10 @@ namespace LINGYUN.Abp.IdentityServer.WeChat.MiniProgram protected AbpWeChatMiniProgramOptionsFactory MiniProgramOptionsFactory { get; } + protected IStringLocalizer WeChatLocalizer { get; } + + protected IFeatureChecker FeatureChecker => ServiceProvider.LazyGetRequiredService(); + public WeChatMiniProgramGrantValidator( IEventService eventService, IWeChatOpenIdFinder weChatOpenIdFinder, @@ -31,12 +39,27 @@ namespace LINGYUN.Abp.IdentityServer.WeChat.MiniProgram IIdentityUserRepository userRepository, IStringLocalizer identityLocalizer, IStringLocalizer identityServerLocalizer, + IStringLocalizer wechatLocalizer, AbpWeChatMiniProgramOptionsFactory miniProgramOptionsFactory) : base(eventService, weChatOpenIdFinder, userManager, userRepository, identityLocalizer, identityServerLocalizer) { + WeChatLocalizer = wechatLocalizer; MiniProgramOptionsFactory = miniProgramOptionsFactory; } + protected override async Task CheckFeatureAsync(ExtensionGrantValidationContext context) + { + if (!await FeatureChecker.IsEnabledAsync(WeChatMiniProgramFeatures.EnableAuthorization)) + { + context.Result = new GrantValidationResult( + TokenRequestErrors.InvalidGrant, + IdentityServerLocalizer["AuthorizationDisabledMessage", + WeChatLocalizer["Features:WeChat.MiniProgram.EnableAuthorization"]]); + return false; + } + return true; + } + protected override async Task FindOpenIdAsync(string code) { var options = await MiniProgramOptionsFactory.CreateAsync(); diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialGrantValidator.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialGrantValidator.cs index 660f958c7..690e0b456 100644 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialGrantValidator.cs +++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/Official/WeChatOfficialGrantValidator.cs @@ -1,9 +1,14 @@ -using IdentityServer4.Services; +using IdentityServer4.Models; +using IdentityServer4.Services; +using IdentityServer4.Validation; +using LINGYUN.Abp.WeChat.Localization; using LINGYUN.Abp.WeChat.Official; +using LINGYUN.Abp.WeChat.Official.Features; using LINGYUN.Abp.WeChat.OpenId; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Localization; using System.Threading.Tasks; +using Volo.Abp.Features; using Volo.Abp.Identity; using Volo.Abp.IdentityServer.Localization; using IdentityUser = Volo.Abp.Identity.IdentityUser; @@ -23,19 +28,38 @@ namespace LINGYUN.Abp.IdentityServer.WeChat.Official protected AbpWeChatOfficialOptionsFactory WeChatOfficialOptionsFactory { get; } + protected IStringLocalizer WeChatLocalizer { get; } + + protected IFeatureChecker FeatureChecker => ServiceProvider.LazyGetRequiredService(); + public WeChatOfficialGrantValidator( - IEventService eventService, - IWeChatOpenIdFinder weChatOpenIdFinder, - UserManager userManager, + IEventService eventService, + IWeChatOpenIdFinder weChatOpenIdFinder, + UserManager userManager, IIdentityUserRepository userRepository, - IStringLocalizer identityLocalizer, + IStringLocalizer identityLocalizer, IStringLocalizer identityServerLocalizer, - AbpWeChatOfficialOptionsFactory weChatOfficialOptionsFactory) + IStringLocalizer wechatLocalizer, + AbpWeChatOfficialOptionsFactory weChatOfficialOptionsFactory) : base(eventService, weChatOpenIdFinder, userManager, userRepository, identityLocalizer, identityServerLocalizer) { + WeChatLocalizer = wechatLocalizer; WeChatOfficialOptionsFactory = weChatOfficialOptionsFactory; } + protected override async Task CheckFeatureAsync(ExtensionGrantValidationContext context) + { + if (!await FeatureChecker.IsEnabledAsync(WeChatOfficialFeatures.EnableAuthorization)) + { + context.Result = new GrantValidationResult( + TokenRequestErrors.InvalidGrant, + IdentityServerLocalizer["AuthorizationDisabledMessage", + WeChatLocalizer["Features:WeChat.Official.EnableAuthorization"]]); + return false; + } + return true; + } + protected override async Task FindOpenIdAsync(string code) { var options = await WeChatOfficialOptionsFactory.CreateAsync(); diff --git a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/WeChatGrantValidator.cs b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/WeChatGrantValidator.cs index 234e25509..a8883d4fd 100644 --- a/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/WeChatGrantValidator.cs +++ b/aspnet-core/modules/identityServer/LINGYUN.Abp.IdentityServer.WeChat/LINGYUN/Abp/IdentityServer/WeChat/WeChatGrantValidator.cs @@ -68,6 +68,11 @@ namespace LINGYUN.Abp.IdentityServer.WeChat [UnitOfWork] public async Task ValidateAsync(ExtensionGrantValidationContext context) { + if (!await CheckFeatureAsync(context)) + { + return; + } + var raw = context.Request.Raw; var credential = raw.Get(OidcConstants.TokenRequest.GrantType); if (credential == null || !credential.Equals(GrantType)) @@ -91,8 +96,8 @@ namespace LINGYUN.Abp.IdentityServer.WeChat { var settingProvider = ServiceProvider.LazyGetRequiredService(); // TODO 检查启用用户注册是否有必要引用账户模块 - if (! await settingProvider.IsTrueAsync("Abp.Account.IsSelfRegistrationEnabled") || - ! await settingProvider.IsTrueAsync(WeChatSettingNames.EnabledQuickLogin)) + if (!await settingProvider.IsTrueAsync("Abp.Account.IsSelfRegistrationEnabled") || + !await settingProvider.IsTrueAsync(WeChatSettingNames.EnabledQuickLogin)) { Logger.LogWarning("Invalid grant type: wechat openid not register", wechatOpenId.OpenId); context.Result = new GrantValidationResult(TokenRequestErrors.InvalidGrant, IdentityServerLocalizer["InvalidGrant:WeChatNotRegister"]); @@ -139,5 +144,10 @@ namespace LINGYUN.Abp.IdentityServer.WeChat // 登录之后需要更新安全令牌 (await UserManager.UpdateSecurityStampAsync(currentUser)).CheckErrors(); } + + protected virtual Task CheckFeatureAsync(ExtensionGrantValidationContext context) + { + return Task.FromResult(true); + } } } diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Localization/Resources/en.json b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Localization/Resources/en.json new file mode 100644 index 000000000..6a6402285 --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Localization/Resources/en.json @@ -0,0 +1,37 @@ +{ + "culture": "en", + "texts": { + "LINGYUN.Abp.Message:01400": "Sending the message failed: The message is incomplete!", + "LINGYUN.Abp.Message:01401": "You have not joined the group and cannot operate!", + "LINGYUN.Abp.Message:02301": "Group application has been sent, waiting for administrator's approval", + "LINGYUN.Abp.Message:02302": "You need to validate the questions to join the group chat", + "LINGYUN.Abp.Message:02400": "The administrator has turned on silence mode!", + "LINGYUN.Abp.Message:02403": "The administrator has banned you from speaking!", + "LINGYUN.Abp.Message:02401": "The administrator does not allow anonymous speaking!", + "LINGYUN.Abp.Message:02404": "Sending the message failed: the group does not exist or is disbanded!", + "LINGYUN.Abp.Message:03301": "Friend request has been sent, waiting for the other party's approval", + "LINGYUN.Abp.Message:03302": "You need to verify the problem to add friends", + "LINGYUN.Abp.Message:03400": "The user has rejected all messages!", + "LINGYUN.Abp.Message:03401": "The user rejects the message you sent!", + "LINGYUN.Abp.Message:03402": "Users do not receive anonymous comments!", + "LINGYUN.Abp.Message:03403": "Sending the message failed: the person needs to agree to add a friend!", + "LINGYUN.Abp.Message:03404": "Sending the message failed: the user does not exist or is deactivated!", + "LINGYUN.Abp.Message:03410": "Users refuse to add friends", + "LINGYUN.Abp.Message:03411": "The other party is already your friend or has sent an authentication request. The operation cannot be repeated!", + "Notifications:MultiTenancy": "Multi Tenancy", + "Notifications:Users": "Users", + "Notifications:NewTenantRegisterd": "Tenant creation notification", + "Notifications:WelcomeToApplication": "User Welcome Notice", + "Notifications:IM": "Instant Messaging", + "Notifications:FriendValidation": "Friend verification notification", + "Notifications:NewFriend": "New friend notification", + "Notifications:RequestAddNewFriend": "User {name} has requested that you be added as a friend", + "Notifications:RequestAddNewFriendDetail": "Description: {description}", + "Notifications:JoinGroup": "Join group notification", + "Notifications:ExitGroup": "Exit group notification", + "Notifications:DissolveGroup": "Dissolve group notification", + "AddNewFriendBySearchId": "Add by account search", + "WelcomeToApplicationFormUser": "User :{User} welcome to join us!", + "Messages:NewFriend": "I have added you as a friend, let's chat together!" + } +} \ No newline at end of file diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Localization/Resources/zh-Hans.json b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Localization/Resources/zh-Hans.json new file mode 100644 index 000000000..27b1e8ea8 --- /dev/null +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain.Shared/LINGYUN/Abp/MessageService/Localization/Resources/zh-Hans.json @@ -0,0 +1,37 @@ +{ + "culture": "zh-Hans", + "texts": { + "LINGYUN.Abp.Message:01400": "发送消息失败: 消息不完整!", + "LINGYUN.Abp.Message:01401": "您还未加入群组,不能进行操作!", + "LINGYUN.Abp.Message:02301": "已发送群组申请,等待管理员同意", + "LINGYUN.Abp.Message:02302": "你需要验证问题才能加入群聊", + "LINGYUN.Abp.Message:02400": "管理员已开启全员禁言!", + "LINGYUN.Abp.Message:02403": "管理员已禁止您发言!", + "LINGYUN.Abp.Message:02401": "管理员不允许匿名发言!", + "LINGYUN.Abp.Message:02404": "发送消息失败: 群组不存在或已解散!", + "LINGYUN.Abp.Message:03301": "已发送好友申请,等待对方同意", + "LINGYUN.Abp.Message:03302": "你需要验证问题才能添加好友", + "LINGYUN.Abp.Message:03400": "用户已拒接所有消息!", + "LINGYUN.Abp.Message:03401": "用户拒绝您发送的消息!", + "LINGYUN.Abp.Message:03402": "用户不接收匿名发言!", + "LINGYUN.Abp.Message:03403": "需要对方同意添加好友才能发送消息!", + "LINGYUN.Abp.Message:03404": "发送消息失败: 用户不存在或已注销账号!", + "LINGYUN.Abp.Message:03410": "用户拒绝添加好友", + "LINGYUN.Abp.Message:03411": "对方已是您的好友或已发送验证请求,不能重复操作!", + "Notifications:MultiTenancy": "租户通知", + "Notifications:Users": "用户通知", + "Notifications:NewTenantRegisterd": "租户创建通知", + "Notifications:WelcomeToApplication": "用户欢迎通知", + "Notifications:IM": "即时通讯", + "Notifications:FriendValidation": "好友验证通知", + "Notifications:NewFriend": "新好友通知", + "Notifications:RequestAddNewFriend": "用户 {name} 请求添加您为好友", + "Notifications:RequestAddNewFriendDetail": "附加说明: {description}", + "Notifications:JoinGroup": "加入群组通知", + "Notifications:ExitGroup": "退出群组通知", + "Notifications:DissolveGroup": "群组解散通知", + "AddNewFriendBySearchId": "通过账号搜索添加", + "WelcomeToApplicationFormUser": "用户:{User} 欢迎您的加入!", + "Messages:NewFriend": "我已经添加您为好友,让我们一起聊天吧!" + } +} \ No newline at end of file diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN.Abp.WeChat.MiniProgram.csproj b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN.Abp.WeChat.MiniProgram.csproj index 6c54dd3bf..a0d59ded7 100644 --- a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN.Abp.WeChat.MiniProgram.csproj +++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN.Abp.WeChat.MiniProgram.csproj @@ -18,6 +18,7 @@ + diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/AbpWeChatMiniProgramModule.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/AbpWeChatMiniProgramModule.cs index fb67d3276..62752dccf 100644 --- a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/AbpWeChatMiniProgramModule.cs +++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/AbpWeChatMiniProgramModule.cs @@ -1,4 +1,5 @@ -using LINGYUN.Abp.WeChat.Localization; +using LINGYUN.Abp.Features.LimitValidation; +using LINGYUN.Abp.WeChat.Localization; using Microsoft.Extensions.DependencyInjection; using System; using Volo.Abp.Localization; @@ -8,7 +9,8 @@ using Volo.Abp.VirtualFileSystem; namespace LINGYUN.Abp.WeChat.MiniProgram { [DependsOn( - typeof(AbpWeChatModule))] + typeof(AbpWeChatModule), + typeof(AbpFeaturesLimitValidationModule))] public class AbpWeChatMiniProgramModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Features/WeChatMiniProgramFeatureDefinitionProvider.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Features/WeChatMiniProgramFeatureDefinitionProvider.cs new file mode 100644 index 000000000..0b89a3537 --- /dev/null +++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Features/WeChatMiniProgramFeatureDefinitionProvider.cs @@ -0,0 +1,64 @@ +using LINGYUN.Abp.WeChat.Features; +using LINGYUN.Abp.WeChat.Localization; +using Volo.Abp.Features; +using Volo.Abp.Localization; +using Volo.Abp.Validation.StringValues; + +namespace LINGYUN.Abp.WeChat.MiniProgram.Features +{ + public class WeChatMiniProgramFeatureDefinitionProvider : FeatureDefinitionProvider + { + public override void Define(IFeatureDefinitionContext context) + { + var group = context.GetGroupOrNull(WeChatFeatures.GroupName); + + var miniProgram = group.AddFeature( + name: WeChatMiniProgramFeatures.GroupName, + displayName: L("Features:WeChat.MiniProgram"), + description: L("Features:WeChat.MiniProgramDesc")); + + miniProgram.CreateChild( + name: WeChatMiniProgramFeatures.Enable, + defaultValue: true.ToString(), + displayName: L("Features:WeChat.MiniProgram.Enable"), + description: L("Features:WeChat.MiniProgram.EnableDesc"), + valueType: new ToggleStringValueType(new BooleanValueValidator())); + miniProgram.CreateChild( + name: WeChatMiniProgramFeatures.EnableAuthorization, + defaultValue: true.ToString(), + displayName: L("Features:WeChat.MiniProgram.EnableAuthorization"), + description: L("Features:WeChat.MiniProgram.EnableAuthorizationDesc"), + valueType: new ToggleStringValueType(new BooleanValueValidator())); + + + var message = miniProgram.CreateChild( + name: WeChatMiniProgramFeatures.Messages.Default, + displayName: L("Features:WeChat.MiniProgram.Messages"), + description: L("Features:WeChat.MiniProgram.MessagesDesc")); + + message.CreateChild( + name: WeChatMiniProgramFeatures.Messages.Enable, + defaultValue: true.ToString(), + displayName: L("Features:WeChat.MiniProgram.EnableMessages"), + description: L("Features:WeChat.MiniProgram.EnableMessagesDesc"), + valueType: new ToggleStringValueType(new BooleanValueValidator())); + message.CreateChild( + name: WeChatMiniProgramFeatures.Messages.SendLimit, + defaultValue: WeChatMiniProgramFeatures.Messages.DefaultSendLimit.ToString(), + displayName: L("Features:WeChat.MiniProgram.SendLimit"), + description: L("Features:WeChat.MiniProgram.SendLimitDesc"), + valueType: new FreeTextStringValueType(new NumericValueValidator(1, 100_0000))); + message.CreateChild( + name: WeChatMiniProgramFeatures.Messages.SendLimitInterval, + defaultValue: WeChatMiniProgramFeatures.Messages.DefaultSendLimitInterval.ToString(), + displayName: L("Features:WeChat.MiniProgram.SendLimitInterval"), + description: L("Features:WeChat.MiniProgram.SendLimitIntervalDesc"), + valueType: new FreeTextStringValueType(new NumericValueValidator(1, 100_0000))); + } + + protected LocalizableString L(string name) + { + return LocalizableString.Create(name); + } + } +} diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Features/WeChatMiniProgramFeatures.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Features/WeChatMiniProgramFeatures.cs new file mode 100644 index 000000000..4ce830f11 --- /dev/null +++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Features/WeChatMiniProgramFeatures.cs @@ -0,0 +1,36 @@ +using LINGYUN.Abp.WeChat.Features; + +namespace LINGYUN.Abp.WeChat.MiniProgram.Features +{ + public static class WeChatMiniProgramFeatures + { + public const string GroupName = WeChatFeatures.GroupName + ".MiniProgram"; + + public const string Enable = GroupName + ".Enable"; + + public const string EnableAuthorization = GroupName + ".EnableAuthorization"; + + public static class Messages + { + public const string Default = GroupName + ".Messages"; + + public const string Enable = Default + ".Enable"; + /// + /// 发送次数上限 + /// + public const string SendLimit = Default + ".SendLimit"; + /// + /// 发送次数上限时长 + /// + public const string SendLimitInterval = Default + ".SendLimitInterval"; + /// + /// 默认发布次数上限 + /// + public const int DefaultSendLimit = 1000; + /// + /// 默认发布次数上限时长 + /// + public const int DefaultSendLimitInterval = 1; + } + } +} diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Localization/Resources/en.json b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Localization/Resources/en.json index fee22225d..e7026f595 100644 --- a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Localization/Resources/en.json +++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Localization/Resources/en.json @@ -10,6 +10,20 @@ "DisplayName:WeChat.MiniProgram.Token": "Token", "Description:WeChat.MiniProgram.Token": "Token,See:https://developers.weixin.qq.com/miniprogram/dev/framework/", "DisplayName:WeChat.MiniProgram.EncodingAESKey": "Encoding AES Key", - "Description:WeChat.MiniProgram.EncodingAESKey": "Encoding AES Key,See:https://developers.weixin.qq.com/miniprogram/dev/framework/" + "Description:WeChat.MiniProgram.EncodingAESKey": "Encoding AES Key,See:https://developers.weixin.qq.com/miniprogram/dev/framework/", + "Features:WeChat.MiniProgram": "Mini Program", + "Features:WeChat.MiniProgramDesc": "Mini Program", + "Features:WeChat.MiniProgram.Enable": "Enable", + "Features:WeChat.MiniProgram.EnableDesc": "Enable Wechat MiniProgram", + "Features:WeChat.MiniProgram.EnableAuthorization": "Authentication", + "Features:WeChat.MiniProgram.EnableAuthorizationDesc": "Enable wechat mini program authentication", + "Features:WeChat.MiniProgram.Messages": "Template Message", + "Features:WeChat.MiniProgram.MessagesDesc": "Template Message", + "Features:WeChat.MiniProgram.EnableMessages": "Enable Template Message", + "Features:WeChat.MiniProgram.EnableMessagesDesc": "Enable wechat applet template message", + "Features:WeChat.MiniProgram.SendLimit": "Send Limit", + "Features:WeChat.MiniProgram.SendLimitDesc": "Limit wechat applet template message certain period", + "Features:WeChat.MiniProgram.SendLimitInterval": "Send Duration", + "Features:WeChat.MiniProgram.SendLimitIntervalDesc": "Limit template message can be invoked, unit is Month" } } \ No newline at end of file diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Localization/Resources/zh-Hans.json b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Localization/Resources/zh-Hans.json index 6fe42fc38..e09f24529 100644 --- a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Localization/Resources/zh-Hans.json +++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Localization/Resources/zh-Hans.json @@ -10,6 +10,20 @@ "DisplayName:WeChat.MiniProgram.Token": "小程序Token", "Description:WeChat.MiniProgram.Token": "微信小程序Token,详情见:https://developers.weixin.qq.com/miniprogram/dev/framework/", "DisplayName:WeChat.MiniProgram.EncodingAESKey": "小程序EncodingAESKey", - "Description:WeChat.MiniProgram.EncodingAESKey": "微信小程序EncodingAESKey,详情见:https://developers.weixin.qq.com/miniprogram/dev/framework/" + "Description:WeChat.MiniProgram.EncodingAESKey": "微信小程序EncodingAESKey,详情见:https://developers.weixin.qq.com/miniprogram/dev/framework/", + "Features:WeChat.MiniProgram": "微信小程序", + "Features:WeChat.MiniProgramDesc": "微信小程序", + "Features:WeChat.MiniProgram.Enable": "微信小程序", + "Features:WeChat.MiniProgram.EnableDesc": "在应用程序中启用微信小程序功能", + "Features:WeChat.MiniProgram.EnableAuthorization": "微信小程序认证", + "Features:WeChat.MiniProgram.EnableAuthorizationDesc": "在应用程序中启用微信小程序认证", + "Features:WeChat.MiniProgram.Messages": "模板消息", + "Features:WeChat.MiniProgram.MessagesDesc": "模板消息", + "Features:WeChat.MiniProgram.EnableMessages": "启用模板消息", + "Features:WeChat.MiniProgram.EnableMessagesDesc": "在应用程序中启用微信小程序模板消息", + "Features:WeChat.MiniProgram.SendLimit": "发送消息限制", + "Features:WeChat.MiniProgram.SendLimitDesc": "在一定周期内限制微信小程序模板消息调用上限", + "Features:WeChat.MiniProgram.SendLimitInterval": "发送消息限制时长", + "Features:WeChat.MiniProgram.SendLimitIntervalDesc": "限制模板消息调用上限的时长,周期为月" } } \ No newline at end of file diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Messages/SubscribeMessager.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Messages/SubscribeMessager.cs index cdb1cc6ec..1e7e2e598 100644 --- a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Messages/SubscribeMessager.cs +++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.MiniProgram/LINGYUN/Abp/WeChat/MiniProgram/Messages/SubscribeMessager.cs @@ -1,4 +1,6 @@ -using LINGYUN.Abp.WeChat.OpenId; +using LINGYUN.Abp.Features.LimitValidation; +using LINGYUN.Abp.WeChat.MiniProgram.Features; +using LINGYUN.Abp.WeChat.OpenId; using LINGYUN.Abp.WeChat.Token; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; @@ -11,9 +13,11 @@ using System.Threading; using System.Threading.Tasks; using Volo.Abp; using Volo.Abp.DependencyInjection; +using Volo.Abp.Features; namespace LINGYUN.Abp.WeChat.MiniProgram.Messages { + [RequiresFeature(WeChatMiniProgramFeatures.Enable)] public class SubscribeMessager : ISubscribeMessager, ITransientDependency { public ILogger Logger { get; set; } @@ -35,6 +39,12 @@ namespace LINGYUN.Abp.WeChat.MiniProgram.Messages Logger = NullLogger.Instance; } + [RequiresFeature(WeChatMiniProgramFeatures.Messages.Enable)] + [RequiresLimitFeature( + WeChatMiniProgramFeatures.Messages.SendLimit, + WeChatMiniProgramFeatures.Messages.SendLimitInterval, + LimitPolicy.Month, + WeChatMiniProgramFeatures.Messages.DefaultSendLimit)] public virtual async Task SendAsync( Guid toUser, string templateId, @@ -58,6 +68,12 @@ namespace LINGYUN.Abp.WeChat.MiniProgram.Messages await SendAsync(messageData, cancellation); } + [RequiresFeature(WeChatMiniProgramFeatures.Messages.Enable)] + [RequiresLimitFeature( + WeChatMiniProgramFeatures.Messages.SendLimit, + WeChatMiniProgramFeatures.Messages.SendLimitInterval, + LimitPolicy.Month, + WeChatMiniProgramFeatures.Messages.DefaultSendLimit)] public virtual async Task SendAsync(SubscribeMessage message, CancellationToken cancellationToken = default) { var options = await MiniProgramOptionsFactory.CreateAsync(); diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/Features/WeChatOfficialFeatureDefinitionProvider.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/Features/WeChatOfficialFeatureDefinitionProvider.cs new file mode 100644 index 000000000..88be4b4b4 --- /dev/null +++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/Features/WeChatOfficialFeatureDefinitionProvider.cs @@ -0,0 +1,39 @@ +using LINGYUN.Abp.WeChat.Features; +using LINGYUN.Abp.WeChat.Localization; +using Volo.Abp.Features; +using Volo.Abp.Localization; +using Volo.Abp.Validation.StringValues; + +namespace LINGYUN.Abp.WeChat.Official.Features +{ + public class WeChatOfficialFeatureDefinitionProvider : FeatureDefinitionProvider + { + public override void Define(IFeatureDefinitionContext context) + { + var group = context.GetGroupOrNull(WeChatFeatures.GroupName); + + var official = group.AddFeature( + name: WeChatOfficialFeatures.GroupName, + displayName: L("Features:WeChat.Official"), + description: L("Features:WeChat.OfficialDesc")); + + official.CreateChild( + name: WeChatOfficialFeatures.Enable, + defaultValue: true.ToString(), + displayName: L("Features:WeChat.Official.Enable"), + description: L("Features:WeChat.Official.EnableDesc"), + valueType: new ToggleStringValueType(new BooleanValueValidator())); + official.CreateChild( + name: WeChatOfficialFeatures.EnableAuthorization, + defaultValue: true.ToString(), + displayName: L("Features:WeChat.Official.EnableAuthorization"), + description: L("Features:WeChat.Official.EnableAuthorizationDesc"), + valueType: new ToggleStringValueType(new BooleanValueValidator())); + } + + protected LocalizableString L(string name) + { + return LocalizableString.Create(name); + } + } +} diff --git a/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/Features/WeChatOfficialFeatures.cs b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/Features/WeChatOfficialFeatures.cs new file mode 100644 index 000000000..06849ccc9 --- /dev/null +++ b/aspnet-core/modules/wechat/LINGYUN.Abp.WeChat.Official/LINGYUN/Abp/WeChat/Official/Features/WeChatOfficialFeatures.cs @@ -0,0 +1,13 @@ +using LINGYUN.Abp.WeChat.Features; + +namespace LINGYUN.Abp.WeChat.Official.Features +{ + public static class WeChatOfficialFeatures + { + public const string GroupName = WeChatFeatures.GroupName + ".Official"; + + public const string Enable = GroupName + ".Enable"; + + public const string EnableAuthorization = GroupName + ".EnableAuthorization"; + } +}