I have done many search in this forum and StackOverflow but I wanted to know if I am doing thing properly or is there a better way to manage permission in C#. In my database, I have entities that are assigned either to a User or a Group of users, giving them rights to do things on the entity based on their role. My User class is something like this :
public class User { private Role role; public Role Role; }
and my group class is this :
public class Group { private List<Tuple<User, GroupRole>> members; private IReadOnlyList<Tuple<User, GroupRole>> Members => this.members; }
I have a PermissionManager class in my Application that handle this side of the application :
public class PermissionManager { private List<User> users; public IReadOnlyList<User> Users => this.users; private List<Group> groups; public IReadOnlyList<Group> Groups => this.groups; public User AuthenticatedUser { private set; get; } public User Authenticate(String login, String password) { this.AuthenticatedUser = null; foreach (User user in this.Users) { if (user.CompareCredentials(login, Hash(password))) { this.AuthenticatedUser = user; break; } } return this.AuthenticatedUser; } public void Demand(Role requiredRole, Group group = null, GroupRole? requiredGroupRole = null) { if (AuthenticatedUser == null) throw new PermissionDeniedException("Action needs authentication."); if ((group == null) && (AuthenticatedUser.Role < requiredRole)) throw new PermissionDeniedException("Insufficient rights."); else if (group != null) { var foundUsers = from member in @group.Members where member.Item1 == AuthenticatedUser select member; if (foundUsers.Count() == 0) { throw new PermissionDeniedException("Authenticated user is not a member of the group."); } else { if ((requiredGroupRole != null) && (foundUsers.First().Item2 < requiredGroupRole)) { throw new PermissionDeniedException("Insufficient group rights."); } } } } }
And when I need to ask for permission, I use it like this :
public class User { public readonly Application Application; private String name; public String Name { set { Application.PermissionManager.Demand(Role.ADMINISTRATOR); this.name = value; } get { Application.PermissionManager.Demand(Role.VIEWER); return this.name; } } }
I feel like I am not doing something right, so I came here to ask your opinions about this. Thank you.