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.