2011-09-20 32 views
5

我正在构建一个系统,组织将输入有关其业务的信息。需要向多个级别的用户提供报告,其中一些用户只能访问其组织的统计信息,而较高级别的用户可以访问单个组织的统计信息以及更高级别实体的综合统计信息(请参阅我的示意图层次结构)。用层次结构管理用户权限

Example hierarchy

  • 将有一个直辖市内的一个或多个组织。
  • 将有一个或多个直辖市县
  • 会有的状态的一个或多个县
  • 将有一个或多个国家
  • 组织,市,县,并且可以添加状态在任何时间
  • 当系统添加组织,市镇和县时,已经有权查看该州的用户应该能够自动查看新组织/市/县的报告,而无需管理员明确授予他们许可。对于有权在市级和县级查看报告的用户,只要在系统中添加了他们下方的新实体时,同样适用。

一些例子:

用户1:只能查看组织#报告1

用户2:可以查看下市#所有组织的报告2

用户3:可查看所有市政机构的报告#1 &#2

用户4:可以查看下县#所有组织的报告3

用户5:可以查看下状态#所有县3

我的问题是如何组织这个报告?我不确定为个人组织分配权限而为报告分配权限的最佳方式。这显然不实际。

我在这里看到了几个与ACL有关的问题,但它们似乎并不适用于此。如果确实如此,那么解释它与ACL的关系也将是一个令人满意的答案。

回答

1

我在想,一个办法是,你assing唯一的权限ID对每个实体(oranisation,市,县,州)

所以,你的表应该有一个新列permission_id有以下形式: 组织1将有permission_id O1 组织2将有权限ID O2

市1将有权限编号M1 市2将有权限编号M2

等。

然后,你可以做一个权限表(ID,id_user,权限) 在权限列会像 O1 - permisssion仅供Organisation1 M1 - 在本市权限所有组织1 M1M2 - 许可所有组织在市政府1和2

S1 - 为国家1

许可,这只是我的看法。只要您知道用户有权访问某个市镇,他就可以访问该市政府下的所有内容。 一些可以从当前实体获取路由的php函数可以匹配用户权限。

示例。

你在市区页面。 M2。如果用户拥有S2 的许可权,您的功能将作为市政ID参数,该功能将创建路线:M2,C3,S1。您将S2与S1进行比较,并且权限被拒绝。这样,复杂性是O(n),其中n是实体(组织,市镇,县和州,即4)的数量。

4

我建议在数据库中创建一系列用户组,每个用户组都有一个或多个用户帐户级别,然后将整数作为分层值分配给组,然后对个人帐户进行相同操作组内的水平,这样的事情(这是一个关系结构,使用InnoDB):

table: account_groups (Broader account groupings) 
Fields: 
-id_key - primary key, auto number 
-group - unique index 
-parent - index, foreign key=account_groups.group (this allows you to create group trees, so you can specify that a county group belongs to a state, and a municipality belongs to a county group, etc.) 
-group_hierarchy - integer (0 is highest permission group, each subsequent one step lower) 

table: account_levels (Account levels within a group) 
Fields: 
-id_key - primary key, auto number 
-account_level - unique index 
-group - index, foreign key=account_groups.group 
-account_heirarchy - integer (same as other table but denotes heirarchy within the group 

table: user_accounts (Individual user accounts) 
Fields: 
-id_key - primary key, auto number 
-account_id - unique index, user account name 
-account_level - index, foreign key=account_levels.account_level 

table: user_groups (denotes which tree(s) the user has access to) 
Fields: 
-id_key - primary key, auto number 
-account_id - index, foreign key=user_accounts.account_id 
-group - index, foreign key=account_groups.group 

再来说权限:

table: permissions (directory of permissions that could be applied) 
Fields: 
-id_key - primary key, auto number 
-permission - unique index, permission identifier 
-other stuff you need associated with the individual permissions, based on how you want them to hook into your program 

table: permissions_group_permissions (permissions applied at group level) 
Fields: 
-id_key - primary key, auto number 
-group - index, foreign key=account_groups.group 
-permission - index, foreign key= permissions.permission 

table: permissions_account_permissions (permissions applied at account level) 
Fields: 
-id_key - primary key, auto number 
-account_type - index, foreign key=account_levels.account_level 
-permission - index, foreign key=permissions.permission 

table: permissions_individual_permissions (permissions applied to individual accounts, if neccessary) 
Fields: 
-id_key - primary key, auto number 
-account_id - index, foreign key=user_accounts.account_id 
-permission - index, foreign key=permissions.permission 
-allow_or_deny - boolean (TRUE means permission is granted, FALSE means permission if revoked. This allows you to fine tune individual accounts, either granting custom elevated permissions, or revoking individual permissions for troublesome accounts without demoting them from the group. This can be useful in some special circumstances) 
-expiration - timestamp (allows you to set expiration dates for permissions, like if you want to temporarily suspend a specific action. Programmatically set default value of 00/00/00 00:00:00 as indefinite. You can do this at the account and group levels too by adding this field to those tables.) 

然后可以使用PHP通过对权限进行迭代由fi个人帐户首先获取与帐户级别相关联的组,然后按分层次序对每个后续组进行排列,然后从当前组中的当前帐户级别迭代当前组的层级顺序(作为多维阵列添加到组数组)到组内最后一个现有帐户级别。接下来,您将获取每个后续​​组的所有帐户级别,最后为已添加到阵列的每个帐户级别获取所有关联权限。如果您实现了单独的用户权限,那么您需要在权限数组中添加单独应用的权限,最后从阵列中删除allow_or_deny字段设置为FALSE的任何权限。如果用户需要访问多个树,则可以向account_groups表中添加一条记录,以匹配其帐户ID,表示他们访问的树的最高级别是什么,然后遍历树中所有后续组。要向该帐户授予所有适用的权限,请从user_groups获取account_id的所有组关联,然后为每个树运行先前描述的过程。如果他们只能访问一棵树,则甚至不需要使用user_groups表。

an example of how the structure fits your model: 
group: USA, hierarchy = 0 
group: California, parent-> USA, hierarchy = 1 
group: Los Angeles, parent->California, hierarchy = 2 
group: Texas, parent->USA, hierarchy = 1 
group: Dallas, parent->Texas, hierarchy = 2 

美国组的成员可以访问所有内容。加州的成员可以访问所有后续组在加利福尼亚州的层次结构,而不是团体得克萨斯州,即使它们具有相同层次值(因为它们是不同的家长分支机构)

account levels: 
admin, hierarchy=0 
manager, hierarchy=1 
analyst, hierarchy=2 
staff member, hierarchy=3 

每个帐户级别都有所有的每个后续帐户级别的权限。

user accounts: 
Bob, manager (likes to spam junk email to everyone) 

您仍然可以通过将电子邮件权限permissions_individual_permissions并设置allow_or_deny值设置为FALSE撤销鲍勃电子邮件的权限。这可以让您阻止Bob发送垃圾邮件,而不会将他从管理中降级。

example PHP array: 
$account=array(
    groups=>array(), //Step 1: array_push each group the account is a member of here. Repeat for each tree from user_groups. 
    account_levels=>array(), //Step 2: loop through $account[groups], array_push each level here 
    permissions=>array(), //Step 3: loop through $account[account_levels], array_push each permission here. Then do the same for individual permissions applied to the account 
    restrictions=>array() //Step 4: loop through individual permissions where allow_or_deny=FALSE, array_push here (do the same for group and account level if you implemented restrictions for those tables as well). Tell your program to ignore permissions from this array, even if the account would otherwise have them. 
); 
+0

此外,这将允许您为不同的树设置不同的权限级别,因此单个用户可以在一棵树中访问状态,但只能在另一棵树中访问市级。 – mopsyd