From 7050ef95c2ba65b51ab1e2ea94b1d4baae0ec68c Mon Sep 17 00:00:00 2001 From: maliming Date: Tue, 30 Dec 2025 18:16:24 +0800 Subject: [PATCH] Implement application finder and resource permission management providers --- .../Applications/ApplicationFinderResult.cs | 10 ++++ .../Applications/IApplicationFinder.cs | 12 ++++ .../Applications/AbpApplicationFinder.cs | 46 +++++++++++++++ .../IOpenIddictApplicationRepository.cs | 4 +- .../EfCoreOpenIddictApplicationRepository.cs | 7 +++ .../MongoOpenIddictApplicationRepository.cs | 9 ++- ...ApplicationPermissionManagementProvider.cs | 8 +++ ...ionResourcePermissionManagementProvider.cs | 59 +++++++++++++++++++ ...ourcePermissionProviderKeyLookupService.cs | 45 ++++++++++++++ 9 files changed, 198 insertions(+), 2 deletions(-) create mode 100644 modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Applications/ApplicationFinderResult.cs create mode 100644 modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Applications/IApplicationFinder.cs create mode 100644 modules/openiddict/src/Volo.Abp.OpenIddict.Domain/Volo/Abp/OpenIddict/Applications/AbpApplicationFinder.cs create mode 100644 modules/openiddict/src/Volo.Abp.PermissionManagement.Domain.OpenIddict/Volo/Abp/PermissionManagement/OpenIddict/ApplicationResourcePermissionManagementProvider.cs create mode 100644 modules/openiddict/src/Volo.Abp.PermissionManagement.Domain.OpenIddict/Volo/Abp/PermissionManagement/OpenIddict/ApplicationResourcePermissionProviderKeyLookupService.cs diff --git a/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Applications/ApplicationFinderResult.cs b/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Applications/ApplicationFinderResult.cs new file mode 100644 index 0000000000..5ff4d5041b --- /dev/null +++ b/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Applications/ApplicationFinderResult.cs @@ -0,0 +1,10 @@ +using System; + +namespace Volo.Abp.OpenIddict.Applications; + +public class ApplicationFinderResult +{ + public Guid Id { get; set; } + + public string ClientId { get; set; } +} diff --git a/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Applications/IApplicationFinder.cs b/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Applications/IApplicationFinder.cs new file mode 100644 index 0000000000..02c51c023c --- /dev/null +++ b/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Applications/IApplicationFinder.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Volo.Abp.OpenIddict.Applications; + +public interface IApplicationFinder +{ + Task> SearchAsync(string filter, int page = 1); + + Task> SearchByIdsAsync(Guid[] ids); +} diff --git a/modules/openiddict/src/Volo.Abp.OpenIddict.Domain/Volo/Abp/OpenIddict/Applications/AbpApplicationFinder.cs b/modules/openiddict/src/Volo.Abp.OpenIddict.Domain/Volo/Abp/OpenIddict/Applications/AbpApplicationFinder.cs new file mode 100644 index 0000000000..f102e0cf57 --- /dev/null +++ b/modules/openiddict/src/Volo.Abp.OpenIddict.Domain/Volo/Abp/OpenIddict/Applications/AbpApplicationFinder.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Repositories; +using Volo.Abp.Identity; + +namespace Volo.Abp.OpenIddict.Applications; + +public class AbpApplicationFinder : IApplicationFinder, ITransientDependency +{ + protected IOpenIddictApplicationRepository ApplicationRepository { get; } + + public AbpApplicationFinder(IOpenIddictApplicationRepository applicationRepository) + { + ApplicationRepository = applicationRepository; + } + + public virtual async Task> SearchAsync(string filter, int page = 1) + { + using (ApplicationRepository.DisableTracking()) + { + page = page < 1 ? 1 : page; + var applications = await ApplicationRepository.GetListAsync(nameof(OpenIddictApplication.ClientId), filter: filter, skipCount: (page - 1) * 10, maxResultCount: 10); + return applications.Select(x => new ApplicationFinderResult + { + Id = x.Id, + ClientId = x.ClientId + }).ToList(); + } + } + + public virtual async Task> SearchByIdsAsync(Guid[] ids) + { + using (ApplicationRepository.DisableTracking()) + { + var applications = await ApplicationRepository.GetListByIdsAsync(ids); + return applications.Select(x => new ApplicationFinderResult + { + Id = x.Id, + ClientId = x.ClientId + }).ToList(); + } + } +} diff --git a/modules/openiddict/src/Volo.Abp.OpenIddict.Domain/Volo/Abp/OpenIddict/Applications/IOpenIddictApplicationRepository.cs b/modules/openiddict/src/Volo.Abp.OpenIddict.Domain/Volo/Abp/OpenIddict/Applications/IOpenIddictApplicationRepository.cs index 302f1fd5c7..5a10d9da3f 100644 --- a/modules/openiddict/src/Volo.Abp.OpenIddict.Domain/Volo/Abp/OpenIddict/Applications/IOpenIddictApplicationRepository.cs +++ b/modules/openiddict/src/Volo.Abp.OpenIddict.Domain/Volo/Abp/OpenIddict/Applications/IOpenIddictApplicationRepository.cs @@ -11,7 +11,7 @@ public interface IOpenIddictApplicationRepository : IBasicRepository> GetListAsync(string sorting, int skipCount, int maxResultCount, string filter = null, CancellationToken cancellationToken = default); Task GetCountAsync(string filter = null, CancellationToken cancellationToken = default); - + Task FindByClientIdAsync(string clientId, CancellationToken cancellationToken = default); Task> FindByPostLogoutRedirectUriAsync(string address, CancellationToken cancellationToken = default); @@ -19,4 +19,6 @@ public interface IOpenIddictApplicationRepository : IBasicRepository> FindByRedirectUriAsync(string address, CancellationToken cancellationToken = default); Task> ListAsync(int? count, int? offset, CancellationToken cancellationToken = default); + + Task> GetListByIdsAsync(Guid[] ids, CancellationToken cancellationToken = default); } diff --git a/modules/openiddict/src/Volo.Abp.OpenIddict.EntityFrameworkCore/Volo/Abp/OpenIddict/Applications/EfCoreOpenIddictApplicationRepository.cs b/modules/openiddict/src/Volo.Abp.OpenIddict.EntityFrameworkCore/Volo/Abp/OpenIddict/Applications/EfCoreOpenIddictApplicationRepository.cs index 3963e09630..ceb52374d3 100644 --- a/modules/openiddict/src/Volo.Abp.OpenIddict.EntityFrameworkCore/Volo/Abp/OpenIddict/Applications/EfCoreOpenIddictApplicationRepository.cs +++ b/modules/openiddict/src/Volo.Abp.OpenIddict.EntityFrameworkCore/Volo/Abp/OpenIddict/Applications/EfCoreOpenIddictApplicationRepository.cs @@ -62,4 +62,11 @@ public class EfCoreOpenIddictApplicationRepository : EfCoreRepository>(count.HasValue, count) .ToListAsync(GetCancellationToken(cancellationToken)); } + + public virtual async Task> GetListByIdsAsync(Guid[] ids, CancellationToken cancellationToken = default) + { + return await (await GetDbSetAsync()) + .Where(x => ids.Contains(x.Id)) + .ToListAsync(GetCancellationToken(cancellationToken)); + } } diff --git a/modules/openiddict/src/Volo.Abp.OpenIddict.MongoDB/Volo/Abp/OpenIddict/Applications/MongoOpenIddictApplicationRepository.cs b/modules/openiddict/src/Volo.Abp.OpenIddict.MongoDB/Volo/Abp/OpenIddict/Applications/MongoOpenIddictApplicationRepository.cs index 867bbe71c5..d152cee48a 100644 --- a/modules/openiddict/src/Volo.Abp.OpenIddict.MongoDB/Volo/Abp/OpenIddict/Applications/MongoOpenIddictApplicationRepository.cs +++ b/modules/openiddict/src/Volo.Abp.OpenIddict.MongoDB/Volo/Abp/OpenIddict/Applications/MongoOpenIddictApplicationRepository.cs @@ -17,7 +17,7 @@ public class MongoOpenIddictApplicationRepository : MongoDbRepository dbContextProvider) : base(dbContextProvider) { } - + public virtual async Task> GetListAsync(string sorting, int skipCount, int maxResultCount, string filter = null, CancellationToken cancellationToken = default) { @@ -64,4 +64,11 @@ public class MongoOpenIddictApplicationRepository : MongoDbRepository>(count.HasValue, count) .ToListAsync(GetCancellationToken(cancellationToken)); } + + public virtual async Task> GetListByIdsAsync(Guid[] ids, CancellationToken cancellationToken = default) + { + return await (await GetQueryableAsync(cancellationToken)) + .Where(x => ids.Contains(x.Id)) + .ToListAsync(GetCancellationToken(cancellationToken)); + } } diff --git a/modules/openiddict/src/Volo.Abp.PermissionManagement.Domain.OpenIddict/Volo/Abp/PermissionManagement/OpenIddict/ApplicationPermissionManagementProvider.cs b/modules/openiddict/src/Volo.Abp.PermissionManagement.Domain.OpenIddict/Volo/Abp/PermissionManagement/OpenIddict/ApplicationPermissionManagementProvider.cs index 4c4d6fe398..7cde7a4dfe 100644 --- a/modules/openiddict/src/Volo.Abp.PermissionManagement.Domain.OpenIddict/Volo/Abp/PermissionManagement/OpenIddict/ApplicationPermissionManagementProvider.cs +++ b/modules/openiddict/src/Volo.Abp.PermissionManagement.Domain.OpenIddict/Volo/Abp/PermissionManagement/OpenIddict/ApplicationPermissionManagementProvider.cs @@ -29,6 +29,14 @@ public class ApplicationPermissionManagementProvider : PermissionManagementProvi } } + public override Task CheckAsync(string[] names, string providerName, string providerKey) + { + using (CurrentTenant.Change(null)) + { + return base.CheckAsync(names, providerName, providerKey); + } + } + protected override Task GrantAsync(string name, string providerKey) { using (CurrentTenant.Change(null)) diff --git a/modules/openiddict/src/Volo.Abp.PermissionManagement.Domain.OpenIddict/Volo/Abp/PermissionManagement/OpenIddict/ApplicationResourcePermissionManagementProvider.cs b/modules/openiddict/src/Volo.Abp.PermissionManagement.Domain.OpenIddict/Volo/Abp/PermissionManagement/OpenIddict/ApplicationResourcePermissionManagementProvider.cs new file mode 100644 index 0000000000..30e7d97f61 --- /dev/null +++ b/modules/openiddict/src/Volo.Abp.PermissionManagement.Domain.OpenIddict/Volo/Abp/PermissionManagement/OpenIddict/ApplicationResourcePermissionManagementProvider.cs @@ -0,0 +1,59 @@ +using System.Threading.Tasks; +using Volo.Abp.Authorization.Permissions.Resources; +using Volo.Abp.Guids; +using Volo.Abp.MultiTenancy; + +namespace Volo.Abp.PermissionManagement.OpenIddict; + +public class ApplicationResourcePermissionManagementProvider : ResourcePermissionManagementProvider +{ + public override string Name => ClientResourcePermissionValueProvider.ProviderName; + + public ApplicationResourcePermissionManagementProvider( + IResourcePermissionGrantRepository resourcePermissionGrantRepository, + IGuidGenerator guidGenerator, + ICurrentTenant currentTenant) + : base(resourcePermissionGrantRepository, guidGenerator, currentTenant) + { + } + + public override Task CheckAsync(string name, string resourceName,string resourceKey, string providerName, string providerKey) + { + using (CurrentTenant.Change(null)) + { + return base.CheckAsync(name, resourceName, resourceKey, providerName, providerKey); + } + } + + public override Task CheckAsync(string[] names, string resourceName, string resourceKey, string providerName, string providerKey) + { + using (CurrentTenant.Change(null)) + { + return base.CheckAsync(names, resourceName, resourceKey, providerName, providerKey); + } + } + + public override Task SetAsync(string name, string resourceName,string resourceKey, string providerKey, bool isGranted) + { + using (CurrentTenant.Change(null)) + { + return base.SetAsync(name, resourceName, resourceKey, providerKey, isGranted); + } + } + + protected override async Task GrantAsync(string name, string resourceName, string resourceKey, string providerKey) + { + using (CurrentTenant.Change(null)) + { + await base.GrantAsync(name, resourceName, resourceKey, providerKey); + } + } + + protected override Task RevokeAsync(string name, string resourceName,string resourceKey, string providerKey) + { + using (CurrentTenant.Change(null)) + { + return base.RevokeAsync(name, resourceName, resourceKey, providerKey); + } + } +} diff --git a/modules/openiddict/src/Volo.Abp.PermissionManagement.Domain.OpenIddict/Volo/Abp/PermissionManagement/OpenIddict/ApplicationResourcePermissionProviderKeyLookupService.cs b/modules/openiddict/src/Volo.Abp.PermissionManagement.Domain.OpenIddict/Volo/Abp/PermissionManagement/OpenIddict/ApplicationResourcePermissionProviderKeyLookupService.cs new file mode 100644 index 0000000000..34752d488a --- /dev/null +++ b/modules/openiddict/src/Volo.Abp.PermissionManagement.Domain.OpenIddict/Volo/Abp/PermissionManagement/OpenIddict/ApplicationResourcePermissionProviderKeyLookupService.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using OpenIddict.Abstractions; +using Volo.Abp.Authorization.Permissions.Resources; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Localization; +using Volo.Abp.OpenIddict.Applications; + +namespace Volo.Abp.PermissionManagement.OpenIddict; + +public class ApplicationResourcePermissionProviderKeyLookupService : IResourcePermissionProviderKeyLookupService, ITransientDependency +{ + public string Name => ClientResourcePermissionValueProvider.ProviderName; + + public ILocalizableString DisplayName { get; } + + protected IApplicationFinder ApplicationFinder { get; } + + public ApplicationResourcePermissionProviderKeyLookupService(IApplicationFinder applicationFinder) + { + ApplicationFinder = applicationFinder; + DisplayName = LocalizableString.Create(nameof(ApplicationResourcePermissionProviderKeyLookupService)); + } + + public virtual async Task> SearchAsync(string filter = null, int page = 1, CancellationToken cancellationToken = default) + { + var users = await ApplicationFinder.SearchAsync(filter, page); + return users.Select(u => new ResourcePermissionProviderKeyInfo(u.Id.ToString(), u.ClientId)).ToList(); + } + + public virtual async Task> SearchAsync(string[] keys, CancellationToken cancellationToken = default) + { + var ids = keys + .Select(key => Guid.TryParse(key, out var id) ? (Guid?)id : null) + .Where(id => id.HasValue) + .Select(id => id.Value) + .Distinct() + .ToArray(); + var users = await ApplicationFinder.SearchByIdsAsync(ids.ToArray()); + return users.Select(u => new ResourcePermissionProviderKeyInfo(u.Id.ToString(), u.ClientId)).ToList(); + } +}