One small help before I close this issue, because I really want to use role with permissions.
So why can't the role not be found when using the IDistributedEventHandler but is when seeding data?
[UnitOfWork]
public async virtual Task HandleEventAsync(EntityCreatedEto<UserEto> eventData)
{
using (currentTenant.Change(eventData.Entity.TenantId))
{
//This never returns the roles created when I seed. I have tried to skip the using etc.
var role = await identityRoleRepository
.FindByNormalizedNameAsync(lookupNormalizer.NormalizeName(RoleConstants.TenantClientRole));
if (role is null)
{
var newRole = new IdentityRole(guidGenerator.Create(),
RoleConstants.TenantClientRole) { IsPublic = true, IsStatic = true };
await identityRoleRepository.InsertAsync(newRole, true);
}
//this will just return null
var roleNotFound = await identityRoleRepository
.FindByNormalizedNameAsync(lookupNormalizer.NormalizeName(RoleConstants.TenantClientRole));
//and then I can't AddToRoleAsync because the role is not found!
var userJustCreated = await identityUserManager.GetByIdAsync(eventData.Entity.Id);
//this throws "Role TENANTCLIENTROLE not found"
await identityUserManager.AddToRoleAsync(userJustCreated, RoleConstants.TenantClientRole);
}
}
And if I change to "null" tenant with using (currentTenant.Change(null))
I get the roles but var userJustCreated = await identityUserManager.GetByIdAsync(eventData.Entity.Id);
throws "There is no such an entity".
For completeness sake I´m able to run and seed the role with the DbMigrator with basically the same code
public async Task SeedAsync(DataSeedContext context)
{
var role = await identityRoleRepository
.FindByNormalizedNameAsync(lookupNormalizer.NormalizeName(RoleConstants.TenantClientRole));
if (role is not null)
{
return;
}
// Create the role and insert it
var newRole = new IdentityRole(guidGenerator.Create(),
RoleConstants.TenantClientRole) { IsPublic = true, IsStatic = true };
await identityRoleRepository.InsertAsync(newRole,true);
//returns the role
var roleFound = await identityRoleRepository
.FindByNormalizedNameAsync(lookupNormalizer.NormalizeName(RoleConstants.TenantClientRole));
}
Hopefully I can just close this off after this question. Thanks so much for your asstance!
Ok that was the last missing puzzle for me! Thank you!!
But I´m still not sure if I should use roles with permissions and add them to tenant or add/delete individual permissions.
I really think the roles/permissions documentation should be augmented by more scenarios and Q/A-ish code parts.
Ok I think I got it.
Should I do the following (and correct me if I´m wrong)
permissionManager.DeleteAsync("R", entity.Name);
Is that what we are talking about?
Something like this here?
[UnitOfWork]
public async virtual Task HandleEventAsync(EntityCreatedEto<UserEto> eventData)
{
var isTenant = eventData.Entity.TenantId.HasValue;
if (isTenant)
{
//Delete all the permissions
await permissionManager.DeleteAsync("R", eventData.Entity.Name);
// Give it the correct permissions
var permissions = new List<string>
{
"AbpIdentity.Roles",
"AbpIdentity.Roles.ManagePermissions",
"AbpIdentity.Users",
"AbpIdentity.OrganizationUnits",
"AbpAccount.SettingManagement",
"IdentityServer.ApiResource"
};
foreach (var perm in permissions)
{
await permissionManager.SetForRoleAsync(RoleConstants.TenantClientRole, perm, true);
//No sure about this one...
await permissionManager.SetForUserAsync(eventData.Entity.Id, perm, true);
}
}
}
I can´t see any menu yeat but thats hopefully because I havent added all the permissions. I try that out to morrow if you say that I´m on the right track
Ok but will that not remove ALL the permissions from the tenant?
I just want to remove specific things like e.g. access to the Roles under Identity but I would like to keep access to Users. Like I don't want my tenants to be messing with Language Management or Text Templates.
Am I totally missing how this works? So sorry if I´m...
Thaks I have been trying to get this to work but hitting this code does not remove the permission.
[UnitOfWork]
public async virtual Task HandleEventAsync(EntityCreatedEto<UserEto> eventData)
{
//doesn´t remove the permission
await permissionManager.DeleteAsync("AbpIdentity.Roles.ManagePermissions",eventData.Entity.Name);
}
What am I missing?
I then thought it might be related to it being a IdentityUserCreatedEto
but that code (below) is never hit.
public class TenantCreatedHandler : IDistributedEventHandler<EntityCreatedEto<IdentityUserCreatedEto>>, ITransientDependency
{
public TenantCreatedHandler(IdentityUserManager identityUserManager, IPermissionManager permissionManager)
{
this.identityUserManager = identityUserManager;
this.permissionManager = permissionManager;
}
private readonly IdentityUserManager identityUserManager;
public IPermissionManager permissionManager { get; }
[UnitOfWork]
public async virtual Task HandleEventAsync(EntityCreatedEto<IdentityUserCreatedEto> eventData)
{
//this is never hit...
var entity = await identityUserManager.GetByIdAsync(eventData.Entity.Id);
await permissionManager.DeleteAsync("AbpIdentity.Roles.ManagePermissions", entity.Name);
}
}
Ok I managed to find the issue and it was this https://github.com/abpframework/abp/issues/9579 where I hid the admin menu (just before going on a summer vacation and forgot about it)
BUT that does not negate my issue, of hiding parts of the menu
What do I use to remove these grants/permissions from the tenant?
I have tried IPermissionManager but that doesn´t do it
Here is my code where I´m trying to remove these menu items by trying to remove them from the AbpPermissionGrants table.
public class RegisteredUserHandler : IDistributedEventHandler<EntityCreatedEto<UserEto>>, ITransientDependency
{
public RegisteredUserHandler(IdentityUserManager identityUserManager, IPermissionManager permissionManager)
{
this.identityUserManager = identityUserManager;
this.permissionManager = permissionManager;
}
private readonly IdentityUserManager identityUserManager;
public IPermissionManager permissionManager { get; }
[UnitOfWork]
public async virtual Task HandleEventAsync(EntityCreatedEto<UserEto> eventData)
{
var theJustNowCreatedIdentityUser = await identityUserManager.GetByIdAsync(eventData.Entity.Id);
// Only add this OrdinaryClientRole to none tenant users!
if (!eventData.IsMultiTenant(out _))
{
var result = await identityUserManager.AddToRoleAsync(theJustNowCreatedIdentityUser, RoleConstants.OrdinaryClientRole);
}
else
{
//This does not remove anything
await permissionManager.SetForUserAsync(eventData.Entity.Id, "AbpIdentity.Roles.ManagePermissions", false);
}
}
}
Hopefully you can point me in the right direction...
I noticed (in Blazor) that the Administration side menu is missing for logged in tenant but I can still access the items, so not permission issue. I created a issue for this with more details https://support.abp.io/QA/Questions/1713/Administration-menu-missing-after-update-to-440
Here are two Blazorise GitHub issues that throw this error
Unhandled exception rendering component: Could not find 'blazorise.tooltip.updateContent'
It gets fixed after re-running the bundling tool
Allthought the bunding tool now leves the following warning "Unable to minify the file: AuthenticationService.js. Adding file to the bundle without minification."
Ok I have been looking at this and mabe creating a role and asigning it to the user when he is created is the correct way about doing this.
Here is a working sample for others to follow.
Its still unclear if I should be using IDistributedEventHandler<EntityCreatedEventData<IdentityUser>>
or IDistributedEventHandler<EntityCreatedEto<UserEto>>
. Seemy question here.
public class RegisteredUserHandler : IDistributedEventHandler<EntityCreatedEventData<IdentityUser>>, ITransientDependency
{
private readonly IPermissionManager permissionManager;
private readonly IdentityUserManager identityUserManager;
public RegisteredUserHandler(IPermissionManager permissionManager,IdentityUserManager identityUserManager)
{
this.permissionManager = permissionManager;
this.identityUserManager = identityUserManager;
}
[UnitOfWork]
public async Task HandleEventAsync(EntityCreatedEventData<IdentityUser> eventData)
{
// Add the permission to the role
await permissionManager.SetForRoleAsync("OrdinaryClientRole", "MyPermission.Client", true);
// Add the user to the role.
await identityUserManager.AddToRoleAsync(eventData.Entity, "OrdinaryClientRole");
}
}`
I will seed the role and add the permissions in one go like shown here.
You are misunderstanding this.
I´m trying to have different menu for a user that is not a Tenant and not Host.
I´m the host and Tenants can register with my system and add content that ordinary users can enjoy (for payment to me that I then monthly dish out to Tentans). The ordinary users need to be able to view collection of content from all the tenants in the system.
Did that explain it?