Skip to content

Commit

Permalink
Add MenuContributorBase to check permissions in advance.
Browse files Browse the repository at this point in the history
Resolve #7788
  • Loading branch information
maliming committed Feb 22, 2021
1 parent 0b3fea1 commit 3b5e9b7
Show file tree
Hide file tree
Showing 7 changed files with 160 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Threading.Tasks;

namespace Volo.Abp.UI.Navigation
{
public abstract class MenuContributorBase : IMenuContributor
{
public List<string> PreCheckPermissions { get; }
public IReadOnlyList<string> GrantedPermissions => _grantedPermissions.ToImmutableList();
private readonly List<string> _grantedPermissions;

protected MenuContributorBase()
{
PreCheckPermissions = new List<string>();
_grantedPermissions = new List<string>();
}

public void AddGrantedPermission(string permission)
{
_grantedPermissions.Add(permission);
}

public abstract Task ConfigureMenuAsync(MenuConfigurationContext context);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.DependencyInjection;

namespace Volo.Abp.UI.Navigation
Expand All @@ -13,7 +15,7 @@ public class MenuManager : IMenuManager, ITransientDependency
protected IHybridServiceScopeFactory ServiceScopeFactory { get; }

public MenuManager(
IOptions<AbpNavigationOptions> options,
IOptions<AbpNavigationOptions> options,
IHybridServiceScopeFactory serviceScopeFactory)
{
ServiceScopeFactory = serviceScopeFactory;
Expand All @@ -28,6 +30,26 @@ public async Task<ApplicationMenu> GetAsync(string name)
{
var context = new MenuConfigurationContext(menu, scope.ServiceProvider);

var menuContributorBases = Options.MenuContributors.OfType<MenuContributorBase>().ToList();
var preCheckPermissions = menuContributorBases.SelectMany(x => x.PreCheckPermissions).ToArray();

if (preCheckPermissions.Any())
{
var permissionChecker = context.ServiceProvider.GetRequiredService<IPermissionChecker>();
var grantResult = await permissionChecker.IsGrantedAsync(preCheckPermissions);

foreach (var menuContributorBase in menuContributorBases)
{
foreach (var result in grantResult.Result.Where(x => menuContributorBase.PreCheckPermissions.Contains(x.Key)))
{
if (result.Value == PermissionGrantResult.Granted)
{
menuContributorBase.AddGrantedPermission(result.Key);
}
}
}
}

foreach (var contributor in Options.MenuContributors)
{
await contributor.ConfigureMenuAsync(context);
Expand All @@ -49,4 +71,4 @@ protected virtual void NormalizeMenu(IHasMenuItems menuWithItems)
menuWithItems.Items.Normalize();
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<ItemGroup>
<ProjectReference Include="..\..\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" />
<ProjectReference Include="..\..\src\Volo.Abp.ExceptionHandling\Volo.Abp.ExceptionHandling.csproj" />
<ProjectReference Include="..\..\src\Volo.Abp.UI.Navigation\Volo.Abp.UI.Navigation.csproj" />
<ProjectReference Include="..\AbpTestBase\AbpTestBase.csproj" />
<ProjectReference Include="..\..\src\Volo.Abp.Authorization\Volo.Abp.Authorization.csproj" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@
using Volo.Abp.DynamicProxy;
using Volo.Abp.ExceptionHandling;
using Volo.Abp.Modularity;
using Volo.Abp.UI.Navigation;

namespace Volo.Abp.Authorization
{
[DependsOn(typeof(AbpAutofacModule))]
[DependsOn(typeof(AbpAuthorizationModule))]
[DependsOn(typeof(AbpExceptionHandlingModule))]
[DependsOn(typeof(AbpUiNavigationModule))]
public class AbpAuthorizationTestModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using System.Threading.Tasks;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.DependencyInjection;

namespace Volo.Abp.Authorization
{
public class FakePermissionStore : IPermissionStore, ITransientDependency
{
public Task<bool> IsGrantedAsync(string name, string providerName, string providerKey)
{
var result = name == "MenuPermission1" || name == "MenuPermission4";
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 == "MenuPermission1" || name == "MenuPermission4"
? PermissionGrantResult.Granted
: PermissionGrantResult.Prohibited);
}

return Task.FromResult(result);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using Volo.Abp.UI.Navigation;
using Xunit;

namespace Volo.Abp.Authorization
{
public class MenuContributorPermission_Test : AuthorizationTestBase
{
public static readonly List<string> GrantedPermissions = new List<string>();
private readonly IMenuManager _menuManager;

public MenuContributorPermission_Test()
{
_menuManager = GetRequiredService<IMenuManager>();
}

protected override void AfterAddApplication(IServiceCollection services)
{
services.Configure<AbpNavigationOptions>(options =>
{
options.MenuContributors.Add(new TestMenuContributor1());
options.MenuContributors.Add(new TestMenuContributor2());
});

base.AfterAddApplication(services);
}

[Fact]
public async Task Should_Check_MenuContributor_PreCheckPermissions()
{
await _menuManager.GetAsync(StandardMenus.Main);

GrantedPermissions.Count.ShouldBe(2);
GrantedPermissions.ShouldContain("MenuPermission1");
GrantedPermissions.ShouldContain("MenuPermission4");
}

class TestMenuContributor1 : MenuContributorBase
{
public TestMenuContributor1()
{
PreCheckPermissions.Add("MenuPermission1");
PreCheckPermissions.Add("MenuPermission2");
}

public override Task ConfigureMenuAsync(MenuConfigurationContext context)
{
MenuContributorPermission_Test.GrantedPermissions.AddRange(GrantedPermissions);

return Task.CompletedTask;
}
}

class TestMenuContributor2 : MenuContributorBase
{
public TestMenuContributor2()
{
PreCheckPermissions.Add("MenuPermission3");
PreCheckPermissions.Add("MenuPermission4");
}

public override Task ConfigureMenuAsync(MenuConfigurationContext context)
{
MenuContributorPermission_Test.GrantedPermissions.AddRange(GrantedPermissions);

return Task.CompletedTask;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,16 @@ public override void Define(IPermissionDefinitionContext context)
{
getGroup = context.AddGroup("TestGetGroup");
}

var group = context.AddGroup("TestGroup");

group.AddPermission("MyAuthorizedService1");

group.AddPermission("MenuPermission1");
group.AddPermission("MenuPermission2");
group.AddPermission("MenuPermission3");
group.AddPermission("MenuPermission4");

group.GetPermissionOrNull("MyAuthorizedService1").ShouldNotBeNull();

context.RemoveGroup("TestGetGroup");
Expand Down

0 comments on commit 3b5e9b7

Please sign in to comment.