質問

I am developing an application where the client needs and extremely flexible user rights system. For example, a user should be able to have update rights in Form A but not in Form B (which prevents me from defining broad update rights). Admin should also be able to transfer specific rights to a user.

I was thinking of using the Command Pattern with CanExecute method but not really sure how I can use it in such a dynamic/specific way. Any suggestions ?

役に立ちましたか?

解決

I have a similar situation in my application, which can be extended via plugins and the plugins can bring in their own permission. I solved that the following way:

  • static/common PermissionManager
  • very module/form/plugin can register its available permissions in the manager
  • the "permission manager UI" lists all available permissions and lets the admin assign them to users
  • on access every module/form/plugin asks the manager if the current user has the permission

Simplified class structure:

public class PermissionManager
{
    public static Dictionary<string, IEnumerable<string>> AvailablePermissions { get; set; }
    public static bool? Can(User user, string permission)
    {
        // check DB
        return DENIED ? false : (ALLOWED ? true : null);
    }
}

public class MyPlugin : IPlugin
{
    public void Init()
    {
        PermissionManager.AvailablePermissions["MyPlugin"] = 
            new List<string>() { "Permission1", "Permission2" };
    }

    public void DoWork()
    {
        if (PermissionManager.Can(user, "Permission1") != true)
            throw new NotAllowedException();
        // do work
    }
}

This is the basic patter I use. Of course you should use constants or similar for the permission names/keys. The admin UI can then iterate AvailablePermissions in the configuration UI.

In the DB I have something like the following (EF Code-First):

public class UserProfilePermissions
{
    public UserProfile User { get; set; }
    public Permission Permission { get; set; }
    public bool IsAllowed { get; set; }
}
public class Permission
{
    public int Id { get; set; }
    public string Key { get; set; }
    public string Group { get; set; }
}

So for every permission there is one Permission entry created (on the first assignment) in the DB and mapped via the mapping table using the IsAllowed to define "ALLOWED" or "DENIED".
The null value defines a not set permission so default values can be used (=> not set permission does not always say "DENIED").
The mapping table can also be used in the same style for e.g. roles.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top