We recently updated to ActiveAdmin 1.1.0, on a site which maintains two distinct user models - Users and AdminUsers. ActiveAdmin authenticates AdminUsers, and the rest of the site authenticates Users. Both paths use Devise, like this:
devise_for :users, controllers: {sessions: :practitioner_sessions, passwords: :practitioner_passwords}
admin_devise_config = ActiveAdmin::Devise.config
admin_devise_config[:controllers][:sessions] = :sessions
devise_for :admin_users, admin_devise_config
Now, I have a Rails engine (Resque::Server) mounted which I want to restrict to admins, using a routing constraint like this in config/routes.rb
:
module RouteConstraint
class Admin
def self.matches?(request)
request.env['warden'].user && request.env['warden'].user.admin?
end
end
end
mount ResqueWeb::Engine, :at => "/resque", :constraints => RouteConstraint::Admin
This used to work. However, now when an AdminUser is logged in to ActiveAdmin, request.env['warden'].user
returns nil
and request.env['warden'].authenticated?
returns false
.
Where do I go to check if a user is authenticated with ActiveAdmin in this configuration?
The "scopes" section of the Warden wiki gave me the clues I needed to rewrite two route constraints. Instead of querying the user
method of the Warden object, I passed the relevant Devise scopes as arguments to the authenticated?()
method. Remember that the Devise scopes can be found in routes.rb
, e.g.:
devise_for :admin_users, admin_devise_config
devise_scope :admin_user do
# some stuff
end
So then constraints can be written like this:
module RouteConstraint
class SuperAdmin
def self.matches?(request)
warden = request.env['warden']
warden.authenticated?(:admin_user)
end
end
end
module RouteConstraint
class LoggedIn
def self.matches?(request)
warden = request.env['warden']
warden.authenticated?(:user) || warden.authenticated?(:admin_user)
end
end
end
Then I was able to use the constraints in the same way as before:
mount Resque::Server, :at => "/resque", :constraints => RouteConstraint::SuperAdmin
mount JobState::Engine, :at => "/job_state", :constraints => RouteConstraint::LoggedIn