Page 1 of 3 123 LastLast
Results 1 to 10 of 21

Thread: Commands/Roles and dynamic menus?

  1. #1
    Join Date
    Aug 2005
    Location
    London (the English one!)
    Posts
    378

    Default Commands/Roles and dynamic menus?

    Hi All,

    I am facing a classic issue with users and Roles in a multi-tier environment. Upon login, the GUI will receive a list of commands that the user is allowed to perform.

    I would like the menu to be adapted at that time, the unauthorised commands could either be disabled or made invisible on Menu/shortcuts/toolbar.

    How would you do this?
    Is there any recommended way since the menus and toolbars are tailored via XML in Spring RC...well before the login...

    Any suggestion welcomed

    Many thanks,

    Best regards

    Benoit

  2. #2
    Join Date
    Aug 2005
    Location
    London (the English one!)
    Posts
    378

    Default More thoughts...

    More thoughts on this... and the beginning of an investigation...

    I believe that the main difficulty is based around the programmatic access to the menu.

    1. Accessing the menu, from a View I do
    Code:
    CommandGroup menu = getApplication().getLifecycleAdvisor().getMenuBarCommandGroup();
    I assume that it is working fine.

    The CommandGroup lets you find Commands but does not let you iterate through them. Although, it was probably defined for encapsulation, this is unfortunate in my opinion. When a user is logged in, the client context would receive a list of authorised commands, security nearly always works by giving rights and not eliminating existing ones.

    Basically you would receive a list of command for which one should call setEnabled(true) on and setEnabled(false) on the other ones...

    By not being able to iterate, we then require the knowledge of all possible commands in order to enable/disable them.

    Furthermore, using the CommandGroup.find(...) requires the knowledge of the full path to the command. One could assume that this is not required for security... It is probably preferrable not to rely on a full path but simply say that "showPetOwnerView" should be disabled, being in "fileMenu/showPetOwnerView or window/showView/showPetOwnerView...

    What stops us from doing this?
    The method CommandGroup.getMemberList is unfortunately protected.
    I would therefore suggest that we open it up, may be by providing an iterator or returning an unmodifiableList.

    What do you think? Am I moving in the right direction or is there a better way?

    I may raise a JIRA for it.

    Alternatively, we could build the dynamic aspect in CommandGroup by creating 2 methods:

    Code:
    public void setEnableEndCommands(boolean enable, Set endCommands)
    public void setVisibleEndCommands(boolean visible, Set endCommands)
    These 2 methods would iterate through the member list and if a command id is found in the endCommands it would enable/disable or make it visible/invisible.

    Would this be better? It would also work for Toolbars!

    I do not think that it is easy to extend CommandGroup as it is used in different factories, I would suggest to either:
    - make the getMemberList public
    - or add those 2 methods in CommandGroup

    What do you think? I will give it a go and report back but please let me know if I err as I am only human! ;-)

    2. second question: Where to put this "security" code, in my view, it should run just after the login (at that point my app knows the authorised commands)... How would you trigger the code? Is there an login event? How can I subscribe to it?

    Many thanks

    Benoit.

  3. #3
    Join Date
    Aug 2005
    Location
    London (the English one!)
    Posts
    378

    Default a solution

    Here is a solution with patch and unit test.

    I hope that the change will be approved to go in PR1.

    http://opensource2.atlassian.com/pro...browse/RCP-208

    comments/suggestions?

    Thanks

    Benoit

  4. #4
    Join Date
    Aug 2004
    Location
    San Francisco
    Posts
    423

    Default Re: Commands/Roles and dynamic menus?

    I faced a similar problem recently, although not security based, but basically one where I had a number of commands that I needed to enable/disable based on the state of the application. I ended up solving it a different way which may or may not be applicable in your case.

    In my case the command being enabled/disabled depended on a set of rules based on what I'll call symantic state. That symantic state could change by selecting different objects in different views, and in theory across views. The application was getting complex (ie a pain) to expand by adding new commands, a sure sign I needed to change something.

    So, i ended up firing an internal application event on object selection and made the commands listeners to that event. The command themselves could then determine whether to enable or disable themselves. In your case you could, for example, fire a security event after login (and relogin if needed) and have the command listen for security events configuring themselves based on the payload of the event. Also, if in the future you end up having other situations that change the security settings all they would need do is fire an event corresponding to that change.

    Currently, i like this solution. It seperates ui state from symantic state by a clear, expandable set of rules and it allows commands to configure themselves by listening for events that signal potential changes in state.
    Adding new commands is straight forward as the views do not need to concern themselves with command enabling/disabling.

    Quote Originally Posted by benoitx
    Hi All,

    I am facing a classic issue with users and Roles in a multi-tier environment. Upon login, the GUI will receive a list of commands that the user is allowed to perform.

    I would like the menu to be adapted at that time, the unauthorised commands could either be disabled or made invisible on Menu/shortcuts/toolbar.

    How would you do this?
    Is there any recommended way since the menus and toolbars are tailored via XML in Spring RC...well before the login...

    Any suggestion welcomed

    Many thanks,

    Best regards

    Benoit

  5. #5
    Join Date
    May 2005
    Posts
    394

    Default

    I require this functionality too.

    In a webcontext acegi has tags for this.
    Something like <acegi:ifUserHasRole role="myrole"/>
    The nicest way to configure this would be in the commands xml.
    To be able to put a role on each command which makes it invisible.

  6. #6
    Join Date
    Aug 2005
    Location
    London (the English one!)
    Posts
    378

    Default

    Hi

    Thanks for your comments. 2 thoughts:

    1/ Configuring via XML may be a nice setup but sometimes, one needs the ability to change it at runtime. A command could allowed for multiple roles (as usual ACL are like a growing overlapping set).

    2/ The option of firing events is elegant (could you post some explicit code examples) but often, the need is to enable some and disable other. Firing an series of separate events (say one for each authorised command or role) would not given the sense of authorised "set".

    eg, firing "save", "exit" events would not tell the "close" command that it needs to be disabled or invisible? How would we distinguish between the 2 handling?

    The event fired should contain all authorised commands in one go and we must ensure that all commands listen to it, if their id is not part of the event, they should disable or make themselves invisible (or to decide?).

    Both very good ideas but PR1 is around the corner... so we need a solution now... or may be something a reasonable temporary solution that can be amended later?

    Feel free to comment on the RCP

    Best regards

    Benoit.

  7. #7
    Join Date
    Aug 2005
    Location
    London (the English one!)
    Posts
    378

    Default

    My last post probably wasn't the clearest of all... usual when pressed by time to go to a meeting.

    I can see one issue with configuring the roles in xml. Any application would have to have such a setting, being the 'standard' commands like open/save/login or logout.

    The xml would become big but I can live with that.

    The issue with the command itself knowing when to enable/disable itself based on a role is similar (ie it needs to be setup explicitely). If it based on the command I'd then we could design the command to respond to an event.

    So I think it would be good to separate the role and the mapping to command ids. This way, that mapping could come from db, xml or an ldap server. Once gui has that list of authorised commands, we can look at how to act on it.

    I think it is important to either have a way to find all commands and iterate through them with the authorised list or have, by default, any command listening to 'authorisation' events. At the moment, I believe it is not possible to iterate through the command, but then I may be wrong...

    As mentioned before, the authorisation event should have the full list of authorised command ids. Let me explain:

    Assume that we have 3 commands a,b,c. Assume also that only a and b are authorised.

    If we fire individual events a and then b; how would c know that it should be disabled? The entire list should be part of the event and all commands should listen to it, if the commandId is not part of the list then it should be disabled or invisible.

    This event mechanism would work nicely until we consider the ergonomics of an application. For instance if all commands of an entire menu or submenu were disabled, shouldn't the menu be also disabled?

    I would recommend designing the authorised commandIds to take into account a path as I think it is irrelevant how they are accessed vs the need to disable them.

    So the idea of traversing menus as per rcp 206 probably offers the best ergonomics.

    However it would require to know the top CommandGroup that should be traversed (like menuBar and toolBar) and may be there is a command accessible somehow differently.

    How could we merge the idea of events and menu ergonomics? And best of all, how could we make it with the least amount of changes so it may have a chance to get into PR1?

    Comments?
    (Btw I won't be around until oct 6)

    Best regards
    Benoit

  8. #8
    Join Date
    May 2005
    Posts
    394

    Default

    So I think it would be good to separate the role and the mapping to command ids. This way, that mapping could come from db, xml or an ldap server. Once gui has that list of authorised commands, we can look at how to act on it.
    Do we really need the roles softcoded?
    I cannot image a db or ldap that specifically says which command to show or not for which role, this is db migration hell when a command is added or renamed.

    I 'd propose (actually I stole the idea from acegi's web tags):

    Any application defines a set of roles (admin, employee, customer, ...).
    The nice thing about these roles is that they group a set of authorizations.
    Users are dynamically allowed to use a command based on the roles (comma-seperated) allowed for that command.
    1 command has 1-n roles (default is all).
    1 user has 0-n roles (or 1-n with default is anonymous).
    An outside db or ldap could map it's own roles to our applications roles (like happens now in deployment descriptors).

    Web applications using acegi currently do it like this, so I think this is a good practice.

  9. #9
    Join Date
    Aug 2005
    Location
    London (the English one!)
    Posts
    378

    Default

    most banking app I worked on prefered a centralised mapping Roles/commands... so you can modify it without having to change anything on the client.

    Putting it in XML which in turn is placed in the application jar (like petclinic) would imply a new release for a mapping change... I know that this is not that painful with webstart, but it would look bad that clients have to re-download the app to fix it...

    Hence my suggestion to separate them... may be build a system that could do both? either having the mapping in xml or receiving a list of mapped commands from somewhere? At the end we need this list of authorised commands before applying it...

    Cheers

    Benoit

  10. #10
    Join Date
    Aug 2004
    Location
    San Francisco
    Posts
    423

    Default

    Benoit,

    As for the event firing, I would agree with you, the level of event should be higher than individual commands. As you say, containing the list of all authorized commands would probably be the most straightforward. I guess it all depends on how the allowed commands are stored in the db.

    The more I think about the situation you are describing I don't think the event solution is ideal. I certainly don't use it for all my commands, only those whose enabling logic is not localized (easily) to one view, and so a distributed event concept fits.

    I'd agree, the most straightforward (and generic) way to solve this would be to iterate through the complete list of commands. The problem then becomes what is being discussed - how to map roles to commands.

    I'm lucky, I don't have any security issues with my current app.

    FYI: For my internal application events I'm using the event listening framework at https://elf.dev.java.net/ and I'm finding it very useful. It allows you to specify your own events and listeners and provides event channels to dispatch events of the correct type to their appropriate listener. The events can have multiple types which can then be mapped to different methods in the listener (much the same way as awt events) which allows symatic grouping of internal events.

    Jonny

    Quote Originally Posted by benoitx
    Hi

    Thanks for your comments. 2 thoughts:

    1/ Configuring via XML may be a nice setup but sometimes, one needs the ability to change it at runtime. A command could allowed for multiple roles (as usual ACL are like a growing overlapping set).

    2/ The option of firing events is elegant (could you post some explicit code examples) but often, the need is to enable some and disable other. Firing an series of separate events (say one for each authorised command or role) would not given the sense of authorised "set".

    eg, firing "save", "exit" events would not tell the "close" command that it needs to be disabled or invisible? How would we distinguish between the 2 handling?

    The event fired should contain all authorised commands in one go and we must ensure that all commands listen to it, if their id is not part of the event, they should disable or make themselves invisible (or to decide?).

    Both very good ideas but PR1 is around the corner... so we need a solution now... or may be something a reasonable temporary solution that can be amended later?

    Feel free to comment on the RCP

    Best regards

    Benoit.

Similar Threads

  1. Replies: 3
    Last Post: Mar 9th, 2011, 10:43 AM
  2. Replies: 2
    Last Post: Jul 14th, 2007, 09:05 AM
  3. Replies: 3
    Last Post: Oct 3rd, 2005, 01:58 PM
  4. Dynamic menus in JSP views
    By jowizzle in forum Web
    Replies: 0
    Last Post: Aug 15th, 2005, 01:21 PM
  5. Replies: 3
    Last Post: Nov 6th, 2004, 10:10 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •