From c456a6276ae24f6a686c410aa24831cdf1dc08b0 Mon Sep 17 00:00:00 2001 From: Oriol Collell Date: Fri, 18 Jul 2014 12:16:04 +0200 Subject: [PATCH] Add a more generic build_from method to external --- lib/sorcery/controller/submodules/external.rb | 14 ++++++++++++++ .../app/controllers/sorcery_controller.rb | 11 +++++++++++ spec/rails_app/config/routes.rb | 1 + .../controller_oauth2_shared_examples.rb | 16 ++++++++++++++++ 4 files changed, 42 insertions(+) diff --git a/lib/sorcery/controller/submodules/external.rb b/lib/sorcery/controller/submodules/external.rb index cf69e13d..5f20717a 100644 --- a/lib/sorcery/controller/submodules/external.rb +++ b/lib/sorcery/controller/submodules/external.rb @@ -164,6 +164,20 @@ def create_and_validate_from(provider_name) return user end + def build_from(provider_name) + sorcery_fetch_user_hash provider_name + config = user_class.sorcery_config + + attrs = user_attrs(@provider.user_info_mapping, @user_hash) + + @user = user_class.new + attrs.each do |k,v| + @user.send(:"#{k}=", v) + end + @user.send(config.authentications_class.to_s.downcase.pluralize).build(config.provider_uid_attribute_name => @user_hash[:uid], config.provider_attribute_name => provider_name) + @user + end + # this method automatically creates a new user from the data in the external user hash. # The mappings from user hash fields to user db fields are set at controller config. # If the hash field you would like to map is nested, use slashes. For example, Given a hash like: diff --git a/spec/rails_app/app/controllers/sorcery_controller.rb b/spec/rails_app/app/controllers/sorcery_controller.rb index c82cfc9c..0cb917bf 100644 --- a/spec/rails_app/app/controllers/sorcery_controller.rb +++ b/spec/rails_app/app/controllers/sorcery_controller.rb @@ -195,6 +195,17 @@ def test_create_from_provider redirect_to 'blu', alert: 'Failed!' end end + + def test_build_from_provider + provider = params[:provider] + login_from(provider) + @user = build_from(provider) + if @user.save + redirect_to 'bla', notice: 'Success!' + else + redirect_to 'blu', alert: 'Failed!' + end + end def test_add_second_provider provider = params[:provider] diff --git a/spec/rails_app/config/routes.rb b/spec/rails_app/config/routes.rb index deeb8a2a..cefe61e8 100644 --- a/spec/rails_app/config/routes.rb +++ b/spec/rails_app/config/routes.rb @@ -13,6 +13,7 @@ get :test_logout_with_remember get :test_should_be_logged_in get :test_create_from_provider + get :test_build_from_provider get :test_add_second_provider get :test_return_to_with_external get :test_login_from diff --git a/spec/shared_examples/controller_oauth2_shared_examples.rb b/spec/shared_examples/controller_oauth2_shared_examples.rb index 4552a2e8..78c7fc23 100644 --- a/spec/shared_examples/controller_oauth2_shared_examples.rb +++ b/spec/shared_examples/controller_oauth2_shared_examples.rb @@ -49,4 +49,20 @@ end end + + describe 'using build_from' do + before(:each) do + stub_all_oauth2_requests! + User.delete_all + Authentication.delete_all + end + + it 'builds and saves a new user' do + sorcery_model_property_set(:authentications_class, Authentication) + sorcery_controller_external_property_set(:facebook, :user_info_mapping, { username: 'name' }) + + expect { get :test_build_from_provider, provider: 'facebook' }.to change { User.count }.by 1 + expect(User.first.username).to eq 'Noam Ben Ari' + end + end end