CanCan authorize all controllers - ruby-on-rails

I have CanCan and Rolify set up with ActiveAdmin, and now it's time to force authorization on my controllers.
Do I have to authorize_resource on every controller (We have a couple dozen models and controllers now), or is there a way to apply it to all of my ActiveAdmin controllers?
I tried calling it in a before_filter from ActiveAdmin.setup, but that didn't work.

I made an initializer: config/initializers/active_admin-cancan.rb
module ActiveAdmin
class ResourceController
# If you don't skip loading on #index you will get the exception:
#
# "Collection is not a paginated scope. Set collection.page(params[:page]).per(10) before calling :paginated_collection."
load_resource :except => :index
authorize_resource
def scoped_collection
end_of_association_chain.accessible_by(current_ability)
end
end
end
Borrowed from another user's code, but now I can't find the source any more.

Related

Adding a Controller without corresponding model while using cancancan

I've added a controller collaborators to manage a particular type of join association between Users and Companies. The issue is that whenever I load anything from collaborators, I get the error
uninitialized constant Collaborator
From my understanding, this is because there is no model Collaborator and I am using cancancanfor authorization. From the old cancan (note not cancancan) documentation, I've been able to gather that controllers that don't have a corresponding model need to have a model manually authorized for them something like: load_and_authorize_resource :the_model, :parent => false.
This seems to work if I disable load_and_authorize_resource in my application.rb controller.
SO my quesestion is: what is the best way to authorize controllers that don't have corresponding models with cancancan? Can I continue to load_and_authorize_resource in my application controller?
Many thanks in advance.
This LINK will help.
From the link, I quote,
class ToolsController < ApplicationController
authorize_resource :class => false
def show
# automatically calls authorize!(:show, :tool)
end
end
And in your ability.rb:
class Ability
include CanCan::Ability
def initialize(user)
can :show, :tool
end
end

Skip authentication for specific member action in ActiveAdmin

I'm trying to skip the authentication for a custom ActiveAdmin member action that I've created. Here's what I've been trying, but it still brings me to the login page.
ActiveAdmin.register Foo, as: "Foos" do
controller do
skip_before_action :authenticate_admin_user!, only: :bar
end
member_action :bar, method: :get do
# render something
end
end
Versions:
Rails: 4.1.1
ActiveAdmin: 1.0.0.pre1
Have a look at this gist.
Put the self.filters and self.before_filters methods into controller do block.
Add binding.pry after those methods and restart application server - this should stops on binding.
Type filters(:before) and you will see a list of callbacks.
Find the callback responsible for authentication, e.g. authenticate_active_admin_user.
Add skip_before_filter :authenticate_active_admin_user to controller do block.
Have a break :)

skip authorization for specific controllers using pundit in rails 4

I am using rails 4, devise for authentication and Pundit for authorization. I have restricted my application to check for authorization on every controller by below code.
class ApplicationController < ActionController::Base
include Pundit
after_action :verify_authorized
#.....
end
However, i want to skip authorization for two specific controllers in my application (they are open to public, users do not need to sign in). How can i achieve it without removing verify_authorized in ApplicationController ?
skip_after_action :verify_authorized
I'm working with Rails 5 and I wanted to skip authorization in just one action but not the whole controller. So, what you can do according to the documentation is to use skip_authorization feature in the controller action as shown below:
class Admin::DashboardController < Admin::BaseController
def index
#organizers = Organizer.count
#sponsors = Sponsor.count
#brochures = Brochure.count
skip_authorization
end
def sponsors_approve
# some statements...
end
def organizers_approve
# some statements...
end
end
In this controller the only one action to be skipped is index, the other ones must be authorized.
I hope it could be useful for somebody else.

Non restful actions in Wicked Wizard controller

Can you have non-restful methods in a controller which includes the WickedWizard gem?
Controller:
class Books::BookUpdateController < ApplicationController
include Wicked::Wizard
steps :title_step, :ai_archive_step, :ai_override_step #etc
def show
...
end
def update
...
end
def waterfall
...# loads of code to set up instance variables in the view, which I don't want to have to include in the normal show action for all the wizard steps.
end
end
Routes:
resources :book_update do
member do
get 'waterfall'
... and others
end
end
Version 1 and lower of the gem allows non restful actions, but this commit to solve this PR enforces step names. My error on going to this route http://localhost:3000/book_update/3949/waterfall is
Wicked::Wizard::InvalidStepError in Books::BookUpdateController#waterfall
The requested step did not match any steps defined for this controller.
I suppose I should spark up a new controller and tuck the non restful actions into there, but alternatives would be great.
You need to add:
skip_before_filter :setup_wizard, only: :waterfall
in your wicked controller

How do I test this with rspec?

I'm using the Sorcery gem for user signup/login.
One feature of this gem is the require_login before_filter on any controller you want to authenticate.
I have created a dashboard namespace for my app after they've logged in. For example /dashboard/reports or /dashboard/employees, etc.
Routes file:
# Dashboard
namespace :dashboard do
# Recent Activity
get '' => redirect('/dashboard/recent-activity')
get 'recent-activity' => 'activities#index', :as => 'root'
# Other dashboard controllers and actions
end
I extracted out the before_filter into it's own controller called:
"app/controllers/dashboard/base_controller.rb"
class Dashboard::BaseController < ApplicationController
before_filter :require_login
end
What I'd like to do is make 100% sure in some kind of test that ANY new controller I create within the dashboard folder (or dashboard namespace), inherits from Dashboard::BaseController
Such as my activities controller for example:
class Dashboard::ActivitiesController < Dashboard::BaseController
I dont want to go creating controllers in a few months and accidentally make it inherit from ApplicationController which would still would but wouldnt have login functionality.
I'm using RSpec
Can't quite believe my own eyes that I solved this on my own....
require 'spec_helper'
describe Dashboard::BaseController do
it "is the superclass of every dashboard namespaced controller" do
Rails.application.eager_load!
ApplicationController.descendants.each do |controller|
if controller.to_s.include?("Dashboard::") && controller.to_s != "Dashboard::BaseController"
expect(controller.superclass.to_s).to eq("Dashboard::BaseController")
end
end
end
end

Resources