Create local administrators does not work as intended

Hi

Encountered an issue while trying to replicate the solution described to setup Local Administrators in documentation.

This is not working as intended : “All created users, including the local administrators, will get the local_user role”.

Local admin will have the role because this user is created by admin (no restrictions), but if local admin creates a user (which is the final purpose), the role will not be assigned to new user despite being set as defaultRole.

This is because of the restriction on sec$Role in the access group of local admin: ({E}.description is null or {E}.description not like ‘[hide]’). This also applies to local admin, so when he/she creates a new user the following code from “UserEditor” will not work as intended.

    protected void initNewItem(User item) {
        addDefaultRoles(item);
        item.setLanguage(messages.getTools().localeToString(userSession.getLocale()));
        initUserGroup(item);
    }

 protected void addDefaultRoles(User user) {
        LoadContext<Role> ctx = new LoadContext<>(Role.class);
        ctx.setQueryString("select r from sec$Role r where r.defaultRole = true");
        List<Role> defaultRoles = dataSupplier.loadList(ctx);

        List<UserRole> newRoles = new ArrayList<>();
        if (user.getUserRoles() != null) {
            newRoles.addAll(user.getUserRoles());
        }

        MetaClass metaClass = rolesDs.getMetaClass();
        for (Role role : defaultRoles) {
            UserRole userRole = dataSupplier.newInstance(metaClass);
            userRole.setRole(role);
            userRole.setUser(user);
            newRoles.add(userRole);
        }

        user.setUserRoles(newRoles);
    }

The JPQL query in addDefaultRoles() is filtered by the access_group, so the local_user role will not be selected, which is what we can see in the generated SQL below.

2018-03-05 19:16:08.086 DEBUG [http-nio-8080-exec-18/app-core/localadmin] eclipselink.sql - <t 840224957, conn 1458980324> SELECT ID, IS_DEFAULT_ROLE, DELETE_TS, DELETED_BY, DESCRIPTION, LOC_NAME, NAME, ROLE_TYPE, VERSION FROM SEC_ROLE WHERE (((IS_DEFAULT_ROLE = ?) AND ((DESCRIPTION IS NULL) OR NOT (DESCRIPTION LIKE ?))) AND (DELETE_TS IS NULL))

Now for the solutions, I thought about replacing the constraint on sec$User by constraints on sec$UserRole for CREATE, UPDATE, DELETE, in order to prevent unassigning local_user role by local admins. But needs to write 3 constraints (BTW : why not have a ConstraintOperationType MODIFY unifying the three of them ?).

Or creating a before insert User listener that will enforce local_user default role if connected user has it, doing it while logged as admin (with Authentication) to circumvent constraint.

Or creating a service to handle this logic the same way, and call it in overriden method addDefaultRole from UserEditor screen after extending it.

Which solution would be recommended by CUBA team ?

Mike

Hi Mike,

Thank you for this investigation. You are right, when users are created by a local admin, they do not get the default role for the reason you pointed out.

I have fixed the issue by enforcing default roles in UserEntityListener, see commit on Github. If you cannot wait for the update, you can do the same in your project by overriding the cuba_UserEntityListener bean.

Thanks Konstantin, I’ve also chosen the UserEntityListener path, but without replacing cuba listener one (was not aware of it). Plus a check to ensure not assigning a role twice to be sure.