Browse Source

Add RequiredPermissionName to ApplicationMenuItem.

pull/7799/head
maliming 6 years ago
parent
commit
3aaa1d8423
  1. 7
      framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs
  2. 54
      framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs
  3. 2
      framework/test/Volo.Abp.UI.Navigation.Tests/Volo.Abp.UI.Navigation.Tests.csproj
  4. 21
      framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/AbpUiNavigationTestModule.cs
  5. 28
      framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/FakePermissionStore.cs
  6. 60
      framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/MenuManager_Tests.cs
  7. 24
      framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/TestPermissionDefinitionProvider.cs

7
framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/ApplicationMenuItem.cs

@ -71,6 +71,9 @@ namespace Volo.Abp.UI.Navigation
[NotNull] [NotNull]
public ApplicationMenuItemList Items { get; } public ApplicationMenuItemList Items { get; }
[CanBeNull]
public string RequiredPermissionName { get; }
/// <summary> /// <summary>
/// Can be used to store a custom object related to this menu item. Optional. /// Can be used to store a custom object related to this menu item. Optional.
/// </summary> /// </summary>
@ -95,7 +98,8 @@ namespace Volo.Abp.UI.Navigation
object customData = null, object customData = null,
string target = null, string target = null,
string elementId = null, string elementId = null,
string cssClass = null) string cssClass = null,
string requiredPermissionName = null)
{ {
Check.NotNullOrWhiteSpace(name, nameof(name)); Check.NotNullOrWhiteSpace(name, nameof(name));
Check.NotNullOrWhiteSpace(displayName, nameof(displayName)); Check.NotNullOrWhiteSpace(displayName, nameof(displayName));
@ -109,6 +113,7 @@ namespace Volo.Abp.UI.Navigation
Target = target; Target = target;
ElementId = elementId ?? GetDefaultElementId(); ElementId = elementId ?? GetDefaultElementId();
CssClass = cssClass; CssClass = cssClass;
RequiredPermissionName = requiredPermissionName;
Items = new ApplicationMenuItemList(); Items = new ApplicationMenuItemList();
} }

54
framework/src/Volo.Abp.UI.Navigation/Volo/Abp/Ui/Navigation/MenuManager.cs

@ -2,7 +2,9 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
namespace Volo.Abp.UI.Navigation namespace Volo.Abp.UI.Navigation
@ -13,7 +15,7 @@ namespace Volo.Abp.UI.Navigation
protected IHybridServiceScopeFactory ServiceScopeFactory { get; } protected IHybridServiceScopeFactory ServiceScopeFactory { get; }
public MenuManager( public MenuManager(
IOptions<AbpNavigationOptions> options, IOptions<AbpNavigationOptions> options,
IHybridServiceScopeFactory serviceScopeFactory) IHybridServiceScopeFactory serviceScopeFactory)
{ {
ServiceScopeFactory = serviceScopeFactory; ServiceScopeFactory = serviceScopeFactory;
@ -32,6 +34,8 @@ namespace Volo.Abp.UI.Navigation
{ {
await contributor.ConfigureMenuAsync(context); await contributor.ConfigureMenuAsync(context);
} }
await CheckPermissionsAsync(scope.ServiceProvider, menu);
} }
NormalizeMenu(menu); NormalizeMenu(menu);
@ -39,6 +43,52 @@ namespace Volo.Abp.UI.Navigation
return menu; return menu;
} }
protected virtual async Task CheckPermissionsAsync(IServiceProvider serviceProvider, IHasMenuItems menuWithItems)
{
var requiredPermissionMenus = new List<ApplicationMenuItem>();
GetRequiredPermissionNameMenus(menuWithItems, requiredPermissionMenus);
if (requiredPermissionMenus.Any())
{
var permissionChecker = serviceProvider.GetRequiredService<IPermissionChecker>();
var grantResult = await permissionChecker.IsGrantedAsync(requiredPermissionMenus.Select(x => x.RequiredPermissionName).ToArray());
var toBeDeletedMenus = new List<ApplicationMenuItem>();
foreach (var menu in requiredPermissionMenus)
{
if (grantResult.Result[menu.RequiredPermissionName!] != PermissionGrantResult.Granted)
{
toBeDeletedMenus.Add(menu);
}
}
RemoveMenus(menuWithItems, toBeDeletedMenus);
}
}
protected virtual void GetRequiredPermissionNameMenus(IHasMenuItems menuWithItems, List<ApplicationMenuItem> output)
{
foreach (var menuItem in menuWithItems.Items)
{
if (!menuItem.RequiredPermissionName.IsNullOrWhiteSpace())
{
output.Add(menuItem);
}
GetRequiredPermissionNameMenus(menuItem, output);
}
}
protected virtual void RemoveMenus(IHasMenuItems menuWithItems, List<ApplicationMenuItem> toBeDeleted)
{
menuWithItems.Items.RemoveAll(toBeDeleted.Contains);
foreach (var menuItem in menuWithItems.Items)
{
RemoveMenus(menuItem, toBeDeleted);
}
}
protected virtual void NormalizeMenu(IHasMenuItems menuWithItems) protected virtual void NormalizeMenu(IHasMenuItems menuWithItems)
{ {
foreach (var menuItem in menuWithItems.Items) foreach (var menuItem in menuWithItems.Items)
@ -49,4 +99,4 @@ namespace Volo.Abp.UI.Navigation
menuWithItems.Items.Normalize(); menuWithItems.Items.Normalize();
} }
} }
} }

2
framework/test/Volo.Abp.UI.Navigation.Tests/Volo.Abp.UI.Navigation.Tests.csproj

@ -9,6 +9,8 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\src\Volo.Abp.UI.Navigation\Volo.Abp.UI.Navigation.csproj" /> <ProjectReference Include="..\..\src\Volo.Abp.UI.Navigation\Volo.Abp.UI.Navigation.csproj" />
<ProjectReference Include="..\..\src\Volo.Abp.Authorization\Volo.Abp.Authorization.csproj" />
<ProjectReference Include="..\..\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" />
<ProjectReference Include="..\AbpTestBase\AbpTestBase.csproj" /> <ProjectReference Include="..\AbpTestBase\AbpTestBase.csproj" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" />
</ItemGroup> </ItemGroup>

21
framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/AbpUiNavigationTestModule.cs

@ -0,0 +1,21 @@
using Volo.Abp.Authorization;
using Volo.Abp.Autofac;
using Volo.Abp.Modularity;
namespace Volo.Abp.UI.Navigation
{
[DependsOn(typeof(AbpUiNavigationModule))]
[DependsOn(typeof(AbpAuthorizationModule))]
[DependsOn(typeof(AbpAutofacModule))]
public class AbpUiNavigationTestModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpNavigationOptions>(options =>
{
options.MenuContributors.Add(new MenuManager_Tests.TestMenuContributor1());
options.MenuContributors.Add(new MenuManager_Tests.TestMenuContributor2());
});
}
}
}

28
framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/FakePermissionStore.cs

@ -0,0 +1,28 @@
using System.Threading.Tasks;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.UI.Navigation
{
public class FakePermissionStore : IPermissionStore, ITransientDependency
{
public Task<bool> IsGrantedAsync(string name, string providerName, string providerKey)
{
var result = (name.Contains("Administration") || name.Contains("Dashboard")) && !name.Contains("SubMenu1");
return Task.FromResult(result);
}
public Task<MultiplePermissionGrantResult> IsGrantedAsync(string[] names, string providerName, string providerKey)
{
var result = new MultiplePermissionGrantResult();
foreach (var name in names)
{
result.Result.Add(name, (name.Contains("Administration") || name.Contains("Dashboard")) && !name.Contains("SubMenu1")
? PermissionGrantResult.Granted
: PermissionGrantResult.Prohibited);
}
return Task.FromResult(result);
}
}
}

60
framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/MenuManager_Tests.cs

@ -1,13 +1,17 @@
using System.Threading.Tasks; using System.Collections.Generic;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using NSubstitute;
using Shouldly; using Shouldly;
using Volo.Abp.Modularity; using Volo.Abp.Security.Claims;
using Volo.Abp.Testing; using Volo.Abp.Testing;
using Xunit; using Xunit;
namespace Volo.Abp.UI.Navigation namespace Volo.Abp.UI.Navigation
{ {
public class MenuManager_Tests : AbpIntegratedTest<MenuManager_Tests.TestModule> public class MenuManager_Tests : AbpIntegratedTest<AbpUiNavigationTestModule>
{ {
private readonly IMenuManager _menuManager; private readonly IMenuManager _menuManager;
@ -16,6 +20,24 @@ namespace Volo.Abp.UI.Navigation
_menuManager = ServiceProvider.GetRequiredService<IMenuManager>(); _menuManager = ServiceProvider.GetRequiredService<IMenuManager>();
} }
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options)
{
options.UseAutofac();
}
protected override void AfterAddApplication(IServiceCollection services)
{
var claims = new List<Claim>() {
new Claim(AbpClaimTypes.UserId, "1fcf46b2-28c3-48d0-8bac-fa53268a2775"),
};
var identity = new ClaimsIdentity(claims);
var claimsPrincipal = new ClaimsPrincipal(identity);
var principalAccessor = Substitute.For<ICurrentPrincipalAccessor>();
principalAccessor.Principal.Returns(ci => claimsPrincipal);
Thread.CurrentPrincipal = claimsPrincipal;
}
[Fact] [Fact]
public async Task Should_Get_Menu() public async Task Should_Get_Menu()
{ {
@ -29,22 +51,8 @@ namespace Volo.Abp.UI.Navigation
mainMenu.Items[1].Items[0].Name.ShouldBe("Administration.UserManagement"); mainMenu.Items[1].Items[0].Name.ShouldBe("Administration.UserManagement");
mainMenu.Items[1].Items[1].Name.ShouldBe("Administration.RoleManagement"); mainMenu.Items[1].Items[1].Name.ShouldBe("Administration.RoleManagement");
mainMenu.Items[1].Items[2].Name.ShouldBe("Administration.DashboardSettings"); mainMenu.Items[1].Items[2].Name.ShouldBe("Administration.DashboardSettings");
mainMenu.Items[1].Items[3].Name.ShouldBe("Administration.SubMenu1"); mainMenu.Items[1].Items[3].Name.ShouldBe("Administration.SubMenu1"); //No need permission.
mainMenu.Items[1].Items[3].Items[0].Name.ShouldBe("Administration.SubMenu1.1"); // Administration.SubMenu1.1 and Administration.SubMenu1.2 are removed because of don't have permissions.
mainMenu.Items[1].Items[3].Items[1].Name.ShouldBe("Administration.SubMenu1.2");
}
[DependsOn(typeof(AbpUiNavigationModule))]
public class TestModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpNavigationOptions>(options =>
{
options.MenuContributors.Add(new TestMenuContributor1());
options.MenuContributors.Add(new TestMenuContributor2());
});
}
} }
/* Adds menu items: /* Adds menu items:
@ -65,8 +73,8 @@ namespace Volo.Abp.UI.Navigation
var administration = context.Menu.GetAdministration(); var administration = context.Menu.GetAdministration();
administration.AddItem(new ApplicationMenuItem("Administration.UserManagement", "User Management", url: "/admin/users")); administration.AddItem(new ApplicationMenuItem("Administration.UserManagement", "User Management", url: "/admin/users", requiredPermissionName: "Administration.UserManagement"));
administration.AddItem(new ApplicationMenuItem("Administration.RoleManagement", "Role Management", url: "/admin/roles")); administration.AddItem(new ApplicationMenuItem("Administration.RoleManagement", "Role Management", url: "/admin/roles", requiredPermissionName: "Administration.RoleManagement"));
return Task.CompletedTask; return Task.CompletedTask;
} }
@ -86,16 +94,16 @@ namespace Volo.Abp.UI.Navigation
return Task.CompletedTask; return Task.CompletedTask;
} }
context.Menu.Items.Insert(0, new ApplicationMenuItem("Dashboard", "Dashboard", url: "/dashboard")); context.Menu.Items.Insert(0, new ApplicationMenuItem("Dashboard", "Dashboard", url: "/dashboard", requiredPermissionName: "Dashboard"));
var administration = context.Menu.GetAdministration(); var administration = context.Menu.GetAdministration();
administration.AddItem(new ApplicationMenuItem("Administration.DashboardSettings", "Dashboard Settings", url: "/admin/settings/dashboard")); administration.AddItem(new ApplicationMenuItem("Administration.DashboardSettings", "Dashboard Settings", url: "/admin/settings/dashboard", requiredPermissionName: "Administration.DashboardSettings"));
administration.AddItem( administration.AddItem(
new ApplicationMenuItem("Administration.SubMenu1", "Sub menu 1") new ApplicationMenuItem("Administration.SubMenu1", "Sub menu 1", url: "/submenu1")
.AddItem(new ApplicationMenuItem("Administration.SubMenu1.1", "Sub menu 1.1", url: "/submenu1/submenu1_1")) .AddItem(new ApplicationMenuItem("Administration.SubMenu1.1", "Sub menu 1.1", url: "/submenu1/submenu1_1", requiredPermissionName: "Administration.SubMenu1.1"))
.AddItem(new ApplicationMenuItem("Administration.SubMenu1.2", "Sub menu 1.2", url: "/submenu1/submenu1_2")) .AddItem(new ApplicationMenuItem("Administration.SubMenu1.2", "Sub menu 1.2", url: "/submenu1/submenu1_2", requiredPermissionName: "Administration.SubMenu1.2"))
); );
return Task.CompletedTask; return Task.CompletedTask;

24
framework/test/Volo.Abp.UI.Navigation.Tests/Volo/Abp/Ui/Navigation/TestPermissionDefinitionProvider.cs

@ -0,0 +1,24 @@
using Volo.Abp.Authorization.Permissions;
namespace Volo.Abp.UI.Navigation
{
public class TestPermissionDefinitionProvider : PermissionDefinitionProvider
{
public override void Define(IPermissionDefinitionContext context)
{
var group = context.AddGroup("TestGroup");
group.AddPermission("Dashboard");
group.AddPermission("Administration");
group.AddPermission("Administration.UserManagement");
group.AddPermission("Administration.RoleManagement");
group.AddPermission("Administration.DashboardSettings");
group.AddPermission("Administration.SubMenu1");
group.AddPermission("Administration.SubMenu1.1");
group.AddPermission("Administration.SubMenu1.2");
}
}
}
Loading…
Cancel
Save