Six —— 权限控制Ruby Gem

作者: 老码农不上班 | 来源:发表于2016-08-17 14:36 被阅读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

    • object object trying to access resource(访问资源的对象,这个对象一般为用户)
    • actions action name to check for access(权限描述,比如这里的图书阅读权限)
    • subject resource(权限操作的资源,例如阅读图书权限操作的资源为图书,访问项目权限操作的资源为项)

    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中被执行。
    • 步骤一中的 abilities 和步骤四种的 can? 方法应定义为帮助方法
    • 步骤三中的 add_abilities 应在 ApplicationController 加载时优先被执行。
      before_filter add_abilities
      helper_method :abilities, :can?
      

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

    can?(current_user, :read_project, @project)
    

    相关文章

      网友评论

        本文标题:Six —— 权限控制Ruby Gem

        本文链接:https://www.haomeiwen.com/subject/hipmsttx.html