2011-09-20 58 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