I'm using Authlogic as the login system. Everything is working correctly except that it never updates the failed_login_count field when I purposely type in the wrong password. I am using the email as the login item. In the database there is no 'login' column. Is there something that I need to change or add to make this feature work?
Remember: When you login, the Failed_count_field set to 0.
Is your User model valid? If it's not, the validation will fail and the column can't be saved.
Related
Currenntly, my application is designed using Devise for authentication. I have it so when the first user signs up, an account is created in an Accounts table and the account_id is passed to the User table. I also have it set so that each time a new account is created that user is tagged as an admin. Finally, I have it working where the admin can create new users.
My problem is that at the time the new users are created I need to have these users be assigned the same account_id as the admin to tie the users together. I can do this if I add an account_id field on the form and have the admin manually enter it. What I want to have is that this is automated in the background.
I tried many varieties without success. This is one of the unsuccesful attempts where I put the following in the user.rb
before_save :add_account_id_from_parent
def add_account_id_from_parent
return true unless self.users.present?
self.users.update_attribute(:account_id, 1)
end
I used the number "1" just to see if I could get anything automated and placed in that field.
Like I said manually everything works, but I want it so the acocunt_id is automatically added during sign up based on the admins account_id.
I'm a bit confused why you are calling self.users. If I understand correctly, you want to assign account_id to 1 after a new user is created (as a test). You can do that like this:
before_save :add_account_id_from_parent
def add_account_id_from_parent
self.account_id = 1
end
You don't need to actually update the record since this is assigned before save, and save will write the new value to the db.
Again I might be missing something, if so please clarify.
UPDATE:
If you're validating that account is present, you'll need to change the callback to a before_validation instead of before_save, like so:
before_validation :add_account_id_from_parent
how can I make devise enforce getting correct password before canceling registration (deleting account)
You can either:
Do something along the lines of pst's answer: have a text box for :canceled in a form that when saved, cancels the account. Since it would be part of the user model, devise would force the password check upon the update action.
Do it yourself via a button that warns (similar to the delete buttons often in Rails). The controller that receives the request would simply do something like the following (I seem to remember that Devise uses MD5, maybe it's SHA1, SHA2, unsure- see documentation; the key is to use the same type):
if params[:password] == Digest::MD5.hexdigest(params[:password])
cancel_account(…)
…
end
Yeah, the key here is knowing how to encrypt params[:password] to be able to compare it to the current_user.encrypted_password
Older versions of Devise use a password_salt as well. My advice to you would be to look at how devise does this on sign in, and use the same method in your destroy action, or whatever user-facing page you have for that.
Specifically, I'm using Devise with Typus. But, I think my misunderstanding resides in my knowledge of Devise.
I'm trying to achieve the functionality of when you want to change an important model via form, you have to provide your current password to confirm you can change it, a la google.
Right now, I can log in and change any of the fields of my User model. Including the password, without having to confirm my password prior. Not good. So, I've added current_password to the form. But that didn't do anything. Then I tried to validate presence on current_password. Then it doesn't seem to accept any value for it.
Google didn't help me. All of the relevant posts were about removing current_password instead of confirming it. Which makes me think I'm misunderstanding the use of current_password.
Anyone care to share some insight? Thanks.
You should add the password field to the form, and then in your controller's action you can validate the password using:
user.valid_password?(params[:user][:password])
Note that probably you should change params[:user][:password] to the the name of the param for your password's field in the form (perhaps just params[:password]).
Hope it helps.
Actually, devise has a builtin method for this:
user.update_with_password(params, *options) you can read the rdoc here.
Update record attributes when :current_password matches, otherwise returns error on :current_password. It also automatically rejects :password and :password_confirmation if they are blank.
I am using Devise for my authentication. If a hashed_password isn't set, Rails/Devise's validations will require a password to be set, as well as the password_confirmation.
When I invite new users, I obviously don't want to set their password, so when I create the invitation in my system, it fails because user.password is blank.
I can set a temporary hashed_password on the user, but when they enter their own password, the validation checks for :password and :password_confirmation will not happen because hashed_password is set, which is a real problem.
Is there any way to tell Rails that I want to run all the validations except for the ones associated with :password?
I know Rails has :if conditions, which might fix my problem, but Devise declares the :password validation on my behalf, so that essentially is hidden.
How can I get the desired result here?, hopefully in a way that is not a hack.
My current hypothetical solution that is somewhat messy: The only thing I can think of is to create a new Invitation model that is not the User model, and use the Invitation model for the form. When the invitation is submitted I can validate that Invitation and copy over all the values to the new User model. I can save that User without any validations at all.
That's the best solution I dreamed up.
It seems like my solution will be a lot more work than saying something simple like:
user.save(validations => {:except => :password})
EDIT: I have found one part of the solution, but I am still having problems. In our user model, we can override a Devise method to prevent the validation of the password for invitations with this bit of code:
#protected
def password_required?
!is_invited && super
end
The is_invited attribute is just a column I added to the users table/model.
However, there is one gotcha here. When a user accepts an invitation and they arrive to the form where they need to set their password/password_confirmation, valid? will always return true.
This one has me deeply perplexed. I don't see how requires_password? and valid? can be true at the same time. If it requires the password, it should do a validation check and cause the validations to fail.
I'm starting to hate Devise - or just the idea of using gems to build parts of your application in a blackbox. I think the real solution probably is to rip out Devise and just do it all from scratch. That way your app has total control of how all of this works :(
I recently started using this great devise add-on: devise_invitable
It's commonly used so users (or any model) can invite other users to join.
But I adapt it for manually (via an admin panel) invite new potential users to my app.
Hope this helps!
I'm trying to migrate a legacy app to Rails 3 and change the authentication to use Devise. I've created the model and migrations and imported all the user data.
I don't plan to migrate the passwords over as the existing scheme is not one we'd like to use going forward, but I want to be able to present users with a simple experience.
Ideally I'd like to catch a login error and then check the password with the legacy field and then update the Devise password with it if it matches.
I can see that Warden gives me a callback that can trap errors so I expect I can trap a login error.
However because all the passwords (in Devise) are blank I get errors relating to the hash as the encrypted_password fields are empty.
Is there a way I can update all the user accounts with a random password?
I've seen in Devise::Models::DatabaseAuthenticatable that there is a method 'password=' but if I call that, e.g. in rails console for the app:
User.find(1).password=('new')
=> "new"
I just get the same plain text string back ('new') and saving the user record post this doesn't populate the encrypted_password field.
I've searched around but can't seem to be able to find it. Any suggestions much appreciated!
Ok just in case anyone else is as cloth headed as I have been the last 24 hours, here's how you set the password:
user = User.find(id)
user.password = 'new-password'
user.save
Simple really :)