module Omniauth class Social::Service attr_reader :provider_data, :controller def initialize(auth, controller) @provider_data = auth.env['omniauth.auth'] @controller = controller end def execute if signin_via_social yield(PostService::Success, PostService::Failure) else yield(PostService::Failure, PostService::Success) end end private def signin_via_social false unless @provider_data account = AuthProvider.find_by(provider_params)&.user || User.find_by(email: provider_data.info.email) if account account.auth_providers.find_or_create_by(provider_params) else account = User.create!(user_params) account.auth_providers.create(provider_params) end controller.sign_in(account) controller.session[:user] = account.email true end def provider_params { uid: provider_data.uid, provider: provider_data.provider } end def user_params { username: provider_data.info.name, email: provider_data.info.email, avatar: avatar(provider_data.info.image) } end def avatar(url) file = Tempfile.new file.binmode file.write open(url).read file.rewind file end class Success def self.call yield end end class Failure def self.call; end end end end