如何使用acl9管理用户及其作为管理员的角色

时间:2015-03-20 03:36:55

标签: ruby-on-rails acl9

想知道使用acl9管理用户角色的最佳方法是什么?

这是需要:

  • 管理员应该能够更新用户的角色。

以下是问题:

  1. 我们如何列出所有主题角色? :admin,:manager
  2. 为了保持api端点RESTful,我想在理想情况下在user_controller的update方法中传递角色param。
  3. 如何仅为role属性进行授权,以便用户对象的所有者仍然可以修改其first_name,last_name字段,但不能修改其角色字段?只允许管理员。
  4. 我可以在access_control块之外手动检查参数:

    def secure_params
        if current_user.has_role?(:admin)
            params.require(:user).permit(:first_name, :last_name, :role)
        else
            params.require(:user).permit(:first_name, :last_name)
        end
    end
    

    但我想我会检查一下是否有更清洁的解决方案。

    最后,使用RoleTypes.ADMINRoleTypes.MANAGER而非:admin之类的内容是否可行且明智?如果是这样,那么最好的方法是什么,并且可以通过rails应用程序访问Class?

2 个答案:

答案 0 :(得分:2)

  

我们如何列出所有主题角色? :admin,:manager

Role模型只是一个普通的模型,因此您可以像查询其他任何内容一样进行查询:

Role.uniq.pluck :name
  

为了保持api端点RESTful,我想在理想情况下在user_controller的更新方法中传递角色param。

通常,您最好使用单独的控制器执行管理,并将其放在Admin::命名空间中,并使用namespace :admin do路由等。

然后在该控制器中,您可以使用普通access_control块来确保没有其他人可以进入:

class Admin::UsersController < ApplicationController

  access_control do
    allow :admin
  end

  # ...

end

那么,是的,你可以通过多种方式设置/更新角色,但看到用户可以拥有多个角色,最好不要只有一个:role参数,但是而是使用:

class User < ActiveRecord::Base
  acts_as_authorization_subject
  accepts_nested_attributes_for :roles
end

然后在你的控制器中你会有:

def user_params
  params.require(:user).permit(:first_name, :last_name, roles_attributes: [:name])
end

然后在您的表单中,您可以执行以下操作:

= form_for :user do |f|
  = f.text_field :first_name
  = f.text_field :last_name
  = f.fields_for :roles do |fr|
    = fr.text_field :name

请注意,我假设您在这里只有简单的角色,而不是对象上的角色,如果您有对象角色,那么您需要一些有点棘手的东西来捕获authorizable_id和{{ 1}}用于每个角色,以及某种方式来选择要操作的对象。

  

如何仅为role属性进行授权,以便用户对象的所有者仍然可以修改其first_name,last_name字段,但不能修改其角色字段?只允许管理员。

希望您现在已经自己回答了这个问题 - 通过为管理界面和用户自己的界面使用不同的控制器。

  

最后,是否可以使用RoleTypes.ADMIN,RoleTypes.MANAGER而不是:admin?

不,这些符号更简单,更好,尽管这样做很常见:

authorizable_type

这样你就可以使用class Role < ActiveRecord::Base def self.permitted_roles %i/admin manager foo bar wee/ end end 构建一个复选框数组,或者一个下拉列表,或类似的东西。

答案 1 :(得分:-1)

编辑:完全错过了第一句中的acl9位 - 对不起!

话虽如此,我的答案仍然适用;我会有一个帮助方法或使用acl9的has_role?方法并根据此更改视图。即:

>> <% if @user.has_role?(:foo, nil) %> 
>>    <p>
>>    <%= f.label :usertype %><br />
>>    <%= f.check_box :usertype %>
>>   </p>
>> <% end %>

我会使用帮助器方法使用.has_role!方法实际设置用户角色,即:user.has_role! :some_role,[可选范围],其中user是被分配角色的用户。

有关详细信息,请查看此内容(来自acl9文档): https://github.com/be9/acl9/wiki/Tutorial%3A-securing-a-controller


好的,如果我认为你说的是​​正确的,你想要一种方法让用户可以编辑内容和/或个人资料信息,但管理员可以编辑用户角色。

首先,我将假设角色是您的用户架构的一部分(如果不是,我建议您考虑将其移动到那里)。如果是这样,我建议为您的用户模型may_edit?(content)添加一个方法,该方法根据用户角色或ID返回一个布尔值。即:

  

def may_edit?(content) item.user.id == self.id end

通过控制器中的find_by(id)找到内容的位置。然后,您可以使用控制器中的if来指示哪些内容将显示在节目中:

  

<% if current_user.role == admin %> <%= some button or link or dropdown render %> <% end %>

     

<% if current_user.may_edit?(content) %> <%= some button or link or dropdown render %> <% end %>

或者那些东西。您还可以将if..else作为单独的辅助方法或may_edit?方法编写(我建议将其作为模型方法)。理想情况下,控制器不应该是决定谁能够和不能执行此类事情的人。如果您已在控制器中执行此操作,则可能需要查看控制器顶部的:before_filter,即:

  

:before_filter admin?, except [:foo, :bar]

我不确定要在params中传递哪个用户ID,但是可以找到编辑器/管理员或原始海报的ID - current_user将作为会话[:user_id]和原始对象记录在会话中海报可以通过正在编辑的内容找到,因为它属于用户,可以通过``User.find_by(content.user_id)找到。

最后,您是否在询问如何查看所有用户角色的列表?如果是这样,您可以使用下拉菜单,但是您必须在项目中的某个位置对它们进行硬编码,或者遍历每个用户并聚合它们的角色,尽管后者远非理想且非常低效。

希望这有帮助,祝你好运!