I created a simple Authorization module with Rails. I found that there are other authorization systems, such as CanCanCan, but they grant permissions at Model level and, for this particular website I am developing, it is more convenient to authorize at Controller level.
The idea is simple: the permissions are stored in a YAML file in the config directory and a function checks if the combination of admin_role
, controller
and action
exist in the config file. There is also a wildcard :all
.
# app/controllers/admins/base_controller.rb
class Admins::BaseController < ApplicationController
include Admins::AuthorizationHelper
before_action :authorize_admin
...
end
# app/helpers/admin/authorization_helper.rb
module Admins::AuthorizationHelper
private
def authorize_admin
unless is_authorized? params[:controller], params[:action]
refuse_access_to_admin_site
end
end
def is_authorized?(controller, action)
permissions = Rails.application.config_for :admin_auth
authority = current_admin.authority
if permissions[authority].nil?
false
elsif permissions[authority] == ['all']
true
elsif permissions[authority][controller].nil?
false
elsif permissions[authority][controller] == ['all']
true
elsif permissions[authority][controller].include? action
true
else
false
end
end
def refuse_access_to_admin_site
flash[:error] = 'Permission denied'
if request.referer.present?
redirect_to :back
else
redirect_to admins_products_path
end
end
end
# config/admin_auth.yml
defaults: &defaults
super_admins:
- all
admins:
admins/shops:
- index
- show_used_history
admins/products:
- index
admins/prescriptions:
- all
admins/products:
- index
operators:
admins/products:
- index
admins/prescriptions:
- all
admins/shipments:
- index
- show
test:
<<: *defaults
development:
<<: *defaults
staging:
<<: *defaults
production:
<<: *defaults
if permissions[authority].nil?
;false
. Why not just deny permission if they no permission? \$\endgroup\$permissions[authority][controller]
if authority was nil. But this is because I still didn't know the methodfetch( , [])
for arrays. ;) \$\endgroup\$