feat: Add IsAvailableAsync to resource permission management providers#24951
Conversation
Introduces `IsAvailableAsync()` to `IResourcePermissionManagementProvider` and `IResourcePermissionProviderKeyLookupService`, allowing providers to opt out in certain contexts. `ResourcePermissionManager` respects this flag in permission checks, writes, and UI lookup service listing. OpenIddict and IdentityServer client providers override `IsAvailableAsync()` to return `false` when the current context is a tenant (host-only concept).
There was a problem hiding this comment.
Pull request overview
This PR introduces an availability mechanism for resource permission management providers, allowing providers to conditionally opt out based on context (e.g., multi-tenancy). The primary use case is making OpenIddict and IdentityServer client-related providers available only at the host level, not in tenant contexts.
Changes:
- Added
IsAvailableAsync()method toIResourcePermissionManagementProviderandIResourcePermissionProviderKeyLookupServiceinterfaces with default implementations - Updated
ResourcePermissionManagerto respect availability checks in permission reads, writes, and UI lookup service listings - Implemented host-only logic for OpenIddict and IdentityServer client providers by checking
CurrentTenant.Id == null
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
IResourcePermissionManagementProvider.cs |
Added IsAvailableAsync() method to interface |
IResourcePermissionProviderKeyLookupService.cs |
Added IsAvailableAsync() method to interface |
ResourcePermissionManagementProvider.cs |
Added default implementation of IsAvailableAsync() returning true |
ResourcePermissionManager.cs |
Updated to filter unavailable services in GetProviderKeyLookupServicesAsync(), skip unavailable providers in GetInternalAsync(), and validate availability in SetAsync() |
ApplicationResourcePermissionManagementProvider.cs |
Overridden IsAvailableAsync() to return false when in tenant context |
ApplicationResourcePermissionProviderKeyLookupService.cs |
Overridden IsAvailableAsync() to return false when in tenant context, injected ICurrentTenant |
ClientResourcePermissionManagementProvider.cs |
Overridden IsAvailableAsync() to return false when in tenant context |
ClientResourcePermissionProviderKeyLookupService.cs |
Overridden IsAvailableAsync() to return false when in tenant context, injected ICurrentTenant |
UserResourcePermissionProviderKeyLookupService.cs |
Added IsAvailableAsync() returning true (always available) |
RoleResourcePermissionProviderKeyLookupService.cs |
Added IsAvailableAsync() returning true (always available) |
TestUnavailableResourcePermissionManagementProvider.cs |
Test provider that always returns unavailable |
TestUnavailableResourcePermissionProviderKeyLookupService.cs |
Test lookup service that always returns unavailable |
TestResourcePermissionProviderKeyLookupService.cs |
Added IsAvailableAsync() returning true for existing test service |
AbpPermissionManagementTestBaseModule.cs |
Registered test unavailable providers |
ResourcePermissionManager_Tests.cs |
Added tests for availability filtering and unavailable provider error handling |
Comments suppressed due to low confidence (1)
modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionManager.cs:92
- The GetProviderKeyLookupServiceAsync method should check if the service is available before returning it. Currently, it returns unavailable services, which is inconsistent with GetProviderKeyLookupServicesAsync (which filters by availability). This could allow callers to obtain and use a service that returns false from IsAvailableAsync(). Consider adding an availability check or throwing an exception if the requested service exists but is not available in the current context.
public virtual Task<IResourcePermissionProviderKeyLookupService> GetProviderKeyLookupServiceAsync(string serviceName)
{
var service = _lazyProviderKeyLookupServices.Value.FirstOrDefault(s => s.Name == serviceName);
return service == null
? throw new AbpException("Unknown resource permission provider key lookup service: " + serviceName)
: Task.FromResult(service);
}
...o.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionManager.cs
Show resolved
Hide resolved
...sionManagement.Domain.Tests/Volo/Abp/PermissionManagement/ResourcePermissionManager_Tests.cs
Show resolved
Hide resolved
...o.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionManager.cs
Show resolved
Hide resolved
...sionManagement.Domain/Volo/Abp/PermissionManagement/IResourcePermissionManagementProvider.cs
Show resolved
Hide resolved
...nagement.Domain/Volo/Abp/PermissionManagement/IResourcePermissionProviderKeyLookupService.cs
Show resolved
Hide resolved
…nd add related tests
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 16 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/IResourcePermissionProviderKeyLookupService.cs:18
- Adding
IsAvailableAsync()to this public interface is a breaking change for any external implementations ofIResourcePermissionProviderKeyLookupService. If maintaining compatibility matters, consider a new optional interface for availability (checked viaispattern) so existing implementations continue to work and default to available.
public interface IResourcePermissionProviderKeyLookupService
{
public string Name { get; }
Task<bool> IsAvailableAsync();
public ILocalizableString DisplayName { get; }
Task<List<ResourcePermissionProviderKeyInfo>> SearchAsync(string filter = null, int page = 1, CancellationToken cancellationToken = default);
Task<List<ResourcePermissionProviderKeyInfo>> SearchAsync(string[] keys, CancellationToken cancellationToken = default);
...o.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionManager.cs
Outdated
Show resolved
Hide resolved
...o.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionManager.cs
Show resolved
Hide resolved
… from ResourcePermissionManager
Introduces
IsAvailableAsync()toIResourcePermissionManagementProviderandIResourcePermissionProviderKeyLookupService, allowing providers to opt out in certain contexts.ResourcePermissionManagerrespects this flag in permission checks, writes, and UI lookup service listing.OpenIddict and IdentityServer client providers override
IsAvailableAsync()to returnfalsewhen the current context is a tenant (host-only concept).