public class PermissionDataSeedContributor : IDataSeedContributor, ITransientDependency
{
private readonly IPermissionManager _permissionManager;
public PermissionDataSeedContributor(IPermissionManager permissionManager)
{
_permissionManager = permissionManager;
}
public async Task SeedAsync(DataSeedContext context)
{
await SeedContentPermissionsForCreatorAsync("ContentCreator");
await SeedContentPermissionsForManagerAsync("ContentManager");
await SeedRequestPermissionsForManagerAsync("ContentManager");
// Remove Test permissions from Admin
await RemoveTestContentPermissionsFromAdminAsync("admin");
}
private async Task SeedContentPermissionsForCreatorAsync(string roleName)
{
var basePermission = await _permissionManager.GetForRoleAsync(roleName, "Test.Content");
if (!basePermission.IsGranted)
{
await _permissionManager.SetForRoleAsync(roleName, "Test.Content", true);
await _permissionManager.SetForRoleAsync(roleName, "Test.Content.View", true);
await _permissionManager.SetForRoleAsync(roleName, "Test.Content.Create", true);
await _permissionManager.SetForRoleAsync(roleName, "Test.Content.Edit", true);
await _permissionManager.SetForRoleAsync(roleName, "Test.Content.Delete", true);
}
}
private async Task SeedContentPermissionsForManagerAsync(string roleName)
{
var viewPermission = await _permissionManager.GetForRoleAsync(roleName, "Test.Content.View");
if (!viewPermission.IsGranted)
{
await _permissionManager.SetForRoleAsync(roleName, "Test.Content", true);
await _permissionManager.SetForRoleAsync(roleName, "Test.Content.View", true);
await _permissionManager.SetForRoleAsync(roleName, "Test.Content.Delete", true);
}
}
private async Task SeedRequestPermissionsForManagerAsync(string roleName)
{
var requestViewPermission = await _permissionManager.GetForRoleAsync(roleName, "Test.Requests.View");
if (!requestViewPermission.IsGranted)
{
await _permissionManager.SetForRoleAsync(roleName, "Test.Requests", true);
await _permissionManager.SetForRoleAsync(roleName, "Test.Requests.View", true);
await _permissionManager.SetForRoleAsync(roleName, "Test.Requests.Approve", true);
await _permissionManager.SetForRoleAsync(roleName, "Test.Requests.Reject", true);
await _permissionManager.SetForRoleAsync(roleName, "Test.Requests.Return", true);
}
}
private async Task RemoveTestContentPermissionsFromAdminAsync(string roleName)
{
var TestPermissions = new[]
{
"Test", // Add parent permission to ensure it's removed
"Test.Content",
"Test.Content.View",
"Test.Content.Create",
"Test.Content.Edit",
"Test.Content.Delete",
"Test.Requests",
"Test.Requests.View",
"Test.Requests.Approve",
"Test.Requests.Reject",
"Test.Requests.Return"
};
foreach (var permission in TestPermissions)
{
await _permissionManager.SetForRoleAsync(roleName, permission, false);
}
}
}
}
when run migrator project it is sucees remove permissions from admin of roles ContentCreator and ContentManager permissions but if stop application and run migrator again admin has ContentCreator and ContentManager permissions not i don't use redis
private void ConfigureDistributedLocking(
ServiceConfigurationContext context,
IConfiguration configuration)
{
if (AbpStudioAnalyzeHelper.IsInAnalyzeMode)
{
return;
}
context.Services.AddSingleton<IDistributedLockProvider, NoOpDistributedLockProvider>();
//context.Services.AddSingleton<IDistributedLockProvider>(sp =>
//{
// var connection = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]!);
// return new RedisDistributedSynchronizationProvider(connection.GetDatabase());
//});
}
how to fix
8 Answer(s)
-
0
To ensure that the admin role does not regain permissions after running the migrator multiple times, you need to override the default ABP behavior that grants all permissions to the admin role during data seeding. By default, ABP's
PermissionDataSeedContributor
grants all permissions to the admin role every time seeding runs, which is why your manual removals are overwritten on each migration.Solution: You should replace the default
PermissionDataSeedContributor
with your own implementation that only grants the permissions you want. Here’s how to do it:Create a Custom PermissionDataSeedContributor: Replace the default contributor by using the
Dependency(ReplaceServices = true)
attribute and implement your own logic for seeding admin permissions.[Dependency(ReplaceServices = true)] [ExposeServices(typeof(PermissionDataSeedContributor), typeof(IDataSeedContributor))] public class MyPermissionDataSeedContributor : PermissionDataSeedContributor { public MyPermissionDataSeedContributor( IPermissionDefinitionManager permissionDefinitionManager, IPermissionDataSeeder permissionDataSeeder, ICurrentTenant currentTenant) : base(permissionDefinitionManager, permissionDataSeeder, currentTenant) { } public override Task SeedAsync(DataSeedContext context) { var multiTenancySide = CurrentTenant.GetMultiTenancySide(); var permissionNames = PermissionDefinitionManager .GetPermissions() .Where(p => p.MultiTenancySide.HasFlag(multiTenancySide)) .Where(p => !p.Providers.Any() || p.Providers.Contains(RolePermissionValueProvider.ProviderName)) .Select(p => p.Name) .Where(x => /* filter only the permissions you want admin to have */) .ToArray(); return PermissionDataSeeder.SeedAsync( RolePermissionValueProvider.ProviderName, "admin", permissionNames, context?.TenantId ); } }
- Replace the filter in
.Where(x => ...)
with your logic to select only the permissions you want the admin role to have.
- Replace the filter in
Register Your Contributor: Make sure your custom contributor is registered and the default one is replaced. This is handled by the attributes above.
Remove Manual Permission Removal: You no longer need to manually remove permissions from the admin role in your seeder, as the admin will only be granted the permissions you specify.
Why this works:
ABP’s default seeding always grants all permissions to the admin role. By replacing the default contributor, you control exactly which permissions are seeded for admin, and your changes will persist across migrations and application restarts.References:
- How to define default permissions for the admin role?
- Add permissions to Role while seeding
- ABP Data Seeding Documentation
This response was generated by AI. If it didn’t solve your problem, feel free to post a new answer — our support team will jump in to help you soon.
-
0
hi
Can you share the code of
OverrideAdminPermissionDataSeedContributor
?Thanks.
-
0
hi
Try add
[Dependency(ServiceLifetime.Transient, ReplaceServices = true)]
[Dependency(ServiceLifetime.Transient, ReplaceServices = true)] [ExposeServices(typeof(PermissionDataSeedContributor), typeof(IDataSeedContributor))] public class OverrideAdminPermissionDataSeedContributor : PermissionDataSeedContributor
-
0
hi
Can you share a project to reproduce it?
liming.ma@volosoft.com
Thanks.
-
0
hi
You don't need to add
context.Services.AddTransient<OverrideAdminPermissionDataSeedContributor>();
Can you share a project?
I will check your code.
Thanks.
-
0
hi
You can share a project that reproduces the
ComponentNotRegisteredException
, and I will review the code to determine the reason.Thanks.
-
0
Thanks. You can share it with https://wetransfer.com/
-
0
Great 👍