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
のディレクトリに配置することで新しい権限の登録が完了します。
実際には以下のような書式で設定を行いました。
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
また、独自のモデルやアクションに対してのパーミッションを定義する場合には、この書式にならってパーミッションセットを作るのが便利です。実際には下記の書式で定義が可能でした。
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コマースは個人情報のような秘匿性の高い情報を扱う分、セキュリティの対策は十二分に施しておきたいところです。