From a071e719b0ba5d59299c2fb681ee92a33bb39bc0 Mon Sep 17 00:00:00 2001 From: cKey <35512826+colinin@users.noreply.github.com> Date: Tue, 28 Sep 2021 11:22:47 +0800 Subject: [PATCH] add im message blocker --- .../LINGYUN.Abp.EventBus.CAP.xml | 911 +++++++++--------- .../Messages/SignalRMessageSenderProvider.cs | 141 +-- .../LINGYUN/Abp/IM/AbpIMOptions.cs | 33 +- .../Abp/IM/Messages/IMessageBlocker.cs | 9 + .../Abp/IM/Messages/MessageSendResult.cs | 45 + .../IM/Messages/MessageSenderProviderBase.cs | 120 +-- .../Abp/IM/Messages/NullMessageBlocker.cs | 14 + .../MessageService/Chat/UserChatSetting.cs | 106 +- .../SettingManagement/SettingAppService.cs | 766 +++++++-------- .../Distributed/ChatMessageEventHandler.cs | 114 ++- 10 files changed, 1165 insertions(+), 1094 deletions(-) create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/IMessageBlocker.cs create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/MessageSendResult.cs create mode 100644 aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/NullMessageBlocker.cs diff --git a/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN.Abp.EventBus.CAP.xml b/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN.Abp.EventBus.CAP.xml index a0a7a85fd..b5cd0708d 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN.Abp.EventBus.CAP.xml +++ b/aspnet-core/modules/common/LINGYUN.Abp.EventBus.CAP/modules/common/LINGYUN.Abp.EventBus.CAP/LINGYUN.Abp.EventBus.CAP.xml @@ -1,455 +1,456 @@ - - - - LINGYUN.Abp.EventBus.CAP - - - - - 消费者查找器 - - - - - CAP配置 - - - - - Abp分布式事件配置 - - - - - 服务提供者 - - - - - Creates a new . - - - - - 查找消费者集合 - - - - - - - 获取事件处理器集合 - - - - - - - - 过期消息清理任务 - - - - - 过期消息清理配置 - - - - - Initializer - - - - - Storage - - - - - 创建过期消息清理任务 - - - - - - - - - - 异步执行任务 - - - - - - - CapProcessingServer - - - - - CapProcessingServer - - - - - - - - Start - - - - - Pulse - - - - - Dispose - - - - - AbpCAPEventBusModule - - - - - ConfigureServices - - - - - - OnApplicationInitialization - - - - - - 过期消息清理配置项 - - - - - 发布消息处理失败通知 - default: false - - - - - 批量清理数量 - default: 1000 - - - - - 执行间隔(ms) - default: 3600000 (1 hours) - - - - - AbpECAPExecutionFailedException - - - - - MessageType - - - - - Message - - - - - constructor - - - - - - - constructor - - - - - - - - constructor - - - - - - - - - CAP消息扩展 - - - - - 尝试获取消息标头中的租户标识 - - - - - - - - 获取消息标头中的租户标识 - - - - - - - 重写 ISubscribeInvoker 实现 Abp 租户集成 - - - - - AbpCAPSubscribeInvoker - - - - - - - - - 调用订阅者方法 - - - - - - - - 获取事件处理类实例 - - - - - - - - 通过给定的类型实例与参数调用订阅者方法 - - - - - - - - - CAP分布式事件总线 - - - - - Abp分布式事件总线配置 - - - - - CAP消息发布接口 - - - - - 自定义事件注册接口 - - - - - 本地事件处理器工厂对象集合 - - - - - 本地事件集合 - - - - - 当前用户 - - - - - 当前客户端 - - - - - 取消令牌 - - - - - constructor - - - - - - - - - - - - - 订阅事件 - - - - - - - - 退订事件 - - 事件类型 - - - - - 退订事件 - - 事件类型 - 事件处理器 - - - - 退订事件 - - 事件类型 - 事件处理器工厂 - - - - 退订所有事件 - - 事件类型 - - - - 订阅事件 - - 事件类型 - 事件处理器 - - - - - 发布事件 - - 事件类型 - 事件数据对象 - - - - - 获取事件处理器工厂列表 - - - - - - - 自定义事件订阅者 - - - - - 订阅事件 - - - - - - - 取消订阅 - - - - - - - Executes the configured method on . This can be used whether or not - the configured method is asynchronous. - - - Even if the target method is asynchronous, it's desirable to invoke it using Execute rather than - ExecuteAsync if you know at compile time what the return type is, because then you can directly - "await" that value (via a cast), and then the generated code will be able to reference the - resulting awaitable as a value-typed variable. If you use ExecuteAsync instead, the generated - code will have to treat the resulting awaitable as a boxed object, because it doesn't know at - compile time what type it would be. - - The object whose method is to be executed. - Parameters to pass to the method. - The method return value. - - - - Executes the configured method on . This can only be used if the configured - method is asynchronous. - - - If you don't know at compile time the type of the method's returned awaitable, you can use ExecuteAsync, - which supplies an awaitable-of-object. This always works, but can incur several extra heap allocations - as compared with using Execute and then using "await" on the result value typecasted to the known - awaitable type. The possible extra heap allocations are for: - 1. The custom awaitable (though usually there's a heap allocation for this anyway, since normally - it's a reference type, and you normally create a new instance per call). - 2. The custom awaiter (whether or not it's a value type, since if it's not, you need a new instance - of it, and if it is, it will have to be boxed so the calling code can reference it as an object). - 3. The async result value, if it's a value type (it has to be boxed as an object, since the calling - code doesn't know what type it's going to be). - - The object whose method is to be executed. - Parameters to pass to the method. - An object that you can "await" to get the method return value. - - - - Provides a common awaitable structure that can - return, regardless of whether the underlying value is a System.Task, an FSharpAsync, or an - application-defined custom awaitable. - - - - - Helper for detecting whether a given type is FSharpAsync`1, and if so, supplying - an for mapping instances of that type to a C# awaitable. - - - The main design goal here is to avoid taking a compile-time dependency on - FSharp.Core.dll, because non-F# applications wouldn't use it. So all the references - to FSharp types have to be constructed dynamically at runtime. - - - - - CAP ServiceCollectionExtensions - - - - - Adds and configures the consistence services for the consistency. - - - - - - - + + + + LINGYUN.Abp.EventBus.CAP + + + + + 消费者查找器 + + + + + CAP配置 + + + + + Abp分布式事件配置 + + + + + 服务提供者 + + + + + Creates a new . + + + + + 查找消费者集合 + + + + + + + 获取事件处理器集合 + + + + + + + + 过期消息清理任务 + + + + + 过期消息清理配置 + + + + + Initializer + + + + + Storage + + + + + 创建过期消息清理任务 + + + + + + + + + + 异步执行任务 + + + + + + + CapProcessingServer + + + + + CapProcessingServer + + + + + + + + Start + + + + + Pulse + + + + + Dispose + + + + + AbpCAPEventBusModule + + + + + ConfigureServices + + + + + + OnApplicationInitialization + + + + + + 过期消息清理配置项 + + + + + 发布消息处理失败通知 + default: false + + + + + 批量清理数量 + default: 1000 + + + + + 执行间隔(ms) + default: 3600000 (1 hours) + + + + + AbpECAPExecutionFailedException + + + + + MessageType + + + + + Message + + + + + constructor + + + + + + + constructor + + + + + + + + constructor + + + + + + + + + CAP消息扩展 + + + + + 尝试获取消息标头中的租户标识 + + + + + + + + 获取消息标头中的租户标识 + + + + + + + 重写 ISubscribeInvoker 实现 Abp 租户集成 + + + + + AbpCAPSubscribeInvoker + + + + + + + + + 调用订阅者方法 + + + + + + + + 获取事件处理类实例 + + + + + + + + 通过给定的类型实例与参数调用订阅者方法 + + + + + + + + + CAP分布式事件总线 + + + + + Abp分布式事件总线配置 + + + + + CAP消息发布接口 + + + + + 自定义事件注册接口 + + + + + 本地事件处理器工厂对象集合 + + + + + 本地事件集合 + + + + + 当前用户 + + + + + 当前客户端 + + + + + 取消令牌 + + + + + constructor + + + + + + + + + + + + + + 订阅事件 + + + + + + + + 退订事件 + + 事件类型 + + + + + 退订事件 + + 事件类型 + 事件处理器 + + + + 退订事件 + + 事件类型 + 事件处理器工厂 + + + + 退订所有事件 + + 事件类型 + + + + 订阅事件 + + 事件类型 + 事件处理器 + + + + + 发布事件 + + 事件类型 + 事件数据对象 + + + + + 获取事件处理器工厂列表 + + + + + + + 自定义事件订阅者 + + + + + 订阅事件 + + + + + + + 取消订阅 + + + + + + + Executes the configured method on . This can be used whether or not + the configured method is asynchronous. + + + Even if the target method is asynchronous, it's desirable to invoke it using Execute rather than + ExecuteAsync if you know at compile time what the return type is, because then you can directly + "await" that value (via a cast), and then the generated code will be able to reference the + resulting awaitable as a value-typed variable. If you use ExecuteAsync instead, the generated + code will have to treat the resulting awaitable as a boxed object, because it doesn't know at + compile time what type it would be. + + The object whose method is to be executed. + Parameters to pass to the method. + The method return value. + + + + Executes the configured method on . This can only be used if the configured + method is asynchronous. + + + If you don't know at compile time the type of the method's returned awaitable, you can use ExecuteAsync, + which supplies an awaitable-of-object. This always works, but can incur several extra heap allocations + as compared with using Execute and then using "await" on the result value typecasted to the known + awaitable type. The possible extra heap allocations are for: + 1. The custom awaitable (though usually there's a heap allocation for this anyway, since normally + it's a reference type, and you normally create a new instance per call). + 2. The custom awaiter (whether or not it's a value type, since if it's not, you need a new instance + of it, and if it is, it will have to be boxed so the calling code can reference it as an object). + 3. The async result value, if it's a value type (it has to be boxed as an object, since the calling + code doesn't know what type it's going to be). + + The object whose method is to be executed. + Parameters to pass to the method. + An object that you can "await" to get the method return value. + + + + Provides a common awaitable structure that can + return, regardless of whether the underlying value is a System.Task, an FSharpAsync, or an + application-defined custom awaitable. + + + + + Helper for detecting whether a given type is FSharpAsync`1, and if so, supplying + an for mapping instances of that type to a C# awaitable. + + + The main design goal here is to avoid taking a compile-time dependency on + FSharp.Core.dll, because non-F# applications wouldn't use it. So all the references + to FSharp types have to be constructed dynamically at runtime. + + + + + CAP ServiceCollectionExtensions + + + + + Adds and configures the consistence services for the consistency. + + + + + + + diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Messages/SignalRMessageSenderProvider.cs b/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Messages/SignalRMessageSenderProvider.cs index 4b7ab5cd5..32f3341d5 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Messages/SignalRMessageSenderProvider.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.IM.SignalR/LINGYUN/Abp/IM/SignalR/Messages/SignalRMessageSenderProvider.cs @@ -1,70 +1,71 @@ -using LINGYUN.Abp.IM.Messages; -using LINGYUN.Abp.IM.SignalR.Hubs; -using LINGYUN.Abp.RealTime.Client; -using Microsoft.AspNetCore.SignalR; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using System; -using System.Collections.Immutable; -using System.Linq; -using System.Threading.Tasks; - -namespace LINGYUN.Abp.IM.SignalR.Messages -{ - public class SignalRMessageSenderProvider : MessageSenderProviderBase - { - public override string Name => "SignalR"; - private readonly AbpIMSignalROptions _options; - - private readonly IOnlineClientManager _onlineClientManager; - - private readonly IHubContext _hubContext; - - public SignalRMessageSenderProvider( - IOnlineClientManager onlineClientManager, - IHubContext hubContext, - IServiceProvider serviceProvider, - IOptions options) - : base(serviceProvider) - { - _options = options.Value; - _hubContext = hubContext; - _onlineClientManager = onlineClientManager; - } - - protected override async Task SendMessageToGroupAsync(ChatMessage chatMessage) - { - var signalRClient = _hubContext.Clients.Group(chatMessage.GroupId); - if (signalRClient == null) - { - Logger.LogDebug("Can not get group " + chatMessage.GroupId + " from SignalR hub!"); - return; - } - - await signalRClient.SendAsync(_options.GetChatMessageMethod, chatMessage); - } - - protected override async Task SendMessageToUserAsync(ChatMessage chatMessage) - { - try - { - var onlineClientContext = new OnlineClientContext(chatMessage.TenantId, chatMessage.ToUserId.Value); - var onlineClients = _onlineClientManager.GetAllByContext(onlineClientContext); - - var onlineClientConnectionIds = onlineClients.Select(client => client.ConnectionId).ToImmutableArray(); - var signalRClients = _hubContext.Clients.Clients(onlineClientConnectionIds); - if (signalRClients == null) - { - Logger.LogDebug("Can not get user " + onlineClientContext.UserId + " connection from SignalR hub!"); - return; - } - await signalRClients.SendAsync(_options.GetChatMessageMethod, chatMessage); - } - catch (Exception ex) - { - Logger.LogWarning("Could not send message to user: {0}", chatMessage.ToUserId); - Logger.LogWarning("Send to user message error: {0}", ex.Message); - } - } - } -} +using LINGYUN.Abp.IM.Messages; +using LINGYUN.Abp.IM.SignalR.Hubs; +using LINGYUN.Abp.RealTime.Client; +using Microsoft.AspNetCore.SignalR; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Immutable; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace LINGYUN.Abp.IM.SignalR.Messages +{ + public class SignalRMessageSenderProvider : MessageSenderProviderBase + { + public override string Name => "SignalR"; + private readonly AbpIMSignalROptions _options; + + private readonly IOnlineClientManager _onlineClientManager; + + private readonly IHubContext _hubContext; + + public SignalRMessageSenderProvider( + IOnlineClientManager onlineClientManager, + IHubContext hubContext, + IAbpLazyServiceProvider serviceProvider, + IOptions options) + : base(serviceProvider) + { + _options = options.Value; + _hubContext = hubContext; + _onlineClientManager = onlineClientManager; + } + + protected override async Task SendMessageToGroupAsync(ChatMessage chatMessage) + { + var signalRClient = _hubContext.Clients.Group(chatMessage.GroupId); + if (signalRClient == null) + { + Logger.LogDebug("Can not get group " + chatMessage.GroupId + " from SignalR hub!"); + return; + } + + await signalRClient.SendAsync(_options.GetChatMessageMethod, chatMessage); + } + + protected override async Task SendMessageToUserAsync(ChatMessage chatMessage) + { + try + { + var onlineClientContext = new OnlineClientContext(chatMessage.TenantId, chatMessage.ToUserId.Value); + var onlineClients = _onlineClientManager.GetAllByContext(onlineClientContext); + + var onlineClientConnectionIds = onlineClients.Select(client => client.ConnectionId).ToImmutableArray(); + var signalRClients = _hubContext.Clients.Clients(onlineClientConnectionIds); + if (signalRClients == null) + { + Logger.LogDebug("Can not get user " + onlineClientContext.UserId + " connection from SignalR hub!"); + return; + } + await signalRClients.SendAsync(_options.GetChatMessageMethod, chatMessage); + } + catch (Exception ex) + { + Logger.LogWarning("Could not send message to user: {0}", chatMessage.ToUserId); + Logger.LogWarning("Send to user message error: {0}", ex.Message); + } + } + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/AbpIMOptions.cs b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/AbpIMOptions.cs index 01b49fd6e..9edd10278 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/AbpIMOptions.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/AbpIMOptions.cs @@ -1,15 +1,18 @@ -using LINGYUN.Abp.IM.Messages; -using Volo.Abp.Collections; - -namespace LINGYUN.Abp.IM -{ - public class AbpIMOptions - { - public ITypeList Providers { get; } - - public AbpIMOptions() - { - Providers = new TypeList(); - } - } -} +using LINGYUN.Abp.IM.Messages; +using Volo.Abp.Collections; + +namespace LINGYUN.Abp.IM +{ + public class AbpIMOptions + { + /// + /// 消息发送者 + /// + public ITypeList Providers { get; } + + public AbpIMOptions() + { + Providers = new TypeList(); + } + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/IMessageBlocker.cs b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/IMessageBlocker.cs new file mode 100644 index 000000000..0d01a38c1 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/IMessageBlocker.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace LINGYUN.Abp.IM.Messages +{ + public interface IMessageBlocker + { + Task InterceptAsync(ChatMessage message); + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/MessageSendResult.cs b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/MessageSendResult.cs new file mode 100644 index 000000000..a83b4ee97 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/MessageSendResult.cs @@ -0,0 +1,45 @@ +namespace LINGYUN.Abp.IM.Messages +{ + public class MessageSendResult + { + public bool Success { get; } + public string Error { get; } + public int Code { get; } + public string Form { get; } + public string To { get; } + public string Content { get; } + public static MessageSendResult Successed(string form, string to, string content) + { + return new MessageSendResult(form, to, content); + } + + public static MessageSendResult Failed(int code, string error, string form, string to, string content) + { + return new MessageSendResult(code, error, form, to, content); + } + private MessageSendResult( + int code, + string error, + string form, + string to, + string content) + { + Code = code; + Error = error; + Form = form; + To = to; + Success = false; + } + + private MessageSendResult( + string form, + string to, + string content) + { + Form = form; + To = to; + Content = content; + Success = true; + } + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/MessageSenderProviderBase.cs b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/MessageSenderProviderBase.cs index ef8f3223c..5a708a8b5 100644 --- a/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/MessageSenderProviderBase.cs +++ b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/MessageSenderProviderBase.cs @@ -1,70 +1,50 @@ -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Abstractions; -using System; -using System.Threading.Tasks; -using Volo.Abp.DependencyInjection; - -namespace LINGYUN.Abp.IM.Messages -{ - public abstract class MessageSenderProviderBase : IMessageSenderProvider, ITransientDependency - { - public abstract string Name { get; } - - protected IServiceProvider ServiceProvider { get; } - - protected readonly object ServiceProviderLock = new object(); - - public ILoggerFactory LoggerFactory => LazyGetRequiredService(ref _loggerFactory); - private ILoggerFactory _loggerFactory; - - protected ILogger Logger => _lazyLogger.Value; - private Lazy _lazyLogger => new Lazy(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true); - - protected TService LazyGetRequiredService(ref TService reference) - { - if (reference == null) - { - lock (ServiceProviderLock) - { - if (reference == null) - { - reference = ServiceProvider.GetRequiredService(); - } - } - } - - return reference; - } - - protected MessageSenderProviderBase(IServiceProvider serviceProvider) - { - ServiceProvider = serviceProvider; - } - - public virtual async Task SendMessageAsync(ChatMessage chatMessage) - { - try - { - if (!chatMessage.GroupId.IsNullOrWhiteSpace()) - { - await SendMessageToGroupAsync(chatMessage); - } - else - { - await SendMessageToUserAsync(chatMessage); - } - } - catch (Exception ex) - { - Logger.LogWarning("Could not send message, group: {0}, formUser: {1}, toUser: {2}", - chatMessage.GroupId, chatMessage.FormUserName, - chatMessage.ToUserId.HasValue ? chatMessage.ToUserId.ToString() : "None"); - Logger.LogWarning("Send group message error: {0}", ex.Message); - } - } - - protected abstract Task SendMessageToGroupAsync(ChatMessage chatMessage); - protected abstract Task SendMessageToUserAsync(ChatMessage chatMessage); - } -} +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using System; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace LINGYUN.Abp.IM.Messages +{ + public abstract class MessageSenderProviderBase : IMessageSenderProvider, ITransientDependency + { + public abstract string Name { get; } + + protected IAbpLazyServiceProvider ServiceProvider { get; } + + protected ILoggerFactory LoggerFactory => ServiceProvider.LazyGetRequiredService(); + + protected ILogger Logger => _lazyLogger.Value; + private Lazy _lazyLogger => new Lazy(() => LoggerFactory?.CreateLogger(GetType().FullName) ?? NullLogger.Instance, true); + + protected MessageSenderProviderBase(IAbpLazyServiceProvider serviceProvider) + { + ServiceProvider = serviceProvider; + } + + public virtual async Task SendMessageAsync(ChatMessage chatMessage) + { + try + { + if (!chatMessage.GroupId.IsNullOrWhiteSpace()) + { + await SendMessageToGroupAsync(chatMessage); + } + else + { + await SendMessageToUserAsync(chatMessage); + } + } + catch (Exception ex) + { + Logger.LogWarning("Could not send message, group: {0}, formUser: {1}, toUser: {2}", + chatMessage.GroupId, chatMessage.FormUserName, + chatMessage.ToUserId.HasValue ? chatMessage.ToUserId.ToString() : "None"); + Logger.LogWarning("Send group message error: {0}", ex.Message); + } + } + + protected abstract Task SendMessageToGroupAsync(ChatMessage chatMessage); + protected abstract Task SendMessageToUserAsync(ChatMessage chatMessage); + } +} diff --git a/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/NullMessageBlocker.cs b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/NullMessageBlocker.cs new file mode 100644 index 000000000..0f583c065 --- /dev/null +++ b/aspnet-core/modules/common/LINGYUN.Abp.IM/LINGYUN/Abp/IM/Messages/NullMessageBlocker.cs @@ -0,0 +1,14 @@ +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace LINGYUN.Abp.IM.Messages +{ + [Dependency(TryRegister = true)] + public class NullMessageBlocker : IMessageBlocker, ISingletonDependency + { + public Task InterceptAsync(ChatMessage message) + { + return Task.CompletedTask; + } + } +} diff --git a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserChatSetting.cs b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserChatSetting.cs index 75adcc56c..cf6e74ea3 100644 --- a/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserChatSetting.cs +++ b/aspnet-core/modules/message/LINGYUN.Abp.MessageService.Domain/LINGYUN/Abp/MessageService/Chat/UserChatSetting.cs @@ -1,54 +1,52 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Volo.Abp.Domain.Entities; -using Volo.Abp.MultiTenancy; - -namespace LINGYUN.Abp.MessageService.Chat -{ - public class UserChatSetting : Entity, IMultiTenant - { - /// - /// 租户 - /// - public virtual Guid? TenantId { get; protected set; } - /// - /// 用户标识 - /// - public virtual Guid UserId { get; protected set; } - /// - /// 允许匿名聊天 - /// - public virtual bool AllowAnonymous { get; set; } - /// - /// 允许添加好友 - /// - public virtual bool AllowAddFriend { get; set; } - /// - /// 添加好友需要验证 - /// - public virtual bool RequireAddFriendValition { get; set; } - /// - /// 允许接收消息 - /// - public virtual bool AllowReceiveMessage { get; set; } - /// - /// 允许发送消息 - /// - public virtual bool AllowSendMessage { get; set; } - protected UserChatSetting() - { - } - public UserChatSetting(Guid userId, Guid? tenantId) - : this() - { - UserId = userId; - TenantId = tenantId; - AllowAnonymous = false; - AllowAddFriend = true; - AllowReceiveMessage = true; - AllowSendMessage = true; - RequireAddFriendValition = true; - } - } -} +using System; +using Volo.Abp.Domain.Entities; +using Volo.Abp.MultiTenancy; + +namespace LINGYUN.Abp.MessageService.Chat +{ + public class UserChatSetting : Entity, IMultiTenant + { + /// + /// 租户 + /// + public virtual Guid? TenantId { get; protected set; } + /// + /// 用户标识 + /// + public virtual Guid UserId { get; protected set; } + /// + /// 允许匿名聊天 + /// + public virtual bool AllowAnonymous { get; set; } + /// + /// 允许添加好友 + /// + public virtual bool AllowAddFriend { get; set; } + /// + /// 添加好友需要验证 + /// + public virtual bool RequireAddFriendValition { get; set; } + /// + /// 允许接收消息 + /// + public virtual bool AllowReceiveMessage { get; set; } + /// + /// 允许发送消息 + /// + public virtual bool AllowSendMessage { get; set; } + protected UserChatSetting() + { + } + public UserChatSetting(Guid userId, Guid? tenantId) + : this() + { + UserId = userId; + TenantId = tenantId; + AllowAnonymous = false; + AllowAddFriend = true; + AllowReceiveMessage = true; + AllowSendMessage = true; + RequireAddFriendValition = true; + } + } +} diff --git a/aspnet-core/modules/settings/LINGYUN.Abp.SettingManagement.Application/LINGYUN/Abp/SettingManagement/SettingAppService.cs b/aspnet-core/modules/settings/LINGYUN.Abp.SettingManagement.Application/LINGYUN/Abp/SettingManagement/SettingAppService.cs index c475a37ba..518df2bba 100644 --- a/aspnet-core/modules/settings/LINGYUN.Abp.SettingManagement.Application/LINGYUN/Abp/SettingManagement/SettingAppService.cs +++ b/aspnet-core/modules/settings/LINGYUN.Abp.SettingManagement.Application/LINGYUN/Abp/SettingManagement/SettingAppService.cs @@ -1,377 +1,389 @@ -using Microsoft.AspNetCore.Authorization; -using Microsoft.Extensions.Options; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Volo.Abp.Account.Settings; -using Volo.Abp.Application.Dtos; -using Volo.Abp.Application.Services; -using Volo.Abp.Caching; -using Volo.Abp.Emailing; -using Volo.Abp.Identity.Settings; -using Volo.Abp.Localization; -using Volo.Abp.MultiTenancy; -using Volo.Abp.SettingManagement; -using Volo.Abp.SettingManagement.Localization; -using Volo.Abp.Settings; -using Volo.Abp.Timing; -using Volo.Abp.Users; -using Volo.Abp.EventBus.Distributed; -using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; - -namespace LINGYUN.Abp.SettingManagement -{ - [Authorize(AbpSettingManagementPermissions.Settings.Default)] - public class SettingAppService : ApplicationService, ISettingAppService - { - protected AbpLocalizationOptions LocalizationOptions { get; } - - protected IDistributedEventBus EventBus { get; } - protected ISettingManager SettingManager { get; } - protected ISettingDefinitionManager SettingDefinitionManager { get; } - - protected IDistributedCache Cache { get; } - public SettingAppService( - IDistributedEventBus eventBus, - ISettingManager settingManager, - IDistributedCache cache, - IOptions localizationOptions, - ISettingDefinitionManager settingDefinitionManager) - { - Cache = cache; - EventBus = eventBus; - SettingManager = settingManager; - SettingDefinitionManager = settingDefinitionManager; - LocalizationOptions = localizationOptions.Value; - LocalizationResource = typeof(AbpSettingManagementResource); - } - - [Authorize(AbpSettingManagementPermissions.Settings.Manager)] - public virtual async Task SetGlobalAsync(UpdateSettingsDto input) - { - foreach (var setting in input.Settings) - { - await SettingManager.SetGlobalAsync(setting.Name, setting.Value); - } - - CurrentUnitOfWork.OnCompleted(async () => - { - // 发送刷新用户缓存事件 - await EventBus.PublishAsync(new CurrentApplicationConfigurationCacheResetEventData()); - }); - - await CurrentUnitOfWork.SaveChangesAsync(); - } - - [Authorize(AbpSettingManagementPermissions.Settings.Manager)] - public virtual async Task SetCurrentTenantAsync(UpdateSettingsDto input) - { - if (CurrentTenant.IsAvailable) - { - foreach (var setting in input.Settings) - { - await SettingManager.SetForTenantAsync(CurrentTenant.GetId(), setting.Name, setting.Value); - } - - CurrentUnitOfWork.OnCompleted(async () => - { - // 发送刷新用户缓存事件 - await EventBus.PublishAsync(new CurrentApplicationConfigurationCacheResetEventData()); - }); - - await CurrentUnitOfWork.SaveChangesAsync(); - } - } - - //[Authorize] - [AllowAnonymous] - public virtual async Task> GetAllForCurrentTenantAsync() - { - return await GetAllForProviderAsync(TenantSettingValueProvider.ProviderName, CurrentTenant.GetId().ToString()); - } - - [AllowAnonymous] - public virtual async Task> GetAllForGlobalAsync() - { - return await GetAllForProviderAsync(GlobalSettingValueProvider.ProviderName, null); - } - - protected virtual async Task> GetAllForProviderAsync(string providerName, string providerKey) - { - /* - * 2020-11-19 - * colin@foxmail.com - * - * 之所以重构为这种看似硬编码的设计,是因为硬编码的都是常用的自带的配置 - * - * 自定义的应用模块可以实现返回相同Dto的配置服务,然后通过路由的聚合功能, - * 轻松加入到前端的设置管理(因为vue前端已设计为动态表单页面) - * - * 最初的设计才是不合理的,前端不能硬编码设置管理界面,这应该是后端的事情 - */ - - var settingGroups = new List(); - - #region 系统设置 - - var sysSettingGroup = new SettingGroupDto(L["DisplayName:System"], L["Description:System"]); - // 语言 - var languageSetting = sysSettingGroup.AddSetting(L["DisplayName:System.Language"], L["Description:System.Language"]); - languageSetting.AddDetail( - SettingDefinitionManager.Get(LocalizationSettingNames.DefaultLanguage), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(LocalizationSettingNames.DefaultLanguage, providerName, providerKey), - ValueType.Option) - .AddOptions(LocalizationOptions.Languages.Select(l => new OptionDto(l.DisplayName, l.CultureName))); - // 时区 - var timingSetting = sysSettingGroup.AddSetting(L["DisplayName:System.Timing"], L["Description:System.Timing"]); - timingSetting.AddDetail( - SettingDefinitionManager.Get(TimingSettingNames.TimeZone), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(TimingSettingNames.TimeZone, providerName, providerKey), - ValueType.String); - settingGroups.Add(sysSettingGroup); - - #endregion - - #region 安全设置 - - var securitySettingGroup = new SettingGroupDto(L["DisplayName:Security"], L["Description:Security"]); - - // 用户账户 - var accountSetting = securitySettingGroup.AddSetting(L["DisplayName:Security.Account"], L["Description:Security.Account"]); - // 启用本地登录 - accountSetting.AddDetail( - SettingDefinitionManager.Get(AccountSettingNames.EnableLocalLogin), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(AccountSettingNames.EnableLocalLogin, providerName, providerKey), - ValueType.Boolean); - accountSetting.AddDetail( - SettingDefinitionManager.Get(AccountSettingNames.IsSelfRegistrationEnabled), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(AccountSettingNames.IsSelfRegistrationEnabled, providerName, providerKey), - ValueType.Boolean); - - settingGroups.Add(securitySettingGroup); - - #endregion - - #region 身份标识设置 - - // 身份标识设置 - var identitySetting = new SettingGroupDto(L["DisplayName:Identity"], L["Description:Identity"]); - - #region 用户锁定 - - var lockoutSetting = identitySetting.AddSetting(L["DisplayName:Identity.Lockout"], L["Description:Identity.Lockout"]); - lockoutSetting.AddDetail( - SettingDefinitionManager.Get(IdentitySettingNames.Lockout.AllowedForNewUsers), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(IdentitySettingNames.Lockout.AllowedForNewUsers, providerName, providerKey), - ValueType.Boolean); - lockoutSetting.AddDetail( - SettingDefinitionManager.Get(IdentitySettingNames.Lockout.LockoutDuration), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(IdentitySettingNames.Lockout.LockoutDuration, providerName, providerKey), - ValueType.Number); - lockoutSetting.AddDetail( - SettingDefinitionManager.Get(IdentitySettingNames.Lockout.MaxFailedAccessAttempts), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(IdentitySettingNames.Lockout.MaxFailedAccessAttempts, providerName, providerKey), - ValueType.Number); - - #endregion - - #region 用户 - - var userSetting = identitySetting.AddSetting(L["DisplayName:Identity.User"], L["Description:Identity.User"]); - userSetting.AddDetail( - SettingDefinitionManager.Get(IdentitySettingNames.User.IsEmailUpdateEnabled), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(IdentitySettingNames.User.IsEmailUpdateEnabled, providerName, providerKey), - ValueType.Boolean); - userSetting.AddDetail( - SettingDefinitionManager.Get(IdentitySettingNames.User.IsUserNameUpdateEnabled), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(IdentitySettingNames.User.IsUserNameUpdateEnabled, providerName, providerKey), - ValueType.Boolean); - userSetting.AddDetail( - SettingDefinitionManager.Get(LINGYUN.Abp.Identity.Settings.IdentitySettingNames.User.SmsNewUserRegister), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(LINGYUN.Abp.Identity.Settings.IdentitySettingNames.User.SmsNewUserRegister, providerName, providerKey), - ValueType.String); - userSetting.AddDetail( - SettingDefinitionManager.Get(LINGYUN.Abp.Identity.Settings.IdentitySettingNames.User.SmsResetPassword), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(LINGYUN.Abp.Identity.Settings.IdentitySettingNames.User.SmsResetPassword, providerName, providerKey), - ValueType.String); - userSetting.AddDetail( - SettingDefinitionManager.Get(LINGYUN.Abp.Identity.Settings.IdentitySettingNames.User.SmsUserSignin), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(LINGYUN.Abp.Identity.Settings.IdentitySettingNames.User.SmsUserSignin, providerName, providerKey), - ValueType.String); - userSetting.AddDetail( - SettingDefinitionManager.Get(LINGYUN.Abp.Identity.Settings.IdentitySettingNames.User.SmsPhoneNumberConfirmed), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(LINGYUN.Abp.Identity.Settings.IdentitySettingNames.User.SmsPhoneNumberConfirmed, providerName, providerKey), - ValueType.String); - userSetting.AddDetail( - SettingDefinitionManager.Get(LINGYUN.Abp.Identity.Settings.IdentitySettingNames.User.SmsRepetInterval), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(LINGYUN.Abp.Identity.Settings.IdentitySettingNames.User.SmsRepetInterval, providerName, providerKey), - ValueType.Number); - - #endregion - - #region 登录 - - var signinSetting = identitySetting.AddSetting(L["DisplayName:Identity.SignIn"], L["Description:Identity.SignIn"]); - signinSetting.AddDetail( - SettingDefinitionManager.Get(IdentitySettingNames.SignIn.EnablePhoneNumberConfirmation), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(IdentitySettingNames.SignIn.EnablePhoneNumberConfirmation, providerName, providerKey), - ValueType.Boolean); - signinSetting.AddDetail( - SettingDefinitionManager.Get(IdentitySettingNames.SignIn.RequireConfirmedEmail), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(IdentitySettingNames.SignIn.RequireConfirmedEmail, providerName, providerKey), - ValueType.Boolean); - signinSetting.AddDetail( - SettingDefinitionManager.Get(IdentitySettingNames.SignIn.RequireConfirmedPhoneNumber), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(IdentitySettingNames.SignIn.RequireConfirmedPhoneNumber, providerName, providerKey), - ValueType.Boolean); - - #endregion - - #region 密码 - - var passwordSetting = identitySetting.AddSetting(L["DisplayName:Identity.Password"], L["Description:Identity.Password"]); - passwordSetting.AddDetail( - SettingDefinitionManager.Get(IdentitySettingNames.Password.RequireDigit), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(IdentitySettingNames.Password.RequireDigit, providerName, providerKey), - ValueType.Boolean); - passwordSetting.AddDetail( - SettingDefinitionManager.Get(IdentitySettingNames.Password.RequiredLength), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(IdentitySettingNames.Password.RequiredLength, providerName, providerKey), - ValueType.Number); - passwordSetting.AddDetail( - SettingDefinitionManager.Get(IdentitySettingNames.Password.RequiredUniqueChars), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(IdentitySettingNames.Password.RequiredUniqueChars, providerName, providerKey), - ValueType.Number); - passwordSetting.AddDetail( - SettingDefinitionManager.Get(IdentitySettingNames.Password.RequireLowercase), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(IdentitySettingNames.Password.RequireLowercase, providerName, providerKey), - ValueType.Boolean); - passwordSetting.AddDetail( - SettingDefinitionManager.Get(IdentitySettingNames.Password.RequireUppercase), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(IdentitySettingNames.Password.RequireUppercase, providerName, providerKey), - ValueType.Boolean); - passwordSetting.AddDetail( - SettingDefinitionManager.Get(IdentitySettingNames.Password.RequireNonAlphanumeric), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(IdentitySettingNames.Password.RequireNonAlphanumeric, providerName, providerKey), - ValueType.Boolean); - - #endregion - - #region 双因素 - - // Removed See: https://github.com/abpframework/abp/pull/7719 - //var twoFactorSetting = identitySetting.AddSetting(L["DisplayName:Identity.TwoFactor"], L["Description:Identity.TwoFactor"]); - //twoFactorSetting.AddDetail( - // SettingDefinitionManager.Get(IdentitySettingNames.TwoFactor.Behaviour), - // StringLocalizerFactory, - // await SettingManager.GetOrNullAsync(IdentitySettingNames.TwoFactor.Behaviour, providerName, providerKey), - // ValueType.Option) - // .AddOption(IdentityTwoFactorBehaviour.Optional.ToString(), IdentityTwoFactorBehaviour.Optional.ToString()) - // .AddOption(IdentityTwoFactorBehaviour.Forced.ToString(), IdentityTwoFactorBehaviour.Forced.ToString()) - // .AddOption(IdentityTwoFactorBehaviour.Disabled.ToString(), IdentityTwoFactorBehaviour.Disabled.ToString()); - //twoFactorSetting.AddDetail( - // SettingDefinitionManager.Get(IdentitySettingNames.TwoFactor.UsersCanChange), - // StringLocalizerFactory, - // await SettingManager.GetOrNullAsync(IdentitySettingNames.TwoFactor.UsersCanChange, providerName, providerKey), - // ValueType.Boolean); - - #endregion - - #region 组织机构 - - var ouSetting = identitySetting.AddSetting(L["DisplayName:Identity.OrganizationUnit"], L["Description:Identity.OrganizationUnit"]); - ouSetting.AddDetail( - SettingDefinitionManager.Get(IdentitySettingNames.OrganizationUnit.MaxUserMembershipCount), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(IdentitySettingNames.OrganizationUnit.MaxUserMembershipCount, providerName, providerKey), - ValueType.Number); - - settingGroups.Add(identitySetting); - - #endregion - - #endregion - - #region 邮件设置 - - var emailSettingGroup = new SettingGroupDto(L["DisplayName:Emailing"], L["Description:Emailing"]); - var defaultMailSetting = emailSettingGroup.AddSetting(L["DisplayName:Emailing.Default"], L["Description:Emailing.Default"]); - defaultMailSetting.AddDetail( - SettingDefinitionManager.Get(EmailSettingNames.DefaultFromAddress), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(EmailSettingNames.DefaultFromAddress, providerName, providerKey), - ValueType.String); - defaultMailSetting.AddDetail( - SettingDefinitionManager.Get(EmailSettingNames.DefaultFromDisplayName), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(EmailSettingNames.DefaultFromDisplayName, providerName, providerKey), - ValueType.String); - - var smtpSetting = emailSettingGroup.AddSetting(L["DisplayName:Emailing.Smtp"], L["Description:Emailing.Smtp"]); - smtpSetting.AddDetail( - SettingDefinitionManager.Get(EmailSettingNames.Smtp.EnableSsl), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(EmailSettingNames.Smtp.EnableSsl, providerName, providerKey), - ValueType.Boolean); - smtpSetting.AddDetail( - SettingDefinitionManager.Get(EmailSettingNames.Smtp.UseDefaultCredentials), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(EmailSettingNames.Smtp.UseDefaultCredentials, providerName, providerKey), - ValueType.Boolean); - smtpSetting.AddDetail( - SettingDefinitionManager.Get(EmailSettingNames.Smtp.Domain), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(EmailSettingNames.Smtp.Domain, providerName, providerKey), - ValueType.String); - smtpSetting.AddDetail( - SettingDefinitionManager.Get(EmailSettingNames.Smtp.Host), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(EmailSettingNames.Smtp.Host, providerName, providerKey), - ValueType.String); - smtpSetting.AddDetail( - SettingDefinitionManager.Get(EmailSettingNames.Smtp.Port), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(EmailSettingNames.Smtp.Port, providerName, providerKey), - ValueType.Number); - smtpSetting.AddDetail( - SettingDefinitionManager.Get(EmailSettingNames.Smtp.UserName), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(EmailSettingNames.Smtp.UserName, providerName, providerKey), - ValueType.String); - smtpSetting.AddDetail( - SettingDefinitionManager.Get(EmailSettingNames.Smtp.Password), - StringLocalizerFactory, - await SettingManager.GetOrNullAsync(EmailSettingNames.Smtp.Password, providerName, providerKey), - ValueType.String); - - settingGroups.Add(emailSettingGroup); - - #endregion - - return new ListResultDto(settingGroups); - } - } -} +using Microsoft.AspNetCore.Authorization; +using Microsoft.Extensions.Options; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.Account.Settings; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; +using Volo.Abp.Caching; +using Volo.Abp.Emailing; +using Volo.Abp.Identity.Settings; +using Volo.Abp.Localization; +using Volo.Abp.MultiTenancy; +using Volo.Abp.SettingManagement; +using Volo.Abp.SettingManagement.Localization; +using Volo.Abp.Settings; +using Volo.Abp.Timing; +using Volo.Abp.Users; +using Volo.Abp.EventBus.Distributed; +using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; +using Volo.Abp.Features; + +namespace LINGYUN.Abp.SettingManagement +{ + [Authorize(AbpSettingManagementPermissions.Settings.Default)] + public class SettingAppService : ApplicationService, ISettingAppService + { + protected AbpLocalizationOptions LocalizationOptions { get; } + + protected IDistributedEventBus EventBus { get; } + protected ISettingManager SettingManager { get; } + protected ISettingDefinitionManager SettingDefinitionManager { get; } + + protected IDistributedCache Cache { get; } + public SettingAppService( + IDistributedEventBus eventBus, + ISettingManager settingManager, + IDistributedCache cache, + IOptions localizationOptions, + ISettingDefinitionManager settingDefinitionManager) + { + Cache = cache; + EventBus = eventBus; + SettingManager = settingManager; + SettingDefinitionManager = settingDefinitionManager; + LocalizationOptions = localizationOptions.Value; + LocalizationResource = typeof(AbpSettingManagementResource); + } + + [Authorize(AbpSettingManagementPermissions.Settings.Manager)] + public virtual async Task SetGlobalAsync(UpdateSettingsDto input) + { + // 增加特性检查 + await CheckFeatureAsync(); + + foreach (var setting in input.Settings) + { + await SettingManager.SetGlobalAsync(setting.Name, setting.Value); + } + + CurrentUnitOfWork.OnCompleted(async () => + { + // 发送刷新用户缓存事件 + await EventBus.PublishAsync(new CurrentApplicationConfigurationCacheResetEventData()); + }); + + await CurrentUnitOfWork.SaveChangesAsync(); + } + + [Authorize(AbpSettingManagementPermissions.Settings.Manager)] + public virtual async Task SetCurrentTenantAsync(UpdateSettingsDto input) + { + // 增加特性检查 + await CheckFeatureAsync(); + + if (CurrentTenant.IsAvailable) + { + foreach (var setting in input.Settings) + { + await SettingManager.SetForTenantAsync(CurrentTenant.GetId(), setting.Name, setting.Value); + } + + CurrentUnitOfWork.OnCompleted(async () => + { + // 发送刷新用户缓存事件 + await EventBus.PublishAsync(new CurrentApplicationConfigurationCacheResetEventData()); + }); + + await CurrentUnitOfWork.SaveChangesAsync(); + } + } + + //[Authorize] + [AllowAnonymous] + public virtual async Task> GetAllForCurrentTenantAsync() + { + return await GetAllForProviderAsync(TenantSettingValueProvider.ProviderName, CurrentTenant.GetId().ToString()); + } + + [AllowAnonymous] + public virtual async Task> GetAllForGlobalAsync() + { + return await GetAllForProviderAsync(GlobalSettingValueProvider.ProviderName, null); + } + + protected virtual async Task> GetAllForProviderAsync(string providerName, string providerKey) + { + /* + * 2020-11-19 + * colin@foxmail.com + * + * 之所以重构为这种看似硬编码的设计,是因为硬编码的都是常用的自带的配置 + * + * 自定义的应用模块可以实现返回相同Dto的配置服务,然后通过路由的聚合功能, + * 轻松加入到前端的设置管理(因为vue前端已设计为动态表单页面) + * + * 最初的设计才是不合理的,前端不能硬编码设置管理界面,这应该是后端的事情 + */ + + var settingGroups = new List(); + + #region 系统设置 + + var sysSettingGroup = new SettingGroupDto(L["DisplayName:System"], L["Description:System"]); + // 语言 + var languageSetting = sysSettingGroup.AddSetting(L["DisplayName:System.Language"], L["Description:System.Language"]); + languageSetting.AddDetail( + SettingDefinitionManager.Get(LocalizationSettingNames.DefaultLanguage), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(LocalizationSettingNames.DefaultLanguage, providerName, providerKey), + ValueType.Option) + .AddOptions(LocalizationOptions.Languages.Select(l => new OptionDto(l.DisplayName, l.CultureName))); + // 时区 + var timingSetting = sysSettingGroup.AddSetting(L["DisplayName:System.Timing"], L["Description:System.Timing"]); + timingSetting.AddDetail( + SettingDefinitionManager.Get(TimingSettingNames.TimeZone), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(TimingSettingNames.TimeZone, providerName, providerKey), + ValueType.String); + settingGroups.Add(sysSettingGroup); + + #endregion + + #region 安全设置 + + var securitySettingGroup = new SettingGroupDto(L["DisplayName:Security"], L["Description:Security"]); + + // 用户账户 + var accountSetting = securitySettingGroup.AddSetting(L["DisplayName:Security.Account"], L["Description:Security.Account"]); + // 启用本地登录 + accountSetting.AddDetail( + SettingDefinitionManager.Get(AccountSettingNames.EnableLocalLogin), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(AccountSettingNames.EnableLocalLogin, providerName, providerKey), + ValueType.Boolean); + accountSetting.AddDetail( + SettingDefinitionManager.Get(AccountSettingNames.IsSelfRegistrationEnabled), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(AccountSettingNames.IsSelfRegistrationEnabled, providerName, providerKey), + ValueType.Boolean); + + settingGroups.Add(securitySettingGroup); + + #endregion + + #region 身份标识设置 + + // 身份标识设置 + var identitySetting = new SettingGroupDto(L["DisplayName:Identity"], L["Description:Identity"]); + + #region 用户锁定 + + var lockoutSetting = identitySetting.AddSetting(L["DisplayName:Identity.Lockout"], L["Description:Identity.Lockout"]); + lockoutSetting.AddDetail( + SettingDefinitionManager.Get(IdentitySettingNames.Lockout.AllowedForNewUsers), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(IdentitySettingNames.Lockout.AllowedForNewUsers, providerName, providerKey), + ValueType.Boolean); + lockoutSetting.AddDetail( + SettingDefinitionManager.Get(IdentitySettingNames.Lockout.LockoutDuration), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(IdentitySettingNames.Lockout.LockoutDuration, providerName, providerKey), + ValueType.Number); + lockoutSetting.AddDetail( + SettingDefinitionManager.Get(IdentitySettingNames.Lockout.MaxFailedAccessAttempts), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(IdentitySettingNames.Lockout.MaxFailedAccessAttempts, providerName, providerKey), + ValueType.Number); + + #endregion + + #region 用户 + + var userSetting = identitySetting.AddSetting(L["DisplayName:Identity.User"], L["Description:Identity.User"]); + userSetting.AddDetail( + SettingDefinitionManager.Get(IdentitySettingNames.User.IsEmailUpdateEnabled), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(IdentitySettingNames.User.IsEmailUpdateEnabled, providerName, providerKey), + ValueType.Boolean); + userSetting.AddDetail( + SettingDefinitionManager.Get(IdentitySettingNames.User.IsUserNameUpdateEnabled), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(IdentitySettingNames.User.IsUserNameUpdateEnabled, providerName, providerKey), + ValueType.Boolean); + userSetting.AddDetail( + SettingDefinitionManager.Get(LINGYUN.Abp.Identity.Settings.IdentitySettingNames.User.SmsNewUserRegister), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(LINGYUN.Abp.Identity.Settings.IdentitySettingNames.User.SmsNewUserRegister, providerName, providerKey), + ValueType.String); + userSetting.AddDetail( + SettingDefinitionManager.Get(LINGYUN.Abp.Identity.Settings.IdentitySettingNames.User.SmsResetPassword), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(LINGYUN.Abp.Identity.Settings.IdentitySettingNames.User.SmsResetPassword, providerName, providerKey), + ValueType.String); + userSetting.AddDetail( + SettingDefinitionManager.Get(LINGYUN.Abp.Identity.Settings.IdentitySettingNames.User.SmsUserSignin), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(LINGYUN.Abp.Identity.Settings.IdentitySettingNames.User.SmsUserSignin, providerName, providerKey), + ValueType.String); + userSetting.AddDetail( + SettingDefinitionManager.Get(LINGYUN.Abp.Identity.Settings.IdentitySettingNames.User.SmsPhoneNumberConfirmed), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(LINGYUN.Abp.Identity.Settings.IdentitySettingNames.User.SmsPhoneNumberConfirmed, providerName, providerKey), + ValueType.String); + userSetting.AddDetail( + SettingDefinitionManager.Get(LINGYUN.Abp.Identity.Settings.IdentitySettingNames.User.SmsRepetInterval), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(LINGYUN.Abp.Identity.Settings.IdentitySettingNames.User.SmsRepetInterval, providerName, providerKey), + ValueType.Number); + + #endregion + + #region 登录 + + var signinSetting = identitySetting.AddSetting(L["DisplayName:Identity.SignIn"], L["Description:Identity.SignIn"]); + signinSetting.AddDetail( + SettingDefinitionManager.Get(IdentitySettingNames.SignIn.EnablePhoneNumberConfirmation), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(IdentitySettingNames.SignIn.EnablePhoneNumberConfirmation, providerName, providerKey), + ValueType.Boolean); + signinSetting.AddDetail( + SettingDefinitionManager.Get(IdentitySettingNames.SignIn.RequireConfirmedEmail), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(IdentitySettingNames.SignIn.RequireConfirmedEmail, providerName, providerKey), + ValueType.Boolean); + signinSetting.AddDetail( + SettingDefinitionManager.Get(IdentitySettingNames.SignIn.RequireConfirmedPhoneNumber), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(IdentitySettingNames.SignIn.RequireConfirmedPhoneNumber, providerName, providerKey), + ValueType.Boolean); + + #endregion + + #region 密码 + + var passwordSetting = identitySetting.AddSetting(L["DisplayName:Identity.Password"], L["Description:Identity.Password"]); + passwordSetting.AddDetail( + SettingDefinitionManager.Get(IdentitySettingNames.Password.RequireDigit), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(IdentitySettingNames.Password.RequireDigit, providerName, providerKey), + ValueType.Boolean); + passwordSetting.AddDetail( + SettingDefinitionManager.Get(IdentitySettingNames.Password.RequiredLength), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(IdentitySettingNames.Password.RequiredLength, providerName, providerKey), + ValueType.Number); + passwordSetting.AddDetail( + SettingDefinitionManager.Get(IdentitySettingNames.Password.RequiredUniqueChars), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(IdentitySettingNames.Password.RequiredUniqueChars, providerName, providerKey), + ValueType.Number); + passwordSetting.AddDetail( + SettingDefinitionManager.Get(IdentitySettingNames.Password.RequireLowercase), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(IdentitySettingNames.Password.RequireLowercase, providerName, providerKey), + ValueType.Boolean); + passwordSetting.AddDetail( + SettingDefinitionManager.Get(IdentitySettingNames.Password.RequireUppercase), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(IdentitySettingNames.Password.RequireUppercase, providerName, providerKey), + ValueType.Boolean); + passwordSetting.AddDetail( + SettingDefinitionManager.Get(IdentitySettingNames.Password.RequireNonAlphanumeric), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(IdentitySettingNames.Password.RequireNonAlphanumeric, providerName, providerKey), + ValueType.Boolean); + + #endregion + + #region 双因素 + + // Removed See: https://github.com/abpframework/abp/pull/7719 + //var twoFactorSetting = identitySetting.AddSetting(L["DisplayName:Identity.TwoFactor"], L["Description:Identity.TwoFactor"]); + //twoFactorSetting.AddDetail( + // SettingDefinitionManager.Get(IdentitySettingNames.TwoFactor.Behaviour), + // StringLocalizerFactory, + // await SettingManager.GetOrNullAsync(IdentitySettingNames.TwoFactor.Behaviour, providerName, providerKey), + // ValueType.Option) + // .AddOption(IdentityTwoFactorBehaviour.Optional.ToString(), IdentityTwoFactorBehaviour.Optional.ToString()) + // .AddOption(IdentityTwoFactorBehaviour.Forced.ToString(), IdentityTwoFactorBehaviour.Forced.ToString()) + // .AddOption(IdentityTwoFactorBehaviour.Disabled.ToString(), IdentityTwoFactorBehaviour.Disabled.ToString()); + //twoFactorSetting.AddDetail( + // SettingDefinitionManager.Get(IdentitySettingNames.TwoFactor.UsersCanChange), + // StringLocalizerFactory, + // await SettingManager.GetOrNullAsync(IdentitySettingNames.TwoFactor.UsersCanChange, providerName, providerKey), + // ValueType.Boolean); + + #endregion + + #region 组织机构 + + var ouSetting = identitySetting.AddSetting(L["DisplayName:Identity.OrganizationUnit"], L["Description:Identity.OrganizationUnit"]); + ouSetting.AddDetail( + SettingDefinitionManager.Get(IdentitySettingNames.OrganizationUnit.MaxUserMembershipCount), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(IdentitySettingNames.OrganizationUnit.MaxUserMembershipCount, providerName, providerKey), + ValueType.Number); + + settingGroups.Add(identitySetting); + + #endregion + + #endregion + + #region 邮件设置 + + var emailSettingGroup = new SettingGroupDto(L["DisplayName:Emailing"], L["Description:Emailing"]); + var defaultMailSetting = emailSettingGroup.AddSetting(L["DisplayName:Emailing.Default"], L["Description:Emailing.Default"]); + defaultMailSetting.AddDetail( + SettingDefinitionManager.Get(EmailSettingNames.DefaultFromAddress), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(EmailSettingNames.DefaultFromAddress, providerName, providerKey), + ValueType.String); + defaultMailSetting.AddDetail( + SettingDefinitionManager.Get(EmailSettingNames.DefaultFromDisplayName), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(EmailSettingNames.DefaultFromDisplayName, providerName, providerKey), + ValueType.String); + + var smtpSetting = emailSettingGroup.AddSetting(L["DisplayName:Emailing.Smtp"], L["Description:Emailing.Smtp"]); + smtpSetting.AddDetail( + SettingDefinitionManager.Get(EmailSettingNames.Smtp.EnableSsl), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(EmailSettingNames.Smtp.EnableSsl, providerName, providerKey), + ValueType.Boolean); + smtpSetting.AddDetail( + SettingDefinitionManager.Get(EmailSettingNames.Smtp.UseDefaultCredentials), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(EmailSettingNames.Smtp.UseDefaultCredentials, providerName, providerKey), + ValueType.Boolean); + smtpSetting.AddDetail( + SettingDefinitionManager.Get(EmailSettingNames.Smtp.Domain), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(EmailSettingNames.Smtp.Domain, providerName, providerKey), + ValueType.String); + smtpSetting.AddDetail( + SettingDefinitionManager.Get(EmailSettingNames.Smtp.Host), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(EmailSettingNames.Smtp.Host, providerName, providerKey), + ValueType.String); + smtpSetting.AddDetail( + SettingDefinitionManager.Get(EmailSettingNames.Smtp.Port), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(EmailSettingNames.Smtp.Port, providerName, providerKey), + ValueType.Number); + smtpSetting.AddDetail( + SettingDefinitionManager.Get(EmailSettingNames.Smtp.UserName), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(EmailSettingNames.Smtp.UserName, providerName, providerKey), + ValueType.String); + smtpSetting.AddDetail( + SettingDefinitionManager.Get(EmailSettingNames.Smtp.Password), + StringLocalizerFactory, + await SettingManager.GetOrNullAsync(EmailSettingNames.Smtp.Password, providerName, providerKey), + ValueType.String); + + settingGroups.Add(emailSettingGroup); + + #endregion + + return new ListResultDto(settingGroups); + } + + protected virtual async Task CheckFeatureAsync() + { + await FeatureChecker.CheckEnabledAsync(SettingManagementFeatures.Enable); + } + } +} diff --git a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/ChatMessageEventHandler.cs b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/ChatMessageEventHandler.cs index a9247aa97..59b1a8a8f 100644 --- a/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/ChatMessageEventHandler.cs +++ b/aspnet-core/services/messages/LINGYUN.Abp.MessageService.HttpApi.Host/EventBus/Distributed/ChatMessageEventHandler.cs @@ -1,53 +1,61 @@ -using LINGYUN.Abp.IM; -using LINGYUN.Abp.IM.Messages; -using LINGYUN.Abp.RealTime; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Logging.Abstractions; -using Microsoft.Extensions.Options; -using System.Threading.Tasks; -using Volo.Abp.DependencyInjection; -using Volo.Abp.EventBus.Distributed; - -namespace LINGYUN.Abp.MessageService.EventBus.Distributed -{ - public class ChatMessageEventHandler : IDistributedEventHandler>, ITransientDependency - { - /// - /// Reference to . - /// - public ILogger Logger { get; set; } - /// - /// Reference to . - /// - protected AbpIMOptions Options { get; } - - protected IMessageStore MessageStore { get; } - protected IMessageSenderProviderManager MessageSenderProviderManager { get; } - - public ChatMessageEventHandler( - IOptions options, - IMessageStore messageStore, - IMessageSenderProviderManager messageSenderProviderManager) - { - Options = options.Value; - MessageStore = messageStore; - MessageSenderProviderManager = messageSenderProviderManager; - - Logger = NullLogger.Instance; - } - - public virtual async Task HandleEventAsync(RealTimeEto eventData) - { - Logger.LogDebug($"Persistent chat message."); - - await MessageStore.StoreMessageAsync(eventData.Data); - - // 发送消息 - foreach (var provider in MessageSenderProviderManager.Providers) - { - Logger.LogDebug($"Sending message with provider {provider.Name}"); - await provider.SendMessageAsync(eventData.Data); - } - } - } -} +using LINGYUN.Abp.IM; +using LINGYUN.Abp.IM.Messages; +using LINGYUN.Abp.RealTime; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Microsoft.Extensions.Options; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.EventBus.Distributed; + +namespace LINGYUN.Abp.MessageService.EventBus.Distributed +{ + public class ChatMessageEventHandler : IDistributedEventHandler>, ITransientDependency + { + /// + /// Reference to . + /// + public ILogger Logger { get; set; } + /// + /// Reference to . + /// + protected AbpIMOptions Options { get; } + + protected IMessageStore MessageStore { get; } + protected IMessageBlocker MessageBlocker { get; } + protected IMessageSenderProviderManager MessageSenderProviderManager { get; } + + public ChatMessageEventHandler( + IOptions options, + IMessageStore messageStore, + IMessageBlocker messageBlocker, + IMessageSenderProviderManager messageSenderProviderManager) + { + Options = options.Value; + MessageStore = messageStore; + MessageBlocker = messageBlocker; + MessageSenderProviderManager = messageSenderProviderManager; + + Logger = NullLogger.Instance; + } + + public virtual async Task HandleEventAsync(RealTimeEto eventData) + { + Logger.LogDebug($"Persistent chat message."); + + var message = eventData.Data; + // 消息拦截 + // 扩展敏感词汇过滤 + await MessageBlocker.InterceptAsync(message); + + await MessageStore.StoreMessageAsync(message); + + // 发送消息 + foreach (var provider in MessageSenderProviderManager.Providers) + { + Logger.LogDebug($"Sending message with provider {provider.Name}"); + await provider.SendMessageAsync(message); + } + } + } +}