Browse Source

Merge pull request #26130 from abpframework/auto-merge-forward/rel-10.7-to-dev-30

Auto-merge forward rel-10.7 → dev
dev
Volosoft Agent 19 hours ago
committed by GitHub
parent
commit
18dcd779ea
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 11
      modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RolePermissionManagementProvider.cs
  2. 18
      modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/PermissionManager_Tests.cs
  3. 40
      modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/PermissionAppService.cs
  4. 40
      modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor.MudBlazor/Components/PermissionManagementModal.razor.cs
  5. 41
      modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor.cs
  6. 6
      modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionManagementProvider.cs
  7. 30
      modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionManager.cs
  8. 25
      modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionStore.cs
  9. 59
      modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/PermissionManagementModal.cshtml.cs
  10. 46
      modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/permission-management-modal.js
  11. 24
      modules/permission-management/test/Volo.Abp.PermissionManagement.Application.Tests/Volo/Abp/PermissionManagement/PermissionAppService_Tests.cs
  12. 1
      modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/AbpPermissionManagementTestModule.cs
  13. 63
      modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionManager_Tests.cs
  14. 19
      modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionStore_Tests.cs
  15. 6
      modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/AbpPermissionManagementTestBaseModule.cs
  16. 53
      modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestGlobalPermissionStateChecker.cs

11
modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RolePermissionManagementProvider.cs

@ -65,9 +65,18 @@ public class RolePermissionManagementProvider : PermissionManagementProvider
return multiplePermissionValueProviderGrantInfo;
}
var permissionGrantsByName = new Dictionary<string, PermissionGrant>();
foreach (var permissionGrant in permissionGrants)
{
if (!permissionGrantsByName.ContainsKey(permissionGrant.Name))
{
permissionGrantsByName[permissionGrant.Name] = permissionGrant;
}
}
foreach (var permissionName in names)
{
var permissionGrant = permissionGrants.FirstOrDefault(x => x.Name == permissionName);
var permissionGrant = permissionGrantsByName.GetOrDefault(permissionName);
if (permissionGrant != null)
{
multiplePermissionValueProviderGrantInfo.Result[permissionName] = new PermissionValueProviderGrantInfo(true, permissionGrant.ProviderKey);

18
modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/PermissionManager_Tests.cs

@ -87,6 +87,24 @@ public class PermissionManager_Tests : AbpIdentityDomainTestBase
ShouldNotHavePermission(grantInfos, TestPermissionNames.MyPermission2_ChildPermission1);
}
[Fact]
public async Task Should_Report_A_Single_Role_Provider_When_Several_Roles_Grant_The_Permission()
{
var user = GetUser("john.nash");
var grantInfos = await _permissionManager.GetAllForUserAsync(user.Id);
var grantInfo = grantInfos.Single(x => x.Name == TestPermissionNames.MyPermission1);
grantInfo.IsGranted.ShouldBeTrue();
var roleProviders = grantInfo.Providers
.Where(x => x.Name == RolePermissionValueProvider.ProviderName)
.ToList();
roleProviders.Count.ShouldBe(1);
roleProviders.Single().Key.ShouldBeOneOf("moderator", "supporter");
}
private static void RoleShouldHavePermission(List<PermissionWithGrantedProviders> grantInfos, string roleName, string permissionName)
{
grantInfos.ShouldContain(

40
modules/permission-management/src/Volo.Abp.PermissionManagement.Application/Volo/Abp/PermissionManagement/PermissionAppService.cs

@ -78,20 +78,29 @@ public class PermissionAppService : ApplicationService, IPermissionAppService
.Where(x => !x.Providers.Any() || x.Providers.Contains(providerName))
.Where(x => x.MultiTenancySide.HasFlag(multiTenancySide));
var neededCheckPermissions = new List<PermissionDefinition>();
foreach (var permission in permissions)
var candidatePermissions = permissions.Distinct().ToArray();
var childrenByParent = candidatePermissions
.Where(x => x.Parent != null)
.GroupBy(x => x.Parent!)
.ToDictionary(x => x.Key, x => x.ToArray());
/* The state checkers of a permission only run when its parent is enabled,
so each tree level is checked in its own batch. */
var enabledPermissions = new HashSet<PermissionDefinition>();
var currentLevel = candidatePermissions.Where(x => x.Parent == null).ToArray();
while (currentLevel.Any())
{
if (permission.Parent != null && !neededCheckPermissions.Contains(permission.Parent))
{
continue;
}
var levelResult = await SimpleStateCheckerManager.IsEnabledAsync(currentLevel);
var enabledLevelPermissions = currentLevel.Where(x => levelResult[x]).ToArray();
enabledPermissions.UnionWith(enabledLevelPermissions);
if (await SimpleStateCheckerManager.IsEnabledAsync(permission))
{
neededCheckPermissions.Add(permission);
}
currentLevel = enabledLevelPermissions
.SelectMany(x => childrenByParent.GetOrDefault(x) ?? Array.Empty<PermissionDefinition>())
.ToArray();
}
var neededCheckPermissions = candidatePermissions.Where(enabledPermissions.Contains).ToList();
if (!neededCheckPermissions.Any())
{
continue;
@ -106,11 +115,20 @@ public class PermissionAppService : ApplicationService, IPermissionAppService
providerName,
providerKey);
var grantInfoByName = new Dictionary<string, PermissionWithGrantedProviders>();
foreach (var grantInfo in multipleGrantInfo.Result)
{
if (!grantInfoByName.ContainsKey(grantInfo.Name))
{
grantInfoByName[grantInfo.Name] = grantInfo;
}
}
foreach (var permissionGroup in permissionGroups)
{
foreach (var permission in permissionGroup.Permissions)
{
var grantInfo = multipleGrantInfo.Result.FirstOrDefault(x => x.Name == permission.Name);
var grantInfo = grantInfoByName.GetOrDefault(permission.Name);
if (grantInfo == null)
{
continue;

40
modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor.MudBlazor/Components/PermissionManagementModal.razor.cs

@ -28,6 +28,7 @@ public partial class PermissionManagementModal
protected string? _entityDisplayName;
protected List<PermissionGroupDto>? _allGroups;
protected Dictionary<string, bool> _loadedPermissionValues = new Dictionary<string, bool>();
protected List<PermissionGroupDto>? _groups;
protected int _activeTabIndex = 0;
@ -60,6 +61,10 @@ public partial class PermissionManagementModal
_allGroups = result.Groups.OrderBy(x => x.DisplayName).ToList();
_groups = _allGroups.ToList();
_loadedPermissionValues = _allGroups
.SelectMany(x => x.Permissions)
.ToDictionary(x => x.Name, x => x.IsGranted);
NormalizePermissionGroup();
GrantAll = _allGroups.SelectMany(x => x.Permissions).All(p => p.IsGranted);
@ -134,15 +139,14 @@ public partial class PermissionManagementModal
return;
}
var updateDto = new UpdatePermissionsDto
{
Permissions = _allGroups
.SelectMany(g => g.Permissions)
.Select(p => new UpdatePermissionDto { IsGranted = p.IsGranted, Name = p.Name })
.ToArray()
};
var permissions = _allGroups.SelectMany(g => g.Permissions).ToList();
var changedPermissions = permissions
.Where(p => !_loadedPermissionValues.TryGetValue(p.Name, out var loadedValue) || loadedValue != p.IsGranted)
.Select(p => new UpdatePermissionDto { IsGranted = p.IsGranted, Name = p.Name })
.ToArray();
if (!updateDto.Permissions.Any(x => x.IsGranted))
if (!permissions.Any(p => p.IsGranted))
{
var confirmed = await DialogService.ShowMessageBoxAsync(
L["Warning"],
@ -156,15 +160,21 @@ public partial class PermissionManagementModal
}
}
await PermissionAppService.UpdateAsync(_providerName!, _providerKey!, updateDto);
Guid? userId = null;
if (_providerName == UserPermissionValueProvider.ProviderName && Guid.TryParse(_providerKey, out var parsedUserId))
if (changedPermissions.Any())
{
userId = parsedUserId;
}
await PermissionAppService.UpdateAsync(_providerName!, _providerKey!, new UpdatePermissionsDto
{
Permissions = changedPermissions
});
await CurrentApplicationConfigurationCacheResetService.ResetAsync(userId);
Guid? userId = null;
if (_providerName == UserPermissionValueProvider.ProviderName && Guid.TryParse(_providerKey, out var parsedUserId))
{
userId = parsedUserId;
}
await CurrentApplicationConfigurationCacheResetService.ResetAsync(userId);
}
_isVisible = false;
await InvokeAsync(StateHasChanged);

41
modules/permission-management/src/Volo.Abp.PermissionManagement.Blazor/Components/PermissionManagementModal.razor.cs

@ -26,6 +26,8 @@ public partial class PermissionManagementModal
protected string _entityDisplayName;
protected List<PermissionGroupDto> _allGroups;
protected Dictionary<string, bool> _loadedPermissionValues = new Dictionary<string, bool>();
protected List<PermissionGroupDto> _groups;
protected string _selectedTabName;
@ -58,6 +60,10 @@ public partial class PermissionManagementModal
_allGroups = result.Groups.OrderBy(x => x.DisplayName).ToList();
_groups = _allGroups.ToList();
_loadedPermissionValues = _allGroups
.SelectMany(x => x.Permissions)
.ToDictionary(x => x.Name, x => x.IsGranted);
NormalizePermissionGroup();
GrantAll = _allGroups.SelectMany(x => x.Permissions).All(p => p.IsGranted);
@ -121,15 +127,14 @@ public partial class PermissionManagementModal
try
{
var updateDto = new UpdatePermissionsDto
{
Permissions = _allGroups
.SelectMany(g => g.Permissions)
.Select(p => new UpdatePermissionDto { IsGranted = p.IsGranted, Name = p.Name })
.ToArray()
};
var permissions = _allGroups.SelectMany(g => g.Permissions).ToList();
if (!updateDto.Permissions.Any(x => x.IsGranted))
var changedPermissions = permissions
.Where(p => !_loadedPermissionValues.TryGetValue(p.Name, out var loadedValue) || loadedValue != p.IsGranted)
.Select(p => new UpdatePermissionDto { IsGranted = p.IsGranted, Name = p.Name })
.ToArray();
if (!permissions.Any(p => p.IsGranted))
{
if (!await Message.Confirm(L["SaveWithoutAnyPermissionsWarningMessage"].Value))
{
@ -137,15 +142,21 @@ public partial class PermissionManagementModal
}
}
await PermissionAppService.UpdateAsync(_providerName, _providerKey, updateDto);
Guid? userId = null;
if (_providerName == UserPermissionValueProvider.ProviderName && Guid.TryParse(_providerKey, out var parsedUserId))
if (changedPermissions.Any())
{
userId = parsedUserId;
}
await PermissionAppService.UpdateAsync(_providerName, _providerKey, new UpdatePermissionsDto
{
Permissions = changedPermissions
});
await CurrentApplicationConfigurationCacheResetService.ResetAsync(userId);
Guid? userId = null;
if (_providerName == UserPermissionValueProvider.ProviderName && Guid.TryParse(_providerKey, out var parsedUserId))
{
userId = parsedUserId;
}
await CurrentApplicationConfigurationCacheResetService.ResetAsync(userId);
}
await InvokeAsync(_modal.Hide);
await Notify.Success(L["SavedSuccessfully"]);

6
modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionManagementProvider.cs

@ -1,4 +1,5 @@
using System.Linq;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Guids;
@ -44,10 +45,11 @@ public abstract class PermissionManagementProvider : IPermissionManagementProvid
}
var permissionGrants = await PermissionGrantRepository.GetListAsync(names, providerName, providerKey);
var grantedPermissionNames = new HashSet<string>(permissionGrants.Select(x => x.Name));
foreach (var permissionName in names)
{
var isGrant = permissionGrants.Any(x => x.Name == permissionName);
var isGrant = grantedPermissionNames.Contains(permissionName);
multiplePermissionValueProviderGrantInfo.Result[permissionName] = new PermissionValueProviderGrantInfo(isGrant, providerKey);
}

30
modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionManager.cs

@ -218,14 +218,22 @@ public class PermissionManager : IPermissionManager, ISingletonDependency
var permissionNames = permissions.Select(x => x.Name).ToArray();
var multiplePermissionWithGrantedProviders = new MultiplePermissionWithGrantedProviders(permissionNames);
var stateCheckPermissions = permissions
.Where(x => x.IsEnabled)
.Where(x => x.MultiTenancySide.HasFlag(CurrentTenant.GetMultiTenancySide()))
.Where(x => !x.Providers.Any() || x.Providers.Contains(providerName))
.Distinct()
.ToArray();
var stateCheckResult = stateCheckPermissions.Any()
? await SimpleStateCheckerManager.IsEnabledAsync(stateCheckPermissions)
: new SimpleStateCheckerResult<PermissionDefinition>();
var neededCheckPermissions = new List<PermissionDefinition>();
foreach (var permission in permissions
.Where(x => x.IsEnabled)
.Where(x => x.MultiTenancySide.HasFlag(CurrentTenant.GetMultiTenancySide()))
.Where(x => !x.Providers.Any() || x.Providers.Contains(providerName)))
foreach (var permission in stateCheckPermissions)
{
if (await SimpleStateCheckerManager.IsEnabledAsync(permission))
if (stateCheckResult[permission])
{
neededCheckPermissions.Add(permission);
}
@ -236,6 +244,15 @@ public class PermissionManager : IPermissionManager, ISingletonDependency
return multiplePermissionWithGrantedProviders;
}
var permissionsWithGrantedProvidersByName = new Dictionary<string, PermissionWithGrantedProviders>();
foreach (var permissionWithGrantedProviders in multiplePermissionWithGrantedProviders.Result)
{
if (!permissionsWithGrantedProvidersByName.ContainsKey(permissionWithGrantedProviders.Name))
{
permissionsWithGrantedProvidersByName[permissionWithGrantedProviders.Name] = permissionWithGrantedProviders;
}
}
foreach (var provider in ManagementProviders)
{
permissionNames = neededCheckPermissions.Select(x => x.Name).ToArray();
@ -245,8 +262,7 @@ public class PermissionManager : IPermissionManager, ISingletonDependency
{
if (providerResultDict.Value.IsGranted)
{
var permissionWithGrantedProvider = multiplePermissionWithGrantedProviders.Result
.First(x => x.Name == providerResultDict.Key);
var permissionWithGrantedProvider = permissionsWithGrantedProvidersByName[providerResultDict.Key];
permissionWithGrantedProvider.IsGranted = true;
permissionWithGrantedProvider.Providers.Add(new PermissionValueProviderInfo(provider.Name, providerResultDict.Value.ProviderKey));

25
modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionStore.cs

@ -154,16 +154,29 @@ public class PermissionStore : IPermissionStore, ITransientDependency
var newCacheItems = await SetCacheItemsAsync(providerName, providerKey, notCacheKeys);
var result = new List<KeyValuePair<string, PermissionGrantCacheItem>>();
foreach (var key in cacheKeys)
var newCacheItemsByKey = new Dictionary<string, PermissionGrantCacheItem>();
foreach (var newCacheItem in newCacheItems)
{
var item = newCacheItems.FirstOrDefault(x => x.Key == key);
if (item.Value == null)
if (!newCacheItemsByKey.ContainsKey(newCacheItem.Key))
{
item = cacheItems.FirstOrDefault(x => x.Key == key);
newCacheItemsByKey[newCacheItem.Key] = newCacheItem.Value;
}
}
result.Add(new KeyValuePair<string, PermissionGrantCacheItem>(key, item.Value));
var cacheItemsByKey = new Dictionary<string, PermissionGrantCacheItem>();
foreach (var cacheItem in cacheItems)
{
if (!cacheItemsByKey.ContainsKey(cacheItem.Key))
{
cacheItemsByKey[cacheItem.Key] = cacheItem.Value;
}
}
var result = new List<KeyValuePair<string, PermissionGrantCacheItem>>();
foreach (var key in cacheKeys)
{
var item = newCacheItemsByKey.GetOrDefault(key) ?? cacheItemsByKey.GetOrDefault(key);
result.Add(new KeyValuePair<string, PermissionGrantCacheItem>(key, item));
}
return result;

59
modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/PermissionManagementModal.cshtml.cs

@ -32,6 +32,16 @@ public class PermissionManagementModal : AbpPageModel
[BindProperty]
public List<PermissionGroupViewModel> Groups { get; set; }
/* A replaced view that still posts the whole Groups tree does not set this, so it keeps working. */
[BindProperty]
public bool OnlyChangedPermissions { get; set; }
[BindProperty]
public string GrantedPermissionNames { get; set; }
[BindProperty]
public string RevokedPermissionNames { get; set; }
public string EntityDisplayName { get; set; }
public bool SelectAllInThisTab { get; set; }
@ -89,14 +99,21 @@ public class PermissionManagementModal : AbpPageModel
{
ValidateModel();
var updatePermissionDtos = Groups
.SelectMany(g => g.Permissions)
.Select(p => new UpdatePermissionDto
{
Name = p.Name,
IsGranted = p.IsGranted
})
.ToArray();
var updatePermissionDtos = OnlyChangedPermissions
? GetChangedPermissions()
: Groups
.SelectMany(g => g.Permissions)
.Select(p => new UpdatePermissionDto
{
Name = p.Name,
IsGranted = p.IsGranted
})
.ToArray();
if (updatePermissionDtos.IsNullOrEmpty())
{
return NoContent();
}
await PermissionAppService.UpdateAsync(
ProviderName,
@ -118,6 +135,32 @@ public class PermissionManagementModal : AbpPageModel
return NoContent();
}
protected virtual UpdatePermissionDto[] GetChangedPermissions()
{
var permissions = new Dictionary<string, bool>();
foreach (var name in SplitPermissionNames(GrantedPermissionNames))
{
permissions[name] = true;
}
foreach (var name in SplitPermissionNames(RevokedPermissionNames))
{
permissions[name] = false;
}
return permissions
.Select(permission => new UpdatePermissionDto { Name = permission.Key, IsGranted = permission.Value })
.ToArray();
}
protected virtual string[] SplitPermissionNames(string names)
{
return names.IsNullOrWhiteSpace()
? Array.Empty<string>()
: names.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
}
public class PermissionGroupViewModel
{
public string Name { get; set; }

46
modules/permission-management/src/Volo.Abp.PermissionManagement.Web/Pages/AbpPermissionManagement/permission-management-modal.js

@ -299,6 +299,48 @@ var abp = abp || {};
setSelectAllInAllTabs();
var $form = $("#PermissionManagementForm");
// defaultChecked holds the state the server rendered.
function submitChangedPermissions() {
// A replaced view without these attributes posts the whole tree instead.
var $permissions = $form.find('[data-permission-name]');
if (!$permissions.length) {
$form.submit();
return;
}
var granted = [];
var revoked = [];
$permissions.each(function () {
var $permission = $(this);
var checkbox = $permission.find('input[type="checkbox"]')[0];
if (!checkbox || checkbox.checked === checkbox.defaultChecked) {
return;
}
(checkbox.checked ? granted : revoked)
.push($permission.attr('data-permission-name'));
});
var $treeInputs = $form.find('fieldset').find('input').not(':disabled');
var $postedInputs = $()
.add($('<input type="hidden" name="OnlyChangedPermissions" value="true" />'))
.add($('<input type="hidden" name="GrantedPermissionNames" />').val(granted.join('\n')))
.add($('<input type="hidden" name="RevokedPermissionNames" />').val(revoked.join('\n')));
$treeInputs.prop('disabled', true);
$form.append($postedInputs);
try {
$form.submit();
} finally {
// The form is serialized synchronously, so the inputs can be restored right away.
$treeInputs.prop('disabled', false);
$postedInputs.remove();
}
}
var $submitButton = $form.find("button[type='submit']");
if ($submitButton) {
$submitButton.click(function (e) {
@ -308,12 +350,12 @@ var abp = abp || {};
abp.message.confirm(l("SaveWithoutAnyPermissionsWarningMessage"))
.then(function (confirmed) {
if (confirmed) {
$form.submit();
submitChangedPermissions();
}
});
}
else {
$form.submit();
submitChangedPermissions();
}
});
}

24
modules/permission-management/test/Volo.Abp.PermissionManagement.Application.Tests/Volo/Abp/PermissionManagement/PermissionAppService_Tests.cs

@ -17,6 +17,7 @@ public class PermissionAppService_Tests : AbpPermissionManagementApplicationTest
private readonly IPermissionGrantRepository _permissionGrantRepository;
private readonly ICurrentPrincipalAccessor _currentPrincipalAccessor;
private readonly FakePermissionChecker _fakePermissionChecker;
private readonly TestGlobalPermissionStateCheckerCounter _stateCheckerCounter;
public PermissionAppService_Tests()
{
@ -24,6 +25,29 @@ public class PermissionAppService_Tests : AbpPermissionManagementApplicationTest
_permissionGrantRepository = GetRequiredService<IPermissionGrantRepository>();
_currentPrincipalAccessor = GetRequiredService<ICurrentPrincipalAccessor>();
_fakePermissionChecker = GetRequiredService<FakePermissionChecker>();
_stateCheckerCounter = GetRequiredService<TestGlobalPermissionStateCheckerCounter>();
}
[Fact]
public async Task Get_Should_Not_Check_The_State_Of_A_Permission_Whose_Parent_Is_Not_Enabled()
{
_stateCheckerCounter.Reset();
await _permissionAppService.GetAsync(UserPermissionValueProvider.ProviderName,
PermissionTestDataBuilder.User1Id.ToString());
_stateCheckerCounter.CheckedPermissionNames.ShouldContain("MyPermission5");
_stateCheckerCounter.CheckedPermissionNames.ShouldNotContain("MyPermission5.ChildPermission1");
using (_currentPrincipalAccessor.Change(new Claim(AbpClaimTypes.Role, "super-admin")))
{
_stateCheckerCounter.Reset();
await _permissionAppService.GetAsync(UserPermissionValueProvider.ProviderName,
PermissionTestDataBuilder.User1Id.ToString());
_stateCheckerCounter.CheckedPermissionNames.ShouldContain("MyPermission5.ChildPermission1");
}
}
[Fact]

1
modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/AbpPermissionManagementTestModule.cs

@ -22,6 +22,7 @@ public class AbpPermissionManagementTestModule : AbpModule
{
context.Services.AddEntityFrameworkInMemoryDatabase();
var databaseName = Guid.NewGuid().ToString();
Configure<AbpDbContextOptions>(options =>

63
modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionManager_Tests.cs

@ -1,10 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Shouldly;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Security.Claims;
using Xunit;
namespace Volo.Abp.PermissionManagement;
@ -13,11 +15,15 @@ public class PermissionManager_Tests : PermissionTestBase
{
private readonly IPermissionManager _permissionManager;
private readonly IPermissionGrantRepository _permissionGrantRepository;
private readonly ICurrentPrincipalAccessor _currentPrincipalAccessor;
private readonly TestGlobalPermissionStateCheckerCounter _stateCheckerCounter;
public PermissionManager_Tests()
{
_permissionManager = GetRequiredService<IPermissionManager>();
_permissionGrantRepository = GetRequiredService<IPermissionGrantRepository>();
_currentPrincipalAccessor = GetRequiredService<ICurrentPrincipalAccessor>();
_stateCheckerCounter = GetRequiredService<TestGlobalPermissionStateCheckerCounter>();
}
[Fact]
@ -71,6 +77,63 @@ public class PermissionManager_Tests : PermissionTestBase
grantedProviders.Result.Last().Providers.ShouldContain(x => x.Key == "Test");
}
[Fact]
public async Task Multiple_Get_Should_Apply_State_Checkers_Per_Permission()
{
await _permissionGrantRepository.InsertAsync(new PermissionGrant(
Guid.NewGuid(),
"MyPermission1",
"Test",
"Test")
);
await _permissionGrantRepository.InsertAsync(new PermissionGrant(
Guid.NewGuid(),
"MyPermission5",
"Test",
"Test")
);
var names = new[] { "MyPermission1", "MyPermission5" };
_stateCheckerCounter.Reset();
var grantedProviders = await _permissionManager.GetAsync(names, "Test", "Test");
_stateCheckerCounter.BatchCheckCount.ShouldBe(1);
_stateCheckerCounter.SingleCheckCount.ShouldBe(0);
grantedProviders.Result.Single(x => x.Name == "MyPermission1").IsGranted.ShouldBeTrue();
grantedProviders.Result.Single(x => x.Name == "MyPermission5").IsGranted.ShouldBeFalse();
using (_currentPrincipalAccessor.Change(new Claim(AbpClaimTypes.Role, "super-admin")))
{
grantedProviders = await _permissionManager.GetAsync(names, "Test", "Test");
grantedProviders.Result.Single(x => x.Name == "MyPermission1").IsGranted.ShouldBeTrue();
grantedProviders.Result.Single(x => x.Name == "MyPermission5").IsGranted.ShouldBeTrue();
}
}
[Fact]
public async Task Multiple_Get_Should_Return_Not_Granted_When_Every_Permission_Is_Filtered_Out()
{
await _permissionGrantRepository.InsertAsync(new PermissionGrant(
Guid.NewGuid(),
"MyDisabledPermission1",
"Test",
"Test")
);
_stateCheckerCounter.Reset();
var grantedProviders = await _permissionManager.GetAsync(
new[] { "MyDisabledPermission1", "MyPermission1NotExist" },
"Test",
"Test");
grantedProviders.Result.Count.ShouldBe(2);
grantedProviders.Result.ShouldAllBe(x => !x.IsGranted);
_stateCheckerCounter.BatchCheckCount.ShouldBe(0);
_stateCheckerCounter.SingleCheckCount.ShouldBe(0);
}
[Fact]
public async Task Get_Should_Return_Not_Granted_When_Permission_Undefined()
{

19
modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/PermissionStore_Tests.cs

@ -39,4 +39,23 @@ public class PermissionStore_Tests : PermissionTestBase
result.Result.FirstOrDefault(x => x.Key == "MyPermission1").Value.ShouldBe(PermissionGrantResult.Granted);
result.Result.FirstOrDefault(x => x.Key == "MyPermission1NotExist").Value.ShouldBe(PermissionGrantResult.Undefined);
}
[Fact]
public async Task IsGranted_Multiple_Should_Combine_Cached_And_Uncached_Permissions()
{
(await _permissionStore.IsGrantedAsync("MyPermission1",
UserPermissionValueProvider.ProviderName,
PermissionTestDataBuilder.User1Id.ToString())).ShouldBeTrue();
var result = await _permissionStore.IsGrantedAsync(
new[] { "MyPermission3", "MyPermission1", "MyPermission1NotExist" },
UserPermissionValueProvider.ProviderName,
PermissionTestDataBuilder.User1Id.ToString());
result.Result.Count.ShouldBe(3);
result.Result.FirstOrDefault(x => x.Key == "MyPermission3").Value.ShouldBe(PermissionGrantResult.Granted);
result.Result.FirstOrDefault(x => x.Key == "MyPermission1").Value.ShouldBe(PermissionGrantResult.Granted);
result.Result.FirstOrDefault(x => x.Key == "MyPermission1NotExist").Value.ShouldBe(PermissionGrantResult.Undefined);
}
}

6
modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/AbpPermissionManagementTestBaseModule.cs

@ -4,6 +4,7 @@ using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Autofac;
using Volo.Abp.DistributedLocking;
using Volo.Abp.Modularity;
using Volo.Abp.SimpleStateChecking;
using Volo.Abp.Threading;
namespace Volo.Abp.PermissionManagement;
@ -19,6 +20,11 @@ public class AbpPermissionManagementTestBaseModule : AbpModule
{
context.Services.Replace(ServiceDescriptor.Singleton<IAbpDistributedLock, NullAbpDistributedLock>());
context.Services.Configure<AbpSimpleStateCheckerOptions<PermissionDefinition>>(options =>
{
options.GlobalStateCheckers.Add<TestGlobalPermissionStateChecker>();
});
context.Services.Configure<PermissionManagementOptions>(options =>
{
options.ManagementProviders.Add<TestPermissionManagementProvider>();

53
modules/permission-management/test/Volo.Abp.PermissionManagement.TestBase/Volo/Abp/PermissionManagement/TestGlobalPermissionStateChecker.cs

@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.DependencyInjection;
using Volo.Abp.SimpleStateChecking;
namespace Volo.Abp.PermissionManagement;
public class TestGlobalPermissionStateCheckerCounter : ISingletonDependency
{
public int BatchCheckCount { get; set; }
public int SingleCheckCount { get; set; }
public HashSet<string> CheckedPermissionNames { get; } = new HashSet<string>();
public void Reset()
{
BatchCheckCount = 0;
SingleCheckCount = 0;
CheckedPermissionNames.Clear();
}
}
public class TestGlobalPermissionStateChecker : ISimpleBatchStateChecker<PermissionDefinition>, ITransientDependency
{
public Task<bool> IsEnabledAsync(SimpleStateCheckerContext<PermissionDefinition> context)
{
var counter = GetCounter(context.ServiceProvider);
counter.SingleCheckCount++;
counter.CheckedPermissionNames.Add(context.State.Name);
return Task.FromResult(true);
}
public Task<SimpleStateCheckerResult<PermissionDefinition>> IsEnabledAsync(SimpleBatchStateCheckerContext<PermissionDefinition> context)
{
var counter = GetCounter(context.ServiceProvider);
counter.BatchCheckCount++;
foreach (var state in context.States)
{
counter.CheckedPermissionNames.Add(state.Name);
}
return Task.FromResult(new SimpleStateCheckerResult<PermissionDefinition>(context.States));
}
private static TestGlobalPermissionStateCheckerCounter GetCounter(IServiceProvider serviceProvider)
{
return serviceProvider.GetRequiredService<TestGlobalPermissionStateCheckerCounter>();
}
}
Loading…
Cancel
Save