Ruby & RailsRuby on RailsRuby、Rails知识

Six —— 权限控制Ruby Gem

2016-08-17  本文已影响249人  老码农不上班

权限控制对于一个web站点为极其重要。例如 Git@OSC 中,应保证私有项目不被非项目成员访问,下载仓库,并且对于项目成员角色也应做对应的权限控制:报告者只能提 issue、开发者能进行 pull request,编写 wiki 等操作;在线阅读的站点,判断用户是非有阅读某一本书的权限。可以看出,相对于规模稍微大点的用户系统站点,权限控制为必须且为极其重要的一部分。
那么,提供给 Rubyist 的权限控制Gem都有哪些呢?punditSixcancan都为不错的选择。Git@OSC和开源项目gitlabhq使用的都是是 Six ,我对此相对熟悉,于是催生出了 Six 使用过程中的一点学习总结。

快速开始

要使用ruby gem毫无疑问得安装相对应的gem: gem install six 使用six十分简单,分为四步即可。

  1. 创建 abilities 对象
abilities = Six.new
  1. 创建定义了 allowed 方法的类或对象
    allowed 返回的是整个系统的权限规则数组,譬如在 Git@OSC 中项目访客对公有项目的权限为:read_project、read_wiki、read_issue、download_code、read_team_member、read_pull_request ...
    譬如对于在线阅读的站点,有编辑图书,阅读图书的权限:
class BookRules
    def self.allowed(author,book)
      [:read_book,:edit_book]
    end
  end

看到了吧, allowed 方法中返回一个数组,元素包含了read_book,和edit_book的规则。这些规则的作用在第四步“如何使用”体现出来。

  1. 把第二步新建的对象添加到第一步新建的 obilities 对象
abilities << BookRules
  1. 至此,可在业务开发过程中对应用户角色的权限判断了
abilities.allowed?(@user,:read_book,@book) #true

解释一下 Six 中的allow? 方法中的三个参数。首先查看其的源代码 def allowed?(object, actions, subject);....;end

Six在Ruby on Rails中的应用

从某种层面上看, Rails 确实驱动了 Ruby 的推广。使用 Six ,相信大部分开发者都是在Rails中应用,那么在Rails中如何使用Six呢?
有了上述的 quick start ,再结合Rails的规范,使用 Six 将不会是难题。首先在Gemfile中添加 gem "six"

  1. 在 ApplicationController 新建 abilities 对象。
def abilities
  @abilities ||= Six.new
end
  1. 可独立在model文件夹下新建一个 Abilities 类集中管理全站的权限,例如:
  #app/model/ability.rb
  class Ability
    self.def allow(user,subject)
      return not_auth_abilities(user,subject) if user.nil?
      return [] unless user.kind_of?(User)
      return [] if user.blocked?

      case subject.class.name
      when "Project" then project_abilities(user,subject)
      when "Issue" then issue_abilities(user,subject)
      ....
      else []
      end
    end

    def project_abilities(user,project)
      rules = []
      rules << project_guest_rules if project.public?
      ....
      rules.flatten
    end

    def project_guest_rules
      [
          :read_project,
          :read_wiki,
          .....
          :write_issue
      ]
    end
  end

allowed方法最终返回一个包含各种权限的数组

  1. 在 ApplicationController 中把 Ability 类添加到 @abilities 对象
def add_abilities
  abilities << Ability
end
  1. 在controller和view中使用six做权限判断
    把six的allowed?方法封装为帮助方法:
def can?(object,action,subject)
  abilities.allowed?(object,action,subject)
end
  1. 确保步骤1,3,4在ApplicationController中被执行。

最后你可以在任意controller或view中使用帮助方法 can? 对用户进行权限判断了。
例如在view中判断用户是非有读仓库的操作:

can?(current_user, :read_project, @project)
上一篇下一篇

猜你喜欢

热点阅读