Reputation: 14372
In my rails app I am using devise
for authentication and my model name is user
for which I have a Boolean field admin
. In my routes.rb
, I am trying to limit all users except admins from accessing a url.
mount Resque::Server.new, :at => "/resque"
. I tried using devise's current_user helper like
mount Resque::Server.new, :at => "/resque" if current_user.admin == true
But got the error undefined local variable or method 'current_user' for #<ActionDispatch::Routing::Mapper:0x000000053ac780> (NameError)
. How to do this? I am new to rails please help
Upvotes: 1
Views: 1116
Reputation: 14372
Finally this is what worked for me
# routes.rb
match "/resque" => Resque::Server, :anchor => false, :constraints => lambda { |req|
req.env['warden'].authenticated? and req.env['warden'].user.is_admin?
}
# user.rb
class MUserLogin < ActiveRecord::Base
.
.
.
def is_admin?
# your admin logic here for example:
self.admin == true
end
end
Upvotes: 1
Reputation: 12719
The best solution for this kind of behavior is to add a before_action
to your controller which will produce an error if the user is not an admin:
before_action :authorize_admin_only
def authorize_admin_only
raise RoutingError.new('Not found') if !current_user.admin
end
Your routes file is interpreted once on startup, and even if you can find ways to make routes depend on the request (e.g. with routing_filter
) it is not a good idea to use this for authorization purpose.
In authorize_admin_only
, you can also render an error file or simply redirect the user to another page, e.g. login.
For your specific case, as you want to mount another engine, you can also define authentication on a admin
model in your routes (and special resque example)
authenticate :admin_user do #replace admin_user(s) with whatever model your users are stored in.
mount Resque::Server.new, :at => "/jobs"
end
If you don't have an admin model, then you can refer to the devise documentation for authenticate
and do something like this :
authenticate(:user, &:admin?) do
mount Resque::Server.new, :at => "/jobs"
end
(&:admin?
produce the same result as lambda{|user| user.admin?}
, remove the ?
if you did not define such alias)
Upvotes: 2
Reputation: 2784
There is a wiki page just for that in device,
https://github.com/plataformatec/devise/wiki/How-To:-Protect-Resque-Web-with-Devise
Upvotes: 1