使用层次结构管理用户权限

Joh*_*nde 5 php mysql reporting user-permissions

我正在构建一个系统,组织将输入与其业务相关的信息.报告需要在多个级别上为用户提供,其中一些用户只能访问其组织的统计信息,而更高级别的用户将可以访问单个组织统计信息以及更高级别的实体的汇总统计信息(请参阅我的图表,其中包含图示层次结构).

示例层次结构

  • 市内将有一个或多个组织.
  • 一个县将有一个或多个市镇
  • 一个州将有一个或多个县
  • 将有一个或多个州
  • 可以随时添加组织,市政,县和州
  • 当组织,市,县被添加到系统中时,已经有权查看该状态的用户应该能够自动查看新组织/市/县的报告,而无需管理员明确授予他们权限.这同样适用于有权在层次结构中将其下面的新实体添加到系统时在市级和县级查看报告的用户.

一些例子:

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

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

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

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

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

我的问题是如何组织这个?我不确定在不向各个组织分配权限的情况下为报告分配权限的最佳方法.这显然是不切实际的.

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

mop*_*syd 5

我建议在数据库中创建一系列用户组,每个用户组中都有一个或多个用户帐户级别,然后为该组分配一个整数作为层次结构值,然后对组中的各个帐户级别进行相同的操作,就像这样(这是一个关系结构,使用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
Run Code Online (Sandbox Code Playgroud)

然后获得权限:

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.)
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用php遍历单个帐户的权限,方法是首先获取与帐户级别相关联的组,以层次结构顺序排列每个后续组的数组,然后遍历当前组的层次结构顺序(添加(从多维数组到组数组),从组中的当前帐户级别到组中的最后一个现有帐户级别。接下来,您将获取每个后续​​组的所有帐户级别,最后获取已添加到阵列的每个帐户级别的所有关联权限。如果实现单个用户权限,则需要在权限数组后面附加单独应用的权限,最后将其allow_or_deny字段设置为FALSE的所有权限从数组中删除。如果用户需要访问多棵树,则将一条记录添加到与其帐户ID相匹配的account_groups表中,指明他们可以访问的树的最高级别是什么,然后遍历树中的所有后续组。要授予该帐户所有适用的权限,请从user_groups中获取该account_id的所有组关联,然后为每个树运行上述过程。如果他们只能访问一棵树,则甚至不需要使用user_groups表。从user_groups中获取account_id的所有组关联,然后为每个树运行上述过程。如果他们只能访问一棵树,则甚至不需要使用user_groups表。从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
Run Code Online (Sandbox Code Playgroud)

美国组的成员可以访问所有内容。加利福尼亚州的成员可以访问加利福尼亚层次结构中的所有后续组,但不能访问德克萨斯州的组,即使它们具有相同的层次结构值(因为它们是不同的父母分支机构)

account levels:
admin, hierarchy=0
manager, hierarchy=1
analyst, hierarchy=2
staff member, hierarchy=3
Run Code Online (Sandbox Code Playgroud)

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

user accounts:
Bob, manager (likes to spam junk email to everyone)
Run Code Online (Sandbox Code Playgroud)

您仍然可以通过将电子邮件权限添加到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.
);
Run Code Online (Sandbox Code Playgroud)


Dan*_*dea 1

我认为一种方法是为每个实体(组织、市、县、州)分配一个唯一的权限 ID

因此,您的表应该有一个新列permission_id,其形式如下:组织1将具有permission_id O1组织2将具有权限id O2

市政府 1 将拥有权限 ID M1 市政府 2 将拥有权限 ID M2

等等。

然后,您可以创建一个权限表(id、id_user、权限),其中权限列类似于 O1 - 仅对组织 1 的权限 M1 - 对市镇 1 中所有组织的权限 M1M2 - 对市镇 1 和 2 中所有组织的权限

S1——状态1的许可

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

例子。

您正在访问市政当局页面。M2。对于具有 S2 权限的用户,您的函数将获取市政 id 作为参数,并且该函数将创建一条路线: M2 、 C3 、 S1 。然后您将 S2 与 S1 进行比较,并且权限被拒绝。这样,复杂度为 O(n),其中 n 是实体的数量(组织、市、县和州,即 4)。