Skip to content

Commit 165cd38

Browse files
authored
Merge pull request #139 from solidusio-contrib/revert-127
Revert #129 and #127 due to security implications
2 parents 9c0ed09 + 01c3307 commit 165cd38

File tree

47 files changed

+216
-625
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+216
-625
lines changed

Gemfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
source 'https://rubygems.org'
44
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
55

6-
solidus_branch = ENV.fetch('SOLIDUS_BRANCH', 'main')
7-
gem 'solidus', github: 'solidusio/solidus', branch: solidus_branch
6+
branch = ENV.fetch('SOLIDUS_BRANCH', 'main')
7+
gem 'solidus', github: 'solidusio/solidus', branch: branch
88

99
# The solidus_frontend gem has been pulled out since v3.2
1010
gem 'solidus_frontend'

README.md

Lines changed: 57 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ SolidusSocial
66

77
Social login support for Solidus. Solidus Social handles authorization, account
88
creation and association through third-party services.
9-
Currently Google, Facebook, Github and X (formely Twitter) are available out of the box.
10-
Support for Apple ID and Microsoft (Entra and O365) might be offered down the road.
9+
Currently Facebook, Github and Google OAuth2 are available out of the box.
1110

1211
Installation
1312
------------
@@ -26,15 +25,12 @@ bundle exec rails g solidus_social:install
2625
bundle exec rails db:migrate
2726
```
2827

29-
Preference(optional): By default the login path will be `/users/auth/:provider`. If you wish to modify the url to:
30-
`/member/auth/:provider`, `/profile/auth/:provider`, or `/auth/:provider` then you can do this accordingly in
31-
your **config/initializers/spree.rb** file as described below:
28+
This will install a new initializer `config/initializers/solidus_social.rb` into
29+
your project that allows you to setup the services you want configured for your app.
30+
31+
Optional: By default the login path will be '/users/auth/:provider'. If you
32+
want something else, configure it in `config/initializers/solidus_social.rb`.
3233

33-
```ruby
34-
Spree::SocialConfig[:path_prefix] = 'member' # for /member/auth/:provider
35-
Spree::SocialConfig[:path_prefix] = 'profile' # for /profile/auth/:provider
36-
Spree::SocialConfig[:path_prefix] = '' # for /auth/:provider
37-
```
3834

3935
Using OAuth Sources
4036
-------------------
@@ -43,29 +39,12 @@ Login as an admin user and navigate to Configuration > Social Authentication Met
4339

4440
Click "New Authentication Method" and choose one of your configured providers.
4541

46-
Click on the New Authentication Method button to enter the key obtained from their respective source, (See below for instructions on setting up the various providers).
47-
48-
Multiple key entries can now be entered based on the rails environment. This allows for portability and the lack of need to check in your key to your repository. You also have the ability to enable and disable sources. These setting will be reflected on the client UI as well.
49-
50-
Alternatively you can ship keys as environment variables and create these Authentication Method records on application boot via an initializer. Below is an example for facebook.
51-
52-
```ruby
53-
# Ensure our environment is bootstrapped with a facebook connect app
54-
if ActiveRecord::Base.connection.data_source_exists? 'spree_authentication_methods'
55-
Spree::AuthenticationMethod.where(environment: Rails.env, provider: 'facebook').first_or_create do |auth_method|
56-
auth_method.api_key = ENV['FACEBOOK_APP_ID']
57-
auth_method.api_secret = ENV['FACEBOOK_APP_SECRET']
58-
auth_method.active = true
59-
end
60-
end
61-
```
62-
6342
**You MUST restart your application after configuring or updating an authentication method.**
6443

6544
Registering Your Application
6645
----------------------------
6746

68-
OAuth Applications @ Facebook, Twitter, Google and / or Github are supported out of the
47+
Facebook, Github and Google OAuth2 are supported out of the
6948
box but, you will need to register your application with each of the sites you
7049
want to use.
7150

@@ -107,46 +86,72 @@ Make sure you specifity the right IP address.
10786

10887
> More info: [https://developers.google.com/identity/protocols/OAuth2](https://developers.google.com/identity/protocols/OAuth2)
10988
110-
### Twitter
111-
[Twitter / Application Management / Create an application](https://docs.x.com/resources/fundamentals/authentication/oauth-2-0/overview)
89+
### Other OAuth Providers
11290

113-
1. Name and Description must be filled in with something
114-
2. Configure user authentication setting with:
115-
- App permissions: Read (default) and enable Request email from users option.
116-
- Application Website: http://your_computer.local:3000 for development / http://your-site.com for production
117-
- Application Type: Web App, Automated App or Bot
118-
- Callback URL: http://your_computer.local:3000 for development / http://your-site.com for production
119-
3. Save Application
91+
Other OAuth providers are supported, given that there is an [OmniAuth
92+
strategy][12] for them. (If there isn't, you can [write one][13].)
12093

121-
### Adding other OAuth sources
94+
#### LinkedIn Example
12295

123-
It is easy to add any OAuth source, given there is an OmniAuth strategy gem for it (and if not, you can easily write one by yourself). For instance, if you want to add authorization via LinkedIn, the steps will be:
124-
1. Add gem `"omniauth-linkedin"` to your Gemfile, run `bundle install`.
125-
2. In an initializer file, e.g. `config/initializers/devise.rb`, add and init a new provider for SolidusSocial:
96+
1. Add `gem "omniauth-linkedin"` to your Gemfile and run `bundle install`.
97+
2. In `config/initializers/solidus_social.rb` add and initialize a new provider
98+
for SolidusSocial:
12699

127-
**Optional:** If you want to skip the sign up phase where the user has to provide an email and a password, add a third parameter to the provider entry and the Spree user will be created directly using the email field in the [Auth Hash Schema](https://github.com/omniauth/omniauth/wiki/Auth-Hash-Schema):
100+
```ruby
128101

129-
```ruby
130-
Provider = Struct.new(:title, :key, :skip_signup)
131-
SolidusSocial::OAUTH_PROVIDERS << Provider.new("LinkedIn", "linkedin", true)
132-
SolidusSocial.init_provider('linkedin')
133-
```
134-
3. Activate your provider as usual (via initializer or admin interface).
102+
config.providers = {
103+
# The configuration key has to match your omniauth strategy.
104+
linkedin: {
105+
api_key: ENV['LINKEDIN_API_KEY'],
106+
api_secret: ENV['LINKEDIN_API_SECRET'],
107+
},
108+
# More providers here
109+
```
110+
3. Activate your provider as usual.
135111
4. Do **one** of the following:
136112

137-
- For legacy frontend, override the `spree/users/social` view to render OAuth links to display
138-
your LinkedIn link and for starter frontend override `spree/starter_frontend/shared/social`.
113+
- Override the `spree/users/social` view to render OAuth links to display
114+
your LinkedIn link.
139115
- Include in your CSS a definition for `.icon-spree-linkedin-circled` and an
140-
embedded icon font for LinkedIn from [Fontello](12) (the way existing
116+
embedded icon font for LinkedIn from [Fontello][14] (the way existing
141117
icons for Facebook etc are implemented). You can also override
142118
CSS classes for other providers, `.icon-spree-<provider>-circled`, to use
143119
different font icons or classic background images, without having to
144120
override views.
145121

122+
#### Apple Id Example
123+
124+
1. Add `gem "omniauth-apple"` to your Gemfile and run `bundle install`.
125+
2. In `config/initializers/solidus_social.rb` add and initialize a new provider
126+
for SolidusSocial:
127+
128+
```ruby
129+
130+
config.providers = {
131+
apple: {
132+
icon: 'fa-apple',
133+
title: 'Apple'
134+
},
135+
# More providers here
136+
```
137+
add its configuration after `SolidusSocial.init_providers` line:
138+
```ruby
139+
140+
Devise.setup do |config|
141+
# The configuration key has to match your omniauth strategy.
142+
config.omniauth :apple, ENV['APPLE_CLIENT_ID'], '',
143+
scope: 'email',
144+
team_id: ENV['APPLE_TEAM_ID'],
145+
key_id: ENV['APPLE_KEY_ID'],
146+
pem: ENV['APPLE_PRIVATE_KEY'].gsub('\n', "\n")
147+
end
148+
```
149+
Notice: APPLE_PRIVATE_KEY should consist from one-line p8-file content, like this `'\n-----BEGIN PRIVATE KEY-----\nsecret\n-----END PRIVATE KEY-----\n'`
150+
146151
Documentation
147152
-------------
148153

149-
API documentation is available [on RubyDoc.info][13].
154+
API documentation is available [on RubyDoc.info][15].
150155

151156
Contributing
152157
------------
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
/*
2-
*= require spree/frontend/fontello
2+
*= require spree/frontend
33
*= require_tree .
44
*/

app/controllers/concerns/route_resolver.rb

Lines changed: 0 additions & 12 deletions
This file was deleted.

app/controllers/spree/admin/authentication_methods_controller.rb

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,6 @@
33
module Spree
44
module Admin
55
class AuthenticationMethodsController < ResourceController
6-
private
7-
8-
def build_resource
9-
model_class.new(
10-
store_ids: [Spree::Store.default.id].compact
11-
)
12-
end
136
end
147
end
158
end

app/controllers/spree/omniauth_callbacks_controller.rb

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ class Spree::OmniauthCallbacksController < Devise::OmniauthCallbacksController
55
include Spree::Core::ControllerHelpers::Order
66
include Spree::Core::ControllerHelpers::Auth
77
include Spree::Core::ControllerHelpers::Store
8-
include RouteResolver
98

109
class << self
1110
def provides_callback_for(*providers)
@@ -15,16 +14,14 @@ def provides_callback_for(*providers)
1514
end
1615
end
1716

18-
SolidusSocial::OAUTH_PROVIDERS.each do |provider|
19-
provides_callback_for provider.key.to_sym
17+
Spree::SocialConfig.providers.keys.each do |provider|
18+
provides_callback_for provider
2019
end
2120

22-
after_action :set_current_order, only: SolidusSocial::OAUTH_PROVIDERS.map(&:key)
23-
2421
def omniauth_callback
2522
if request.env['omniauth.error'].present?
2623
flash[:error] = I18n.t('devise.omniauth_callbacks.failure', kind: auth_hash['provider'], reason: I18n.t('spree.user_was_not_valid'))
27-
redirect_back_or_default(resolve_route_for(:root_url))
24+
redirect_back_or_default(root_url)
2825
return
2926
end
3027

@@ -37,7 +34,7 @@ def omniauth_callback
3734
spree_current_user.apply_omniauth(auth_hash)
3835
spree_current_user.save!
3936
flash[:notice] = I18n.t('devise.sessions.signed_in')
40-
redirect_back_or_default(resolve_route_for(:account_url))
37+
redirect_back_or_default(account_url)
4138
else
4239
user = Spree.user_class.find_by(email: auth_hash['info']['email']) || Spree.user_class.new
4340
user.apply_omniauth(auth_hash)
@@ -47,7 +44,7 @@ def omniauth_callback
4744
else
4845
session[:omniauth] = auth_hash.except('extra')
4946
flash[:notice] = I18n.t('spree.one_more_step', kind: auth_hash['provider'].capitalize)
50-
redirect_to resolve_route_for(:new_spree_user_registration_url)
47+
redirect_to new_spree_user_registration_url
5148
return
5249
end
5350
end
@@ -61,7 +58,7 @@ def omniauth_callback
6158

6259
def failure
6360
set_flash_message :alert, :failure, kind: failed_strategy.name.to_s.humanize, reason: failure_message
64-
redirect_to resolve_route_for(:login_path)
61+
redirect_to spree.login_path
6562
end
6663

6764
def passthru
@@ -71,8 +68,4 @@ def passthru
7168
def auth_hash
7269
request.env['omniauth.auth']
7370
end
74-
75-
def after_sign_in_path_for(resource_or_scope)
76-
stored_location_for(resource_or_scope) || resolve_route_for(:account_path)
77-
end
7871
end
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
# frozen_string_literal: true
22

3-
class Spree::UserAuthenticationsController < Spree::BaseController
4-
include RouteResolver
5-
3+
class Spree::UserAuthenticationsController < Spree::StoreController
64
def index
75
@authentications = spree_current_user.user_authentications if spree_current_user
86
end
@@ -11,6 +9,6 @@ def destroy
119
@authentication = spree_current_user.user_authentications.find(params[:id])
1210
@authentication.destroy
1311
flash[:notice] = I18n.t('spree.destroy', scope: :authentications)
14-
redirect_to resolve_route_for(:account_path)
12+
redirect_to spree.account_path
1513
end
1614
end

app/decorators/controllers/solidus_social/spree/user_registrations_controller_decorator.rb

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,8 @@ def build_resource(*args)
2020
def clear_omniauth
2121
session[:omniauth] = nil unless @spree_user.new_record?
2222
end
23+
24+
::Spree::UserRegistrationsController.prepend self
2325
end
2426
end
2527
end
26-
27-
if defined?(::UserRegistrationsController)
28-
::UserRegistrationsController.prepend SolidusSocial::Spree::UserRegistrationsControllerDecorator
29-
else
30-
::Spree::UserRegistrationsController.prepend SolidusSocial::Spree::UserRegistrationsControllerDecorator
31-
end

app/decorators/models/solidus_social/spree/store_decorator.rb

Lines changed: 0 additions & 16 deletions
This file was deleted.

app/decorators/models/solidus_social/spree/user_decorator.rb

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@ def self.prepended(base)
1212
end
1313

1414
def apply_omniauth(omniauth)
15-
skip_signup_providers = SolidusSocial::OAUTH_PROVIDERS.select { |provider| provider.skip_signup }.map(&:key)
16-
if skip_signup_providers.include?(omniauth['provider']) && email.blank?
17-
self.email = omniauth['info']['email']
15+
if omniauth.fetch('info', {})['email'].present?
16+
self.email = omniauth['info']['email'] if email.blank?
1817
end
1918
user_authentications.build(provider: omniauth['provider'], uid: omniauth['uid'])
2019
end

0 commit comments

Comments
 (0)