2016-01-07 3 views
2

У меня есть существующие приложения Rails с Devise аутентичностью User модели и Pundit Идентификации по Enrollment с моделью, которая связывает User моей Company модели. Оба User и Company находятся в открытой схеме квартиры. Я не подозреваю, что квартира является частью проблемы, но я подумал, что я бы сказал об этом.Активного Admin, Разрабатывают и Пандит (Пандит :: PolicyScopingNotPerformedError)

Я добавил Active Admin с классом AdminUser - я хочу, чтобы пользователь моего администратора был отдельно от пользователей приложения.

Если я пытаюсь получить доступ к /admin или /admin/dashboard я получаю:

Pundit::PolicyScopingNotPerformedError at /admin/users 
Pundit::PolicyScopingNotPerformedError 

Если бы я попробовать свои модели, как /admin/users кажется Пандит игнорировать политику active_admin и идет к основным политики приложений. В моем случае приложение выдает исключение, потому что оно ожидает Enrollment против AdminUser.

Если я вывожу:

##/config/initializers/active_admin.rb 
    config.authorization_adapter = ActiveAdmin::PunditAdapter 

##/controllers/application_controller 
    after_action :verify_authorized, except: [:landing, :dashboard], unless: :devise_controller? 
    after_action :verify_policy_scoped, only: [:index] 

все это работает, но тогда я потеряю Pundit и т.д. в моем главном приложении.

Вот суть моего кода:

https://gist.github.com/jasper502/4b2f1b8b6f21a26c64a5

Вот соответствующие сообщения, которые могли бы найти по этому вопросу:

https://gorails.com/forum/using-pundit-with-activeadmin

How to get Active Admin to work with Pundit after login

Я искал для отключения Pundit все вместе в этом сообщении (Can you disable Pundit with Devise and Active Admin?) b Было бы неплохо просто сделать эту работу.

UPDATE

У меня есть работа вокруг, но я до сих пор не знаю, если это должно работать из коробки и у меня есть некоторые странные проблемы, вызывая все это. Обновлен Gist.

Я закончил с использованием:

https://viget.com/extend/8-insanely-useful-activeadmin-customizations

и немного:

Documentation for conditional before_action/before_filter

и немного ответа ниже. Я зачеркнул фильтр, чтобы заставить АА вызвать авторизацию на ресурсы и коллекции внутри АА. Далее следует добавить области политики, но мой мозг слишком сильно болит.

Мне также пришлось добавить еще один фильтр, чтобы обходить аутентификацию на панели мониторинга, поскольку она безголовая. Кажется, работает до сих пор.

UPDATE 2

Хммм ... Я думаю, что я говорил слишком рано.Это все работает только в том случае, если я вошел в систему как обычный User. - Если я выйду из системы, все это снова развалится.

ответ

5

@ дан-Tappin Я полагаю, вы уже нашли подобное решение на основе ваших комментариев, но вот то, что я в конечном итоге добавив к каждому из моих регистраций модели AA:

#app/admin/user.rb 
ActiveAdmin.register User do 
    controller do 
    before_filter :authorize_index, only: :index 
    def authorize_index 
     policy_scope(User) 
    end 

    before_filter :authorize_show_edit_destroy, only: [:show, :edit, :destroy] 
    def authorize_show_edit_destroy 
     authorize resource 
    end 
    end 
end 

В основном это использует способность для выполнения в области контроллера с использованием обычных рельсов перед синтаксисом before_filter, чтобы ограничить выполнение только с помощью:. Затем, поскольку before_filter происходит после фильтров inherrited_resources, у нас есть доступ к «ресурсу», и мы можем разрешить его, как обычно, против любого экземпляра модели. См: https://github.com/activeadmin/activeadmin/issues/1108#issuecomment-14711733

Причина сфера политики необходима в первую очередь потому, что обычная установка пандит требует следующее в application_controller.rb

#app/controllers/application_controller.rb: 
class ApplicationController < ActionController::Base 
    # Prevent CSRF attacks by raising an exception. 
    # For APIs, you may want to use :null_session instead. 
    include Pundit 
    protect_from_forgery with: :exception 

    #before_action :authenticate_is_admin! 

    after_action :verify_authorized, except: [:index, :dashboard], unless: :devise_controller? 
    after_action :verify_policy_scoped, only: :index, unless: :devise_controller? 

    rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized 

    private 
    def authenticate_admin! 
    redirect_to new_user_session_path unless current_user.admin? 
    end 

    private 
    def pundit_user 
    current_user 
    end 

    private 
    def user_not_authorized 
    flash[:error] = "You are not authorized to perform this action." 
    redirect_to(request.referrer || new_user_session_path) 
    end 
end 

Он ожидает вызова сферы политики модели для всех действия индекса. Контроллер панели управления делает действие индекса по умолчанию, поэтому это требует взлома before_filter.

+2

Спасибо за это. Вместо вашего первого 'before_filter' в admin/{resource} .rb вы можете изменить ApplicationController:' after_action: verify_policy_scoped, only:: index, если:: devise_or_pundit_controller? '...' def devise_or_pundit_controller? devise_controller? || self.class.name.match (/^Admin /) end' – Jay

+0

Ницца, который чище! –

0

Можете ли вы просто пропустить область действия в вашем контроллере активного администратора с помощью skip_policy_scope?

Смотрите documentation:

Если вы используете verify_authorized в контроллерах, но нужно условно перепускной проверки, вы можете использовать skip_authorization. Для обход verify_policy_scoped, используйте skip_policy_scope.

+0

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

+0

Хммм ... единственный способ показать, что я делаю то, что с №1 от https://viget.com/extend/8-insanely-useful-activeadmin-customizations Теперь я получаю ошибки «Pundit :: AuthorizationNotPerformedError». –