Created
March 3, 2014 14:40
-
-
Save tanraya/9326355 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Oauth-specific user methods | |
class User::Oauth2Service | |
def initialize(auth, user = nil) | |
@policy = policy(auth) | |
@user = user || User.where(email: @policy.email).first_or_initialize | |
@account = Oauth2::Account.where(provider: @policy.provider, uid: @policy.uid).first_or_initialize | |
end | |
def workflow(controller, &block) | |
@controller = controller | |
instance_eval(&block) if block_given? | |
# User found by email or already logged in | |
if @user.persisted? | |
# User already linked with account | |
if @account.persisted? | |
refresh_tokens! | |
run(on_sign_in, @account, @policy.provider_title) | |
else # User haven't account for current provider | |
create_account! | |
run(on_sign_in, @account, @policy.provider_title) | |
end | |
# Oauth2 provider does not provide email, or user not logged in | |
else | |
# Generate passwords for user | |
password = Devise.friendly_token.first(8) | |
@user.password ||= password | |
@user.password_confirmation ||= password | |
# FIXME: Should not confirm users automatically when user enter his email in form by hands | |
if @user.valid? | |
@user.skip_confirmation! | |
@user.save! | |
create_account! | |
run(on_sign_in, @account, @policy.provider_title) | |
else | |
# Ask user for required info | |
@user.name = @policy.username | |
@user.errors.clear | |
run(on_invalid_credentials, @user, @policy.provider_title) | |
end | |
end | |
end | |
def on_invalid_credentials(&block) | |
@on_invalid_credentials ||= block | |
end | |
def on_sign_in(&block) | |
@on_sign_in ||= block | |
end | |
protected | |
def create_account! | |
@account = @user.oauth2_accounts.create!( | |
provider: @policy.provider, | |
uid: @policy.uid, | |
oauth_token: @policy.oauth_token, | |
oauth_expires: @policy.oauth_expires, | |
oauth_secret: @policy.oauth_secret, | |
username: @policy.username, | |
remote_userpic_url: @policy.userpic_url, | |
profile_url: @policy.profile_url | |
) | |
end | |
def refresh_tokens! | |
@account.update_attributes( | |
oauth_token: @policy.oauth_token, | |
oauth_expires: @policy.oauth_expires, | |
oauth_secret: @policy.oauth_secret | |
) | |
end | |
def policy(auth) | |
"Oauth2::Policy::#{auth.provider.classify}".constantize.new(auth) | |
end | |
# Execute proc in context of controller and pass account into it | |
def run(proc, *args) | |
@controller.instance_exec(*args, &proc) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment