Integrating Row-Level Roles with Resource Roles

Hello

I have a question regarding the integration of Row-Level Roles with Resource Roles in Jmix.

I’ve successfully created some Row-Level Roles in my Jmix application to control access to specific rows of data. Now, when assigning roles to users, I’m wondering if there’s a way to integrate these Row-Level Roles with Resource Roles.

Is there a direct mechanism or best practice for associating Row-Level Roles with Resource Roles during role assignment to a user?

Thanks in advance for your help!

Hi @t.meunier

There is no built-in mechanism for assigning both resource and row-level roles to users. But you can easily implement your own solution by manipulating RoleAssignmentEntity entities.

Let’s consider a simple example based on GitHub - jmix-framework/jmix-onboarding-2: Example application created in Jmix Tutorial.

We’ll assign a set of roles defined beforehand for a “group” - a synthetic user with the hr-manager-group name.

First, let’s create a button that prepares the set of roles by using assignments of the existing user:

<button id="generateHrManagerGroupBtn" text="Generate HR Manager Group"/>
@Autowired
private DataManager dataManager;
@Autowired
private Notifications notifications;

@Subscribe(id = "generateHrManagerGroupBtn", subject = "clickListener")
public void onGenerateGroupsBtnClick(final ClickEvent<JmixButton> event) {
    // Load all Alice's role assignments
    dataManager.load(RoleAssignmentEntity.class)
            .query("e.username = ?1", "alice")
            .list()
            .forEach(prototypeAssignment -> {
                // And save them for hr-manager-group user (which actually doesn't exist)
                RoleAssignmentEntity groupAssignment = dataManager.create(RoleAssignmentEntity.class);
                groupAssignment.setUsername("hr-manager-group");
                groupAssignment.setRoleType(prototypeAssignment.getRoleType());
                groupAssignment.setRoleCode(prototypeAssignment.getRoleCode());
                dataManager.save(groupAssignment);
            });
    notifications.show("Done");
}

Now start the application and click “Generate HR Manager Group” once. The set of roles for HR managers will be created. Of course you can do it on the application start or include in Liquibase changelogs.

Then create a button that assigns the set of roles to a selected user (should be a new one):

<button id="assignHrManagerRolesBtn" text="Assign HR Manager Roles"/>
@ViewComponent
private DataGrid<User> usersDataGrid;

@Subscribe(id = "assignHrManagerRolesBtn", subject = "clickListener")
public void onAssignHrManagerRolesBtnClick(final ClickEvent<JmixButton> event) {
    User user = usersDataGrid.getSingleSelectedItem();
    if (user != null) {
        dataManager.load(RoleAssignmentEntity.class)
                .query("e.username = ?1", "hr-manager-group")
                .list()
                .forEach(prototypeAssignment -> {
                    RoleAssignmentEntity groupAssignment = dataManager.create(RoleAssignmentEntity.class);
                    groupAssignment.setUsername(user.getUsername());
                    groupAssignment.setRoleType(prototypeAssignment.getRoleType());
                    groupAssignment.setRoleCode(prototypeAssignment.getRoleCode());
                    dataManager.save(groupAssignment);
                });
        notifications.show("Done");
    } else {
        notifications.show("Select a user");
    }
}

After that, create a new user, select it and click “Assign HR Manager Roles”. The predefined roles will be assigned.

The whole project:
onboarding.zip (526.5 KB)

1 Like

Thank you for your answer, we implemented this solution.
:grinning: