Skip to content

Commit 71ff980

Browse files
authored
Merge pull request #907 from portagenetwork/aaron/issues/sso-link
Update Handling of SSO Linking
2 parents 08b56bb + 02b714e commit 71ff980

File tree

4 files changed

+33
-11
lines changed

4 files changed

+33
-11
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
# Changelog
22

3-
## [Unreleased]
3+
## [4.1.1+portage-4.2.2] - 2024-09-18
44

55
### Changed
66

7+
- Update Handling of SSO Linking [#907](https://github.com/portagenetwork/roadmap/pull/907)
8+
79
- Updated SSO button string [portagenetwork/roadmap#903](https://github.com/portagenetwork/roadmap/issues/903)
810

911
## [4.1.1+portage-4.2.1] - 2024-09-12

app/controllers/users/omniauth_callbacks_controller.rb

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ module Users
55
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
66
# This is for the OpenidConnect CILogon
77

8-
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength
8+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
99
def openid_connect
1010
# First or create
1111
auth = request.env['omniauth.auth']
@@ -22,11 +22,18 @@ def openid_connect
2222

2323
identifier_scheme = IdentifierScheme.find_by(name: auth.provider)
2424

25-
if current_user.nil?
26-
# We need to register
27-
if user.nil?
28-
# Register and sign in
25+
if current_user.nil? # if user is not signed in (They clicked the SSO sign in button)
26+
if user.nil? # If an entry does not exist in the identifiers table for the chosen SSO account
2927
user = User.create_from_provider_data(auth)
28+
if user.nil? # if a user was NOT created (a match was found for User.find_by(email: auth.info.email)
29+
# Do not link SSO credentials for the signed out, existing user
30+
flash[:alert] = _('That email appears to be associated with an existing account.<br>' \
31+
'Sign into your existing account, and you can link that ' \
32+
"account with SSO from the 'Edit Profile' page.")
33+
redirect_to root_path
34+
return
35+
end
36+
# A new user was created, link the SSO credentials (we can do this for a newly created user)
3037
user.identifiers << Identifier.create(identifier_scheme: identifier_scheme,
3138
value: auth.uid,
3239
attrs: auth,
@@ -51,7 +58,7 @@ def openid_connect
5158
redirect_to edit_user_registration_path
5259
end
5360
end
54-
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
61+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
5562

5663
def orcid
5764
handle_omniauth(IdentifierScheme.for_authentication.find_by(name: 'orcid'))

app/models/user.rb

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,11 +186,11 @@ def self.from_omniauth(auth)
186186
# Handle user creation from provider
187187
# rubocop:disable Metrics/AbcSize
188188
def self.create_from_provider_data(provider_data)
189-
user = User.find_by email: provider_data.info.email
189+
user = User.find_or_initialize_by(email: provider_data.info.email)
190190

191-
return user if user
191+
return unless user.new_record?
192192

193-
User.create!(
193+
user.update!(
194194
firstname: provider_data.info&.first_name.present? ? provider_data.info.first_name : _('First name'),
195195
surname: provider_data.info&.last_name.present? ? provider_data.info.last_name : _('Last name'),
196196
email: provider_data.info.email,
@@ -199,6 +199,7 @@ def self.create_from_provider_data(provider_data)
199199
accept_terms: true,
200200
password: Devise.friendly_token[0, 20]
201201
)
202+
user
202203
end
203204
# rubocop:enable Metrics/AbcSize
204205

spec/integration/openid_connect_sso_spec.rb

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,19 @@
3939
expect(page).to have_content('John Doe')
4040
end
4141

42-
it 'links account from external credentails' do
42+
it 'does not create SSO link when user is signed out and SSO email is an existing account email' do
43+
# Hardcode user email to what we are mocking via OmniAuth.config.mock_auth[:openid_connect]
44+
user = create(:user, :org_admin, org: @org, email: 'user@organization.ca', firstname: 'DMP Name',
45+
surname: 'DMP Lastname')
46+
expect(user.identifiers.count).to eql(0)
47+
visit root_path
48+
click_link 'Sign in with CILogon'
49+
error_message = 'That email appears to be associated with an existing account'
50+
expect(page).to have_content(error_message)
51+
expect(user.identifiers.count).to eql(0)
52+
end
53+
54+
xit 'links account from external credentails' do
4355
# Create existing user
4456
user = create(:user, :org_admin, org: @org, email: 'user@organization.ca', firstname: 'DMP Name',
4557
surname: 'DMP Lastname')

0 commit comments

Comments
 (0)