solidus_social 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.hound.yml +26 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +8 -0
  6. data/.travis.yml +19 -0
  7. data/CHANGELOG.md +5 -0
  8. data/CONTRIBUTING.md +31 -0
  9. data/Gemfile +7 -0
  10. data/Guardfile +10 -0
  11. data/LICENSE.md +26 -0
  12. data/README.md +148 -0
  13. data/Rakefile +15 -0
  14. data/app/assets/javascripts/spree/backend/solidus_social.js +1 -0
  15. data/app/assets/javascripts/spree/frontend/solidus_social.js +1 -0
  16. data/app/assets/stylesheets/spree/backend/solidus_social.css +3 -0
  17. data/app/assets/stylesheets/spree/frontend/fontello.css +64 -0
  18. data/app/assets/stylesheets/spree/frontend/solidus_social.css +4 -0
  19. data/app/controllers/spree/admin/authentication_methods_controller.rb +18 -0
  20. data/app/controllers/spree/omniauth_callbacks_controller.rb +67 -0
  21. data/app/controllers/spree/user_authentications_controller.rb +12 -0
  22. data/app/controllers/spree/user_registrations_controller_decorator.rb +15 -0
  23. data/app/helpers/spree/omniauth_callbacks_helper.rb +5 -0
  24. data/app/models/spree/authentication_method.rb +13 -0
  25. data/app/models/spree/social_configuration.rb +5 -0
  26. data/app/models/spree/user_authentication.rb +3 -0
  27. data/app/models/spree/user_decorator.rb +16 -0
  28. data/app/overrides/add_authentications_to_account_summary.rb +5 -0
  29. data/app/overrides/admin_configuration_decorator.rb +5 -0
  30. data/app/overrides/user_registrations_decorator.rb +17 -0
  31. data/app/views/spree/admin/authentication_methods/_form.html.erb +45 -0
  32. data/app/views/spree/admin/authentication_methods/edit.html.erb +18 -0
  33. data/app/views/spree/admin/authentication_methods/index.html.erb +54 -0
  34. data/app/views/spree/admin/authentication_methods/new.html.erb +18 -0
  35. data/app/views/spree/admin/shared/_configurations_menu.html.erb +4 -0
  36. data/app/views/spree/shared/_social.html.erb +11 -0
  37. data/app/views/spree/shared/_user_form.html.erb +19 -0
  38. data/app/views/spree/users/_new-customer.html.erb +5 -0
  39. data/app/views/spree/users/_social.html.erb +28 -0
  40. data/bin/rails +7 -0
  41. data/config/initializers/devise.rb +13 -0
  42. data/config/locales/de.yml +26 -0
  43. data/config/locales/en.yml +26 -0
  44. data/config/locales/es-MX.yml +26 -0
  45. data/config/locales/fr.yml +26 -0
  46. data/config/locales/nl.yml +26 -0
  47. data/config/locales/pt-BR.yml +26 -0
  48. data/config/locales/sv.yml +26 -0
  49. data/config/routes.rb +14 -0
  50. data/db/migrate/20120120163432_create_user_authentications.rb +10 -0
  51. data/db/migrate/20120123163222_create_authentication_methods.rb +13 -0
  52. data/lib/generators/solidus_social/install/install_generator.rb +24 -0
  53. data/lib/solidus_social.rb +10 -0
  54. data/lib/solidus_social/engine.rb +70 -0
  55. data/lib/solidus_social/version.rb +18 -0
  56. data/solidus_social.gemspec +47 -0
  57. data/spec/controllers/spree/omniauth_callbacks_controller_spec.rb +160 -0
  58. data/spec/features/spree/admin/authentication_methods_configuration_spec.rb +79 -0
  59. data/spec/features/spree/sign_in_spec.rb +81 -0
  60. data/spec/lib/spree_social/engine_spec.rb +16 -0
  61. data/spec/models/spree/user_decorator_spec.rb +54 -0
  62. data/spec/spec_helper.rb +36 -0
  63. data/spec/support/capybara.rb +18 -0
  64. data/spec/support/database_cleaner.rb +24 -0
  65. data/spec/support/devise.rb +3 -0
  66. data/spec/support/factory_girl.rb +7 -0
  67. data/spec/support/spree.rb +8 -0
  68. metadata +429 -0
@@ -0,0 +1,26 @@
1
+ ---
2
+ nl:
3
+ devise:
4
+ omniauth_callbacks:
5
+ success: "U bent nu aangemeld met uw %{kind}-account."
6
+ spree:
7
+ user_was_not_valid: Gebruiker was niet geldig.
8
+ add_another_service: 'Nog een log-in dienst toevoegen:'
9
+ authentications:
10
+ destroy: "Met succes vernietigd authenticatiemethode."
11
+ back_to_authentication_methods_list: "Terug naar de lijst verificatiemethoden"
12
+ edit_social_method: 'Bewerk Social Authenticatie Methodes'
13
+ new_social_method: 'Nieuwe Authenticatie Methode'
14
+ no_authentication_methods_found: "Geen verificatiemethoden gevonden"
15
+ one_more_step: 'Laatste stap om registratie met %{kind} te voltooien'
16
+ remove_authentication_option_confirmation: 'Weet je zeker dat je deze authenticatie methode wilt verwijderen?'
17
+ sign_into_account: 'Je kunt bij deze account inlogen met:'
18
+ sign_in_through_one_of_these_services: 'Log in met een van de volgende diensten:'
19
+ social_api_key: 'API Key'
20
+ social_api_secret: 'API Secret'
21
+ social_authentication_methods: 'Social Authenticatie Methodes'
22
+ social_authentication_methods_description: 'OAuth Authenticatie Methodes Instellen'
23
+ social_provider: 'Social Provider'
24
+ please_confirm_your_email: 'Bevestig je email adres om verder te gaan'
25
+ sign_in_with: 'Login met %{provider}'
26
+ you_have_signed_in_with_these_services: "Je hebt in deze diensten ondertekend"
@@ -0,0 +1,26 @@
1
+ ---
2
+ pt-BR:
3
+ devise:
4
+ omniauth_callbacks:
5
+ success: "Você está logado agora com a sua conta do %{kind}."
6
+ spree:
7
+ user_was_not_valid: "Usuário não era válido."
8
+ add_another_service: "Adicione outro serviço para se logar:"
9
+ authentications:
10
+ destroy: 'Método de autenticação destruído com sucesso.'
11
+ back_to_authentication_methods_list: "Voltar Para Lista de Métodos de Autenticação"
12
+ edit_social_method: "Editando Método de Autenticação Social"
13
+ new_social_method: "Novo Método de Autenticação"
14
+ no_authentication_methods_found: "Métodos de Autenticação Não Encontrados"
15
+ one_more_step: 'Um passo apenas para completar seu registro pelo %{kind}'
16
+ remove_authentication_option_confirmation: "Você tem certeza que deseja remover este método de autenticação ?"
17
+ sign_into_account: "Você pode acessar esta conta usando:"
18
+ sign_in_through_one_of_these_services: "Acesse através de um destes serviços:"
19
+ social_api_key: "Chave API"
20
+ social_api_secret: "Segredo API"
21
+ social_authentication_methods: "Métodos de Autenticação Social"
22
+ social_authentication_methods_description: "Configure Métodos de Autenticação OAuth"
23
+ social_provider: "Provedor Social"
24
+ please_confirm_your_email: "Por favor confirme seu endereço de e-mail para continuar"
25
+ sign_in_with: "Login com %{provider}"
26
+ you_have_signed_in_with_these_services: "Você se cadastrou com estes serviços"
@@ -0,0 +1,26 @@
1
+ ---
2
+ sv:
3
+ devise:
4
+ omniauth_callbacks:
5
+ success: "Du är nu inloggad med ditt %{kind} konto."
6
+ spree:
7
+ user_was_not_valid: "Användaren var inte giltigt."
8
+ add_another_service: "Lägg en annan tjänst för att logga in med:"
9
+ authentications:
10
+ destroy: "Autentiseringsmetoden har nu blivit borttagen."
11
+ back_to_authentication_methods_list: "Tillbaka till listan med autentiseringsmetoder"
12
+ edit_social_method: "Redigera social autentiseringsmetod"
13
+ new_social_method: "Ny autentiseringsmetod"
14
+ no_authentication_methods_found: "Inga autentiseringsmetoder funna"
15
+ one_more_step: "Ett steg från att slutföra din registrering från %{kind}"
16
+ remove_authentication_option_confirmation: "Är du säker på att du vill ta bort denna autentiseringsmetod?"
17
+ sign_into_account: "Du kan logga in på detta konto med hjälp av:"
18
+ sign_in_through_one_of_these_services: "Logga in genom en av dessa tjänster:"
19
+ social_api_key: "API-nyckel"
20
+ social_api_secret: "API lösenord"
21
+ social_authentication_methods: "Sociala autentiseringsmetoder"
22
+ social_authentication_methods_description: "Sätt upp OAuth autentiseringsmetoder"
23
+ social_provider: "Social tjänst"
24
+ please_confirm_your_email: "Bekräfta din e-postadress för att fortsätta"
25
+ sign_in_with: "Logga in med %{provider}"
26
+ you_have_signed_in_with_these_services: "Du har loggat in via dessa tjänster"
@@ -0,0 +1,14 @@
1
+ Spree::Core::Engine.add_routes do
2
+ devise_for :spree_user,
3
+ class_name: Spree::User,
4
+ only: [:omniauth_callbacks],
5
+ controllers: { omniauth_callbacks: 'spree/omniauth_callbacks' },
6
+ path: Spree::SocialConfig[:path_prefix]
7
+ resources :user_authentications
8
+
9
+ get 'account' => 'users#show', as: 'user_root'
10
+
11
+ namespace :admin do
12
+ resources :authentication_methods
13
+ end
14
+ end
@@ -0,0 +1,10 @@
1
+ class CreateUserAuthentications < ActiveRecord::Migration
2
+ def change
3
+ create_table :spree_user_authentications do |t|
4
+ t.integer :user_id
5
+ t.string :provider
6
+ t.string :uid
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,13 @@
1
+ class CreateAuthenticationMethods < ActiveRecord::Migration
2
+ def change
3
+ create_table :spree_authentication_methods do |t|
4
+ t.string :environment
5
+ t.string :provider
6
+ t.string :api_key
7
+ t.string :api_secret
8
+ t.boolean :active
9
+
10
+ t.timestamps
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,24 @@
1
+ module SolidusSocial
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ class_option :auto_run_migrations, type: :boolean, default: false
5
+
6
+ def add_stylesheets
7
+ inject_into_file 'vendor/assets/stylesheets/spree/frontend/all.css', " *= require spree/frontend/solidus_social\n", before: /\*\//, verbose: true
8
+ end
9
+
10
+ def add_migrations
11
+ run 'bundle exec rake railties:install:migrations FROM=solidus_social'
12
+ end
13
+
14
+ def run_migrations
15
+ run_migrations = options[:auto_run_migrations] || ['', 'y', 'Y'].include?(ask 'Would you like to run the migrations now? [Y/n]')
16
+ if run_migrations
17
+ run 'bundle exec rake db:migrate'
18
+ else
19
+ puts 'Skipping rake db:migrate, don\'t forget to run it!'
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,10 @@
1
+ require 'spree_core'
2
+ require 'solidus_auth_devise'
3
+ require 'omniauth-twitter'
4
+ require 'omniauth-facebook'
5
+ require 'omniauth-github'
6
+ require 'omniauth-google-oauth2'
7
+ require 'omniauth-amazon'
8
+ require 'solidus_social/engine'
9
+ require 'solidus_social/version'
10
+ require 'coffee_script'
@@ -0,0 +1,70 @@
1
+ module SolidusSocial
2
+ OAUTH_PROVIDERS = [
3
+ %w(Facebook facebook),
4
+ %w(Twitter twitter),
5
+ %w(Github github),
6
+ %w(Google google_oauth2),
7
+ %w(Amazon amazon)
8
+ ]
9
+
10
+ class Engine < Rails::Engine
11
+ engine_name 'solidus_social'
12
+
13
+ config.autoload_paths += %W(#{config.root}/lib)
14
+
15
+ initializer 'solidus_social.environment', before: 'spree.environment' do
16
+ Spree::SocialConfig = Spree::SocialConfiguration.new
17
+ end
18
+
19
+ def self.activate
20
+ Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
21
+ Rails.configuration.cache_classes ? require(c) : load(c)
22
+ end
23
+ end
24
+
25
+ config.to_prepare(&method(:activate).to_proc)
26
+ end
27
+
28
+ # Setup all OAuth providers
29
+ def self.init_provider(provider)
30
+ return unless ActiveRecord::Base.connection.table_exists?('spree_authentication_methods')
31
+ key, secret = nil
32
+ Spree::AuthenticationMethod.where(environment: ::Rails.env).each do |auth_method|
33
+ next unless auth_method.provider == provider
34
+ key = auth_method.api_key
35
+ secret = auth_method.api_secret
36
+ Rails.logger.info("[Spree Social] Loading #{auth_method.provider.capitalize} as authentication source")
37
+ end
38
+ setup_key_for(provider.to_sym, key, secret)
39
+ end
40
+
41
+ def self.setup_key_for(provider, key, secret)
42
+ Devise.setup do |config|
43
+ config.omniauth provider, key, secret, setup: true
44
+ end
45
+ end
46
+ end
47
+
48
+ module OmniAuth
49
+ module Strategies
50
+ class Facebook < OAuth2
51
+ MOBILE_USER_AGENTS = 'palm|blackberry|nokia|phone|midp|mobi|symbian|chtml|ericsson|minimo|' \
52
+ 'audiovox|motorola|samsung|telit|upg1|windows ce|ucweb|astel|plucker|' \
53
+ 'x320|x240|j2me|sgh|portable|sprint|docomo|kddi|softbank|android|mmp|' \
54
+ 'pdxgw|netfront|xiino|vodafone|portalmmm|sagem|mot-|sie-|ipod|up\\.b|' \
55
+ 'webos|amoi|novarra|cdm|alcatel|pocket|ipad|iphone|mobileexplorer|' \
56
+ 'mobile'
57
+ def request_phase
58
+ options[:scope] ||= 'email'
59
+ options[:info_fields] ||= 'email'
60
+ options[:display] = mobile_request? ? 'touch' : 'page'
61
+ super
62
+ end
63
+
64
+ def mobile_request?
65
+ ua = Rack::Request.new(@env).user_agent.to_s
66
+ ua.downcase =~ Regexp.new(MOBILE_USER_AGENTS)
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,18 @@
1
+ module SolidusSocial
2
+ module_function
3
+
4
+ # Returns the version of the currently loaded SolidusSocial as a
5
+ # <tt>Gem::Version</tt>.
6
+ def version
7
+ Gem::Version.new VERSION::STRING
8
+ end
9
+
10
+ module VERSION
11
+ MAJOR = 1
12
+ MINOR = 0
13
+ TINY = 0
14
+ PRE = nil
15
+
16
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
17
+ end
18
+ end
@@ -0,0 +1,47 @@
1
+ lib = File.expand_path('../lib/', __FILE__)
2
+ $LOAD_PATH.unshift lib unless $LOAD_PATH.include?(lib)
3
+
4
+ require 'solidus_social/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.platform = Gem::Platform::RUBY
8
+ s.name = 'solidus_social'
9
+ s.version = SolidusSocial.version
10
+ s.summary = 'Adds social network login services (OAuth) to Spree'
11
+ s.description = s.summary
12
+ s.required_ruby_version = '>= 1.9.3'
13
+
14
+ s.author = 'John Dyer'
15
+ s.email = 'jdyer@spreecommerce.com'
16
+ s.homepage = 'http://www.spreecommerce.com'
17
+ s.license = 'BSD-3'
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.test_files = `git ls-files -- spec/*`.split("\n")
21
+ s.require_path = 'lib'
22
+ s.requirements << 'none'
23
+
24
+ s.add_runtime_dependency 'solidus_core', ["~> 1.0"]
25
+ s.add_runtime_dependency 'omniauth'
26
+ s.add_runtime_dependency 'oa-core'
27
+ s.add_runtime_dependency 'omniauth-twitter'
28
+ s.add_runtime_dependency 'omniauth-facebook'
29
+ s.add_runtime_dependency 'omniauth-github'
30
+ s.add_runtime_dependency 'omniauth-google-oauth2'
31
+ s.add_runtime_dependency 'omniauth-amazon'
32
+
33
+ s.add_development_dependency 'capybara', '~> 2.4.1'
34
+ s.add_development_dependency 'database_cleaner', '1.3.0'
35
+ s.add_development_dependency 'rspec-rails', '~> 3.1.0'
36
+ s.add_development_dependency 'factory_girl', '~> 4.4'
37
+ s.add_development_dependency 'pry-rails'
38
+ s.add_development_dependency 'selenium-webdriver', '>= 2.41.0'
39
+ s.add_development_dependency 'poltergeist', '~> 1.5.0'
40
+ s.add_development_dependency 'simplecov', '~> 0.9.0'
41
+ s.add_development_dependency 'sqlite3', '~> 1.3.10'
42
+ s.add_development_dependency 'coffee-rails'
43
+ s.add_development_dependency 'sass-rails'
44
+ s.add_development_dependency 'guard-rspec'
45
+ s.add_development_dependency 'rubocop', '>= 0.24.1'
46
+ s.add_development_dependency 'rake', '< 11'
47
+ end
@@ -0,0 +1,160 @@
1
+ RSpec.describe Spree::OmniauthCallbacksController, type: :controller do
2
+ let(:user) { create(:user) }
3
+ let(:omni_params) { double('omni', :[] => nil).as_null_object }
4
+ let(:order) { double('Spree::Order', associate_user: nil) }
5
+
6
+ before do
7
+ Rails.application.routes.default_url_options[:host] = 'test.host'
8
+ request.env['omniauth.auth'] = omni_params
9
+ allow(controller).to receive(:sign_in_and_redirect)
10
+ allow(controller).to receive(:redirect_back_or_default)
11
+ allow(Spree::User).to receive(:anonymous!).with(user)
12
+ end
13
+
14
+ shared_examples_for 'denied_permissions' do
15
+ before { request.env['omniauth.error'] = 'FAIL' }
16
+
17
+ it 'redirects properly' do
18
+ expect(controller).to receive(:redirect_back_or_default)
19
+ controller.twitter
20
+ end
21
+
22
+ it 'displays an error message' do
23
+ controller.twitter
24
+ expect(flash[:error]).not_to be_blank
25
+ end
26
+
27
+ it 'does not attempt authentication' do
28
+ expect(controller).not_to receive(:sign_in_and_redirect)
29
+ controller.twitter
30
+ end
31
+ end
32
+
33
+ shared_examples_for 'associate_order' do
34
+ before { allow(controller).to receive(:current_order).and_return(order) }
35
+
36
+ it 'associates the order with the user' do
37
+ expect(order).to receive(:associate_user!).with(user)
38
+ controller.twitter
39
+ end
40
+ end
41
+
42
+ shared_examples_for 'authenticate_as_user' do
43
+ it 'authenticates as that user' do
44
+ expect(controller).to receive(:sign_in_and_redirect).with(user, event: :authentication)
45
+ end
46
+ end
47
+
48
+ context '#callback' do
49
+ context 'when user is authenticated' do
50
+ before do
51
+ allow(controller).to receive(:spree_current_user).and_return(user)
52
+ end
53
+
54
+ it_should_behave_like 'denied_permissions'
55
+
56
+ context 'when existing user_authentication' do
57
+ let(:user_authentication) { double('user_authentication', user: user) }
58
+ before do
59
+ allow(Spree::UserAuthentication).to receive(:find_by_provider_and_uid).and_return(user_authentication)
60
+ end
61
+
62
+ it 'does not need to create the user_authentication' do
63
+ expect(user.user_authentications).not_to receive(:create!)
64
+ controller.twitter
65
+ end
66
+
67
+ it 'sets the flash notice' do
68
+ controller.twitter
69
+ expect(flash[:notice]).not_to be_blank
70
+ end
71
+
72
+ it 'authenticates as that user' do
73
+ expect(controller).to receive(:sign_in_and_redirect)
74
+ controller.twitter
75
+ end
76
+ end
77
+
78
+ context 'when no existing user_authentication' do
79
+ before do
80
+ allow(Spree::UserAuthentication).to receive(:find_by_provider_and_uid).and_return(nil)
81
+ end
82
+
83
+ it 'creates a new user_authentication' do
84
+ expect(user).to receive(:apply_omniauth)
85
+ expect(user).to receive(:save!)
86
+ controller.twitter
87
+ end
88
+
89
+ it 'sets the flash notice' do
90
+ controller.twitter
91
+ expect(flash[:notice]).not_to be_blank
92
+ end
93
+
94
+ it 'redirects properly' do
95
+ expect(controller).to receive(:redirect_back_or_default)
96
+ controller.twitter
97
+ end
98
+
99
+ it_should_behave_like 'associate_order'
100
+ end
101
+ end
102
+
103
+ context 'when user is not authenticated' do
104
+ before do
105
+ allow(controller).to receive(:spree_current_user).and_return(nil)
106
+ end
107
+
108
+ it_should_behave_like 'denied_permissions'
109
+
110
+ context 'when existing user_authentication' do
111
+ let(:user_authentication) { double('user_authentication', user: user) }
112
+ before do
113
+ allow(Spree::UserAuthentication).to receive(:find_by_provider_and_uid).and_return(user_authentication)
114
+ end
115
+
116
+ it 'does not need to create the user_authentication' do
117
+ expect(user.user_authentications).not_to receive(:create!)
118
+ controller.twitter
119
+ end
120
+
121
+ it 'does not create a new user account' do
122
+ expect(Spree::User).not_to receive :new
123
+ controller.twitter
124
+ end
125
+
126
+ it 'authenticates as that user' do
127
+ expect(controller).to receive(:sign_in_and_redirect).with(:spree_user, user)
128
+ controller.twitter
129
+ end
130
+ end
131
+
132
+ context 'when no existing user_authentication' do
133
+ let(:user) { Spree::User.new }
134
+ before do
135
+ allow(Spree::UserAuthentication).to receive(:find_by_provider_and_uid).and_return(nil)
136
+ allow(controller).to receive(:auth_hash).and_return('provider' => 'facebook', 'info' => { 'email' => 'spree@gmail.com' }, 'uid' => '123')
137
+ end
138
+
139
+ context "email doesn't belongs to anyone" do
140
+ it 'creates a new user' do
141
+ expect(controller).to receive(:sign_in_and_redirect)
142
+ expect { controller.twitter }.to change(Spree::User, :count).by(1)
143
+ end
144
+ end
145
+
146
+ context 'email belongs to existing user' do
147
+ before { @user = create(:user, email: 'spree@gmail.com') }
148
+
149
+ it 'does not create new user' do
150
+ expect { controller.twitter }.to_not change(Spree::User, :count)
151
+ end
152
+
153
+ it 'assigns authentication to existing user' do
154
+ expect { controller.twitter }.to change(@user.user_authentications, :count).by(1)
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
160
+ end