2013-05-10 1 views
1

В моем приложении rails я использую Devise, который аутентифицирует пользователей в приложении. Это дает мне переменные, такие как current_user.id, который является текущим пользователем UserID пользователя.В Rails, как я могу проверить, имеет ли пользователь доступ к изменению записи?

В моем приложении каждый пользователь является членом хотя бы одной группы. Любой пользователь может создать один или несколько Брелок и может назначить каждый Брелок одной из своих групп.

Итак, вот мои модели:

User has_many :memberships 
User has_many :groups, :through => :memberships 

Group has_many :memberships 
Group has_many :users, :through => :memberships 
Group has_many :trinkets 

Trinket belongs_to :group 

Так что мои модели! Все отлично работает!

Когда пользователь обновляет Trinket, он может назначить эту Trinket одной из своих групп.

НО, есть дефект безопасности! Если кто-то просмотрит Trinket/edit или Trinket/new page, скопирует исходный код HTML, изменит значения тегов <SELECT> или <INPUT> в форме, они могут фактически отправить свои Trinket в чужой GroupID.

Я хотел бы добавить валидацию в модель или контроллер, чтобы убедиться, что пользователь действительно имеет доступ к использованию представленных значений перед их записью в базу данных. В этом случае я хочу узнать, является ли GroupID для этого Trinket GroupID в пределах User.find(current_user.id).groups, но я не могу понять, как сделать эту проверку в модели Trinket.

Кто-нибудь знает, как проверить, что пользователь пытается присвоить значение тому, что действительно имеет доступ для его назначения? Есть ли у разработчика или другого драгоценного камня способ проверки ассоциаций для представленных пользователями данных?

Текущий файл Аксессуар модель только имеет:

attr_accessible :trinketname, :group_id 
validates_presence_of :trinketname 

Надеется, что это имеет смысл. Помощь приветствуется! :-)

Версии: Rails 3.2.13, Ruby 1.9.3p392, Devise 2.2.4. У меня есть protect_from_forgery в моем файле application_controller.rb.

ответ

1

Вы можете поместить в свое действие заявление if. Это, вероятно, неточно, но я надеюсь, что он набирает обороты:

+0

вы можете добавить проверку в создание и обновление действия в контроллере. что-то вроде, если Tricket.group_id == current_user.group_id, тогда сделайте свое действие action else flash [: warn] «вам не разрешено» –

+0

Спасибо, iRichLau. Это работает! Поскольку мои отношения User-Group - это многие-ко-многим, мне пришлось выполнять поиск массива вместо прямого соответствия '=='. Для 'def create':' if current_user.groups.include? (Group.find @ trinket.group_id) 'и для' def update': 'if current_user.groups.include? (Параметры Group.find [: trinket] [: group_id]).Если представленные данные включают group_id, что Пользователь не является членом, он возвращает false. Если представленная group_id не существует в базе данных, она выдает ActiveRecord :: RecordNotFound, которая была непреднамеренной, но приемлемой, поскольку это также допустимая ошибка. Ура! –

1

Вам нужна авторизация.

Рассмотрите возможность использования одной из многих доступных систем авторизации для достижения своей цели.

CanCan автор: Райан Бэйтс - один из самых проверенных боевых действий.

UPDATE: Ability можно сделать:

class Ability 
    include CanCan::Ability 

    def initialize(user) 
    can :manage, Trinket, group: { id: user.group_ids } 
    end 
end 
+0

не разделяет такие роли, как пользователи и администратор. многие пользователи могут иметь роли пользователей, и они смогут получить к ней доступ независимо. –

+0

Ну, да и нет. В то время как он помогает вам разделяться между разными типами пользователей, например, CanCan 'Ability', дает вам более тонкий контроль над правами« User ». Посмотрите UPDATE выше. – pungoyal

+0

прохладный. это тоже работает. хотя, если вам не нужны роли и вы просто хотите иметь простую авторизацию. я бы пошел со вспомогательным методом и поставил это, где бы вы хотели. –

Смежные вопросы