爲自定義應用程序設計專用ACL系統時出現了這個問題,但我認爲它適用於一般的ACL系統,因爲我還沒有發現如何解決這個問題通過看一些主流系統,如Zend_ACL
。構建'雙向'OO動態ACL系統
在我的應用程序中,權限是動態授予的,例如:用戶獲取某活動的查看權限,因爲他是該活動所鏈接到的團隊的成員。這建立在假定你總是有一個Employee
(用戶)想要對Item
(我的應用程序中的一個對象,例如Activity,Team等)執行操作(查看/編輯/等)。這對我的目標使用來說已經足夠了。
$Activity = new Activity($_POST['activity_id']);
$Acl = new Acl($Activity);
if (!$Acl->check('edit') {
throw new AclException('no permission to edit');
}
我Acl
類包含所有的業務規則,以授予的權限,他們是「對飛」創建(儘管有時緩存性能的原因);
/**
* Check the permissions on a given activity.
* @param Activity $Activity
* @param int $permission (optional) check for a specific permission
* @return mixed integer containing all the permissions, or a bool when $permission is set
*/
public function checkActivity(Activity $Activity, $permission = null) {
$permissions = 0;
if ($Activity->owner_actor_id == $this->Employee->employee_id) {
$permissions |= $this->activity['view'];
$permissions |= $this->activity['remove'];
$permissions |= $this->activity['edit'];
} elseif (in_array($this->Employee->employee_id, $Activity->contributor_ids_arr)) {
$permissions |= $this->activity['view'];
} else {
/**
* Logged in user is not the owner of the activity, he can contribute
* if he's in the team the activity is linked to
*/
if ($Activity->getTeam()->isMember($this->Employee)) {
$permissions |= $this->activity['view'];
}
}
return ($permission ? (($permission & $permissions) === $permission) : $permissions);
}
該系統按原樣正常工作。
當您想要「反向」ACL規則時,會出現此方法的問題。例如,「獲取我可以編輯的所有活動」。我不想在需要這些活動的代碼中放入任何邏輯,例如WHERE owner_actor_id = $Employee->employee_id
,因爲這是Acl
類的職責,應該保持集中。在目前的實現中,我沒有別的選擇來獲取代碼中的所有活動,然後逐個聲明它們。這當然是一種非常低效的方法。
所以,我正在尋找的是一個良好的架構(或指向現有ACL實現或一些相關的設計模式)的一些想法來創建一個ACL系統,該系統能以某種方式做到既hasPermission($Item, $permission)
和fetchAllItems($permission)
,最好用相同的業務規則集。
謝謝大家提前!
我已經看過Zend_ACL
的實現,但更多地關注於一般權限。我還發現了以下問題在這裏SO:
但不幸的是他們似乎並不要麼回答這個問題。
什麼是反對把'fetchAllItems參數()'方法在'Acl'課程?我不確定我真的明白這個問題。 – erisco