Skip to content

Instantly share code, notes, and snippets.

@tanraya
Created March 3, 2014 14:40
Show Gist options
  • Save tanraya/9326355 to your computer and use it in GitHub Desktop.
Save tanraya/9326355 to your computer and use it in GitHub Desktop.
# 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