Anish
Anish

Reputation: 912

Suggest design pattern for an application having different user roles

Can you please suggest me which design pattern can be used for an application (Web application) having different user roles. My application has an Admin, HR, Managers, Assistant Mangers and Staffs

Admin has the right to access every page in the web application HR has only the right to access only few pages say page 1 and page 2 (Note that Admin can add privileged to more pages in future) Managers -Managers can view there corresponding staffs

etc

Is there any design pattern to implement the above feature. Since more user roles and pages can be added in future

Thanks

Upvotes: 1

Views: 4967

Answers (4)

ScottM
ScottM

Reputation: 121

I know this is a very old post, but I was searching for the same answer and never found an acceptable answer. The Decorator pattern seems the most obvious at first, but it isn't really what I wanted because all roles would have to implement the same methods (do we really want a customer to have a BlockUserAccount() method even if it doesn't do anything?), and every role would have to be extended every time a new behavior is implemented.

Instead, I found through experimentation that a variation of the Delegation pattern seems to be best. I say "variation" because everything I've read about the Delegation pattern involves a superclass of the main object, but that is not what I ended up doing.

What I have done is to use a basic user object, and it contains a collection of roles. These roles are defined as a different type of class altogether, each with its own methods, and each with its own interface. Then the roles are delegated out, as needed.

public interface ICustomerAlaCarte 
{
    void AuthorizePayment(decimal paymentAmount); 
}

public abstract class UserRole { }

public class CustomerAlaCarte : UserRole, ICustomerAlaCarte 
{
    public void AuthorizePayment(decimal paymentAmount) 
    {
        // Logic here
    } 
}

public class User
{
    private List<UserRole> _userRoles;

    public void AddUserRole(UserRole newRole)
    {
        _userRoles.Add(newRole);
    }

    public ICustomerAlaCarte AsAlaCarteCustomer()
    {
        ICustomerAlaCarte alaCarteRole = _userRoles.OfType<ICustomerAlaCarte>().FirstOrDefault();

        if (alaCarteRole != null)
        {
            return alaCarteRole;
        }
        else
        {
            throw new UserRoleNotAssignedException(); // Custom exception
        }
    }
}

Then to use:

var user = new User();
user.AddUserRole(new CustomerAlaCarte());

ICustomerAlaCarte customer = user.AsAlaCarteCustomer();
customer.AuthorizePayment(9.99);

Using this pattern, you could even have nested roles. For example, you could have a user admin and a reports admin, and each would inherit from Admin. When you only need basic admin functionality (or identity), you would pull an Admin delegate, but you could also specify IUserAdmin for the aforementioned BlockUserAccount() behavior, because each role only has methods that make sense for it.

Upvotes: 0

Francis Manoj Fernnado
Francis Manoj Fernnado

Reputation: 262

Well I know it's a old post.. but here's what I designed for something similar you can have any number of roles. Initially every user is a visitor after login in they can have any user role. I have used the decorator pattern for this.

plus I have added Database and Communication interfaces. (Most of the web applications need this) I have used Strategy design pattern so Users can have various database classes (Mysql,MsSql) and various communication methods (Email,SMS). Same way you can add your own Payment Interface to handle various type of payment options.

img

Upvotes: 2

Oussama Zoghlami
Oussama Zoghlami

Reputation: 1708

Generally, when designing user roles, the Decorator Pattern is the appropriate solution.

Upvotes: 4

Glenner003
Glenner003

Reputation: 1552

If you are blocking access on page level, you will find everything you need in one or the other security framework (like spring security).

If you want to be able to lock access to certain functionality, there are some options.

For most of those options it is better not the use the roles, but to use permissions. A role can have several permission. This allows for a lot of flexibility.

You can take a look at some MVC derivations. The methods on the controllers there can be secured. You can map each function to a permission.

If you combine this with the command pattern you can add the security at this level then a permission maps one to one to a command. With this it becomes very easy to let the UI controls reflect the permissions of the current user. (see Actions in Delphi and Spring)

This last option if to me the most beautiful and user friendly.

Upvotes: 1

Related Questions