我有 ActiveAdmin 和 Pundit 设置和工作。我的用户模型有一个角色属性(rails 4.1 枚举)。如何只允许具有 admin 角色的用户登录 /admin?
2 回答
这是执行此操作的另一种方法,无需触摸ActiveAdmin::BaseController.
在您的 AA 初始化程序中,添加
# config/initializers/active_admin.rb
config.on_unauthorized_access = :user_not_authorized
并实施ApplicationController#user_not_authorized
# app/controllers/application_controller.rb
:
def user_not_authorized(exception)
sign_out # or user will end up in a redirection loop
flash[:error] = "Access has been denied because ..."
redirect_to new_user_session_path
end
最后,更新 AA 页面(或仪表板等)的策略
# app/policies/active_admin/page_policy.rb
module ActiveAdmin
class PagePolicy < ::ActiveAdminPolicy
def show?
User.roles[user.role] >= User.roles['manager']
end
end
end
完成后,只有管理员及以上人员才能登录。
我遇到了同样的问题,我是这样解决的:
角色在 中定义User#role。
class User < ActiveRecord::Base
enum role: [ :client, :reseller, :manager, :admin, :super ]
end
以下是如何限制/admin作为客户或经销商的用户对 AA 的所有访问权限。
首先,将 a 添加before_filter到 AA ,如此处BaseController所述。
# lib/active_admin/deny_unprivileged/usage.rb
module ActiveAdmin
##
# Only users showing a minimum user level (role)
# should be allowed to access the administration interface.
module DenyUnprivilegedUsage
extend ActiveSupport::Concern
included do
before_filter :deny_unprivileged_usage
end
private
##
# Deny access to /admin, unless user is, at least, a manager.
#
# This does the same as Devise::Controllers::Helpers#sign_out_and_redirect,
# but adds a flash message explaining why access has been denied.
#
# See Devise::Controllers::Helpers#sign_out_and_redirect
def deny_unprivileged_usage
if current_user and not User.roles[current_user.role] >= User.roles['manager']
resource_or_scope = current_user
scope = ::Devise::Mapping.find_scope!(resource_or_scope)
redirect_path = new_user_session_path
::Devise.sign_out_all_scopes ? sign_out : sign_out(scope)
flash[:error] = "!!!"
redirect_to redirect_path
end
end
end
end
创建一个初始化器。
# config/initializers/active_admin_extensions.rb
require 'active_admin/deny_unprivileged_usage'
ActiveAdmin::BaseController.send(:include, ActiveAdmin::DenyUnprivilegedUsage)
重新启动您的服务器。
现在,至少不是经理的用户将被拒绝访问/admin. 用户实际上会成功登录,但是,登录后,上面定义的过滤器将立即注销用户并重定向回登录页面。
该deny_unprivileged_usage方法几乎是一个副本Devise::Controllers::Helpers#sign_out_and_redirect- 除了它添加了一条消息,向用户解释为什么登录被拒绝。如果没有此更改,用户将只能返回登录页面,不知道登录被拒绝的原因。
更新
再想一想,如果用户注册了,很难想象他们永远无法登录。
因此,对于不同的命名空间使用不同的授权适配器和策略来实现基于角色的访问限制可能会更干净。如此处所述。
然后,/reseller将能够登录并更改他们的密码,同时/manager将提供更多功能。这样,政策和 AA 资源将被明确分离。