Rails 3.2 CanCan - ограничить доступ к проектам, URL которых не принадлежит - PullRequest
1 голос
/ 15 января 2012

Я пытаюсь ограничить доступ к проектам, которые пользователь не создал.Кажется, это нормально работает с:

if user.has_role?(:Student)
  can :create, Project
  can :manage, Project, :user_id => user.id
end

(Дополнительный вопрос: есть ли лучший способ написать это? ^^)

Однако я все еще могу получить доступ к URL: / users/ 5 / projects

Я просто не вижу проекты, как ожидалось.Я предпочел бы сказать, что я не могу получить доступ к странице и перенаправить.У меня есть это в моем контроллере приложения:

rescue_from CanCan::AccessDenied do |exception|
  redirect_to root_url, :alert => exception.message
end

Но я не получаю перенаправление или сообщение об ошибке.Нужно ли добавить что-то еще к способностям, чтобы это работало?

У меня есть load_and_authorize_resource в ProjectsController и UsersController.

Для записи мои маршруты выглядят так:

resources :users do
  resources :projects
end

Ответы [ 2 ]

1 голос
/ 15 января 2012

Попробуйте это

if user.has_role?(:Student)
  can :create, Project
  can :manage, Project do |P|
    user && P.user == user
end

Он проверит, владеет ли текущий пользователь проектом или нет. Если ему не принадлежит проект, он не сможет его изменить.

Первое условие - просто проверить, существует ли user объект или нет, вы также можете использовать там обработчик исключений. Вот пример этого:

comment.try(:user) == user
0 голосов
/ 15 января 2012

Если вы хотите включить поведение перенаправления, если пользователь не может прочитать ни одного проекта в текущей коллекции, переопределите действие индекса и добавьте дополнительное принудительное выполнение:

def index
  # @projects is loaded by the CanCan before filter load_and_authorize_resource
  unless @projects.any?{|project| can?(:read, project)}
    raise CanCanAccessDenied.new("no project readable there", :read, Project)
  end
end

В действиях контроллера, подобных индексу (коллекции)CanCan применяет ACL через authorize :read, ModelClass.
https://github.com/ryanb/cancan/wiki/Checking-Abilities, см. Раздел «Проверка с помощью класса».
Как вы можете прочитать, если есть возможность, чтобы пользователь: прочитал любой из экземпляров ModelClass(даже если эти экземпляры еще не существуют) запрос authorize :action, ModelClass будет авторизован.

С учетом вашего URL /users/5/projects и маршрутов resources :users do resources :projects end Я считаю, что это действие является индексом проектов для конкретного пользователя.Таким образом, действие индекса CanCan будет авторизовано, учитывая can :manage, Project, :user_id => user.id, поэтому могут существовать проекты, которые пользователь может: читать как таковые => авторизовать.Позже, я верю, что вы авторизуете каждый конкретный экземпляр проекта can? :read, project, и там они фильтруются, так как страница остается пустой.

...