I need to make timeout_in as dynamic value like below,But here self is not a instance of User model. can any one have idea how I can use that condition .
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable,
:token_authenticatable, :confirmable, :lockable, :timeoutable , :omniauthable,:timeout_in => (self.email.nil? ? 111.minutes : 112.minutes)
This feature is on Devise master and should be released on a new Devise version soon. You can point your Gemfile to Devise git repository and start using it right now.
https://github.com/plataformatec/devise/wiki/How-To:-Add-timeout_in-value-dynamically
https://github.com/plataformatec/devise/pull/1462
I don't know if you can do that this way, since you are on a class scope.
To do what you want, define a method called timeout_in method that implements this logic. Because it has this method Devise tries to load timeout_in from an instance method, and after this it tries to get it from the class method.
EDIT: removed the monkey patch solution added a better one.
EDIT2: Improving the answer.
Related
I'm currently building a rails application that contains 3 user types. This is my first experience with web development, and I would like to avoid making crucial design errors that will cost me later on. Hopefully more experienced rails users and web developers will be able to guide me in the right direction.
I want to use Devise as my primary authentication system, and I am currently planning something like this in order to support 3 user-types within the Devise framework:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
attr_accessible :email, :password, :password_confirmation, :remember_me
belongs_to :rolable, :polymorphic => true
end
For each of the three user-types:
# usertype1.rb
class UserType1 < ActiveRecord::Base
has_one :user, :as => :rolable
end
# usertype2.rb
class UserType2 < ActiveRecord::Base
has_one :user, :as => :rolable
end
Essentially, there is a polymorphic association between the user class and the several different user types. My hope is that this approach will allow me to eventually add different associative keywords within the user-type models (such as has-many) that will allow convenient querying of the database.
I'm also concerned about how to implement user-dependent routing. The idea is that each user-type will see a separate "hub" when they log-in, with different dashboards, different actions, etc. I was thinking that I would approach this by overriding the Devise SessionsController. Something like this:
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:email])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
if user.type == 1
redirect_to hub_typeone
else if user.type == 2
redirect_to hub_typetwo
else
redirect_to hub_typethree
else
flash.now.alert = "Email or password is invalid"
render "new"
end
end
def destroy
session[:user_id] = nil
redirect_to root_url, notice: "Logged out!"
end
end
The idea is that upon successful authentication, the user is routed to a different page based on user type. I'm planning on using the devise current_user framework to then query the database to populate the hubs with the user-specific data.
Do you guys have any pointers for me? Do you see any huge flaws in my plans/reasoning/approach? Thanks in advance!
I get a feeling you are over-engineering this, and building something You Aren't Gonna Need It
It's best if you are clear about what the three different user types are. Most applications would require the following three user types:
Guest users, who aren't logged in, and can access some part of the application
Regular users
Admin users who administer the rights of regular users.
I am curious to know what other user types you would need if they are not in this list.
Devise wikipages has suggestions on how to create a guest user, and how to add an admin role. Probably best to start by implementing the functionality of the regular users of your application, and then use the above mentioned resources to add other user types.
My Rails 3 app is using Devise and I noticed that my users table was missing it's authentication_token column. Not sure how it's been authenticating users up until now, but in either case I'm looking to add the authentication_token column to repeat what was done in this tutorial: http://ariejan.net/2011/03/27/rails-3-devise-uploadify-no-flash-session-hacks. How do I go about adding this in?
Edit
I did notice that in my config/initializers/devise.rb I had this, which I take is an alternative to auth tokens?
# If true, uses the password salt as remember token. This should be turned
# to false if you are not using database authenticatable.
config.use_salt_as_remember_token = true
Edit 2
I also tried adding the following to my Users model but nothing changed.
devise :database_authenticatable
Here is my current user model:
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
Token authentication is only used for API style authentication where you receive a JSON response from another application. By default Devise uses email and password authentication, which is what the :database_authenticatable is configuring.
In order to set your app up this way you can follow either tutorial from the Devise Wiki. Either one of them will point you in the right direction.
I recently got Devise working. New users sign in, sign up, logout etc etc just fine. Old users however have an issue. I have gotten it to a point where I get a 401 unauthorized, which seems to me that the hash is just incorrectly being created when signing in and of course not matching correctly.
My user model:
class User < ActiveRecord::Base
require "digest/sha1"
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :encryptable, :encryptor => :old_cakephp_auth
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me
has_many :events
end
Cakephp uses sha1, but I don't know the specifics of how it does things. This obviously doesn't work, which is why I am here:
require "digest/sha1"
module Devise
module Encryptors
class OldCakephpAuth < Base
def self.digest(password, stretches, salt, pepper)
Digest::SHA1.hexdigest("#{salt}#{password}")
end
end
end
end
I got that from the how to add a custom encryptor example. They had this:
Digest::SHA1.hexdigest("--#{salt}--#{password}--")
That didn't work either. Anyone have any ideas?
I saw a variation of this on the create your own custom encryptor wiki. I don't know how I didn't see it before. Perhaps someone updated it recently.
Place the following in your user model. It should overwrite valid password from devise:
def valid_password?(password)
return false if encrypted_password.blank?
Devise.secure_compare(Digest::SHA1.hexdigest(self.password_salt+password), self.encrypted_password)
end
You need to make sure to fill in the password salt you used in cake into all legacy user's rows. You also need to change password to encrypted password according to devise's instructions.
I feel like I may need to add a way encrypt from user model as well for new users. Or perhaps the custom encryptor I created handles that aspect.
I have a little app with Rails and Devise, and until now we were registering new users by Rails console. Now I have been asked to give a view for admin only, where they can signup, delete and view other Users.
My question is, which is the best way to go from here with Devise to accomplish this? I have checked similar questions here, on Devise wiki and other sites, and the conclusion I take from them is to have my own User controller.
What I need basically is a index view to list all users with a link on each one of them for editing and destroy and a new view for signup users. How much code from devise controllers I will new to override?
Also, my user model has the devise module: :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :timeoutable.
Thank you in advance.
From what it sounds like ... you just want have a client side for devise, (the user needs to register, login, etc. because they cant use the console). What I think your asking for, i think you should follow this tutorial to set up devise https://github.com/fortuity/rails3-subdomain-devise/wiki/Tutorial-%28Walkthrough%29 , (i followed this up to Set Up Subdomains, because that is what was important for me in my rails app). It should set up the functionality you are talking about. After you do this, if you find sign out throws an error, change
devise_for :users
in your routes, to
devise_for :users do
get "/users/sign_out" => "devise/sessions#destroy", :as => :destroy_user_session
end
If this wasn't what you were looking for, go into a little more detail
I'm a Rails noob and am hoping someone can help me wrap my head around this issue. I have an app that has a single User model using Authlogic for authentication and CanCan for authorization. There are three roles: Consumer, Business, and Admin. A user can have any number of these roles.
Businesses have additional attributes, however, and I need to model this such that I can add roles that each have potentially different attributes. Instinct tells me that I need to have a separate model to represent each role's attributes, i.e. BusinessRoleProfile, ConsumerRoleProfile, etc and then maybe mixin a module programmatically that adds the appropriate has_one reference(s) to the profile model(s).
Is this the best way to handle the separate attributes? If so, can someone guide me through how to dynamically include those mixins based on what role the user has?
EDIT:
Did some more research, this may help you. https://github.com/thefrontiergroup/scoped_attr_accessible
Looks like you can do things like:
class User < ActiveRecord::Base
# All attributes are accessible for the admin scope.
attr_accessible :all, :scope => :admin
# The default scope can only access a and b.
attr_accessible :a, :b
# Make both :c and :d accessible for owners and the default scope
attr_accessible :c, :d, :scope => [:owner, :default]
# Also, it works the same with attr_protected!
attr_protected :n, :scope => :default
end
OLD ANSWER
Looks like it may be featured in CanCan 2.0.
https://github.com/ryanb/cancan/issues/326