使用角色和小组模型在更复杂的环境中定义能力 [英] Defining abilities in more complex environment with role and group models

查看:76
本文介绍了使用角色和小组模型在更复杂的环境中定义能力的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的Rails应用程序中(我使用devise和cancan),每个(注册)用户完全属于 一个角色(管理员"或用户"),但至少属于 一组(例如家庭",朋友",同事").在运行时,创建新文件夹(见下文)时,可以设置与一个或多个组的habtm关系,该关系定义了谁可以访问该文件夹.完全选择 no 组将导致在世界范围内可访问的文件夹(即,无需登录用户即可访问这些文件夹).但是现在,我还不知道如何在我的capability.rb中定义这样的可在世界范围访问的文件夹,因为我不知道如何定义可以读取没有与其关联的组的文件夹".

in my rails app (I use devise and cancan), each (registered) user belongs to exactly one role ('Administrator' or 'Users') but to at least one group (something like 'Family', 'Friends', 'Co-workers'). At runtime, when a new folder (see below) is created, a habtm relation to one or many groups can be set, which defines who can access the folder. Selecting no group at all should result in a world-wide accessible folder (i.e. users do not have to be logged in to access these folders). But right now, I don't know yet, how to define such world-wide accessible folders in my ability.rb, because I do not know how to define "can read folders which have no groups associated to it".

我的app/models/ability.rb的相关代码段如下所示:

The relevant snippet of my app/models/ability.rb looks like this:

user ||= User.new
if user.role? :Administrator
  can :manage, :all
elsif user.role? :Users
  # user should only be able to read folders, whose associated groups they are member of
  can :read, Folder, :groups => { :id => user.group_ids }
else
  # here goes the world-wide-accessible-folders part, I guess
  # but I don't know how to define it:
  ## can :read, Folder, :groups => { 0 } ???
end

我的app/controllers/folders_controller.rb的相关代码段如下所示:

The relevant snippet of my app/controllers/folders_controller.rb looks like this:

class FoldersController < ApplicationController
  before_filter :authenticate_user!
  load_and_authorize_resource

有人可以给我一个提示吗?

Can someone give me a hint?

推荐答案

前几天我遇到了同样的问题.在阅读CanCan自述文件后,我想出了解决方案,如果尚未阅读,则应该执行此操作.

I had the same problem just the other day. I figured out the solution after reading the CanCan readme, which you should do if you haven't yet.

您可以在此处查看我的解决方案:使用CanCan进行上下文感知的授权

You can view my solution here: Context aware authorization using CanCan

要给您一个更具体的用例答案,请执行以下操作:

To give you an answer more specific to your use case, do the follow:

在应用程序控制器中,您需要定义一些逻辑来选择您的能力.

In your application controller you need to define some logic which will pick your abilities.

class ApplicationController < ActionController::Base
  check_authorization

  def current_ability
    if <no group selected logic> # Maybe: params[:controller] == 'groups'
      @current_ability = NoGroupSelectedAbility.new(current_user)
    else
      @current_ability = GroupSelectedAbility.new(current_user)
    end
  end

  # Application Controller Logic Below
end

然后,您需要在app/models/文件夹中创建一个或多个新功能.您也可以做一些很酷的事情:

You'll then need to create a new ability (or abilities) in your app/models/ folder. You can also do cool stuff like this:

if request.path_parameters[:controller] == groups
  @current_ability = GroupsAbility.new(current_group_relation)
end 

在app/controllers/groups_controller.rb中定义了current_group_relation的位置.这将为您提供特定控制器的特定功能.请记住,父类可以在Ruby的子类中调用方法.您可以在控制器中定义一个方法,然后从ApplicationController调用它,只要您确定当前正在使用哪个控制器来处理请求即可.

Where current_group_relation is defined in app/controllers/groups_controller.rb. This will give you specific abilities for specific controllers. Remember that a parent classes can call methods in child classes in Ruby. You can define a method in your controller, and call it from ApplicationController, as long as you are certain what controller is currently being used to handle the request.

希望有帮助.

我想向您展示自定义功能的外观.

I wanted to show you what a custom ability looks like.

# File path: app/models/group_ability.rb
class GroupsAbility
  include CanCan::Ability

  # This can take in whatever you want, you decide what to argument to 
  # use in your Application Controller
  def initialize(group_relation)
    group_relation ||= GroupRelation.new

    if group_relation.id.nil?
      # User does not have a relation to a group
      can :read, all
    elsif group_relation.moderator?
      # Allow a mod to manage all group relations associated with the mod's group.
      can :manage, :all, :id => group_relation.group.id
    end
  end
end

这篇关于使用角色和小组模型在更复杂的环境中定义能力的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆