Сложная проблема с дизайном класса

Я работаю над реализацией класса для управления разрешениями пользователей на моем веб-сайте.

Например: сотрудники могут просматривать записи о клиентах, но ничего больше, работодатели могут просматривать клиентов, а также управлять сотрудниками, а администраторы могут делать и то, и другое, а также управлять работодателями.

Пока что у меня есть следующее:

  • Я сохранил список разрешений, например addCustomer, delCustomer и т. Д. Каждое разрешение связано со списком ролей пользователей, которым разрешено выполнять это действие.

  • У меня есть простой класс разрешений. Я использую это примерно так:

    if ($ permissions-> can ('addCustomer')) echo «Добавить клиента»; else echo 'Не разрешено добавлять клиентов';

Однако сложность в том, что в некоторых местах мне нужно быть более конкретным. Например: у клиента есть разрешение: readMsgs, которое позволяет ему читать сообщения между собой и сотрудником. Однако, если у него есть это разрешение, он может просто изменить URL-адрес с:

site.com/messages/read/100

to

site.com/messages/read/101

И также прочтите сообщение №101, которое может быть между другим клиентом и сотрудником. Клиент не должен иметь возможность читать чьи-либо сообщения, кроме себя.

Точно так же клиент получил editCustomer разрешение, которое позволяет ему редактировать свой профиль, перейдя по ссылке:

site.com/customers/99

(где 99 - его идентификатор клиента)

Но если он перейдет на site.com/customers/100

Ему нельзя разрешать доступ к этой странице.

Как я могу решить эту проблему? В идеале я хотел бы передать идентификатор классу разрешений. Например:

if (! $permissions->can('readMsg', $msgId))
   echo 'not allowed';

if (! $permissions->can('editCustomer', $requestedCustomerId))
   echo 'not allowed';

Любые идеи, как мне пришлось бы реструктурировать структуру моего класса, чтобы разрешить вышеупомянутые вещи?


person Ali    schedule 22.04.2011    source источник


Ответы (2)


Я хотел бы более детально описать свою таксономию разрешений (например, «readOwnMsgs» против «readAnyMsg»). Это приведет к уточнению вашего кода проверки разрешений (например, site.com/messages/read/### идет что-то вроде «продолжить, если canReadAnyMsg или если canReadOwnMsg и автор сообщения является текущим пользователем»), предполагая, что эта логика должна быть инкапсулированы в отдельные классы с разбивкой по типу ресурса или любым другим обстоятельствам, которые могут повлиять на контекстную информацию, необходимую для принятия таких решений.

person Jollymorphic    schedule 22.04.2011

У меня был бы класс сообщений с функцией canRead(User). Это проверит права пользователя и скажет: «О, я сообщение от менеджера сотруднику. Если пользователь не является получателем сообщения, они не могут его прочитать». или так же просто: «Я - сообщение от менеджера к сотруднику. Пользователь является менеджером, поэтому он может его прочитать».

Я печатаю его на английском, потому что у меня отстой php (который, похоже, является предпочтительным языком).

person corsiKa    schedule 22.04.2011
comment
Я знаю Java, так что не стесняйтесь вводить это, если это будет проще. Но проблема в том, как класс узнает, является ли это запросом на чтение сообщения от сотрудника X к клиенту X или это запрос на редактирование профиля клиента X? В обоих случаях, как только класс узнает, что это за класс, он может затем проверить, является ли текущий пользователь клиентом Y, и в этом случае запрос будет отклонен. - person Ali; 23.04.2011
comment
Я не уверен, что понимаю суть вашего уточняющего вопроса. Как бы ваш запрос не узнал? messages/read/XYZ довольно четко определяет поведение. - person corsiKa; 23.04.2011