Настройка модели CanCan Способность .rs - PullRequest
4 голосов
/ 02 марта 2011

Я успешно создал систему входа в систему с Devise и CanCan, и у меня есть 3 типа пользователей. Админ, внутренние и глобальные пользователи. Я создал контроллеры и индексные действия: Admin, Cpanel, Report и State и хочу ограничить доступ к этим контроллерам для некоторых пользователей.

Администратор должен иметь права доступа: отчеты (все), состояние (чтение), администратор (все)

Глобальный пользователь должен иметь права доступа: отчеты (только чтение), состояние (чтение), Cpanel (все)

Внутренний пользователь должен иметь права доступа: отчеты (все), состояние (чтение)

И я попытался сделать это с помощью следующего кода в способе .rs :

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # guest user (not logged in)

    if user.role? :admin
      can :manage, [Report, Admin]
      can :read, State
    elsif user.role? :global_user
      can :read, [Report, State]
      can :manage, Cpanel
    elsif user.role? :internal_user
      can :manage, Report
      can :read, State     
    end
   end
end

В настоящее время у меня есть только действия индексации в этих контроллерах, и когда я вхожу в приложение с внутренним пользователем, я могу, например, получить доступ к / admin, и это не то поведение, которое я хочу. Я хочу ограничить доступ ко всем контроллерам вместо контроллеров, перечисленных в классеility.rb.

Исходный код здесь

Ответы [ 3 ]

8 голосов
/ 02 марта 2011

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

def check_permissions
 raise CanCan::AccessDenied unless @current_user.role?(:admin)
end

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

def update
  raise CanCan::AccessDenied unless can?(:update,Thing)
  ...
end

def create
  raise CanCan::AccessDenied unless can?(:create,Thing)
  ...
end

Вы можете обработать исключение CanCan::AccessDenied в контроллере приложения:

rescue_from CanCan::AccessDenied do |exception|
    flash[:error] = exception.message
    redirect_to no_access_path
  end

У меня есть несколько хороших сообщений о CanCan и Devise здесь и здесь

UPDATE Я использую этот метод в контроллере приложения для установки моей текущей пользовательской переменной:

# Make the current user object available to views
  #----------------------------------------------------------------------------
  def get_user
    @current_user = session[:current_user]
  end
2 голосов
/ 02 марта 2011

Вам необходимо добавить проверки для авторизации cancan на ваши контроллеры.

Это может быть просто добавление строки типа

authorize! :read, @state

к вашему действию индекса контроллера состояния и аналогично для всехдругие действия с индексами.

РЕДАКТИРОВАТЬ: Извините, в действии индекса контроллера состояния у вас, скорее всего, нет @state, поэтому вышеприведенное не будет применяться.Возможно, что-то вроде

authorize! :read, State

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

load_and_authorize_resource: state

, и это должно быть перед вашими действиями.

Возможно, вы захотите посмотреть на это Railscast на канкан авторизации для полной базовой настройки (в rails2).

Я подозреваю, что для устранения других проблем, возможно, нам понадобится еще немного кода.Попробуйте опубликовать часть кода вашего контроллера.

Я не использовал это в rails3, но я предполагаю, что большая часть его остается более или менее похожей.

0 голосов
/ 02 марта 2011

Я решил эту проблему с помощью

def check_permissions
 raise CanCan::AccessDenied unless current_user.role?(:admin)
end

, но учтите, что мне нужно изменить @current_user на current_user (без @)

Спасибо, Тони

...