I have an engine mounted to my main app and I want to protect certain controllers and actions within that engine.
The engine is mounted with:
mount SomeEngine::Engine => '/some_engine'
Devise/CanCan is working with the rest of the main app's controllers and actions, but letting things run without anything else produces this error:
This action failed the check_authorization because it does not authorize_resource. Add skip_authorization_check to bypass this check.
So I open up the engine controllers from the main app using the decorator approach and add:
load_and_authorize_resource
Then I get this error:
No route matches {:action=>"new", :controller=>"devise/sessions"}
I can get things working using the following, but it's clunky when I try to implement roles:
authenticate :administrator do
mount SomeEngine::Engine => '/some_engine'
end
By clunky I mean I'll have to reproduce the above block of code in the routes.rb file for each role that has access to the engine...unless there's another way to use authenticate with roles that I don't know about???
I'd like to use the normal Devise/CanCan authorization/authentication approach in the controller if possible. But I think "no route match" error occurs because the engine does not know how to get to the main app's Devise controllers. But how do I get around this from the main app?
To throw one more issue into the mix...there is one specific controller/action in the engine that I do want to make public to all users. Thus far I've just added this before the authenticate block of code in the routes.rb file.
match '/some_engine' => 'some_engine/some_controller#public_action'
It works...but this line with the block in the routes.rb seems like I'm doing something wrong. And it doesn't allow me to implement roles nicely.
You can inherit application controller for use devise and cancan from main app.
module SomeEngine
class ApplicationController < ::ApplicationController
before_filter :merge_abilities
private
def merge_abilities
current_ability.merge(SomeEngine::Ability.new(current_user))
end
end
end
After this you can create abilities for engine by create own.
module SomeEngine
class Ability
include ::CanCan::Ability
def initialize(user)
return if user.nil?
can :manage, SomeModel
end
end
end
SomeModel
(SomeEngine::SomeModel
) is model at SomeEngine
engine.
At resource controllers you must specify class name of resource.
load_and_authorize_resource class: SomeEngine::SomeModel
And do not forgot change route helper to main_app.MAIN_APP_PATHS
at main application layout if you want to use it at engine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With