Action type="list_itemTracking" and security

Dear Support

Attached you find a project which is demonstrating my problem / question

I have created a user demo with readonly access to the application and entities.

When logged in with user demo and password demo I select Objects.

In the tObjectsDataGrid I added a button
<action id="copyAndEdit" text="msg:///action.copyAndEdit" icon="EDIT" type="list_itemTracking"/>

a) I did program in the controller the mechanism to disable this button if there is isUpdatePermitted = false.
→ is this the correct way ( quit some code ! ) or isn’t there an easier solution ?

b) There is a Master-detail view Collections

  • as the demo user has read-only access, the button edit changes to “read”, which is nice
    → but if the user clicks on this button, there is a Save and Cancel Button. I think here there should be only a close button ?
  • there is a readButton. If the user clicks the read button, there is an error “NoSuchViewException: View ‘TCollection.detail’ is not defined”, which is basically not needed.

Thank you for your attention, as I need to adapt perhaps a big project ;/

Regards
Felix
Security.zip (130.4 KB)

Hi,

a) You have incorrect implementation of your copyAndEdit action.

  1. If a button is bound to an action, then you need to implement Action’s ActionPerformedEvent handler instead of Button’s ClickEvent listener.
  2. InMemoryCrudEntityContext defines an authorization point for checking access to entity operations by testing predicates, i.e. checks Row-level permissions. In your case, you defined Resource permission, so UiEntityContext must be used instead.
  3. The action state is refreshed during interaction with the DataGrid, for example, when the selection changes. Disabling a button/action in InitEvent/ReadyEvent has no effect. You need to implement the Action’s enabledRule.

Correct implementation:

public class TObjectListView extends StandardListView<TObject> {

    @ViewComponent
    private DataGrid<TObject> tObjectsDataGrid;

    @ViewComponent
    private CollectionContainer<TObject> tObjectsDc;

    @Autowired
    private AccessManager accessManager;
    @Autowired
    private DialogWindows dialogWindows;
    @Autowired
    private MetadataTools metadataTools;
    @Autowired
    private CurrentAuthentication currentAuthentication;

    @Subscribe("tObjectsDataGrid.copyAndEdit")
    public void onTObjectsDataGridCopyAndEdit(final ActionPerformedEvent event) {
        Set<TObject> tObject = tObjectsDataGrid.getSelectedItems();
        for (TObject object : tObject) {
            TObject tObjectCopy = createCopy(object);

            dialogWindows.detail(tObjectsDataGrid)
                    .withViewClass(TObjectDetailView.class)
                    .newEntity(tObjectCopy)
                    .open();
        }
    }

    protected TObject createCopy(TObject tObject) {
        TObject tObjectCopy = metadataTools.copy(tObject);
        tObjectCopy.setId(null);
        tObjectCopy.setObjAdminCreator(currentAuthentication.getUser().getUsername());
        return tObjectCopy;
    }

    @Install(to = "tObjectsDataGrid.copyAndEdit", subject = "enabledRule")
    private boolean tObjectsDataGridCopyAndEditEnabledRule() {
        UiEntityContext entityContext = new UiEntityContext(tObjectsDc.getEntityMetaClass());
        accessManager.applyRegisteredConstraints(entityContext);

        return entityContext.isCreatePermitted();
    }
}

b)

The complete layout and controller of Master-detail view is scaffolded, so you have full control over it and can adjust its behaviour according to your needs.

Pay attention that the create and edit action handlers have been overridden to adjust their logic for the Mater-detail view. Simply adding a read action is not enough to make it work in the same way.

Regards,
Gleb

1 Like

Hi @gorelov

Thank you for your time and detailed reply!

I will check your solution and am very happy to have my abstraction layer in place.

I’d like to share some insights into what led me to my (incorrect) solution:

a) Jmix is a Rapid Application Development (RAD) framework, and within the IDE, it features a Jmix UI. When I examine the handler of a button with an action, I notice that there is no ActionPerformedEvent available (though I understand I can add this manually and will do so).

The usage of CrudEntityContext was suggested by Jmix AI (no complaints there). For reference, you can find it here
https://ai-assistant.jmix.io/chatbot?chatSessionId=019c3e58-190d-719b-b7a2-eba0b9147cfe

If I check in the documentation.
image

same with the
image

Thank you again for your input; it will help me adapt my approach and do further research.

b) + c) I expected that the Jmix RAD would generate complete code with standard features out of the box. It might be helpful to mention somewhere that the Master-Detail View is just a scaffold.

Lastly, I fully acknowledge that documentation is often never exhaustive and can be quite challenging to produce. Please don’t interpret my feedback as a complaint; rather, consider it a remark on areas where there’s room for improvement.

Best regards
Felix