30

Using Resque and Devise, i have roles for User, like:

User.first.role #=> admin
User.last.role #=> regular

I want to setup an authentication for Resque. So, inside config/routes.rb i have:

namespace :admin do
  mount Resque::Server.new, :at => "/resque", :as => :resque
end

And, of course it's accessible for all logged in users.

Is there any way to use a role from User.role? It should be accessible only by users with 'admin' role.

Thanks a lot.

There Are Four Lights
  • 1,406
  • 3
  • 19
  • 35

4 Answers4

39

Use a route constraint, in your routes.rb file:

  resque_constraint = lambda do |request|
    request.env['warden'].authenticate? and request.env['warden'].user.admin?
  end

  constraints resque_constraint do
    mount Resque::Server, :at => "/admin/resque"
  end
Fa11enAngel
  • 4,690
  • 2
  • 39
  • 38
jpemberthy
  • 7,473
  • 8
  • 44
  • 52
  • 2
    This does work, however unauthorized users will receive a 404 page and will not get directed to a login page. Keep this in mind when using this technique. – ARun32 Jan 04 '13 at 17:34
22

in your routes.rb file:

authenticate :user, lambda {|u| u.role == 'admin' } do
    mount Resque::Server.new, :at => "/resque"
end

Also, make sure you have devise_for :users somewhere in that file

Yossi Shasho
  • 3,632
  • 31
  • 47
14

You can try subclassing the Resque::Server class this way:

require 'resque/server'

class SecureResqueServer < Resque::Server

  before do
    redirect '/login' unless some_condition_is_met! 
  end

end

And using it in your routes this way:

mount SecureResqueServer.new, :at => '/resque'

I got this information from this blog. Give it a try.

cicloon
  • 1,099
  • 5
  • 13
  • Looks fine, but how could i check curent_user's role from here? Any ideas? – There Are Four Lights Sep 02 '11 at 15:02
  • 3
    This solution is much better than using a route constraint. This is because authentication should be performed within the controller, not within the routes. – nickh Oct 22 '11 at 18:11
  • 1
    Also, the route constraint only creates the route if the constraint is met, otherwise it gives a 404. This is likely to behave differently than the rest of the admin panel. – ben Jul 19 '12 at 13:58
  • this is what I use, remember that you need to include any helpers that you use for authentication, and also init sessions again – Dmitry Sep 06 '13 at 16:11
  • Does anyone have a comparable solution for the new Resque-Web gem? It seems that it doesn't use the Resque::Server, but the Rails Engine to mount the app. – Nemo Jul 14 '14 at 09:38
  • while it's not clear from this answer where to put the class (note also that the link to the blog post is broken) in my case I've placed the class in an initializer file (under config/initializers/) and it worked fine – medBouzid Oct 26 '20 at 21:38
10

There is always the new solution, type this in your routes.rb for rails > 3.1:

  authenticate :admin do
    mount Resque::Server.new, :at => "/resque"
  end

And don't forget:

devise_for :admins
Calin
  • 6,661
  • 7
  • 49
  • 80
  • This does seem like the better idea, but devise seems to redirect to /resque/admin/login if not authenticated. You know of any way to specify the un-authed redirect? – jtesch Apr 05 '12 at 17:01
  • Check cicloon's solution bellow solves that problem and it's a better – Calin Apr 05 '12 at 19:22
  • Regarding your route issue you can try adding "match "/resque/admins/sign_in" => redirect("/admins/sign_in")" in your routes.rb, see http://stackoverflow.com/questions/9731550/devise-authentication-for-sinatra-app-mounted-in-rails – Calin Apr 08 '12 at 12:21
  • This worked the best for me versus the other solutions. It also directs you to the proper URL after logging in.. e.g. /jobs -> redirects to /admin/login -> back to /jobs (after successful login) – ARun32 Jan 04 '13 at 17:33
  • This worked for me, but I can't figure out what gem is providing that authenticate method, and it's bugging me... – odigity Apr 09 '14 at 19:45
  • Ah, found it: http://rdoc.info/github/plataformatec/devise/master/ActionDispatch/Routing/Mapper:authenticate – odigity Apr 09 '14 at 19:46