-
Notifications
You must be signed in to change notification settings - Fork 45
Cantango with devise users
CanTango has been designed from the start with an eye for easy and flexible integration with the popular popular authentication system Devise.
In Devise, you can create devise models. These models can be seen as either Users or Accounts depending on your configuration and your needs. For simple cases, Users and Accounts are seen as one and the same. In more complex scenarios it makes sense to split Users and Accounts into distinct models (see Cantango with devise accounts). In this example we will work with the Devise models as User classes that includes account functionality.
Generating a Devise User
model:
$ rails generate devise User
This will create a User model with a set of devise strategies.
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable, :confirmable, :recoverable, # ...
end
Now use the tango_user
macro to register this class as a user class.
class User < ActiveRecord::Base
tango_user
devise :database_authenticatable, :registerable, :confirmable, :recoverable, # ...
# user logic
end
A common scenario is then to create an Admin user class like this:
class Admin < User
tango_user
# admin logic
end
The user class Admin can then be specialized to have its own devise strategies, validation and other logic. One example is to require a stricter password enforcement strategy and another sign-up flow.
You could also choose to make the Admin class a Devise model directly by running.
$ rails g devise Admin
In any case, you will have to make your App aware of your devise models in your routes:
# routes.rb
devise_for :users, :admins
This will generate distinct devise route sets for both User and Admin user types. The following devise methods will be made available in views and controllers
- current_user - the current logged in User user (if any)
- current_admin - the current logged in Admin user (if any)
- user_signed_in? - is there a current logged in User user (in the session) ?
- admin_signed_in? - is there a current logged in User user (in the session) ?
The CanCan can?
and cannot?
methods (the CanCan API) only wraps the #current_user
method, since this method is available for most authentication systems including authlogic.
In CanTango we have extended the Can API to wrap all the #current_[user]
methods exposed by Devise.
Another issue is how to get the concept of a Guest user integrated. Traditionally, most people have opted to try to tweak Devise methods such as #current_user
to return a guest user if no current_user is present.
This is an intrusive hack which has its own problems as it can have consequences with other methods that rely on the default logic.
CanTango takes a non-intrusive approach. In the [user]_can?
methods, it will attempt to initiate and use a Guest user if no current_[user]
can be found. Whatever user is "found" is then passed of to the CanTango::Ability
and evaluated with regards to permissions.
CanTango also generates a set of methods of the form session_[user class]
, fx session_user
and session_admin
for the above scenario. These methods will return a logged in user for the given user type or if none logged in will return the Guest user for that session.