By Ger Cannoll - 4/17/2009
Ok. Its been a while since the course and I think I may have forgotten more than I learnt !!Just looking for a few pointers at this stage. I want to set up a menu type system where there will be say 50 forms, and different users that log in to the app should only be able to run specifc forms.. e.g User Joe might be able to run FormA, FormD and FormG whereas Steve may run Forma, FormB and FormX. (The users would also be in Groups) Which control would be the most appropriate to use for this type of access. Ideally, when Joe logs in he should only see FormA, FormD and FormG. In Foxpro, I used GenMenux for this ,but dont necessarily want to use a Menu if some other control is more appropriate or more 'in fashion' these days
|
By Edhy Rijo - 4/17/2009
Well, this is something that you will need to handle manually in a table where you have all your groups and forms assigned.
I am currently working with the Infragistic UltraToolbarManager which mimics the Office 2007 UI and allow you to create as many ToolItems as you want, then create several Tabs for your grouping and assign any Toolitem to any Tabs programmatically. This control will allow you to have your forms definition in a Toolitem, and then you can have this information in a table and when the user login read this table and assign the ToolItems to the corresponding Tab.
Keep in mind that this control allows you to set Visible any object programmatically giving you the flexibility you need. Of course there are other vendors with similar tools other than Infragistics.
|
By Greg McGuffey - 4/17/2009
I think the first thing is to do as Edhy suggested and have some meta data driven way to manage this, likely via a table(s) to manage the association of roles/groups/users to forms. You could also use a configuration file or a web service or ... Tables are easiest.
Then you'd use BOs to access this data. Then you'd need to manage some UI elements. Edhy suggested an Ingragistics tool, but there are many choices, including standard .NET or SF tools. Here are some suggestions:
1. Create menu with all items shown, then hide the ones that the user doesn't have access to. This might seem the easiest, but can be a bit challenging as you have to do lots of looks up.
2. Load a combo in a menu/toolstrip with the list of forms they can open. This is easy, but not very friendly.
3. Use a navigation panel on the left of your main form (assuming MDI here), and load either a SF Listbox or a SF ListView. This is even easier, as you can just use the standard SF list population methods to load the list of forms for a user.
4. Use a SF ThemedLinkMenu in the panel on the left. This looks slick and has some nice UI elements. You'd have to manage this more manually. I.e. get the data, then create the ThemedLinkMenuItems. However, there are samples of how to do this in the StrataFlix sample. In that case, they are using the ThemedLinkMenu for actions (like edit, search, delete), but the concept is the same. Also, I believe they sub class the ThemedLinkMenuItems, so that might be something you'd do also, such that each ThemedLinkMenuItem would know how to actually open the form.
5. Create a switchboard form, that has a list of forms they can use. Here you could use just about anything, including the listbox, listview, a tree control, create a list of link labels. This can be nice to provide context for occasional users or beginners, but can get old for experienced users, who'd appreciate faster navigation.
Then there are all of the other third party options, like Edhy suggested. Many of these will have Office 2007 like ribbon options or Outlook like options.
I hope this sparks some ideas and/or conversation on the topic for you!
|
By Ger Cannoll - 4/17/2009
Hi Edhy and Greg.. thanks for your very informative replies.I've narrowed down the parameters for the menu type control I would like to use : 1. Is a SF control (dont want to at this stage get 3rd party controls and also want to play around with SF controls) 2. Is 'easy' to set up at this stage .. does not have to be that pretty (to get familiar with stuff) 3. Comes close to the type of Outlook 2007 functionality... Would welcome suggestions
|
By Trent L. Taylor - 4/18/2009
We take a different approach and use only SF controls (no surprise there, right? ). We use a ThemedLinkMenu for most of our menus. You can add, hide, etc. However, off of one of our links in a ThemedLinkmenu, we use the Popup class that comes with SF (Has to be implemented in code) which allows you to hose any other control as a popup (like a combo drop down, menus, etc.). We have a customizable section that is retained by logged-in user that let's them pick the most common things that they go into. You could take a similar approach as well for menus that wil be dynamic. But like the guys said, you are going to have to create your application environment and then using meta-data would be the best way to go (data that aides in the display of which menus [or links] will appear).Just another idea Note: In the image above, the links on the left and right are ThemedLinkMenus (SF Controls).
|
By Trent L. Taylor - 4/18/2009
One other example I thought I would share is our "Main" application button menu. When you click our Application Button, it pops down (using the Popup class again) another user control that has a ThemedLinkMenu on the left that when selected shows an SF ThemedContextMenu (all of which can be shown, hidden, programmatically added, removed, etc.).Just thought this might be another idea.
|
By Greg McGuffey - 4/18/2009
First, nice examples! I'm getting some great ideas here, even though Gerard asked the question!
Second, I think Trent was looking over my shoulder when he typed this:
...which allows you to hose any other control...
|
By Trent L. Taylor - 4/18/2009
LOL...I meant that to be "host"
|
By Aaron Young - 4/18/2009
Like Edhy I use the Infragistics "ribbon" but instead of implementing form access using tables, I use the SF security system to determine form access. Each form has a permission and any menu/toolbar item which calls a form is able to work out the correct security permission to check. When the ribbon loads it checks permissions on all toolbar items and hides the items the user is not allowed to see. This could also mean that a group or tab is also hidden if the user isn't allowed to see any items within the group or tab.I appreciate you don't want to use a third party control but the SF security system is very easy to use.
|
By Edhy Rijo - 4/19/2009
Aaron Young (04/18/2009) When the ribbon loads it checks permissions on all toolbar items and hides the items the user is not allowed to see. This could also mean that a group or tab is also hidden if the user isn't allowed to see any items within the group or tab.
Hi Aaron,
This approach looks to be pretty good since the RBS will host all Menu Items. I have a couple of questions about your approach:
1) In order for you to hide a tab or group, in the RBS are you creating a Permission for each Tab and also each form?
2) At design, are you assigning the ToolItems to the Tabs?
3) At runtime, are you looping through the security RBS records to load the ToolItems, or are you looping all the ribbon Tabs and checking the security for each to load the ToolItems?
|
By Aaron Young - 4/19/2009
Hi Edhy,
Please find answers below:-
1) In order for you to hide a tab or group, in the RBS are you creating a Permission for each Tab and also each form?
Each form has a permission as does each tab. The groups don't have permissions but will be hidden if all of the tools within the group are hidden. Even though the tabs have permissions, the tabs will also be automatically hidden if all groups are hidden. The only reason I added a permission to each Tab was to give a quick and easy way of turning off the complete tab without having to individually turn off each tool - which could have been a big task if you use popup menu tools with many nested layers. Having a tab permission means I can turn it off with a single click.
2) At design, are you assigning the ToolItems to the Tabs?
Yes, I build the ribbon as normal at design time and all ToolItems are added to the correct tabs and groups. The only extra step at this stage is I use the tool.SharedProps.Tag property to store the form name that will be launched when a user clicks the tool. I have a small general purpose routine which simply checks the tag and calls the form rather than having a separate click method for each tool/form.
The Tag property is also used during the security check to determine if the tool is visible. I use a strict naming convention for form permissions:- "Is" + FormName + "Enabled". For example, a form called "Customer" would have a permission called "IsCustomerEnabled". A ToolItem which launches the customer form will have a Tag of "Customer" so this gives me both the form name and also allows me to work out the correct permission to check. I also have a special value for the Tag property if I don't want a security check for a specific tool and that is "NoSecurityCheck".
I wanted to have the option of having several tools which load the same form which is why I use the Tag property rather than assuming the ToolItem will be called the same name as the form.
3) At runtime, are you looping through the security RBS records to load the ToolItems, or are you looping all the ribbon Tabs and checking the security for each to load the ToolItems?
The ToolItems have already been loaded into the correct tabs and groups at designtime. I have a routine called CheckMenuRibbonSecurity which runs once during initialization and removes tools which are denied based on permissions. This method does the following:-
1. It checks the Tag property of all tools in the ultraToolbarsManager.Tools collection. If the tag is "NoSecurityCheck" then the tool is allowed to remain visible. If the tag contains a form name then I check the "Is" + FormName + "Enabled" permission. If disallowed, then the tool is hidden.
2. Hidden tools still appear in the Application Menu and Groups in a disabled state so they must still be removed. The routine scans through all tools in the ultraToolbarsManager.Ribbon.ApplicationMenu.ToolAreaLeft.Tools collection. Hidden controls are then removed by calling the ultraToolbarsManager.Ribbon.ApplicationMenu.ToolAreaLeft.Tools.Remove() method. Please note it is vital to scan through the tool collection from last to first to avoid the Remove command from confusing your scan, i.e. if you have 10 tools then check and remove the 10th before moving to the 9th and so on.
3. Each tab is checked. If it's permission is denied then the whole tab is hidden simply by setting the visible property. If the tab is allowed, then the routine will scan through all groups within the ultraToolbarsManager1.Ribbon.Tabs.Groups collection. For each group, the group's Tools collection is scanned and any hidden tools are removed using the same technique as in point 2. If all tools are removed from a group, then the group is removed using Remove(). If there are no groups within a tab because they have all been removed, then the tab is hidden. Again, it is vital to scan through the group and tool collections in reverse order. If not, then you will get some weird results
Please note that one side-effect of using the security system is an "Administrator" sees all tool items as an administrator always passes security checks.
In effect, I am simply setting up the ribbon at designtime and removing denied tools at runtime. Allowed tools don't require any additional action as they are already on the ribbon in a visible state.
Please let me know if you have any other questions.
Aaron
|
By Edhy Rijo - 4/19/2009
Hi Aaron,
Thanks a lot for the detail explanation. I will follow your lead and use the RBS with this tool, it does make a lot of sense and I like the idea of having one single point to hide/show the tool items via the RBS.
|
By Ger Cannoll - 4/20/2009
Hi Aaron. Sounds like exactly waht I am looking for. When I sais I did not want to use a 3rd party control, I meant a non SF controlAt this point, I want to concentrate on SF first and maybe afterwards I will look at other 3rd party controls Is the functionality you descibe 'in the box' (regarding Rights for different users/groups) or does it require a fair amount of plumbing ?
|
By Edhy Rijo - 4/20/2009
Gerard O Carroll (04/20/2009) Is the functionality you describe 'in the box' (regarding Rights for different users/groups) or does it require a fair amount of plumbing ?
Gerard,
Yes this is handle by the SF-RBS of course you need to create your form's permission and assign their Keys to the form's ViewSecurityKey. Read about how to setup the RBS and also there is a good white paper on how to setup security here http://forum.strataframe.net/Topic14216-26-1.aspx.
Basically with Aaron's detailed approach I was able to use the RBS to enable/disable menu items in a very short period of time.
Also you need to check each item permission using code like this:
If SecurityBasics.CurrentUser.GetPermission(customViewSecurityKey).Action <> PermissionAction.Grant Then
Return False
End If
|
By Edhy Rijo - 4/20/2009
Hi Aaron,
One more question about the "NoSecurityCheck" feature, you mention that you use this "NoSecurityCheck" instead of the form's name to skip the security and load the menu item, but in that case, the ShareProps.Tag will be "NoSecurityCheck", then how will you know what form's or command to execute?
Before your posting, I was using the Tool.Key to store my form name like "frmInventory", but based on your explanation, I also have the need to open the same form from different tools and the Key must be unique for each item, so I am adopting your logic which at the end simplifies the whole process, specially adding new menu items.
|
By Aaron Young - 4/20/2009
Hi Edhy,
I have a small handful of special tools (File Exit, Security Editor, Database Connection, Upgrade Database) and for these I use the tool.Key to separate them from my "normal" SF forms. My tool click method first checks the key and if it is one of the above then they are handled separately. For the "File Exit" tool I set the Tag to "NoSecurityCheck" as I want everyone to see it. If the key isn't one of the above then it is a regular form and the Tag contains both the form name and effectively the permission.
You mentioned in a post to Gerard the need to set the form's ViewSecurityKey. In theory it doesn't have to be set. If a form is denied then the tools will be removed and there is no way for the form to be run by the user. SF checks the ViewSecurityKey when the form is run so if you are removing the tool the form can only be run whenever permission has been granted.
Regards,
Aaron
|
By Edhy Rijo - 4/20/2009
Aaron Young (04/20/2009) Hi Edhy,
I have a small handful of special tools (File Exit, Security Editor, Database Connection, Upgrade Database) and for these I use the tool.Key to separate them from my "normal" SF forms. My tool click method first checks the key and if it is one of the above then they are handled separately. For the "File Exit" tool I set the Tag to "NoSecurityCheck" as I want everyone to see it. If the key isn't one of the above then it is a regular form and the Tag contains both the form name and effectively the permission.
Ok, I got it now. Thanks!
You mentioned in a post to Gerard the need to set the form's ViewSecurityKey. In theory it doesn't have to be set. If a form is denied then the tools will be removed and there is no way for the form to be run by the user. SF checks the ViewSecurityKey when the form is run so if you are removing the tool the form can only be run whenever permission has been granted.
Yes you are right on this, you may get away from setting the ViewSecurityKey, in my case I already have those setup and it may be used as a insurance that the form will be protected in case something is missed. During my test using your approach it was really useful to had the ViewSecurityKey since I call the Security Editor form from another place and the key prevented the form from showing up.
|
|