I am building a C# application for a law firm. In every Form
there are some Control
s which only some of the users can access (for other users - those Control
s will be disabled).
I have built it like this: There is a class called AuthorizedForm
that inherits from Form
. This class has a method called SetAuthorization
, which enables all the Control
s the user may access, and disables the rest. Each form in the application inherits from AuthorizedForm
.
When the user logs in, the SetAuthorization
method is called and receives as parameters the id of the logged in user, and a list of rules. Every rule consists of a Control
, and a list of users that can access that Control
.
The list is actually divided into two lists: user groups (such as lawyers, paralegals etc.) and individual users. So if, for example, I put the id of the group "Administrators" and the id of the group "lawyers" in the first list, and the id of one of the secretaries in the second list - then the Control
will be defined as Enabled
for all administrators and lawyers, and also for that secretary, while for the other office employees the Control
will be defined as Disabled
.
The list is called AuthorizationList
and is actually a class that inherits from the List
class of type Tuple
, which receives a Control
, a GroupList
and a UserList
(the last two are nothing but a List
of type byte
).
The definition of GroupList
and UserList
:
public class GroupList : List<byte> { }
public class UserList : List<byte> { }
The code of the AuthorizedList
class (built with help from this answer) :
public class AuthorizationList : List<Tuple<Control, GroupList, UserList>>
{
public void Add(Control control, GroupList groups, UserList users)
{
Add(new Tuple<Control, GroupList, UserList>(control, groups, users));
}
}
The AuthorizedForm
class:
public class AuthorizedForm : Form
{
public void SetAuthorization(User loggedInUser, AuthorizationList authorizationList)
{
foreach (var rule in authorizationList)
{
bool isAuthorized = false;
foreach (byte group in rule.Item2)
{
if (group == loggedInUser.Group)
{
isAuthorized = true;
break;
}
}
if (!isAuthorized)
{
foreach (byte user in rule.Item3)
{
if (user == loggedInUser.Id)
{
isAuthorized = true;
break;
}
}
}
if(!isAuthorized)
{
rule.Item1.Enabled = false;
}
}
}
}
The call for the SetAuthorization
from the login function:
if (user.isLoggedIn)
{
SetAuthorization(user, new AuthorizationList()
{
/*
CONTROL | GROUPS IDS LIST | USER IDS LIST
*/
{ textBox1, new GroupList() { 1, 2, 3 }, new UserList() { 4 } },
{ textBox2, new GroupList() { 1, 2 }, new UserList() { 4 } },
{ button1, new GroupList() { 1 }, new UserList() { 4, 3 } },
});
}
Now, I want to let AuthorizationList
be also of type Tuple
which receives a Control
and a GroupList
only, or a Control
and a UserList
only, so I can set permissions for user groups only, or for individual users only.
I can not think of a way to do this without significantly changing the code I have written. Is there a way to do this in a relatively easy and elegant way? If not, how would you suggest to do it?
How about using an object that isn't a Tuple to hold the Authorizations, it's more elegant than Tuple<>:
public class GroupList : List<byte> { }
public class UserList : List<byte> { }
public class Authorization
{
public Control Control { get; set; }
public GroupList Groups { get; set; }
public UserList Users { get; set; }
}
public class AuthorizationList : List<Authorization>
{
public void Add(Control control, GroupList groupList, UserList userList)
{
Add(new Authorization
{
Control = control,
Groups = groupList,
Users = userList
});
}
public void Add(Control control, GroupList groupList)
{
Add(control, groupList, null);
}
public void Add(Control control, UserList userList)
{
Add(control, null, userList);
}
}
You can utilize the fact that passing an empty list does not affect your logic.
To make it "more elegant", add two more Add
overloads to your AuthorizationList
class:
public class AuthorizationList : List<Tuple<Control, GroupList, UserList>>
{
public void Add(Control control, GroupList groups, UserList users)
{
Add(new Tuple<Control, GroupList, UserList>(control, groups, users));
}
public void Add(Control control, GroupList groups)
{
Add(new Tuple<Control, GroupList, UserList>(control, groups, new UserList()));
}
public void Add(Control control, UserList users)
{
Add(new Tuple<Control, GroupList, UserList>(control, new GroupList(), users));
}
}
Now you can pass GroupList
, UserList
or both:
SetAuthorization(user, new AuthorizationList()
{
{ textBox1, new GroupList() { 1, 2, 3 }, new UserList() { 4 } },
{ textBox2, new GroupList() { 1, 2 } },
{ button1, new UserList() { 4, 3 } },
});
I'm trying to understand your question... AuthorizationList is a List of Tuples
And you want it to receive only 2 parameters either aa COntrol and grouplist or a Control and User list
To me it seems like AuthorizationList should be a KeyValuePair>
or something similar. Then check the type to see if the List is a user list or group list
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.