Design patterns for enabling user interface elements based on user permissions?
Asked Answered
H

5

12

We have a web application and its front end is implemented with GWT/GXT. Users can belong to various groups and these groups can then have various permissions. The permissions are quite fine grained, for example comment_create, comment_edit, comment_delete and comment_read.

What would be the best way to enable and disable user interface controls based on user permissions? We have an utility method that returns boolean value with given user and permission name. But at the moment each control is wrapped inside if clause and that makes the code bit messy.

Harlem answered 6/7, 2010 at 9:22 Comment(1)
Example from MS for C#: msdn.microsoft.com/en-us/library/aa480723.aspxHarlem
B
3

I had the same problem, here my solution.

Each UI component has an on/off state (visible/hidden, enabled/disabled, editable/readonly) and the state can be bound to one or more permission. For example the edit button can be enabled if the user has an EDIT permission, or disabled otherwise.

I've created a binder class that binds the UI component to a permission. The binder knows the current user permissions (all the permissions) through a event bus where a set of permissions is sent using an event. Each time the event is received the binder check if the permission is present or not (an alternative is use a boolean for each permission) and apply the changes to the component (for example enabling or disabling it).

The event bus is the only connection between all the UI components.

Using Gin and some helper class I've ended up with something like this for the binding code:

FeatureBinder.bind(editButton, EDIT_PERMISSION);
Bookbindery answered 23/10, 2013 at 16:0 Comment(2)
+1 Sounds interesting. Can you provide some more pseudocode on this approach? Does the FeatureBinder hold references to all controls requiring permissions?Chopin
The FeatureBinder is a simple helper class that creates an event handler for the permissions set change event. When a new event occurs the handler checks if the specified permission (EDIT_PERMISSION in the example) is in the set enablig/disabling the component (editButton) in consequence. The handler is bound to a particular bus dedicated to permissions set propagation.Bookbindery
W
1

I'm not sure how you'd implement this in GWT/GXT, but the old MFC way of enabling menus might be a place to start.

This had a separate ON_UPDATE_COMMAND_UI message which you gave a menu id and method name. The method would be called and you could enable or disable that menu option depending on your logic. In your case it would be based on the user id. This is on a per menu id basis and is therefore as fine grained as you need it to be.

Willardwillcox answered 6/7, 2010 at 9:30 Comment(0)
C
1

Acris security

Look at Securing GWT Clients With AcrIS: using annotations to define permissions on controls in a declarative fashion. From the article,

public class CustomerPanel extends SecuredComposite {
...
    @Secured(Grants.SECURITY_MANAGEMENT)
    protected TextBox securityID;
...
}

While the approach looks very promising, the project doesn't appear that active. The downloads page has the latest release in May 2012 with only a few hundred downloads of each version (although this doesn't account for use as a Maven dependency). The latest on acris' forum is a post from June 2013 on a move to Git.

Also, the latest published version is compatible with GWT 2.3, with current development focused on GWT 2.5.

Additionally, the framework looks very extensive, and I have concerns about its modularity. Just trying to pull in the security module requires a number of dependencies and other modules.

Even if you don't use acris, the approach is work looking into. (This is the same approach as mentioned in Attribute-Based Authorization linked in a comment on the OP.) Looking at the source, it looks like metaprogramming using a generator and SourceWriter.

Chopin answered 15/1, 2014 at 16:23 Comment(0)
G
0

See the decorator pattern.

Glaswegian answered 6/7, 2010 at 9:40 Comment(0)
P
0

You can use setEnabled(boolean) on the restricted widgets and save 2 lines of code compared to the if version:

Button editButton = new Button();
editButton.setText("Edit");
editButton.setEnabled(SecurityManager.userHasPermission(currentUser, Permissions.DOCUMENT_EDIT));
toolbar.add(editButton);

Button deleteButton = new Button();
deleteButton.setText("Delete");
deleteButton.setEnabled(SecurityManager.userHasPermission(currentUser, Permissions.DOCUMENT_DELETE));
toolbar.add(deleteButton);
Procaine answered 8/7, 2011 at 5:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.