Browse Source

Add resource-based permission to PermissionDefinition system.

pull/24374/head
maliming 7 months ago
parent
commit
4c35fc9759
No known key found for this signature in database GPG Key ID: A646B9CB645ECEA4
  1. 8
      framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/ICanAddChildPermission.cs
  2. 39
      framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs
  3. 30
      framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionGroupDefinition.cs
  4. 14
      framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionType.cs
  5. 10
      modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/PermissionGrantConsts.cs
  6. 5
      modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionDefinitionRecord.cs
  7. 21
      modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionDefinitionSerializer.cs
  8. 52
      modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionGrant.cs
  9. 17
      modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/AbpPermissionManagementDbContextModelBuilderExtensions.cs
  10. 6
      modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/IPermissionManagementDbContext.cs
  11. 1
      modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/PermissionManagementDbContext.cs
  12. 9
      modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/AbpPermissionManagementMongoDbContextExtensions.cs
  13. 6
      modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/IPermissionManagementMongoDbContext.cs
  14. 1
      modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/PermissionManagementMongoDbContext.cs
  15. 3
      modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/CalculateHash_Tests.cs

8
framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/ICanAddChildPermission.cs

@ -11,4 +11,10 @@ public interface ICanAddChildPermission
ILocalizableString? displayName = null,
MultiTenancySides multiTenancySide = MultiTenancySides.Both,
bool isEnabled = true);
}
PermissionDefinition AddResourcePermission(
[NotNull] string name,
ILocalizableString? displayName = null,
MultiTenancySides multiTenancySide = MultiTenancySides.Both,
bool isEnabled = true);
}

39
framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionDefinition.cs

@ -7,7 +7,7 @@ using Volo.Abp.SimpleStateChecking;
namespace Volo.Abp.Authorization.Permissions;
public class PermissionDefinition :
public class PermissionDefinition :
IHasSimpleStateCheckers<PermissionDefinition>,
ICanAddChildPermission
{
@ -16,6 +16,11 @@ public class PermissionDefinition :
/// </summary>
public string Name { get; }
/// <summary>
/// Type of the permission.
/// </summary>
public PermissionType Type { get; set; }
/// <summary>
/// Parent of this permission if one exists.
/// If set, this permission can be granted only if parent is granted.
@ -78,11 +83,13 @@ public class PermissionDefinition :
protected internal PermissionDefinition(
[NotNull] string name,
PermissionType type = PermissionType.UserBased,
ILocalizableString? displayName = null,
MultiTenancySides multiTenancySide = MultiTenancySides.Both,
bool isEnabled = true)
{
Name = Check.NotNull(name, nameof(name));
Type = type;
DisplayName = displayName ?? new FixedLocalizableString(name);
MultiTenancySide = multiTenancySide;
IsEnabled = isEnabled;
@ -98,9 +105,25 @@ public class PermissionDefinition :
ILocalizableString? displayName = null,
MultiTenancySides multiTenancySide = MultiTenancySides.Both,
bool isEnabled = true)
{
return AddChild(
name,
PermissionType.UserBased,
displayName,
multiTenancySide,
isEnabled);
}
public virtual PermissionDefinition AddChild(
[NotNull] string name,
PermissionType type,
ILocalizableString? displayName = null,
MultiTenancySides multiTenancySide = MultiTenancySides.Both,
bool isEnabled = true)
{
var child = new PermissionDefinition(
name,
type,
displayName,
multiTenancySide,
isEnabled)
@ -109,21 +132,29 @@ public class PermissionDefinition :
};
child[PermissionDefinitionContext.KnownPropertyNames.CurrentProviderName] = this[PermissionDefinitionContext.KnownPropertyNames.CurrentProviderName];
_children.Add(child);
return child;
}
PermissionDefinition ICanAddChildPermission.AddPermission(
string name,
ILocalizableString? displayName = null,
MultiTenancySides multiTenancySide = MultiTenancySides.Both,
bool isEnabled = true)
{
return this.AddChild(name, displayName, multiTenancySide, isEnabled);
return this.AddChild(name, PermissionType.ResourceBased, displayName, multiTenancySide, isEnabled);
}
PermissionDefinition ICanAddChildPermission.AddResourcePermission(
string name,
ILocalizableString? displayName = null,
MultiTenancySides multiTenancySide = MultiTenancySides.Both,
bool isEnabled = true)
{
return this.AddChild(name, PermissionType.ResourceBased, displayName, multiTenancySide, isEnabled);
}
/// <summary>
/// Sets a property in the <see cref="Properties"/> dictionary.

30
framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionGroupDefinition.cs

@ -53,9 +53,39 @@ public class PermissionGroupDefinition : ICanAddChildPermission
ILocalizableString? displayName = null,
MultiTenancySides multiTenancySide = MultiTenancySides.Both,
bool isEnabled = true)
{
return AddPermission(
name,
PermissionType.UserBased,
displayName,
multiTenancySide,
isEnabled);
}
public virtual PermissionDefinition AddResourcePermission(
[NotNull] string name,
ILocalizableString? displayName = null,
MultiTenancySides multiTenancySide = MultiTenancySides.Both,
bool isEnabled = true)
{
return AddPermission(
name,
PermissionType.ResourceBased,
displayName,
multiTenancySide,
isEnabled);
}
protected virtual PermissionDefinition AddPermission(
[NotNull] string name,
PermissionType type,
ILocalizableString? displayName = null,
MultiTenancySides multiTenancySide = MultiTenancySides.Both,
bool isEnabled = true)
{
var permission = new PermissionDefinition(
name,
type,
displayName,
multiTenancySide,
isEnabled

14
framework/src/Volo.Abp.Authorization.Abstractions/Volo/Abp/Authorization/Permissions/PermissionType.cs

@ -0,0 +1,14 @@
namespace Volo.Abp.Authorization.Permissions;
public enum PermissionType
{
/// <summary>
/// Based on user(roles/claims).
/// </summary>
UserBased = 0,
/// <summary>
/// Based on resource(entities).
/// </summary>
ResourceBased = 1
}

10
modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/PermissionGrantConsts.cs

@ -11,4 +11,14 @@ public static class PermissionGrantConsts
/// Default value: 64
/// </summary>
public static int MaxProviderKeyLength { get; set; } = 64;
/// <summary>
/// Default value: 256
/// </summary>
public static int MaxResourceNameLength { get; set; } = 256;
/// <summary>
/// Default value: 256
/// </summary>
public static int MaxResourceKeyLength { get; set; } = 256;
}

5
modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionDefinitionRecord.cs

@ -1,4 +1,5 @@
using System;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Data;
using Volo.Abp.Domain.Entities;
using Volo.Abp.MultiTenancy;
@ -11,6 +12,8 @@ public class PermissionDefinitionRecord : BasicAggregateRoot<Guid>, IHasExtraPro
public string Name { get; set; }
public PermissionType Type { get; set; }
public string ParentName { get; set; }
public string DisplayName { get; set; }
@ -41,6 +44,7 @@ public class PermissionDefinitionRecord : BasicAggregateRoot<Guid>, IHasExtraPro
Guid id,
string groupName,
string name,
PermissionType type,
string parentName,
string displayName,
bool isEnabled = true,
@ -51,6 +55,7 @@ public class PermissionDefinitionRecord : BasicAggregateRoot<Guid>, IHasExtraPro
{
GroupName = Check.NotNullOrWhiteSpace(groupName, nameof(groupName), PermissionGroupDefinitionRecordConsts.MaxNameLength);
Name = Check.NotNullOrWhiteSpace(name, nameof(name), PermissionDefinitionRecordConsts.MaxNameLength);
Type = type;
ParentName = Check.Length(parentName, nameof(parentName), PermissionDefinitionRecordConsts.MaxNameLength);
DisplayName = Check.NotNullOrWhiteSpace(displayName, nameof(displayName), PermissionDefinitionRecordConsts.MaxDisplayNameLength);
IsEnabled = isEnabled;

21
modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/PermissionDefinitionSerializer.cs

@ -19,7 +19,7 @@ public class PermissionDefinitionSerializer : IPermissionDefinitionSerializer, I
public PermissionDefinitionSerializer(
IGuidGenerator guidGenerator,
ISimpleStateCheckerSerializer stateCheckerSerializer,
ISimpleStateCheckerSerializer stateCheckerSerializer,
ILocalizableStringSerializer localizableStringSerializer)
{
StateCheckerSerializer = stateCheckerSerializer;
@ -27,16 +27,16 @@ public class PermissionDefinitionSerializer : IPermissionDefinitionSerializer, I
GuidGenerator = guidGenerator;
}
public async Task<(PermissionGroupDefinitionRecord[], PermissionDefinitionRecord[])>
public async Task<(PermissionGroupDefinitionRecord[], PermissionDefinitionRecord[])>
SerializeAsync(IEnumerable<PermissionGroupDefinition> permissionGroups)
{
var permissionGroupRecords = new List<PermissionGroupDefinitionRecord>();
var permissionRecords = new List<PermissionDefinitionRecord>();
foreach (var permissionGroup in permissionGroups)
{
permissionGroupRecords.Add(await SerializeAsync(permissionGroup));
foreach (var permission in permissionGroup.GetPermissionsWithChildren())
{
permissionRecords.Add(await SerializeAsync(permission, permissionGroup));
@ -45,7 +45,7 @@ public class PermissionDefinitionSerializer : IPermissionDefinitionSerializer, I
return (permissionGroupRecords.ToArray(), permissionRecords.ToArray());
}
public Task<PermissionGroupDefinitionRecord> SerializeAsync(PermissionGroupDefinition permissionGroup)
{
using (CultureHelper.Use(CultureInfo.InvariantCulture))
@ -60,11 +60,11 @@ public class PermissionDefinitionSerializer : IPermissionDefinitionSerializer, I
{
permissionGroupRecord.SetProperty(property.Key, property.Value);
}
return Task.FromResult(permissionGroupRecord);
}
}
public Task<PermissionDefinitionRecord> SerializeAsync(
PermissionDefinition permission,
PermissionGroupDefinition permissionGroup)
@ -75,6 +75,7 @@ public class PermissionDefinitionSerializer : IPermissionDefinitionSerializer, I
GuidGenerator.Create(),
permissionGroup?.Name,
permission.Name,
permission.Type,
permission.Parent?.Name,
LocalizableStringSerializer.Serialize(permission.DisplayName),
permission.IsEnabled,
@ -87,11 +88,11 @@ public class PermissionDefinitionSerializer : IPermissionDefinitionSerializer, I
{
permissionRecord.SetProperty(property.Key, property.Value);
}
return Task.FromResult(permissionRecord);
}
}
protected virtual string SerializeProviders(ICollection<string> providers)
{
return providers.Any()
@ -103,4 +104,4 @@ public class PermissionDefinitionSerializer : IPermissionDefinitionSerializer, I
{
return StateCheckerSerializer.Serialize(stateCheckers);
}
}
}

52
modules/permission-management/src/Volo.Abp.PermissionManagement.Domain/Volo/Abp/PermissionManagement/ResourcePermissionGrant.cs

@ -0,0 +1,52 @@
using System;
using JetBrains.Annotations;
using Volo.Abp.Domain.Entities;
using Volo.Abp.MultiTenancy;
namespace Volo.Abp.PermissionManagement;
//TODO: To aggregate root?
public class ResourcePermissionGrant : Entity<Guid>, IMultiTenant
{
public virtual Guid? TenantId { get; protected set; }
[NotNull]
public virtual string Name { get; protected set; }
[NotNull]
public virtual string ProviderName { get; protected set; }
[CanBeNull]
public virtual string ProviderKey { get; protected internal set; }
[NotNull]
public virtual string ResourceName { get; protected set; }
[NotNull]
public virtual string ResourceKey { get; protected set; }
protected ResourcePermissionGrant()
{
}
public ResourcePermissionGrant(
Guid id,
[NotNull] string name,
[NotNull] string providerName,
[CanBeNull] string providerKey,
[NotNull] string resourceName,
[NotNull] string resourceKey,
Guid? tenantId = null)
{
Check.NotNull(name, nameof(name));
Id = id;
Name = Check.NotNullOrWhiteSpace(name, nameof(name));
ProviderName = Check.NotNullOrWhiteSpace(providerName, nameof(providerName));
ProviderKey = providerKey;
ResourceName = Check.NotNullOrWhiteSpace(resourceName, nameof(resourceName));
ResourceKey = Check.NotNullOrWhiteSpace(resourceKey, nameof(resourceKey));
TenantId = tenantId;
}
}

17
modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/AbpPermissionManagementDbContextModelBuilderExtensions.cs

@ -27,6 +27,23 @@ public static class AbpPermissionManagementDbContextModelBuilderExtensions
b.ApplyObjectExtensionMappings();
});
builder.Entity<ResourcePermissionGrant>(b =>
{
b.ToTable(AbpPermissionManagementDbProperties.DbTablePrefix + "ResourcePermissionGrants", AbpPermissionManagementDbProperties.DbSchema);
b.ConfigureByConvention();
b.Property(x => x.Name).HasMaxLength(PermissionDefinitionRecordConsts.MaxNameLength).IsRequired();
b.Property(x => x.ProviderName).HasMaxLength(PermissionGrantConsts.MaxProviderNameLength).IsRequired();
b.Property(x => x.ProviderKey).HasMaxLength(PermissionGrantConsts.MaxProviderKeyLength).IsRequired();
b.Property(x => x.ResourceName).HasMaxLength(PermissionGrantConsts.MaxResourceNameLength).IsRequired();
b.Property(x => x.ResourceKey).HasMaxLength(PermissionGrantConsts.MaxResourceKeyLength).IsRequired();
b.HasIndex(x => new { x.TenantId, x.Name, x.ProviderName, x.ProviderKey, x.ResourceName, x.ResourceKey }).IsUnique();
b.ApplyObjectExtensionMappings();
});
if (builder.IsHostDatabase())
{
builder.Entity<PermissionGroupDefinitionRecord>(b =>

6
modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/IPermissionManagementDbContext.cs

@ -8,8 +8,10 @@ namespace Volo.Abp.PermissionManagement.EntityFrameworkCore;
public interface IPermissionManagementDbContext : IEfCoreDbContext
{
DbSet<PermissionGroupDefinitionRecord> PermissionGroups { get; }
DbSet<PermissionDefinitionRecord> Permissions { get; }
DbSet<PermissionGrant> PermissionGrants { get; }
DbSet<ResourcePermissionGrant> ResourcePermissionGrants { get; }
}

1
modules/permission-management/src/Volo.Abp.PermissionManagement.EntityFrameworkCore/Volo/Abp/PermissionManagement/EntityFrameworkCore/PermissionManagementDbContext.cs

@ -10,6 +10,7 @@ public class PermissionManagementDbContext : AbpDbContext<PermissionManagementDb
public DbSet<PermissionGroupDefinitionRecord> PermissionGroups { get; set; }
public DbSet<PermissionDefinitionRecord> Permissions { get; set; }
public DbSet<PermissionGrant> PermissionGrants { get; set; }
public DbSet<ResourcePermissionGrant> ResourcePermissionGrants { get; set; }
public PermissionManagementDbContext(DbContextOptions<PermissionManagementDbContext> options)
: base(options)

9
modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/AbpPermissionManagementMongoDbContextExtensions.cs

@ -13,15 +13,20 @@ public static class AbpPermissionManagementMongoDbContextExtensions
{
b.CollectionName = AbpPermissionManagementDbProperties.DbTablePrefix + "PermissionGroups";
});
builder.Entity<PermissionDefinitionRecord>(b =>
{
b.CollectionName = AbpPermissionManagementDbProperties.DbTablePrefix + "Permissions";
});
builder.Entity<PermissionGrant>(b =>
{
b.CollectionName = AbpPermissionManagementDbProperties.DbTablePrefix + "PermissionGrants";
});
builder.Entity<ResourcePermissionGrant>(b =>
{
b.CollectionName = AbpPermissionManagementDbProperties.DbTablePrefix + "ResourcePermissionGrants";
});
}
}

6
modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/IPermissionManagementMongoDbContext.cs

@ -8,8 +8,10 @@ namespace Volo.Abp.PermissionManagement.MongoDB;
public interface IPermissionManagementMongoDbContext : IAbpMongoDbContext
{
IMongoCollection<PermissionGroupDefinitionRecord> PermissionGroups { get; }
IMongoCollection<PermissionDefinitionRecord> Permissions { get; }
IMongoCollection<PermissionGrant> PermissionGrants { get; }
IMongoCollection<ResourcePermissionGrant> ResourcePermissionGrants { get; }
}

1
modules/permission-management/src/Volo.Abp.PermissionManagement.MongoDB/Volo/Abp/PermissionManagement/MongoDb/PermissionManagementMongoDbContext.cs

@ -10,6 +10,7 @@ public class PermissionManagementMongoDbContext : AbpMongoDbContext, IPermission
public IMongoCollection<PermissionGroupDefinitionRecord> PermissionGroups => Collection<PermissionGroupDefinitionRecord>();
public IMongoCollection<PermissionDefinitionRecord> Permissions => Collection<PermissionDefinitionRecord>();
public IMongoCollection<PermissionGrant> PermissionGrants => Collection<PermissionGrant>();
public IMongoCollection<ResourcePermissionGrant> ResourcePermissionGrants => Collection<ResourcePermissionGrant>();
protected override void CreateModel(IMongoModelBuilder modelBuilder)
{

3
modules/permission-management/test/Volo.Abp.PermissionManagement.Domain.Tests/Volo/Abp/PermissionManagement/CalculateHash_Tests.cs

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization.Metadata;
using Shouldly;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Json.SystemTextJson.Modifiers;
using Xunit;
@ -34,7 +35,7 @@ public class CalculateHash_Tests: PermissionTestBase
json.ShouldNotContain(id.ToString("D"));
json = JsonSerializer.Serialize(new List<PermissionDefinitionRecord>()
{
new PermissionDefinitionRecord(id, "Test", "Test", "Test", "Test")
new PermissionDefinitionRecord(id, "Test", "Test", PermissionType.UserBased, "Test", "Test")
},
jsonSerializerOptions);
json.ShouldNotContain("\"Id\"");

Loading…
Cancel
Save