Redesign permission checker.

pull/216/head
Halil İbrahim Kalkan 8 years ago
parent e0544a12db
commit 82c8dce8e5

@ -1,5 +1,6 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Modularity;
using Volo.Abp.Security;
@ -14,6 +15,12 @@ namespace Volo.Abp.Authorization
services.AddSingleton<IAuthorizationHandler, PermissionRequirementHandler>();
services.Configure<PermissionOptions>(options =>
{
options.ValueProviders.Add<UserPermissionValueProvider>();
options.ValueProviders.Add<RolePermissionValueProvider>();
});
services.AddAssemblyOf<AbpAuthorizationModule>();
}
}

@ -17,7 +17,7 @@ namespace Volo.Abp.Authorization
AuthorizationHandlerContext context,
PermissionRequirement requirement)
{
if (await _permissionChecker.IsGrantedAsync(requirement.PermissionName))
if (await _permissionChecker.IsGrantedAsync(context.User, requirement.PermissionName))
{
context.Succeed(requirement);
}

@ -1,4 +1,5 @@
using System.Threading.Tasks;
using System.Security.Claims;
using System.Threading.Tasks;
namespace Volo.Abp.Authorization.Permissions
{
@ -14,5 +15,10 @@ namespace Volo.Abp.Authorization.Permissions
{
return Task.FromResult(new PermissionGrantInfo(name, true, "AlwaysAllow"));
}
public Task<PermissionGrantInfo> CheckAsync(ClaimsPrincipal claimsPrincipal, string name)
{
return Task.FromResult(new PermissionGrantInfo(name, true, "AlwaysAllow"));
}
}
}

@ -1,4 +1,5 @@
using System.Threading.Tasks;
using System.Security.Claims;
using System.Threading.Tasks;
using JetBrains.Annotations;
namespace Volo.Abp.Authorization.Permissions
@ -6,5 +7,7 @@ namespace Volo.Abp.Authorization.Permissions
public interface IPermissionChecker
{
Task<PermissionGrantInfo> CheckAsync([NotNull]string name);
Task<PermissionGrantInfo> CheckAsync([CanBeNull] ClaimsPrincipal claimsPrincipal, [NotNull]string name);
}
}

@ -7,6 +7,6 @@ namespace Volo.Abp.Authorization.Permissions
{
string Name { get; }
Task<PermissionValueProviderGrantInfo> CheckAsync(PermissionDefinition permission);
Task<PermissionValueProviderGrantInfo> CheckAsync(PermissionValueCheckContext context);
}
}

@ -1,10 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Security.Claims;
namespace Volo.Abp.Authorization.Permissions
{
@ -14,6 +17,8 @@ namespace Volo.Abp.Authorization.Permissions
protected IReadOnlyList<IPermissionValueProvider> ValueProviders => _lazyProviders.Value;
protected ICurrentPrincipalAccessor PrincipalAccessor { get; }
protected PermissionOptions Options { get; }
private readonly Lazy<List<IPermissionValueProvider>> _lazyProviders;
@ -21,8 +26,10 @@ namespace Volo.Abp.Authorization.Permissions
public PermissionChecker(
IOptions<PermissionOptions> options,
IServiceProvider serviceProvider,
ICurrentPrincipalAccessor principalAccessor,
IPermissionDefinitionManager permissionDefinitionManager)
{
PrincipalAccessor = principalAccessor;
PermissionDefinitionManager = permissionDefinitionManager;
Options = options.Value;
@ -35,25 +42,30 @@ namespace Volo.Abp.Authorization.Permissions
);
}
public Task<PermissionGrantInfo> CheckAsync(string name)
public virtual Task<PermissionGrantInfo> CheckAsync(string name)
{
var permission = PermissionDefinitionManager.Get(name);
return GetPermissionGrantInfo(permission);
return CheckAsync(PrincipalAccessor.Principal, name);
}
protected virtual async Task<PermissionGrantInfo> GetPermissionGrantInfo(PermissionDefinition permission)
public virtual async Task<PermissionGrantInfo> CheckAsync(ClaimsPrincipal claimsPrincipal, string name)
{
Check.NotNull(name, nameof(name));
var context = new PermissionValueCheckContext(
PermissionDefinitionManager.Get(name),
claimsPrincipal
);
foreach (var provider in ValueProviders)
{
var result = await provider.CheckAsync(permission);
var result = await provider.CheckAsync(context);
if (result.IsGranted)
{
return new PermissionGrantInfo(permission.Name, true, provider.Name, result.ProviderKey);
return new PermissionGrantInfo(context.Permission.Name, true, provider.Name, result.ProviderKey);
}
}
return new PermissionGrantInfo(permission.Name, false);
return new PermissionGrantInfo(context.Permission.Name, false);
}
}
}

@ -1,4 +1,5 @@
using System.Threading.Tasks;
using System.Security.Claims;
using System.Threading.Tasks;
namespace Volo.Abp.Authorization.Permissions
{
@ -9,6 +10,11 @@ namespace Volo.Abp.Authorization.Permissions
return (await permissionChecker.CheckAsync(name)).IsGranted;
}
public static async Task<bool> IsGrantedAsync(this IPermissionChecker permissionChecker, ClaimsPrincipal principal, string name)
{
return (await permissionChecker.CheckAsync(principal, name)).IsGranted;
}
//TODO: Add sync extensions
}
}

@ -0,0 +1,22 @@
using System.Security.Claims;
using JetBrains.Annotations;
namespace Volo.Abp.Authorization.Permissions
{
public class PermissionValueCheckContext
{
[NotNull]
public PermissionDefinition Permission { get; }
[CanBeNull]
public ClaimsPrincipal Principal { get; }
public PermissionValueCheckContext([NotNull] PermissionDefinition permission, [CanBeNull] ClaimsPrincipal principal)
{
Check.NotNull(permission, nameof(permission));
Permission = permission;
Principal = principal;
}
}
}

@ -13,6 +13,6 @@ namespace Volo.Abp.Authorization.Permissions
PermissionStore = permissionStore;
}
public abstract Task<PermissionValueProviderGrantInfo> CheckAsync(PermissionDefinition permission);
public abstract Task<PermissionValueProviderGrantInfo> CheckAsync(PermissionValueCheckContext context);
}
}

@ -1,8 +1,8 @@
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Security.Claims;
namespace Volo.Abp.Session
namespace Volo.Abp.Authorization.Permissions
{
public class RolePermissionValueProvider : PermissionValueProvider
{
@ -10,24 +10,23 @@ namespace Volo.Abp.Session
public override string Name => ProviderName;
protected ICurrentUser CurrentUser { get; }
public RolePermissionValueProvider(IPermissionStore permissionStore, ICurrentUser currentUser)
public RolePermissionValueProvider(IPermissionStore permissionStore)
: base(permissionStore)
{
CurrentUser = currentUser;
}
public override async Task<PermissionValueProviderGrantInfo> CheckAsync(PermissionDefinition permission)
public override async Task<PermissionValueProviderGrantInfo> CheckAsync(PermissionValueCheckContext context)
{
if (CurrentUser.Id == null || !CurrentUser.Roles.Any())
var roles = context.Principal?.FindAll(AbpClaimTypes.Role).Select(c => c.Value).ToArray();
if (roles == null || !roles.Any())
{
return PermissionValueProviderGrantInfo.NonGranted;
}
foreach (var role in CurrentUser.Roles)
foreach (var role in roles)
{
if (await PermissionStore.IsGrantedAsync(permission.Name, Name, role))
if (await PermissionStore.IsGrantedAsync(context.Permission.Name, Name, role))
{
return new PermissionValueProviderGrantInfo(true, role);
}

@ -1,7 +1,7 @@
using System.Threading.Tasks;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Security.Claims;
namespace Volo.Abp.Session
namespace Volo.Abp.Authorization.Permissions
{
public class UserPermissionValueProvider : PermissionValueProvider
{
@ -9,25 +9,27 @@ namespace Volo.Abp.Session
public override string Name => ProviderName;
protected ICurrentUser CurrentUser { get; }
public UserPermissionValueProvider(IPermissionStore permissionStore, ICurrentUser currentUser)
public UserPermissionValueProvider(IPermissionStore permissionStore)
: base(permissionStore)
{
CurrentUser = currentUser;
}
public override async Task<PermissionValueProviderGrantInfo> CheckAsync(PermissionDefinition permission)
public override async Task<PermissionValueProviderGrantInfo> CheckAsync(PermissionValueCheckContext context)
{
if (CurrentUser.Id == null)
var userId = context.Principal?.FindFirst(AbpClaimTypes.UserId)?.Value;
if (userId == null)
{
return PermissionValueProviderGrantInfo.NonGranted;
}
return new PermissionValueProviderGrantInfo(
await PermissionStore.IsGrantedAsync(permission.Name, Name, CurrentUser.Id.Value.ToString()),
CurrentUser.Id.ToString()
);
if (await PermissionStore.IsGrantedAsync(context.Permission.Name, Name, userId))
{
return new PermissionValueProviderGrantInfo(true, userId);
}
return PermissionValueProviderGrantInfo.NonGranted;
}
}
}

@ -1,4 +1,5 @@
using Volo.Abp.Guids;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Guids;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Permissions;
using Volo.Abp.Session;

@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Session;
namespace Volo.Abp.Permissions

@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Session;
namespace Volo.Abp.Permissions

@ -14,8 +14,6 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Authorization\Volo.Abp.Authorization.csproj" />
<ProjectReference Include="..\Volo.Abp.Core\Volo.Abp.Core.csproj" />
<ProjectReference Include="..\Volo.Abp.Security\Volo.Abp.Security.csproj" />
<ProjectReference Include="..\Volo.Abp.Settings\Volo.Abp.Settings.csproj" />
</ItemGroup>

@ -1,6 +1,4 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Authorization;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Modularity;
using Volo.Abp.Security;
using Volo.Abp.Settings;
@ -9,7 +7,6 @@ namespace Volo.Abp.Session
{
[DependsOn(typeof(AbpSecurityModule))]
[DependsOn(typeof(AbpSettingsModule))]
[DependsOn(typeof(AbpAuthorizationModule))]
public class AbpSessionModule : AbpModule
{
public override void ConfigureServices(IServiceCollection services)
@ -19,12 +16,6 @@ namespace Volo.Abp.Session
options.ValueProviders.Add<UserSettingValueProvider>();
});
services.Configure<PermissionOptions>(options =>
{
options.ValueProviders.Add<UserPermissionValueProvider>();
options.ValueProviders.Add<RolePermissionValueProvider>();
});
services.AddAssemblyOf<AbpSessionModule>();
}
}

@ -6,6 +6,8 @@ using Volo.Abp.Session;
namespace Volo.Abp.Settings
{
//TODO: Consider to move to another package?
public static class UserSettingManagerExtensions
{
public static Task<string> GetOrNullForUserAsync(this ISettingManager settingManager, [NotNull] string name, Guid userId, bool fallback = true)

@ -1,4 +1,5 @@
using Volo.Abp.DependencyInjection;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
using Volo.Abp.Permissions;
using Volo.Abp.Session;

@ -1,9 +1,11 @@
using System;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using NSubstitute;
using Shouldly;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Security.Claims;
using Volo.Abp.Session;
using Xunit;
@ -13,26 +15,16 @@ namespace Volo.Abp.Permissions
{
private readonly IPermissionChecker _permissionChecker;
private Guid? _currentUserId;
public PermissionChecker_User_Tests()
{
_permissionChecker = GetRequiredService<IPermissionChecker>();
}
protected override void AfterAddApplication(IServiceCollection services)
{
var currentUser = Substitute.For<ICurrentUser>();
currentUser.Id.Returns(ci => _currentUserId);
services.AddSingleton(currentUser);
}
[Fact]
public async Task Should_Return_True_For_Granted_Current_User()
{
_currentUserId = PermissionTestDataBuilder.User1Id;
(await _permissionChecker.IsGrantedAsync(
CreatePrincipal(PermissionTestDataBuilder.User1Id),
"MyPermission1"
)).ShouldBeTrue();
}
@ -40,9 +32,8 @@ namespace Volo.Abp.Permissions
[Fact]
public async Task Should_Return_False_For_Non_Granted_Current_User()
{
_currentUserId = PermissionTestDataBuilder.User2Id;
(await _permissionChecker.IsGrantedAsync(
CreatePrincipal(PermissionTestDataBuilder.User2Id),
"MyPermission1"
)).ShouldBeFalse();
}
@ -51,8 +42,21 @@ namespace Volo.Abp.Permissions
public async Task Should_Return_False_For_Current_User_If_Anonymous()
{
(await _permissionChecker.IsGrantedAsync(
CreatePrincipal(null),
"MyPermission1"
)).ShouldBeFalse();
}
private static ClaimsPrincipal CreatePrincipal(Guid? userId)
{
var claimsIdentity = new ClaimsIdentity();
if (userId != null)
{
claimsIdentity.AddClaim(new Claim(AbpClaimTypes.UserId, userId.ToString()));
}
return new ClaimsPrincipal(claimsIdentity);
}
}
}

@ -1,4 +1,5 @@
using System;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
using Volo.Abp.Session;

Loading…
Cancel
Save