I am trying to override update method from PasswordsController from Devise to work for an api rest application (so from the client only come values for password and password_confirmation, without the value for reset_password_token). My question is: how to override update method to not require reset_password_token.
It is not possible, because without the token, you cannot find the existing user record.
And then it's not clear for the app, for which user the password should be updated.
Related
As a part of my application, when I send an invitation out to other users, I need to set a bunch of parameters for the newly created user before they even sign into the application. So, before switching to DeviseTokenAuth(and rails api), I used devise and it allowed me to make user changes from the back-end. For example, if I go to the console and do a user.save, it returns true.
Now after switching to DeviseTokenAuth, I had to enter the following in concerns file within the User model:
include DeviseTokenAuth::Concerns::User
Once i included this, I am unable to make changes to the user from the backend, (for example, rails console> user.save returns false). I presume that it requires a Token every time a user is updated? How can I skip this for specific controller actions where for instance, I would need to update the user withouth the user/client actually calling the action. (sending a token)
In case somebody else comes across this issue: I spent a few hours shooting in the dark finally to realize that it that the uid field for the User object needs to be populated with DeviseTokenAuth. If not, user will not be updatable. i.e.user.save will return false
In my case, I was sending an invitation using devise_invitable which is currently outside the bounds of DeviseTokenAuth defaults. So, when you create a new user using the invite method of Devise_invitable gem, the UID, provider fields are not automatically set. I just needed to add 2 line of code post invitation:
u= User.invite!(params[:email])
u.uid=params[:email] #added
u.provider='email' #added
u.save #added
Now the user object works fine, it had nothing to do with the token itself - so my previous assumption stated in the question was humbug.
Im trying to customize Devise registration process to generate a random password and sends it with the confirmation mail.
What I have already done is to override the default Devise's :validtable and to generate a new random password if needed.
before_validation :password_generation
def password_generation
password_confirmation = password = Devise.friendly_token.first(7) if password.nil? || password.blank?
end
Now my problem is to include the newly generated random password with the original confirmation mail.
Is there any possibility to keep up with the original usability of Devise while customizing it's new user process or should I build the authentication process from scratch ?
Thanks,
Hadar.
(four months too late, but perhaps someone else can use this)
Mostly what you need to do is copy the default Devise mailer and views to your project and in the config/initializers/devise.rb specify your local class in config.mailer. At that point, you can customize the email as you like. (note that Devise uses the term resource as an abstraction, but mostly it means an instance of User).
The only trick will be to find a way to remember the generated password between the time that the new user account is created and when the email is generated and sent. What Devise will store, when saving the user record is an encrypted version of the password. I would have to follow the path of logic in Devise to be sure, but I'll bet you could store it in an instance variable on User, perhaps params or maybe the flash. Be very careful about this; you want this value to be as short-lived as possible -- presumably just the lifetime of the request.
I want users to interact with my site without having to create an account and then later create an account (supply password, name info..etc) if they want more.
This works fine but if user thought they've created an account and then tried to login (likely using a password they use all the time) Devise will through an Exception:
BCrypt::Errors::InvalidHash in Devise/sessionsController#create
Because password is nil. If they go through the signup and then signin again, it works.
I'm using devise (1.2.0), Rails (3.0.4) and Ruby 1.9.2
I mean I can go around it by creating a dummy password and have a field to say if the user has signed up (or check if other mandatory fields have been provided) then resetting the password on actual sign up but I think in all cases it shouldn't through the above exception.
Is there anything I can do/set to go around the problem?
The easiest way is probably to just generate a random one, using something like Devise.friendly_token[0..20] but you could also override the Devise controller and method for logging in, rescue the exception, and just redirect.
I'm using Devise to allow user signup as-well-as using my own user admin to create users manually. When I create a user in the admin, Devise sends a confirmation immediately to the new user. I believe this is due to the fact that both devise and my admin use the same model. How do I delay this email until the administrator is ready to send it?
Additionally, Devise's validation is requiring the admin set a password for the new user. I would much prefer the manually created users specify their own password when they respond the confirmation. Right now manually created users will not know their password unless I send it too them in a supplemental email.
#user.skip_confirmation! confirms the user, so the user can log in
without using the confirmation.
This works for me in devise 3.5
Stop devise to send confirmation email while creating user.
#user.skip_confirmation_notification!
Send confirmation instructions later
#user.send_confirmation_instructions
We do this in one of our apps. You can tell Devise NOT to automatically deliver the confirmation like this:
#user.skip_confirmation!
And then later, you can do
Devise::Mailer.confirmation_instructions(#user).deliver
For Rails 2.x you'd do something like:
DeviseMailer.deliver_confirmation_instructions(#user)
The solution is not so simple as #Ryan Heneise's answer. If you do #user.skip_confirmation! it confirms the user, so the user can log in without using the confirmation, so the confirmation letter in this case is useless. This solution does not allows the user to log in without the confirmation: Rails 3 with Devise for Authentication - How do I manually create a user?
There's now an easier way (was added back in v2.2.4)
Devise's confirmable module now includes the perfect skip_confirmation_notification! method which allows for a cleaner solution:
#user = User.new params[:user]
#user.skip_confirmation_notification!
#user.save
# ... do stuff, then later...
Devise::Mailer.confirmation_instructions(#user).deliver
I just spent some time looking into this, basically you just need to add this and setup delayed_job.
def send_confirmation_instructions
generate_confirmation_token! if self.confirmation_token.nil?
::Devise.mailer.delay.confirmation_instructions(self)
end
Add it in your user model as protected method to override the devise one in confirmable. Also, note the gem was just updated to add a new method to be overridden on create that sends the confirmation instructions.
There is now the devise-async project:
https://github.com/mhfs/devise-async
https://github.com/plataformatec/devise/wiki/How-To:-Send-devise-emails-in-background-(Resque,-Sidekiq-and-Delayed::Job)
Do you use delayed job ? It allows you to define single methods for delayed run.
I'm using Devise in a Rails 3 app, and I successfully configured it so that it uses a username as its authentication method instead of an email. The problem is that in the default registrations controller for devise, it calls an "update_with_password" method on the params passed in, which effectively allows users to change their username, and password. This behaviour makes sense if you're using email as an authentication method, since it's reasonable to expect people to be able to change their email. However, with using usernames, I'd rather users not be able to change them; I only want them to be able to change their password. Would this best way to do this be to override the RegistrationsController, and prevent the mass-assignment of params so that only the password can be changed?
Hope this is clear. Thanks!
Ok, I solved it. I added attr_readonly to the username variable, so that it cannot be changed with mass assignment.