一种简单直观的权限设计
大部分系统都有权限系统,一般来说,它能管控人员对某个页面的访问,对某些字段、控件可见或者不可见,对数据是否可删除、可添加、可新增等等。大部分人都把权限作为一个子系统独立出来。但是这里我不是想设计一个权限管理系统,网上的设计方案太多了,可以说每个开发人员都有自己的开发权限管理系统的想法和思路。
?
在这篇文章中,我先用简单的C#代码模仿一个用户的权限,再使用sql去模拟。这是一种很简单,很直观的方式去判定用户的权限。
?
好吧,先从最简单的开始,定义一个用户(User)类,如下:
?
class User { bool CanDelete; bool CanRead; bool CanWrite; bool CanModify; bool CanCreate;}
?
这里设计5个属性来管控用户的权限。我发现这样虽然很直观,但是不宜扩张。我们将权限独立出来,再看下面的代码:
?
enum PermissionTypes : int { None = 0, Read = 1, Write = 2, Modify = 4, Delete = 8, Create = 16, All = Read | Write | Modify | Delete | Create}class User { public PermissionTypes Permissions = PermissionTypes.None;}
?
我们先试用一下,你就能感觉到神奇之处:
?
//创建一个用户User admin = new User();admin.Permissions = PermissionTypes.Read | PermissionTypes.Write | PermissionTypes.Delete; //验证权限bool canRead = ((PermissionTypes.Read & admin.Permissions) == PermissionTypes.Read);bool canWrite = ((PermissionTypes.Write & admin.Permissions) == PermissionTypes.Write);bool canCreate = ((PermissionTypes.Create & admin.Permissions) == PermissionTypes.Create); //查看结果Console.WriteLine(canRead); //trueConsole.WriteLine(canWrite); //trueConsole.WriteLine(canCreate); //false
?
利用了'|'和'&'两个操作,但是这样看起来很是别扭,初始化权限和验证权限用了一长串'|'和'&'运算的代码,很不直观。我在System.Enum中扩展了一些方法供调用,代码如下:
?
//是否存在权限public static bool Has<T>(this System.Enum type, T value){ try { return (((int)(object)type & (int)(object)value) == (int)(object)value); } catch { return false; }}//判断权限public static bool Is<T>(this System.Enum type, T value){ try { return (int)(object)type == (int)(object)value; } catch { return false; }}//添加权限public static T Add<T>(this System.Enum type, T value){ try { return (T)(object)(((int)(object)type | (int)(object)value)); } catch (Exception ex) { throw new ArgumentException( string.Format( "不能添加类型 '{0}'", typeof(T).Name ), ex); }} //移除权限public static T Remove<T>(this System.Enum type, T value){ try { return (T)(object)(((int)(object)type & ~(int)(object)value)); } catch (Exception ex) { throw new ArgumentException( string.Format( "不能移除类型 '{0}'", typeof(T).Name ), ex); }}
?
使用一下:
?
//创建一个用户User admin = new User();PermissionTypes permissions = new PermissionTypes();admin.Permissions = permissions;//添加权限admin.Permissions = admin.Permissions.Add(PermissionTypes.Create);admin.Permissions = admin.Permissions.Add(PermissionTypes.Read);admin.Permissions = admin.Permissions.Add(PermissionTypes.Write);//判断权限bool canRead = admin.Permissions.Has(PermissionTypes.Read); //truebool canWrite = admin.Permissions.Has(PermissionTypes.Write); //truebool canDelete = admin.Permissions.Has(PermissionTypes.Delete); //falsebool canCreate = admin.Permissions.Has(PermissionTypes.Create); //trueConsole.WriteLine(canRead); //trueConsole.WriteLine(canWrite); //trueConsole.WriteLine(canDelete); //falseConsole.WriteLine(canCreate); //trueConsole.Read();
?
现在按照上面的思路,我在SQL Server里面模拟一下上面的操作,在sql中与或运算是很高效的。先设计两张表User和Permission。
?
?
1、获取有Read权限的所有用户:
?
select * from [User] where PermissionTypes&1 =1
?
?
?
2、获取有Delete权限的所有用户:
?
select * from [User] where PermissionTypes&8 =8
?
?
?
3、判断qilin是否有Delete权限:
?
if exists (select * from [User] where Name='qilin' and PermissionTypes&8 =8) print 'true'else print 'flase'
?