- Replace FormattedStringValueExtracter.Extract with LastIndexOf in
PermissionGrantCacheItem and ResourcePermissionGrantCacheItem to
eliminate repeated string tokenization and object allocations on
every cache key parse (~12,000 calls per request with 4000+ permissions)
- Add fast-path in SimpleStateCheckerManager.InternalIsEnabledAsync to
skip DI scope creation when both StateCheckers and GlobalStateCheckers
are empty, avoiding thousands of unnecessary scope allocations
- Optimize PermissionChecker.IsGrantedAsync(string[]) and
ResourcePermissionChecker.IsGrantedAsync(string[], resourceName, resourceKey)
to load all permission definitions once via GetPermissionsAsync /
GetResourcePermissionsAsync instead of N individual GetOrNullAsync calls,
and use batch StateCheckerManager.IsEnabledAsync for state checking
- Optimize AbpApplicationConfigurationAppService.GetAuthConfigAsync to
pre-load all permission names into a HashSet for O(1) lookup instead
of N async GetOrNullAsync calls inside the loop
- Fix GetResourcePermissionsAsync to deduplicate by (ResourceName, Name)
instead of Name only, matching the actual uniqueness constraint of
resource permissions defined in PermissionDefinitionContext
Production impact (customer with 4000+ permissions): 10s+ -> ~682ms
- Fix ResourcePermissionDefinitions not being populated in DynamicPermissionDefinitionStoreInMemoryCache.FillAsync, causing GetResourcePermissionOrNull and GetResourcePermissions to always return empty
- Fix StaticPermissionSaver incorrectly using newRecords instead of changedRecords when collecting changed permission names for event notification
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).
When selecting "Select All" for a specific permission group, the "Grant All Permissions"
checkbox should display an indeterminate state if not all permissions are granted.
The issue was that GrantAll and GrantAny were calculated based on _groups (filtered list)
instead of _allGroups (all groups), causing incorrect checkbox state when groups were filtered.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added 'ErrorLoadingPermissions' and 'PleaseSelectProviderAndPermissions' keys to all language JSON files in the permission management module to support new error and prompt messages in the UI.
Added new translation keys for 'UpdatePermission', 'NoPermissionsAssigned', 'SelectProvider', 'SearchProviderKey', and 'Provider' across all supported languages in the permission management module. This enhances localization support for new UI features related to provider selection and permission assignment.