views:

112

answers:

4

I need to develop a Winforms application where users are given permissions to access menu-items in a menu-strip as assigned to them.

I have anticipated the following technique:

(1) Menu Strip is mapped into a corresponding treeView with checkBoxes,

(2) A user is selected from the combo-box,

(3) Some tree-view-node check-boxes are checked in treeView to indicate that, "this user would be able to access these menu-items",

(3) A save button is pressed to save the checked tree-Nodes and the user in the DB.

At later stages, when a user logs into the system, Menu-Strip items are populated accordingly from the DB.

Can anyone suggest me any better technique?

A: 

I think your biggest issue is going to be your security object design and "serialization" into the databse, your UI design could more or less be an afterthought, as long as your backing objects/database are well thought out you could change the front end 1000x times to be whatever design you like. I would recommend bit flags if the level of distinction required isn't very expansive.

That said I don't think what you have suggested is a bad idea.

Quintin Robinson
What u personally do to assign menu-permissions (retrieving permissions is not so hard)?
JMSA
I am finding the treeView-node check-boxes hard to manipulate.
JMSA
A: 

Depending on the number of users you'll manage this might be enough - or you might want to provide an additional step by assigning users to groups and permissions (which menu item is visible) to groups. You'd store it in a database as well.

Update 1

Oh, and another idea might be storing a database of windows user/group ids againts permissions. That way you could assign the specific "menu permissions" for a single user or a whole windows group without needing to store too much in the database. User<->Group mapping would then be done in the Windows user management / Active directory without you needing to implement too much stuff.

Update 2 (because of comment)

To store permissions I'd define a table in the database that matches user/group ID and a permission ID. So for each permission (one permission is for example the right to open the "Print" Menu, another on the right to do an "Edit" and so on ...)

So the table could look like

 user/group id           permission
 ----------------------------------
 1-332-1345-5453         OpenFile
 1-332-1345-5453         Edit
 1-254-1345-5412         OpenFile

So each entry in that DB table would be a mapping between a specific user or group and one specific permission. In database speak this is a cross-table, or a many-to-many mapping.

froh42
What u personally do to assign menu-permissions (retrieving permissions is not so hard)?
JMSA
I am finding the treeView-node check-boxes hard to manipulate.
JMSA
I am not concerned about DB-design. I am concerned abt TreeView-nodes...
JMSA
When I just googled for "winforms treeview databinding" I found the following article:http://www.eggheadcafe.com/articles/treeview_databinding.asp
froh42
A: 

You could think about a role model.

Managing user rights that way will be a pain, and usually you have a set of roles that will perform similar functions. Another question is if you need a security modsel that is that flexible...

I would also include those roles in my commands, so it validates if the user has the correct right.

Heiko Hatzfeld
What u personally do to assign menu-permissions (retrieving permissions is not so hard)?
JMSA
I am finding the treeView-node check-boxes hard to manipulate.
JMSA
+1  A: 

We have a similar implementation at work. This is a pretty straightforward design and works well.

You may want to add a unique identifier to each MenuItem. This can be as simple as:

public enum MenuItems
{
    File_New = 100,
    File_Save = 110,
    // ...
}

And you include this number in the database. Then, when you write out the menu items, you can have a dictionary that maps the MenuItems integer to a delegate (for handling the execute event):

delegate void MenuItemExecuteHandler();
IDictionary<int, MenuItemExecuteHandler> MenuItemHandlers;

And somewhere define the mappings:

MenuItemHandlers.Add(MenuItems.File_New, this.OnFileNewClick());

So that when you hookup the menu item event handlers, you can call the right method to perform the right action:

int id = 100; // Retrieved from the database.
MenuItems menuItem = (MenuItems)Enum.TryParse(typeof(MenuItems), id);
string command = "..."; // Retrieved from the database using the MenuItem ID.
MenuItemControl control = new MenuItemControl();
control.Text = command;
control.OnClick += new EventHandler(delegate (object sender, EventArgs args) 
{ 
    MenuItemHandlers[menuItem].Invoke(); 
});

(Something to that effect, I probably have the syntax off slightly)

Update:

The "Tag" property of the tree-view item control gets populated like this, following the example above:

TreeItemControl control = new TreeItemControl();
control.Text = "New File"; // Retrieved from database.
control.Tag = 100; // Retrieved from database.

Then, when looking for what to write out:

if (control.CheckState = CheckState.Checked)
{
   row["MenuItemID"] = control.Tag;
   row["Allowed"] = true;
}
emptyset
Actually retrieving permissions is not so hard. I am stuck with checking tree-nodes and saving them accordingly.
JMSA
You could set the "Tag" property (if one or similar exists) on the item to be the ID. This is done when you populate the tree-view control. This is typically a property on the control which holds an object reference, which allows you to "Tag" the item with any metadata you want.Then you can save out by ID in the database the menu item that was checked.
emptyset