views:

58

answers:

2

I'm building a rails app where login is optional. In other words, many of the same actions/views/controllers/pages will work logged in or logged out. You simply get more functionality if you are logged in (like the app remembers what you've done).

I'm currently using restful_authentication and role_requirement, and wondering which level to use. I could add a new role "user" which all logged in users get, for example, and then require_role "user" and have view blocks using @user.has_role? ... or I could instead enhance the authentication side of things and do checks to see if the user is authenticated. Or I could do something else. Is there any standard way of handling this in rails?

+1  A: 

You would integrate your authentication gem with an authorization gem. To start off, I would recommend cancan as it is very simple and straight forward.

If you are using cancan, you would define what user can/cannot do in models/ability.rb.

class Ability
    include CanCan::Ability

    def initialize(user)
      if user.admin?
        can :manage, :all
      else
        can :read, :all
      end
    end
end

Then in your view you can authorize the features based on user role:

<% if can? :update, @article %>
    <%= link_to "Edit", edit_article_path(@article) %>
<% end %>

If you are looking for more power, you might want to consider other authorization gem such as declarative_authorization.

jpartogi
+1  A: 

There is no need to check for authorization for actions which allow all users.

If you have a default authorization in your ApplicationController, such as:

before_filter :authorize

Then either remove that entirely, and add it back in only for those actions that require authorization, or, in each controller you could disable it with:

skip_before_filter :authorize, :only => [:action_method_name]

You should have a simple method in your ApplicationController where you can pass in a role and get a true if the current user is authorized:

def authorized? role
  return true if current_user.roles.collect{|r| r.name.to_sym}.include(role.to_sym)
  false
end

Then you can check procedurally for whatever role you want in your actions.

fullware
I'd also like certain pages to show different views if the user is logged in vs. not logged in. Any advice on that?
sbwoodside