From e7152d11953a79242c6125db4bbd4f578cd5b7c9 Mon Sep 17 00:00:00 2001 From: colin Date: Sat, 12 Jul 2025 15:10:19 +0800 Subject: [PATCH 1/7] fix(platform): Fixed multiple incorrect email recipient addresses - Use `mailMessage.To.Add()` to add the recipients one by one --- .../Platform/Messages/EmailMessageManager.cs | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Messages/EmailMessageManager.cs b/aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Messages/EmailMessageManager.cs index 4d8ed4017..4fe2898f8 100644 --- a/aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Messages/EmailMessageManager.cs +++ b/aspnet-core/modules/platform/LINGYUN.Platform.Domain/LINGYUN/Platform/Messages/EmailMessageManager.cs @@ -65,27 +65,30 @@ public class EmailMessageManager : DomainService, IEmailMessageManager else { var match = Regex.Match(message.From, FromAddressPattern); - if (match.Success) - { - from = new MailAddress(match.Value); - } - else - { - from = new MailAddress(message.From); - } + from = match.Success ? new MailAddress(match.Value) : new MailAddress(message.From); } - var to = new MailAddress(message.Receiver); - var mailMessage = new MailMessage(from, to) + var mailMessage = new MailMessage { + From = from, Subject = message.Subject, Body = message.Content, IsBodyHtml = message.IsBodyHtml, }; + var toAddresses = message.Receiver.Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries); + foreach (var address in toAddresses) + { + mailMessage.To.Add(address.Trim()); + } + if (!message.CC.IsNullOrWhiteSpace()) { - mailMessage.CC.Add(message.CC); + var ccAddresses = message.CC.Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries); + foreach (var address in ccAddresses) + { + mailMessage.CC.Add(address.Trim()); + } } if (message.Priority.HasValue) @@ -103,7 +106,8 @@ public class EmailMessageManager : DomainService, IEmailMessageManager foreach (var header in message.Headers) { - mailMessage.Headers.Add(header.Key, header.Value); + var sanitizedValue = header.Value?.Replace(",", "") ?? ""; + mailMessage.Headers.Add(header.Key, sanitizedValue); } foreach (var attachment in message.Attachments) From 32085e4e85ab782d16911c5e7d495301a61b1d8d Mon Sep 17 00:00:00 2001 From: colin Date: Sat, 12 Jul 2025 18:15:47 +0800 Subject: [PATCH 2/7] feat(identity): optimize identity session query - Replace the SQL query with the current user Id --- .../LINGYUN/Abp/Account/MyProfileAppService.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/MyProfileAppService.cs b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/MyProfileAppService.cs index cf6500bd8..8194b5edd 100644 --- a/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/MyProfileAppService.cs +++ b/aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/MyProfileAppService.cs @@ -75,12 +75,12 @@ public class MyProfileAppService : AccountApplicationServiceBase, IMyProfileAppS public async virtual Task> GetSessionsAsync(GetMySessionsInput input) { - var user = await GetCurrentUserAsync(); + var userId = CurrentUser.GetId(); var totalCount = await IdentitySessionRepository.GetCountAsync( - user.Id, input.Device, input.ClientId); + userId, input.Device, input.ClientId); var identitySessions = await IdentitySessionRepository.GetListAsync( input.Sorting, input.MaxResultCount, input.SkipCount, - user.Id, input.Device, input.ClientId); + userId, input.Device, input.ClientId); return new PagedResultDto(totalCount, identitySessions.Select(session => new IdentitySessionDto From 06f9e8266597bd83667ab01ad1474decb1c90fb6 Mon Sep 17 00:00:00 2001 From: colin Date: Sat, 12 Jul 2025 18:29:08 +0800 Subject: [PATCH 3/7] fix(identity): Lock when handling user sessions - Lock when cleaning up user sessions - Lock when refreshing the user session --- .../IdentitySessionCacheItemSynchronizer.cs | 71 +++++++++++++++---- .../IdentitySessionCleanupBackgroundWorker.cs | 28 ++++++-- 2 files changed, 79 insertions(+), 20 deletions(-) diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionCacheItemSynchronizer.cs b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionCacheItemSynchronizer.cs index 9ad838cea..1650e7730 100644 --- a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionCacheItemSynchronizer.cs +++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionCacheItemSynchronizer.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.Logging.Abstractions; using System; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; +using Volo.Abp.DistributedLocking; using Volo.Abp.Domain.Entities.Events; using Volo.Abp.Domain.Entities.Events.Distributed; using Volo.Abp.EventBus; @@ -22,15 +23,18 @@ public class IdentitySessionCacheItemSynchronizer : { public ILogger Logger { protected get; set; } protected ISettingProvider SettingProvider { get; } + protected IAbpDistributedLock DistributedLock { get; } protected IIdentitySessionCache IdentitySessionCache { get; } protected IIdentitySessionStore IdentitySessionStore { get; } public IdentitySessionCacheItemSynchronizer( ISettingProvider settingProvider, + IAbpDistributedLock distributedLock, IIdentitySessionCache identitySessionCache, IIdentitySessionStore identitySessionStore) { SettingProvider = settingProvider; + DistributedLock = distributedLock; IdentitySessionCache = identitySessionCache; IdentitySessionStore = identitySessionStore; @@ -45,34 +49,71 @@ public class IdentitySessionCacheItemSynchronizer : [UnitOfWork] public async virtual Task HandleEventAsync(EntityCreatedEto eventData) { - await RefreshSessionCache(eventData.Entity); - await CheckConcurrentLoginStrategy(eventData.Entity); + var lockKey = $"{nameof(IdentitySessionCacheItemSynchronizer)}_{nameof(EntityCreatedEto)}"; + await using (var handle = await DistributedLock.TryAcquireAsync(lockKey)) + { + Logger.LogInformation($"Lock is acquired for {lockKey}"); + + if (handle == null) + { + Logger.LogInformation($"Handle is null because of the locking for : {lockKey}"); + return; + } + + await RefreshSessionCache(eventData.Entity); + await CheckConcurrentLoginStrategy(eventData.Entity); + } } + [UnitOfWork] public async virtual Task HandleEventAsync(IdentitySessionChangeAccessedEvent eventData) { - var idetitySession = await IdentitySessionStore.FindAsync(eventData.SessionId); - if (idetitySession != null) + var lockKey = $"{nameof(IdentitySessionCacheItemSynchronizer)}_{nameof(IdentitySessionChangeAccessedEvent)}"; + await using (var handle = await DistributedLock.TryAcquireAsync(lockKey)) { - if (!eventData.IpAddresses.IsNullOrWhiteSpace()) + Logger.LogInformation($"Lock is acquired for {lockKey}"); + + if (handle == null) { - idetitySession.SetIpAddresses(eventData.IpAddresses.Split(",")); + Logger.LogInformation($"Handle is null because of the locking for : {lockKey}"); + return; } - idetitySession.UpdateLastAccessedTime(eventData.LastAccessed); - await IdentitySessionStore.UpdateAsync(idetitySession); - } - else - { - // 数据库中不存在会话, 清理缓存, 后续请求会话失效 - await IdentitySessionCache.RemoveAsync(eventData.SessionId); + var idetitySession = await IdentitySessionStore.FindAsync(eventData.SessionId); + if (idetitySession != null) + { + if (!eventData.IpAddresses.IsNullOrWhiteSpace()) + { + idetitySession.SetIpAddresses(eventData.IpAddresses.Split(",")); + } + idetitySession.UpdateLastAccessedTime(eventData.LastAccessed); + + await IdentitySessionStore.UpdateAsync(idetitySession); + } + else + { + // 数据库中不存在会话, 清理缓存, 后续请求会话失效 + await IdentitySessionCache.RemoveAsync(eventData.SessionId); + } } } public async virtual Task HandleEventAsync(EntityDeletedEventData eventData) { - // 用户被删除, 移除所有会话 - await IdentitySessionStore.RevokeAllAsync(eventData.Entity.Id); + var lockKey = $"{nameof(IdentitySessionCacheItemSynchronizer)}_{nameof(EntityDeletedEventData)}"; + await using (var handle = await DistributedLock.TryAcquireAsync(lockKey)) + { + Logger.LogInformation($"Lock is acquired for {lockKey}"); + + if (handle == null) + { + Logger.LogInformation($"Handle is null because of the locking for : {lockKey}"); + return; + } + + // 用户被删除, 移除所有会话 + await IdentitySessionStore.RevokeAllAsync(eventData.Entity.Id); + } } protected async virtual Task RefreshSessionCache(IdentitySessionEto session) diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionCleanupBackgroundWorker.cs b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionCleanupBackgroundWorker.cs index 7abbaaccd..b3fab3f24 100644 --- a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionCleanupBackgroundWorker.cs +++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/Session/IdentitySessionCleanupBackgroundWorker.cs @@ -1,20 +1,25 @@ using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System.Threading.Tasks; using Volo.Abp.BackgroundWorkers; +using Volo.Abp.DistributedLocking; using Volo.Abp.Threading; namespace LINGYUN.Abp.Identity.Session; public class IdentitySessionCleanupBackgroundWorker : AsyncPeriodicBackgroundWorkerBase { + protected IAbpDistributedLock DistributedLock { get; } protected IdentitySessionCleanupOptions Options { get; } public IdentitySessionCleanupBackgroundWorker( AbpAsyncTimer timer, IServiceScopeFactory serviceScopeFactory, - IOptions options) + IOptions options, + IAbpDistributedLock distributedLock) : base(timer, serviceScopeFactory) { + DistributedLock = distributedLock; Options = options.Value; timer.Period = Options.CleanupPeriod; } @@ -26,9 +31,22 @@ public class IdentitySessionCleanupBackgroundWorker : AsyncPeriodicBackgroundWor return; } - await workerContext - .ServiceProvider - .GetRequiredService() - .CleanAsync(); + await using (var handle = await DistributedLock.TryAcquireAsync(nameof(IdentitySessionCleanupBackgroundWorker))) + { + Logger.LogInformation($"Lock is acquired for {nameof(IdentitySessionCleanupBackgroundWorker)}"); + + if (handle != null) + { + await workerContext + .ServiceProvider + .GetRequiredService() + .CleanAsync(); + + Logger.LogInformation($"Lock is released for {nameof(IdentitySessionCleanupBackgroundWorker)}"); + return; + } + + Logger.LogInformation($"Handle is null because of the locking for : {nameof(IdentitySessionCleanupBackgroundWorker)}"); + } } } From 22d08084eac14b7065167dbdd7fc2a0da4d83cd7 Mon Sep 17 00:00:00 2001 From: colin Date: Sat, 12 Jul 2025 18:34:30 +0800 Subject: [PATCH 4/7] feat(identity): Declare distributed lock dependencies - Increase the dependency on distributed lock modules --- .../LINGYUN/Abp/Identity/AbpIdentityDomainModule.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/AbpIdentityDomainModule.cs b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/AbpIdentityDomainModule.cs index cfbe9870b..83f45536f 100644 --- a/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/AbpIdentityDomainModule.cs +++ b/aspnet-core/modules/identity/LINGYUN.Abp.Identity.Domain/LINGYUN/Abp/Identity/AbpIdentityDomainModule.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Volo.Abp; using Volo.Abp.AutoMapper; using Volo.Abp.BackgroundWorkers; +using Volo.Abp.DistributedLocking; using Volo.Abp.Domain.Entities.Events.Distributed; using Volo.Abp.Identity; using Volo.Abp.Modularity; @@ -14,6 +15,7 @@ namespace LINGYUN.Abp.Identity; [DependsOn( typeof(AbpIdentityDomainSharedModule), + typeof(AbpDistributedLockingAbstractionsModule), typeof(Volo.Abp.Identity.AbpIdentityDomainModule))] public class AbpIdentityDomainModule : AbpModule { From 8b8d14657e5c8094c2bddd5862319ef98e39fbc2 Mon Sep 17 00:00:00 2001 From: colin Date: Sat, 12 Jul 2025 19:50:07 +0800 Subject: [PATCH 5/7] fix(notifications): Add missing framework dependencies - Add net9.0 dependencies --- .../LINGYUN.Abp.Notifications.Templating.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Templating/LINGYUN.Abp.Notifications.Templating.csproj b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Templating/LINGYUN.Abp.Notifications.Templating.csproj index 188573b06..50a50fc39 100644 --- a/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Templating/LINGYUN.Abp.Notifications.Templating.csproj +++ b/aspnet-core/modules/realtime-notifications/LINGYUN.Abp.Notifications.Templating/LINGYUN.Abp.Notifications.Templating.csproj @@ -4,7 +4,7 @@ - netstandard2.0;netstandard2.1;net8.0 + netstandard2.0;netstandard2.1;net8.0;net9.0 LINGYUN.Abp.Notifications.Templating LINGYUN.Abp.Notifications.Templating false From ad23b8d63d033064aed71c20a1fd5c6c6ef5d935 Mon Sep 17 00:00:00 2001 From: colin Date: Sat, 19 Jul 2025 13:39:15 +0800 Subject: [PATCH 6/7] fix(oss): fix the oss client proxy - Remove the `IFileAppService` interface - Regenerate `generate-proxy.json` --- .../Abp/OssManagement/IFileAppService.cs | 19 -- .../OssManagement/IPrivateFileAppService.cs | 14 +- .../OssManagement/IPublicFileAppService.cs | 18 +- .../Abp/OssManagement/FileAppServiceBase.cs | 2 +- .../PrivateFilesClientProxy.Generated.cs | 4 +- .../PublicFilesClientProxy.Generated.cs | 4 +- .../oss-management-generate-proxy.json | 182 ------------------ 7 files changed, 34 insertions(+), 209 deletions(-) delete mode 100644 aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application.Contracts/LINGYUN/Abp/OssManagement/IFileAppService.cs diff --git a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application.Contracts/LINGYUN/Abp/OssManagement/IFileAppService.cs b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application.Contracts/LINGYUN/Abp/OssManagement/IFileAppService.cs deleted file mode 100644 index 0f1a2cf8e..000000000 --- a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application.Contracts/LINGYUN/Abp/OssManagement/IFileAppService.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Threading.Tasks; -using Volo.Abp.Application.Dtos; -using Volo.Abp.Application.Services; -using Volo.Abp.Content; - -namespace LINGYUN.Abp.OssManagement; - -public interface IFileAppService : IApplicationService -{ - Task UploadAsync(UploadFileInput input); - - Task GetAsync(GetPublicFileInput input); - - Task> GetListAsync(GetFilesInput input); - - Task UploadChunkAsync(UploadFileChunkInput input); - - Task DeleteAsync(GetPublicFileInput input); -} diff --git a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application.Contracts/LINGYUN/Abp/OssManagement/IPrivateFileAppService.cs b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application.Contracts/LINGYUN/Abp/OssManagement/IPrivateFileAppService.cs index 3e5c1d8ab..52d557ef3 100644 --- a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application.Contracts/LINGYUN/Abp/OssManagement/IPrivateFileAppService.cs +++ b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application.Contracts/LINGYUN/Abp/OssManagement/IPrivateFileAppService.cs @@ -1,10 +1,22 @@ using System.Threading.Tasks; using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; +using Volo.Abp.Content; namespace LINGYUN.Abp.OssManagement; -public interface IPrivateFileAppService : IFileAppService +public interface IPrivateFileAppService : IApplicationService { + Task UploadAsync(UploadFileInput input); + + Task GetAsync(GetPublicFileInput input); + + Task> GetListAsync(GetFilesInput input); + + Task UploadChunkAsync(UploadFileChunkInput input); + + Task DeleteAsync(GetPublicFileInput input); + Task ShareAsync(FileShareInput input); Task> GetShareListAsync(); diff --git a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application.Contracts/LINGYUN/Abp/OssManagement/IPublicFileAppService.cs b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application.Contracts/LINGYUN/Abp/OssManagement/IPublicFileAppService.cs index 7e2ed571a..5ec854d6c 100644 --- a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application.Contracts/LINGYUN/Abp/OssManagement/IPublicFileAppService.cs +++ b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application.Contracts/LINGYUN/Abp/OssManagement/IPublicFileAppService.cs @@ -1,5 +1,19 @@ -namespace LINGYUN.Abp.OssManagement; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; +using Volo.Abp.Content; -public interface IPublicFileAppService : IFileAppService +namespace LINGYUN.Abp.OssManagement; + +public interface IPublicFileAppService : IApplicationService { + Task UploadAsync(UploadFileInput input); + + Task GetAsync(GetPublicFileInput input); + + Task> GetListAsync(GetFilesInput input); + + Task UploadChunkAsync(UploadFileChunkInput input); + + Task DeleteAsync(GetPublicFileInput input); } diff --git a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application/LINGYUN/Abp/OssManagement/FileAppServiceBase.cs b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application/LINGYUN/Abp/OssManagement/FileAppServiceBase.cs index 8c8e94a9a..dfd2db5c5 100644 --- a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application/LINGYUN/Abp/OssManagement/FileAppServiceBase.cs +++ b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.Application/LINGYUN/Abp/OssManagement/FileAppServiceBase.cs @@ -14,7 +14,7 @@ using Volo.Abp.Validation; namespace LINGYUN.Abp.OssManagement; -public abstract class FileAppServiceBase : OssManagementApplicationServiceBase, IFileAppService +public abstract class FileAppServiceBase : OssManagementApplicationServiceBase { protected IFileUploader FileUploader { get; } protected IFileValidater FileValidater { get; } diff --git a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.HttpApi.Client/ClientProxies/LINGYUN/Abp/OssManagement/PrivateFilesClientProxy.Generated.cs b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.HttpApi.Client/ClientProxies/LINGYUN/Abp/OssManagement/PrivateFilesClientProxy.Generated.cs index 8a211c7f2..e6e687ad2 100644 --- a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.HttpApi.Client/ClientProxies/LINGYUN/Abp/OssManagement/PrivateFilesClientProxy.Generated.cs +++ b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.HttpApi.Client/ClientProxies/LINGYUN/Abp/OssManagement/PrivateFilesClientProxy.Generated.cs @@ -15,8 +15,8 @@ using Volo.Abp.Http.Modeling; namespace LINGYUN.Abp.OssManagement; [Dependency(ReplaceServices = true)] -[ExposeServices(typeof(IFileAppService), typeof(PrivateFilesClientProxy))] -public partial class PrivateFilesClientProxy : ClientProxyBase, IFileAppService +[ExposeServices(typeof(IPrivateFileAppService), typeof(PrivateFilesClientProxy))] +public partial class PrivateFilesClientProxy : ClientProxyBase, IPrivateFileAppService { public virtual async Task UploadAsync(UploadFileInput input) { diff --git a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.HttpApi.Client/ClientProxies/LINGYUN/Abp/OssManagement/PublicFilesClientProxy.Generated.cs b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.HttpApi.Client/ClientProxies/LINGYUN/Abp/OssManagement/PublicFilesClientProxy.Generated.cs index 7298889ae..f2d593e18 100644 --- a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.HttpApi.Client/ClientProxies/LINGYUN/Abp/OssManagement/PublicFilesClientProxy.Generated.cs +++ b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.HttpApi.Client/ClientProxies/LINGYUN/Abp/OssManagement/PublicFilesClientProxy.Generated.cs @@ -15,8 +15,8 @@ using Volo.Abp.Http.Modeling; namespace LINGYUN.Abp.OssManagement; [Dependency(ReplaceServices = true)] -[ExposeServices(typeof(IFileAppService), typeof(PublicFilesClientProxy))] -public partial class PublicFilesClientProxy : ClientProxyBase, IFileAppService +[ExposeServices(typeof(IPublicFileAppService), typeof(PublicFilesClientProxy))] +public partial class PublicFilesClientProxy : ClientProxyBase, IPublicFileAppService { public virtual async Task UploadAsync(UploadFileInput input) { diff --git a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.HttpApi.Client/ClientProxies/oss-management-generate-proxy.json b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.HttpApi.Client/ClientProxies/oss-management-generate-proxy.json index 48241ed5b..df42ee8ab 100644 --- a/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.HttpApi.Client/ClientProxies/oss-management-generate-proxy.json +++ b/aspnet-core/modules/oss-management/LINGYUN.Abp.OssManagement.HttpApi.Client/ClientProxies/oss-management-generate-proxy.json @@ -1694,97 +1694,6 @@ } } ] - }, - { - "type": "LINGYUN.Abp.OssManagement.IFileAppService", - "name": "IFileAppService", - "methods": [ - { - "name": "UploadAsync", - "parametersOnMethod": [ - { - "name": "input", - "typeAsString": "LINGYUN.Abp.OssManagement.UploadFileInput, LINGYUN.Abp.OssManagement.Application.Contracts", - "type": "LINGYUN.Abp.OssManagement.UploadFileInput", - "typeSimple": "LINGYUN.Abp.OssManagement.UploadFileInput", - "isOptional": false, - "defaultValue": null - } - ], - "returnValue": { - "type": "LINGYUN.Abp.OssManagement.OssObjectDto", - "typeSimple": "LINGYUN.Abp.OssManagement.OssObjectDto" - } - }, - { - "name": "GetAsync", - "parametersOnMethod": [ - { - "name": "input", - "typeAsString": "LINGYUN.Abp.OssManagement.GetPublicFileInput, LINGYUN.Abp.OssManagement.Application.Contracts", - "type": "LINGYUN.Abp.OssManagement.GetPublicFileInput", - "typeSimple": "LINGYUN.Abp.OssManagement.GetPublicFileInput", - "isOptional": false, - "defaultValue": null - } - ], - "returnValue": { - "type": "Volo.Abp.Content.IRemoteStreamContent", - "typeSimple": "Volo.Abp.Content.IRemoteStreamContent" - } - }, - { - "name": "GetListAsync", - "parametersOnMethod": [ - { - "name": "input", - "typeAsString": "LINGYUN.Abp.OssManagement.GetFilesInput, LINGYUN.Abp.OssManagement.Application.Contracts", - "type": "LINGYUN.Abp.OssManagement.GetFilesInput", - "typeSimple": "LINGYUN.Abp.OssManagement.GetFilesInput", - "isOptional": false, - "defaultValue": null - } - ], - "returnValue": { - "type": "Volo.Abp.Application.Dtos.ListResultDto", - "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" - } - }, - { - "name": "UploadChunkAsync", - "parametersOnMethod": [ - { - "name": "input", - "typeAsString": "LINGYUN.Abp.OssManagement.UploadFileChunkInput, LINGYUN.Abp.OssManagement.Application.Contracts", - "type": "LINGYUN.Abp.OssManagement.UploadFileChunkInput", - "typeSimple": "LINGYUN.Abp.OssManagement.UploadFileChunkInput", - "isOptional": false, - "defaultValue": null - } - ], - "returnValue": { - "type": "System.Void", - "typeSimple": "System.Void" - } - }, - { - "name": "DeleteAsync", - "parametersOnMethod": [ - { - "name": "input", - "typeAsString": "LINGYUN.Abp.OssManagement.GetPublicFileInput, LINGYUN.Abp.OssManagement.Application.Contracts", - "type": "LINGYUN.Abp.OssManagement.GetPublicFileInput", - "typeSimple": "LINGYUN.Abp.OssManagement.GetPublicFileInput", - "isOptional": false, - "defaultValue": null - } - ], - "returnValue": { - "type": "System.Void", - "typeSimple": "System.Void" - } - } - ] } ], "actions": { @@ -2317,97 +2226,6 @@ } } ] - }, - { - "type": "LINGYUN.Abp.OssManagement.IFileAppService", - "name": "IFileAppService", - "methods": [ - { - "name": "UploadAsync", - "parametersOnMethod": [ - { - "name": "input", - "typeAsString": "LINGYUN.Abp.OssManagement.UploadFileInput, LINGYUN.Abp.OssManagement.Application.Contracts", - "type": "LINGYUN.Abp.OssManagement.UploadFileInput", - "typeSimple": "LINGYUN.Abp.OssManagement.UploadFileInput", - "isOptional": false, - "defaultValue": null - } - ], - "returnValue": { - "type": "LINGYUN.Abp.OssManagement.OssObjectDto", - "typeSimple": "LINGYUN.Abp.OssManagement.OssObjectDto" - } - }, - { - "name": "GetAsync", - "parametersOnMethod": [ - { - "name": "input", - "typeAsString": "LINGYUN.Abp.OssManagement.GetPublicFileInput, LINGYUN.Abp.OssManagement.Application.Contracts", - "type": "LINGYUN.Abp.OssManagement.GetPublicFileInput", - "typeSimple": "LINGYUN.Abp.OssManagement.GetPublicFileInput", - "isOptional": false, - "defaultValue": null - } - ], - "returnValue": { - "type": "Volo.Abp.Content.IRemoteStreamContent", - "typeSimple": "Volo.Abp.Content.IRemoteStreamContent" - } - }, - { - "name": "GetListAsync", - "parametersOnMethod": [ - { - "name": "input", - "typeAsString": "LINGYUN.Abp.OssManagement.GetFilesInput, LINGYUN.Abp.OssManagement.Application.Contracts", - "type": "LINGYUN.Abp.OssManagement.GetFilesInput", - "typeSimple": "LINGYUN.Abp.OssManagement.GetFilesInput", - "isOptional": false, - "defaultValue": null - } - ], - "returnValue": { - "type": "Volo.Abp.Application.Dtos.ListResultDto", - "typeSimple": "Volo.Abp.Application.Dtos.ListResultDto" - } - }, - { - "name": "UploadChunkAsync", - "parametersOnMethod": [ - { - "name": "input", - "typeAsString": "LINGYUN.Abp.OssManagement.UploadFileChunkInput, LINGYUN.Abp.OssManagement.Application.Contracts", - "type": "LINGYUN.Abp.OssManagement.UploadFileChunkInput", - "typeSimple": "LINGYUN.Abp.OssManagement.UploadFileChunkInput", - "isOptional": false, - "defaultValue": null - } - ], - "returnValue": { - "type": "System.Void", - "typeSimple": "System.Void" - } - }, - { - "name": "DeleteAsync", - "parametersOnMethod": [ - { - "name": "input", - "typeAsString": "LINGYUN.Abp.OssManagement.GetPublicFileInput, LINGYUN.Abp.OssManagement.Application.Contracts", - "type": "LINGYUN.Abp.OssManagement.GetPublicFileInput", - "typeSimple": "LINGYUN.Abp.OssManagement.GetPublicFileInput", - "isOptional": false, - "defaultValue": null - } - ], - "returnValue": { - "type": "System.Void", - "typeSimple": "System.Void" - } - } - ] } ], "actions": { From 00737730383a886605bc7f0dcd3bdc3ad69ecd4e Mon Sep 17 00:00:00 2001 From: colin Date: Tue, 22 Jul 2025 19:40:02 +0800 Subject: [PATCH 7/7] feat(auditing): Record the request header in the audit log - Increase `AbpAspNetCoreAuditingModule` module --- .../FodyWeavers.xml | 3 ++ .../LINGYUN.Abp.AspNetCore.Auditing.csproj | 20 ++++++++ .../AbpAspNetCoreAuditingHeaderOptions.cs | 19 +++++++ .../Auditing/AbpAspNetCoreAuditingModule.cs | 17 +++++++ ...pNetCoreRecordHeaderAuditLogContributor.cs | 51 +++++++++++++++++++ .../LINGYUN.Abp.AspNetCore.Auditing/README.md | 19 +++++++ 6 files changed, 129 insertions(+) create mode 100644 aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/FodyWeavers.xml create mode 100644 aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN.Abp.AspNetCore.Auditing.csproj create mode 100644 aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN/Abp/AspNetCore/Auditing/AbpAspNetCoreAuditingHeaderOptions.cs create mode 100644 aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN/Abp/AspNetCore/Auditing/AbpAspNetCoreAuditingModule.cs create mode 100644 aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN/Abp/AspNetCore/Auditing/AspNetCoreRecordHeaderAuditLogContributor.cs create mode 100644 aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/README.md diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/FodyWeavers.xml b/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/FodyWeavers.xml new file mode 100644 index 000000000..1715698cc --- /dev/null +++ b/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN.Abp.AspNetCore.Auditing.csproj b/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN.Abp.AspNetCore.Auditing.csproj new file mode 100644 index 000000000..4589f07e1 --- /dev/null +++ b/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN.Abp.AspNetCore.Auditing.csproj @@ -0,0 +1,20 @@ + + + + + + + net9.0 + LINGYUN.Abp.AspNetCore.Auditing + LINGYUN.Abp.AspNetCore.Auditing + false + false + false + + + + + + + + diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN/Abp/AspNetCore/Auditing/AbpAspNetCoreAuditingHeaderOptions.cs b/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN/Abp/AspNetCore/Auditing/AbpAspNetCoreAuditingHeaderOptions.cs new file mode 100644 index 000000000..647ea909a --- /dev/null +++ b/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN/Abp/AspNetCore/Auditing/AbpAspNetCoreAuditingHeaderOptions.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; + +namespace LINGYUN.Abp.AspNetCore.Auditing; +public class AbpAspNetCoreAuditingHeaderOptions +{ + /// + /// 是否在审计日志中记录Http请求头,默认: true + /// + public bool IsEnabled { get; set; } + /// + /// 要记录的Http请求头 + /// + public IList HttpHeaders { get; } + public AbpAspNetCoreAuditingHeaderOptions() + { + IsEnabled = true; + HttpHeaders = new List(); + } +} diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN/Abp/AspNetCore/Auditing/AbpAspNetCoreAuditingModule.cs b/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN/Abp/AspNetCore/Auditing/AbpAspNetCoreAuditingModule.cs new file mode 100644 index 000000000..119d69635 --- /dev/null +++ b/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN/Abp/AspNetCore/Auditing/AbpAspNetCoreAuditingModule.cs @@ -0,0 +1,17 @@ +using Volo.Abp.AspNetCore; +using Volo.Abp.Auditing; +using Volo.Abp.Modularity; + +namespace LINGYUN.Abp.AspNetCore.Auditing; + +[DependsOn(typeof(AbpAspNetCoreModule))] +public class AbpAspNetCoreAuditingModule : AbpModule +{ + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.Contributors.Add(new AspNetCoreRecordHeaderAuditLogContributor()); + }); + } +} diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN/Abp/AspNetCore/Auditing/AspNetCoreRecordHeaderAuditLogContributor.cs b/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN/Abp/AspNetCore/Auditing/AspNetCoreRecordHeaderAuditLogContributor.cs new file mode 100644 index 000000000..67f4a59d3 --- /dev/null +++ b/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/LINGYUN/Abp/AspNetCore/Auditing/AspNetCoreRecordHeaderAuditLogContributor.cs @@ -0,0 +1,51 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using System.Collections.Generic; +using System.Collections.Immutable; +using Volo.Abp.Auditing; +using Volo.Abp.Data; +using Volo.Abp.DependencyInjection; + +namespace LINGYUN.Abp.AspNetCore.Auditing; +public class AspNetCoreRecordHeaderAuditLogContributor : AuditLogContributor, ITransientDependency +{ + private const string HttpHeaderRecordKey = "HttpHeaders"; + + public AspNetCoreRecordHeaderAuditLogContributor() + { + } + + public override void PreContribute(AuditLogContributionContext context) + { + var options = context.ServiceProvider.GetRequiredService>(); + if (!options.Value.IsEnabled) + { + return; + } + + var httpContext = context.ServiceProvider.GetRequiredService().HttpContext; + if (httpContext == null) + { + return; + } + + if (context.AuditInfo.HasProperty(HttpHeaderRecordKey)) + { + return; + } + + var headerRcords = new Dictionary(); + var httpHeaders = httpContext.Request.Headers.ToImmutableDictionary(); + + foreach (var headerKey in options.Value.HttpHeaders) + { + if (httpHeaders.TryGetValue(headerKey, out var headers)) + { + headerRcords[headerKey] = headers.JoinAsString(";"); + } + } + + context.AuditInfo.SetProperty(HttpHeaderRecordKey, headerRcords); + } +} diff --git a/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/README.md b/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/README.md new file mode 100644 index 000000000..de6175010 --- /dev/null +++ b/aspnet-core/framework/auditing/LINGYUN.Abp.AspNetCore.Auditing/README.md @@ -0,0 +1,19 @@ +# LINGYUN.Abp.AspNetCore.Auditing + +审计日期扩展模块, 用于在审计日志中加入特定的Http请求头记录 + +## 模块引用 + + +```csharp +[DependsOn(typeof(AbpAspNetCoreAuditingModule))] +public class YouProjectModule : AbpModule +{ + // other +} +``` + +## 配置项 + +* AbpAspNetCoreAuditingHeaderOptions.IsEnabled 是否在审计日志中记录Http请求头,默认: true +* AbpAspNetCoreAuditingHeaderOptions.HttpHeaders 需要在审计日志中记录的Http请求头列表