Rails3 User Changed Password, how do I change the current session password? - ruby-on-rails

I have the need to let the user change their password. I'd like to switch the password in the session to reflect this new password, without logging them out.
def set_auth username, password
# test username and password here?
auth_object = AuthCookie.new
auth_object.set_username username
auth_object.set_password password
session[:user_login] = auth_object
end
I use something like the above, but it doesn't seem to work in changing the current session's password to the new one the use just entered.
What am I doing wrong?

Don't save your whole auth object in the session, the most important thing is you should not save password info in the session. Rails default session storage is cookie based, just base64 encode string. So if you save user password info in the session, there is security problem.
Just put the user identify in the session, for example, the user_id. session[:user_id] = user_id

Related

Devise token auth another user login

I am developing an application through Rails.
I need the ability to login to another user with admin account in devise token auth gem
When user log in, authHeaders are stored in the browser cookie.
Determine user by authHeaders value.
ex)
{ %22access-token%22:%22"access-token value"%22%2C
%22token-type%22:%22Bearer%22%2C
%22client%22:%22"client value"%22%2C
%22expiry%22:%"expiry value"%22%2C
%22uid%22:%22"uid value"%22}
in my controller
returns a new token value when admin clicks user id
def login_as
user = User.find(params[:user_id])
user_new_token_data = user.create_new_auth_token
## return new access-token, token-type, client, expiry, uid in browser cookies format same value
end
I want to change the return value to a browser cookie value and log in as another user, but I do not know how to put it in the cookie.
I would appreciate your help. Thank you

Fetch the Password and confirmation field of a Model object in Rails

Is there any way to fetch the password and password_confirmation field of a Model object in Rails.? Say for example, I have an user object
user = User.find(1)
Now, I want to fetch the value of the password field like this.
password = user.password
confirmation = user.password_confirmation.
I tried this, but it is returning nil.
I know, this is a security issue if they allow these fields to be accessible., But, I want to fetch these values for a feature to be implemented in our application.
Assuming you are using Devise, the only attribute related to the user's password is encrypted_password, it will return the BCrypt encrypted password. You can also read the password_salt User attribute.
You can see all Devise User Model attributes with: User.column_names

How to register users on my app with social auth?

I am allowing users to register/login via facebook and username/passwd.
So if a user registers via fb, then how do I save the "User" instance without username and password ?
Well you have two options:
First: allow null value in both fields.
Second: override some methods like this:
There is a function called create_user in pipeline which calls create_user of your user model's manager. You can override that method and create password by yourself:
def create_user(self, email, username, password, is_staff, is_superuser,
*args, **extra_fields):
"""
Creates and saves a User with the given username and password.
"""
now = timezone.now()
if not username:
username = '' # or randomly generated string
user = self.model(username=username, is_staff=is_staff, email=email,
is_active=True, is_superuser=is_superuser,
last_login=now, date_joined=now)
user.set_password(password) # this generates password
user.save(using=self._db)
return user
This will save a user with generated username and password. You can change it however you want.

reset_password_sent_at assignment for devise

The issue is that devise is checking the reset_password_sent_at when a user clicks on the link to reset their password (from an email) and when trying to reset (in the form) an error occurs:
Reset password token has expired, please request a new one
Meaning, "when a reset_password_token is generated, #user.reset_password_sent_at needs to be set to Time.now, or else when devise runs #user.reset_password_period_valid? to find out if the reset token is still valid, it will get nil and assume the token has expired."
What I don't understand is how and where to assign reset_password_sent_at to Time.now
Do I need to assign Time.now through the console to all Users? If so, How would I do that?
Or, is it a before_create (or something else) that I need to assign Time.now to reset_password_sent_at? If so, how and where should I do this?
You don't need to worry about reset_password_sent_at; that is something devise will take care of setting correctly when a reset_password is sent to the user.
reset_password_sent_at works in conjunction with the reset_password_within parameter, set in the config/initializers/devise.rb file. It should look something like this:
config.reset_password_within = 2.hours
Most likely it is set to nil or 0, and that is making the application throw the password reset token has expired method.

OmniAuth and Devise, how to set optional passwords

I am using OmniAuth and Devise to authenticate users. I would like users that have signed up using OmniAuth providers to be able to set an optional password (needed for API authentication) but I'm running into a wall.
If a user creates an account via OmniAuth and tries to set a password they get the following error:
BCrypt::Errors::InvalidHash in RegistrationsController#update
I believe this is because the password is blank. What's a good way around this? I've thought about generating a random password but the problem with that approach is the user needs to know the current password in order to edit settings.
Edit:
I looked at allowing the user to change settings without requiring a current password and that's what I would like to do only if the user didn't have a password initially.
An alternative is to add the following into your 'user' model class to bypass password verification if there is no password to verify, where provider is some field that is set when using external authentication.
def valid_password?(password)
!provider.nil? || super(password)
end
I assume you don't want the easy way out which would be to simply reset the password if they wanted to set it?
user.send_reset_password_instructions
This comes a bit late but it might help someone else, with Andrew's answer you can in create a password and store it in the database, but you can't login using your email and your new password, solved this by setting:
def valid_password
!provider.nil? && !encrypted_password.present? || super
end
Another alternative. You don't have to include a new field. Just catch the exception raised and return false. Here is the code.
def valid_password?(password)
begin
super(password)
rescue BCrypt::Errors::InvalidHash
return false
end
end
This should do the job.

Resources