Как реализовать сложные правила безопасности в Ruby on Rails - PullRequest
1 голос
/ 21 мая 2009

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

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

Примеры правил:

  • Модераторы могут оставлять комментарии со статусом модератора, но не со статусом администратора.
    • Комментарии. Статус может быть только обычным или модератором (администратор зарезервирован для администраторов)
  • Пользователи не могут изменять значение модератора в комментариях
    • Comments.status может быть только нормальным, Comments.display может быть только нормальным
  • Только модераторы могут приостанавливать учетные записи пользователей.
    • список многочисленных полей
  • Только модераторы могут изменять другие учетные записи пользователей.
    • ограничение по полям с логикой, чтобы определить, принадлежит ли текущий пользователь строке
  • Только пользователи с платными учетными записями могут выполнять X, Y и Z.

У меня проблема в том, куда мне поместить эту логику. Это становится слишком сложным для проверки рельсов. Реализация некоторых из этих правил является трудной или невозможной, если я смотрю только на статус авторизованного пользователя. Текущее решение заключается в создании класса Security, который будет принимать объект базы данных и пользователя и разрешать или запрещать действие.

Если я буду следовать этому курсу действий, реализация будет мерзкой. Прямо сейчас я смотрю на что-то вроде этого

#For every field on an object passed to Security::allow?(user, object), call this private method
def allow_helper?(user, object, field) 
    perm = permissions[user.rank][object.class.name][field] 
    if perm.is_a? Array
          perm.include? object.send(field)
    else
          perm

Что очень быстро станет кошмаром для поддержания. Должна быть альтернатива этому кошмару, о котором я мечтал. Я остановил себя, прежде чем я закодировал это.

1 Ответ

0 голосов
/ 21 мая 2009

Почему бы вам не создать Permissions модель, а затем просто посмотреть, если user.permissions.find(:permission_name_here) при разработке проверок и представлений?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...