Ограничение аром области действия в CakePHP
Хорошо, я предвосхищу это, говоря, что я новичок, и ACL, и архитектура MVC. Я следую учебному пособию по тортам с его сайта http://book.cakephp.org/2.0/en/tutorials-and-examples/simple-acl-controlled-application/part-two.html. Я понимаю содержание учебника, но удивляюсь, как проще всего поднять этот простой ACL на основе группы на следующий уровень. Я искал так безрезультатно. Итак, по вопросу.
Возьмем, например, слегка измененную версию функции в приведенном выше руководстве. Он просто устанавливает разрешения ARO для ACO.
Есть много районов, и много отделов, все с большим количеством пользователей, в каждом.
Отношения таковы: Район имеет много департаментов - один ко многим. В округе много пользователей, и у пользователей может быть много округов (если они принадлежат к отделу в этом районе). У отдела есть пользователи AnBelongsToMany - многие ко многим.
public function initDB() {
$group = $this->User->Group;
//Allow admins to everything
$group->id = 1;
$this->Acl->allow($group, 'controllers');
// issue 1) allow district managers to districts, departments, users
$group->id = 2;
$this->Acl->deny($group, 'controllers');
$this->Acl->allow($group, 'controllers/Districts');
$this->Acl->allow($group, 'controllers/Departments');
$this->Acl->allow($group, 'controllers/Users');
//issue 2) allow department managers to edit departments and users
$group->id = 3;
$this->Acl->deny($group, 'controllers');
$this->Acl->allow($group, 'controllers/Departments');
$this->Acl->allow($group, 'controllers/Users');
//we add an exit to avoid an ugly "missing views" error message
echo "all done";
exit;
}
Итак, эти разрешения устанавливаются, хотя это определенно удобно, но на самом деле решают небольшую часть проблемы. На самом деле, я действительно только мешал администраторам департамента выполнять функции районного уровня. Как администраторы районов, так и администраторы отделов могут выполнять CRUD пользователя без ограничений.
Что я хотел бы сделать, так это ограничить область действия каждого из типов администраторов USER CRUD только теми пользователями, которые находятся в пределах их отдела или района. например, Department Admin Foo не может удалить других пользователей Dept Admin, а Dist Admin Bar не может изменить имена всех других пользователей Dist Admin на nancy.
лол. Я серьезно в недоумении, как этого добиться.
Я полагаю, что одним из подходов было бы получить звание администратора, например, dist admin, а затем выяснить, в каком районе он является пользователем. наконец, верните всех пользователей в этом районе в переменную $userScope. Опять же, я новичок в торгах php и не уверен, как реализовать это предложение, даже если бы оно было хорошей идеей и лучшим способом справиться с этим. Какие-либо предложения?? Заранее спасибо!!!
редактировать: полезный ответ, @nicolae.
Тем не менее, все еще кажется, что я мог бы написать функцию, которая возвращает всех пользователей, которых любой данный администратор (любого данного aco) разрешено редактировать. мне так кажется, потому что я предполагаю, что администратор сам является частью возвращенной базы пользователей. например, dist admin для dist 9, находится в dist 9; Аналогичным образом, администратор отдела 1 находится в отделе 1.
could i write something like:
public getUserScope(){
$id = $this->Auth->user('id');
$dept = $this...
$dist = $this...
$access_level = $this->Session->read('Auth.User.group_id');
if($access_level == 3){
//get all users in this user's dept
} elseif($access_level == 2) {
//find all users in this user's dist
} elseif($access_level == 1) {
//find all users
}
}
Уч. учитывая все соединительные таблицы, связанные с объединением этой информации, это будет выглядеть как волосы медузы, когда на самом деле напечатано. Вы видите мою линию логики. это немного сложно для меня, чтобы сформулировать. дайте мне знать, если я должен уточнить что-нибудь дальше.
1 ответ
Таким образом, вы пытаетесь настроить систему ACL, которая управляет ограничениями, основанными не только на идентификаторе группы и контроллере / действии - вам нужны ограничения на уровне департамента и района.
Насколько я знаю, встроенная система ACL в CakePHP не может управлять этим уровнем ограничений.
В качестве решения я рекомендую вам разрешить пользователям доступ к нужным им местам (например, администраторы dept имеют доступ ACL к пользовательскому интерфейсу CRUD) и вставьте определенные ограничения в контроллер.
function editUserFromDepartment($userId = NULL) {
// Custom ACL check
if (! $this->__checkDepartmentByUserId($userId)) {
// Show the user a custom error message and redirect him to index page
}
// User editing code ...
}
function __checkDepartmentByUserId($userId) {
$dept = $this->Department->getByUserId($userId);
// Check if the current user belongs to this department
$currentUserDepartmentId = $this->Session->read('Auth.User.department_id');
return ($dept['Department']['id'] != $currentUserDepartmentId);
}
Удачи и дайте мне знать, если мое объяснение было достаточно ясным.
Nicolae
Редактировать (пытаясь ответить на редактирование @ Тодда): Я понимаю вашу точку зрения. Ваш код направлен на получение всех пользователей, к которым у текущего пользователя есть доступ. Вместо этого у меня был бы подход, основанный на событиях: когда пользователь X пытается отредактировать, выполните запрос, который определяет, разрешено ли Auth.User выполнять это действие для пользователя X.
Например, вы (Тодд) пытаетесь отредактировать мой профиль (NicolaeS), чтобы изменить идентификатор моего сотрудника, так как мой текущий неверный.
Функция $this->getUserScope('user-ID-of-NicolaeS')
проверит, совпадает ли идентификатор вашего отдела или района с основным и разрешит / запретит вам продолжать ваши действия в соответствии с этой проверкой.
Это выглядит ясно / достаточно просто?
Привет, Николае