Open Closed

Administration menu missing (after update to 4.4.0) #1713


User avatar
1
Sturla created

I just noticed that the administration side menu has completely vanished! If I create a new tenant and log-in never shows up.

BUT I still can navigate to say /idenity/users and access the pages so its not any access control issue.

Here you can see that there is no Administration dropdown in the sidemenu (I know I should have cropped less from the names but trust me, its not there).

I have gone over everything multiple times and I can´t see anywhere that I´m to blame!

No problem sending someone my solution to check this out.

  • ABP Framework version: 4.4.0
  • UI type: Blazor
  • DB provider: EF Core
  • Identity Server Separated: yes

16 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Can you try to using the brand new 4.4 template project?

    Or refresh the page maybe help.

  • User Avatar
    0
    Sturla created

    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...

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    What do I use to remove these grants/permissions from the tenant?

    You can refer to RoleDeletedEventHandler

    https://github.com/abpframework/abp/blob/48c52625f4c4df007f04d5ac6368b07411aa7521/modules/identity/src/Volo.Abp.PermissionManagement.Domain.Identity/Volo/Abp/PermissionManagement/Identity/RoleDeletedEventHandler.cs#L24

  • User Avatar
    0
    Sturla created

    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);
        }
    }
    
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    The providerName of the AbpIdentity.Roles.ManagePermissions is R, The providerKey is admin.

    Task DeleteAsync(string providerName, string providerKey);
    

  • User Avatar
    0
    Sturla created

    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...

  • User Avatar
    0
    Sturla created

    Ok I think I got it.

    Should I do the following (and correct me if I´m wrong)

    1. On Tenant created: Delete all the given role permissions the user has, using permissionManager.DeleteAsync("R", entity.Name);
    2. Create a new role containing the permissions I want a tenant to have. (do this at db seeding)
    3. Add this user to the new role

    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

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    using (CurrentTenant.Change(TargetTenantId))
    {   
        //delete permissionName.
        permissionManager.SetAsync(string permissionName, string providerName, string providerKey, bool isGranted false)
    
        //delete all permissions.
        permissionManager.DeleteAsync(string providerName, string providerKey);
    }
    
  • User Avatar
    0
    Sturla created

    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.

  • User Avatar
    0
    Sturla created

    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!

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    Maybe the SeedAsync method exec in Host side. Can you check the database?

  • User Avatar
    0
    Sturla created

    Yes that is what I gathered

    If I change the tenant to nul l I get the roles

    [UnitOfWork]
    public async virtual Task HandleEventAsync(EntityCreatedEto<UserEto> eventData)
    {
        using (currentTenant.Change(null)) 
        {  
        var roleNotFound = await identityRoleRepository         
            .FindByNormalizedNameAsync(lookupNormalizer
            .NormalizeName(RoleConstants.TenantClientRole));
        }
    }
    

    BUT then I can´t add the role becuse the created user is not found

    // this then throws
    var userJustCreated = await identityUserManager.GetByIdAsync(eventData.Entity.Id/TenantId);
       
    // this
    'There is no such an entity. Entity type: Volo.Abp.Identity.IdentityUser, id: 7f7acfe7-4abe-2a43-f31f-39fe74a2a237'
    

    What secret sauce/steps do I need?

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi Sturla

    Can you share a project and steps to show your question? : ) https://abp.io/get-started

  • User Avatar
    0
    Sturla created

    Here it is but the "create a tenant UI" is missing (not sure how the open source version works) so I couldn´t try that out.

    I added some information to the Readme file but I hope this is all self explanatory what I´m trying to do.

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer
    1. Use virtual in SeedAsync method.
    [UnitOfWork]
    public virtual async Task SeedAsync(DataSeedContext context)
    
    1. Pass the eventData.Entity.TenantId to create new role
    var newRole = new IdentityRole(guidGenerator.Create(), RolesDemoConstants.SelfServiceTenantClientRole, eventData.Entity.TenantId) { IsPublic = true, IsStatic = true };
    
    
  • User Avatar
    0
    Sturla created

    Bingo! That seems to have solved the problem! Thanks for your patiance with me ;-)

Made with ❤️ on ABP v9.1.0-preview. Updated on November 11, 2024, 11:11