Допустим, у меня есть модели, на которые распространяются права при использовании пользователями, но не при использовании бизнес-логикой.
Например:
Когда кто-то создает элемент A, он автоматически создает элемент B.
Пользователи должны иметь право создавать A или B, если он хочет их создать.
Но бизнес-логика при создании B из A не нуждается в каких-либо правах.
Если я добавлю правильную систему в бизнес-логику, я получу классы, которые сильно зависят от сеанса, и A не сможет создать B, если вошедший в систему пользователь не имеет прав.
Если я помещаю управление правами в контроллеры, я чувствую, что моя бизнес-логика небезопасна, так как любой программист может забыть проверить права перед созданием элемента и не будет остановлен, плюс есть дублирование кода, если 2 контроллера могут обновить элемент по любой причине.
Куда бы вы положили управление правами?
Я могу создать наследование каждого объекта, который будет использоваться контроллерами, и реализовать ограничение прав, в то время как бизнес-логика получит доступ к самим объектам. Контроллеры создают UserA, UserB, а объект A напрямую создает объект B.
Но, похоже, мне придется дублировать (наследовать) каждый объект бизнес-логики, который должен использоваться в контроллере, то есть 80% из них.
Я предложу вам использовать Laravel для того же. Laravel предоставляет промежуточное программное обеспечение, которое вам нужно указать в файле маршрута. поэтому каждый раз, когда будет вызван любой контроллер, сначала должно быть вызвано промежуточное программное обеспечение, а затем будут проверены все условия, после чего он будет перенаправлен на контроллер.
в промежуточном программном обеспечении вы можете создать один файл класса, который будет проверять роли и права или необходимые разрешения.
вы можете сослаться https://heera.it/laravel-5-1-x-acl-middleware
или может понравиться https://github.com/Zizaco/entrust#user-relation-to-roles
Вот пример:
<!-- language: php -->
//abstact Model
abstract class Models {
public function save() {
if($this->id === null) {
$this->insert();
} else {
$this->update();
}
}
abstract protected function insert() {
//insertion in DB
}
abstract protected function update() {
//update in DB
}
}//A Model
class A extends Model {
protected function insert() {
//check if logged in user can insert A objects otherwise throw an exception
//insert in DB
$b = new B;
//set $b datas
$b->save();
}
protected function update() {
//check if logged in user can update A objects and has rights on instanciated A otherwise throw an exception
//update in DB
}
}
//B Model
class B extends Model {
protected function insert() {
//check if logged in user can insert B objects otherwise throw an exception
//insert in DB
}
protected function update() {
//check if logged in user can update B objects and has rights on instanciated B otherwise throw an exception
//update in DB
}
}
//A Controller
class AController() {
public function createA() {
$a = new A;
//set $a datas
$a->save()
}
public function updateA($id) {
$a = new A($id);
//set new $a datas
$a->save()
}
}
//B Controller
class BController() {
public function createB() {
$b = new B;
//set $b datas
$b->save()
}
public function updateB($id) {
$b = new B($id);
//set new $b datas
$b->save()
}
}
Если я оставлю проверки внутри моделей, объект A не может создать объект B, если пользователи не могут, но он должен это делать, так как в этом примере B создают не пользователи, а бизнес-логика с помощью кода A.
Если я уберу проверки из моделей, чтобы поместить их в контроллеры, я столкнусь с программистом, который когда-нибудь забудет проверку и может иметь много дубликатов, когда разные контроллеры должны обновить элемент.
До сих пор я думал о:
Ни одна из этих идей полностью не удовлетворяет меня по другой причине: