intridea/omniauth-identity — Issue #19: Need to set password_digest when using this in conjunction with other strategies
Author: j2fly
Created: 2012-02-19 23:41:09+00:00
State: open

Hi Michael,

Oddly I never really played with omniauth when I was at Intridea :) hopefully you can drop a knowledge bomb on me now though. I setup a project to use both twitter and identity and identity is of course using has_secure_password which validates the presence of password_digest on the User model which I setup as the custom class instead of Identity (ActiveRecord is what I'm using there).

I don't want to make folks that only want to use twitter for auth fill out a password when completing their registration (I have to store their omniauth info in a session and redirect to a more robust registration form populated with the data that I do have coming back from the strategy). But if I hide the password fields and submit then I get the password_digest validation error. My solution was to trigger a before validation callback and set the password_digest directly for them.

If I set it to something simple like '0' it'll pass validations and if they try to type in any password other than '0' it properly redirects to the failure action with a nice flash message. But I'm not cool with loose ends like that and if they happened to try the password of '0' outright it'll throw an invalid hash error from bcrypt. I couldn't find a way to rescue that error gracefully at the application level since it seems to be thrown from within omniauth (I think?), so to avoid the unsightly 500 I actually hash a password with a salt when saving the record. I choose the somewhat lengthy and odd "generic_identity_password" string.

Then I added a validation that wouldn't allow someone to set that as their actual password. I also wanted to handle the case where the user might somehow guess the password I set and try to login with it. So I added some controller logic to redirect the exact same way as if they had typed the password incorrectly if they guess the "generic_identity_password" string. This feels messy, but it does work. However, I'd love to refactor it to be better.

Any suggestions?

Thanks!