-
-
Save jastkand/3765692 to your computer and use it in GitHub Desktop.
Active Admin CanCan integration with shared front/backend User model and multi-level autherization
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/ability.rb | |
# All front end users are authorized using this class | |
class Ability | |
include CanCan::Ability | |
def initialize(user) | |
user ||= AdminUser.new | |
case user.role | |
when "admin" | |
can :manage, :all | |
when "school" | |
can :manage, Schedule, :team => { :school_id => user.school_id } | |
# the list of 'cans' of the user with school role | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# lib/activeadmin_cancan.rb | |
# Integration with CanCan | |
module ActiveAdminCanCan | |
def active_admin_collection | |
super.accessible_by current_ability | |
end | |
def resource | |
resource = super | |
authorize! permission, resource | |
resource | |
end | |
private | |
def permission | |
case action_name | |
when "show" | |
:read | |
when "new", "create" | |
:create | |
when "edit" | |
:update | |
else | |
action_name.to_sym | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# config/initializers/activeadmin_filter_conditions.rb | |
# This monkeypatch allows to use conditions if filters like | |
# | |
# filter :school, :as => :select, :collection => proc { School.all }, :if => proc { can? :manage, AdminUser } | |
# | |
# this filter will be shown only for roles who can manage AdminUser model | |
module ActiveAdmin | |
module Filters | |
class FormBuilder < ::ActiveAdmin::FormBuilder | |
def filter(method, options = {}) | |
return "" if method.blank? | |
options[:as] ||= default_input_type(method) | |
return "" if (options[:if].is_a?(Proc) && !template.instance_eval(&options[:if])) || (options[:unless].is_a?(Proc) && template.instance_eval(&options[:unless])) | |
return "" unless options[:as] | |
content = input(method, options) | |
form_buffers.last << content.html_safe if content | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# config/application.rb | |
# Set up config.autoload_paths parameter like this: | |
# | |
# config.autoload_paths += %W(#{config.root}/lib) | |
# | |
# Don't forget to remove comment symbol |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/controllers/application_controller.rb | |
class ApplicationController < ActionController::Base | |
rescue_from CanCan::AccessDenied do |exception| | |
redirect_to admin_dashboard_path, :alert => exception.message | |
end | |
def current_ability | |
@current_ability ||= Ability.new(current_admin_user) | |
end | |
` | |
``# the other source of you application controller | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/admin/foobars.rb | |
ActiveAdmin.register Schedule do | |
# Filter with condition | |
filter :school, :as => :select, :collection => proc { School.all }, :if => proc { can? :manage, AdminUser } | |
# This will authorize the Schedule class | |
controller do | |
authorize_resource | |
include ActiveAdminCanCan | |
def scoped_collection | |
end_of_association_chain.includes(:team) | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# app/models/user.rb | |
class User < ActiveRecord::Base | |
# The order of the ROLES array is important! | |
# All privileges are inherited from left to right | |
ROLES = %w(school admin) | |
# Privileges are inherited between roles in the order specified in the ROLES | |
# array. E.g. A moderator can do the same as an editor + more. | |
# | |
# This method understands that and will therefore return true for moderator | |
# users even if you call `role?('editor')`. | |
def role?(base_role) | |
return false unless role # A user have a role attribute. If not set, the user does not have any roles. | |
ROLES.index(base_role.to_s) <= ROLES.index(role) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment