LoginSignup
1
0

More than 3 years have passed since last update.

Gem(Cancancan, pundit,Banken)を使わずにymlを使った権限管理機能実装方法

Last updated at Posted at 2019-07-17

環境
Ruby 2.5
Rails 5.2.4

実現したいこと

以下の3種類の役割があるとします。
RoleA → フル権限(GET,PUT,PATCH,DELETE)
RoleB → 全ページの閲覧とデータが更新ができる(GET,PATCH)
RoleC → データは更新できないが、全ページの閲覧が可能

この条件で各ページ、メソッド単位で各機能ごとに細かく権限管理したい。(仕様によりがっつりとrequestパラメーター使えない)

前提
UserはActiveRecordを使用しておらず、外部サービスで作られ、データも外部で保持されており必要に応じてRailsから参照しています。それに伴い私にはDeviseのGemが使えなかったためYmlを使用しようと思いました。


current_user[:role] # roleB
で現在のユーザーのroleを取得することはできます。

各ページごとのidを取得することができます。
params[:page_name] # page_a

この二軸で判定を行います

1. ymlを作成する

/config/previlege.ymlを自分で作成し権限とページの軸で記述していきます。

previlege.yml
1はフル権限(GET,PATCH,POST,DELETE)
2は参照と更新のみ(GET,PATCH)
3はアクセス権なし(記載がなければ自動的に3扱い)


roleA:
  page_a: 1
  page_b: 1
  page_c: 1
  page_d: 1
roleB:
  page_a: 1
  page_b: 1
  page_c: 2
  page_d: 2
roleC:
  page_a: 2
  page_b: 2
config/initializers/previlege.rb

file = File.read("#{Rails.root}/config/previlege.yml")
PREVILEGE = YAML.safe_load(file, [] , [], true)

ここまででymlを定義し定数として使えるようになりました。
以下のようにしてハッシュで取れます。



puts PREVILEGE[:roleB]
=> {  page_a: 1
      page_b: 1
      page_c: 2
      page_d: 2 }
app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  helper_method :current_user # helperでcurrent_userが使える

  private
  def current_user
    # 省略=> roleが返ってくる
  end

  def judge_previlege
   if PREVIREGE[current_user[:role]][params[:page_name]] == 1 
       true
     elsif PREVIREGE[current_user[:role]][params[:page_name]] == 2 && request.patch? || request.get?
       true
     else 
       return redirect_to root_path, flash[:error] = "権限がありません"
     end
  end
end


before_actionでメソッドを使う

app/controllers/posts_controller.rb
class PostsController < ApplicationControler
  before_action :judge_previlege

  def index
    省略
  end

  def update
    省略
  end

end

こんな感じでコントローラーの制御はできます。
備忘録で大雑把に書いていますので、気に入っていただけたらあとは応用してもらうのが良いかと思います。

viewの出し分けは

app/helpers/application_helper.rb
module ApplicationHelper


  def showrable?
     if PREVIREGE[current_user[:role]][params[:page_name]] == 1 || PREVIREGE[current_user[:role]][params[:page_name]] == 2
       true
     else
       false
     end
  end

  def clickable?
    if PREVIREGE[current_user[:role]][params[:page_name]] == 1
      true
    else
      false
    end
  end
end
index.html.erb

表示するか
 if showrable?
   表示させる
 end

クリックできるか
link_to_if(clickable?, "リンク",hoge_path)

以上になります
間違えている可能性ありますので(特にviewあたりは適当です....)、参考程度でお願いします...

1
0
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
1
0