4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Solidusでロール別権限管理をする

Posted at

Solidus(Spree)で役職別権限管理する方法についてです。

Solidusでは、初期の状態ではadmin(管理者)とdefault(エンドユーザー)の2つのRoleしか用意されていませんが、わずかなコードを書き足すことによってオリジナルの権限ロールを設定することが可能です。

例えば商品情報のみを編集するeditor、注文情報のみを閲覧できるstaffなどです。この機能はSolidusに標準で組み込まれているgemのdeviseとcancanによって実現されており、コードに少し手を加えることで独自の権限ロールを作成することができるようになっています。deviseとcancanについての説明はここでは割愛しますが、実装前に基本的な部分はおさえておいたほうが良いと思うのでそれぞれのgemの公開されているドキュメント等を流し読みしておくとよいかもしれません。

なおSolidus(Spree)のRoleについての公式ドキュメントはここから閲覧できます(英語)

SECURITY - DEVELOPER GUIDE | SPREE COMMERCE

なおこのドキュメントは以前私が翻訳した日本語版もあります。

[日本語訳] SECURITY - DEVELOPER GUIDE | SPREE COMMERCE

新規Roleの作成

DBへroleを保存

roleはSpree::Roleクラスのインスタンスで管理され、Spree::Userに対して一対多で紐づく形となります。consoleでSpree::Role.allとするとDBに保存されているRoleが全て閲覧できます。初期状態のSolidusではadminのroleが1つあるだけのはずです。新しいRoleを作成するときは、まずSpree::Role.create(name: "staff")などとして新しいRoleをDBに保存する必要があります。この作業はSolidusの管理画面からはできないのでコンソールから行う必要があります。

roleへの権限割当

roleへの権限割当の方法は、Solidusのソースコード内にコメントとして記載されていました。以下の書式で新しいroleに権限を付与することが可能です。

solidus/core/lib/spree/core/role_configuration.rb

# A class responsible for associating {Spree::Role} with a list of permission sets.
#
# @see Spree::PermissionSets
#
# @example Adding order, product, and user display to customer service users.
#   Spree::RoleConfiguration.configure do |config|
#     config.assign_permissions :customer_service, [
#       Spree::PermissionSets::OrderDisplay,
#       Spree::PermissionSets::UserDisplay,
#       Spree::PermissionSets::ProductDisplay
#     ]
#   end

この書式で定義したroleをconfig/initializersのディレクトリに配置することで新しい権限の登録が完了します。

実際には以下のような書式で設定を行いました。

config/initializers/permissons.rb
Spree::RoleConfiguration.configure do |config|
  config.assign_permissions :staff, [
    Spree::PermissionSets::DashboardDisplay,
    ....
  ]
end

なお、Solidusでは業務区分ごとにまとめられたパーミッションセットがあらかじめ用意されています。以下のディレクトリにまとめられたものがありますので、これらをconfig.assign_permissionsにArray形式で与えるだけで簡単にroleの作成が可能となっています。便利ですね。

solidus/core/lib/spree/permission_sets

また、独自のモデルやアクションに対してのパーミッションを定義する場合には、この書式にならってパーミッションセットを作るのが便利です。実際には下記の書式で定義が可能でした。

lib/spree/permission_sets/staff_order_management.rb
module Spree
  module PermissionSets
    class StaffOrderManagement < PermissionSets::Base
      def activate!
        can :display, Spree::ReimbursementType
        can :manage, Spree::Order
        ....
      end
    end
  end
end

ここで定義した独自のパーミッションセットは、標準のそれと同様にconfig.assign_permissionsで使用できます。

アクションごとの細かい設定についてはcancanの書式に準じるのでそちらのドキュメントをご覧いただくのがおすすめです。

もう1つ設定が必要

上記の方法は正しいはずだったのですが、これだけでは正常に動作しませんでした。問題点を探していたところ、以下のようなドキュメントを発見しました。

If you need to create custom controllers for your own models under the Admin namespace, you will need to manually specify the model your controller manipulates by defining a model_class method in that controller.

module Spree
  module Admin
    class WidgetsController < BaseController
      def index
        # Relevant code in here
      end

    private
      def model_class
        Widget
      end
    end
  end
end

admin namespace内に独自のコントローラを作っていた場合、上記のようにmodel_classメソッドを定義してあげないと正しく動作しないようです。これを定義したところ正しく動作することが確認できました。

ユーザーへの権限付与

新しいRoleの定義が完了したら、あとは管理画面から権限の付与が可能です。

/admin/users/:id/edit画面にroleのチェックボックスが表示されますので、ここから権限付与できます。

手軽に独自の権限ロールを設定できるのはありがたいですね。Eコマースは個人情報のような秘匿性の高い情報を扱う分、セキュリティの対策は十二分に施しておきたいところです。

4
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?