Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yurifrl/9748910 to your computer and use it in GitHub Desktop.
Save yurifrl/9748910 to your computer and use it in GitHub Desktop.
# db/migrate/01_add_custom_admin_roles.rb
class AddCustomAdminRoles < ActiveRecord::Migration
@roles = %w[extra]
def self.up
@roles.each do |r|
Role.create(:name => r)
end
end
def self.down
@roles.each do |r|
Role.where(:name => r).first.destroy
end
end
end
# app/models/ability.rb
# Only customized methods are shown here, see the ability class on github for the rest
class Ability
def initialize(user)
user ||= User.new
if user.has_role? 'admin'
can :manage, :all
elsif user.has_role? 'extra'
base_admin
custom_perms
%w/destroy/.each do |act|
can act, "admin/orders"
end
can 'fire', 'cancel'
else
#############################
can :read, User do |resource|
resource == user
end
can :update, User do |resource|
resource == user
end
can :create, User
#############################
can :read, Order do |order, token|
order.user == user || order.token && token == order.token
end
can :update, Order do |order, token|
order.user == user || order.token && token == order.token
end
can :create, Order
#############################
can :read, Product
can :index, Product
#############################
can :read, Taxon
can :index, Taxon
#############################
end
#include any abilities registered by extensions, etc.
Ability.abilities.each do |clazz|
ability = clazz.send(:new, user)
@rules = rules + ability.send(:rules)
end
end
def custom_perms
%w/index edit destroy update show fire/.each do |act|
can act, "admin/products"
can act, "admin/payments"
can act, "admin/shipments"
can act, "admin/return_authorizations"
can act, "admin/adjustments"
end
%w/index edit update show fire/.each do |act|
can act, "admin/orders"
end
%w/next return resume authorize_return/.each do |event|
can 'fire', event
end
can :manage, Product
can :manage, Variant
can :manage, Order
cannot :destroy, Order
can :manage, LineItem
can :manage, Payment
can :manage, Shipment
can :manage, ReturnAuthorization
can :manage, Adjustment
end
def base_admin
can "index", "admin/overview"
can "index", "admin/reports"
end
end
# app/controllers/admin/base_controller_decorator.rb
Admin::BaseController.class_eval do
prepend_before_filter :authorize_admin
def authorize_admin
authorize! params[:action], params[:controller]
end
end
# app/helpers/admin/navigation_helper_decorator.rb
module Admin::NavigationHelper
# customize method for custom roles
def tab(*args)
# doesn't show the tab unless the current role can actually use it
return "" unless can?("index", "admin/#{args.first.to_s}")
options = {:label => args.first.to_s}
if args.last.is_a?(Hash)
options = options.merge(args.pop)
end
options[:route] ||= "admin_#{args.first}"
destination_url = send("#{options[:route]}_path")
## if more than one form, it'll capitalize all words
label_with_first_letters_capitalized = t(options[:label]).gsub(/\b\w/){$&.upcase}
link = link_to(label_with_first_letters_capitalized, destination_url)
css_classes = []
selected = if options[:match_path]
request.fullpath.starts_with?("/admin#{options[:match_path]}")
else
args.include?(controller.controller_name.to_sym)
end
css_classes << 'selected' if selected
if options[:css_class]
css_classes << options[:css_class]
end
content_tag('li', link, :class => css_classes.join(' '))
end
end
# app/controllers/admin/orders_controller_decorator.rb
Admin::OrdersController.class_eval do
before_filter :check_fire_perms
def check_fire_perms
if params[:e]
unauthorized unless can? 'fire', params[:e]
else
return true
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment