-
Notifications
You must be signed in to change notification settings - Fork 118
Expand file tree
/
Copy pathomniauth_callbacks_controller.rb
More file actions
99 lines (85 loc) · 3.7 KB
/
omniauth_callbacks_controller.rb
File metadata and controls
99 lines (85 loc) · 3.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# frozen_string_literal: true
module Users
# Controller that handles callbacks from OmniAuth integrations (e.g. Shibboleth and ORCID)
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
include EmailConfirmationHandler
##
# Dynamically build a handler for each omniauth provider
# -------------------------------------------------------------
IdentifierScheme.for_authentication.each do |scheme|
define_method(scheme.name.downcase) do
handle_omniauth(scheme)
end
end
# Processes callbacks from an omniauth provider and directs the user to
# the appropriate page:
# Not logged in and uid had no match ---> Sign Up page
# Not logged in and uid had a match ---> Sign In and go to Home Page
# Signed in and uid had no match --> Save the uid and go to the Profile Page
# Signed in and uid had a match --> Go to the Home Page
#
# scheme - The IdentifierScheme for the provider
#
def handle_omniauth(scheme)
user = if request.env['omniauth.auth'].nil?
User.from_omniauth(request.env)
else
User.from_omniauth(request.env['omniauth.auth'])
end
# If the user isn't logged in
if current_user.nil?
handle_omniauth_for_signed_out_user(user, scheme)
# The user is already logged in and just registering the uid with us
else
handle_omniauth_for_signed_in_user(user, scheme)
end
end
def failure
redirect_to root_path
end
private
# rubocop:disable Metrics/AbcSize
def handle_omniauth_for_signed_in_user(user, scheme)
# If the user could not be found by that uid then attach it to their record
if user.nil?
if Identifier.create(identifier_scheme: scheme,
value: request.env['omniauth.auth'].uid,
attrs: request.env['omniauth.auth'],
identifiable: current_user)
flash[:notice] = format(_('Your account has been successfully linked to %{scheme}.'),
scheme: scheme.description)
else
flash[:alert] = format(_('Unable to link your account to %{scheme}.'),
scheme: scheme.description)
end
elsif user.id != current_user.id
# If a user was found but does NOT match the current user then the identifier has
# already been attached to another account (likely the user has 2 accounts)
flash[:alert] = _("The current #{scheme.description} iD has been already linked " \
"to a user with email #{identifier.user.email}")
end
# Redirect to the User Profile page
redirect_to edit_user_registration_path
end
# rubocop:enable Metrics/AbcSize
# rubocop:disable Metrics/AbcSize
def handle_omniauth_for_signed_out_user(user, scheme)
# If the uid didn't have a match in the system send them to register
if user.nil?
session["devise.#{scheme.name.downcase}_data"] = request.env['omniauth.auth']
redirect_to new_user_registration_url
# Otherwise sign them in
elsif scheme.name == 'shibboleth'
# Until ORCID becomes supported as a login method
# (see app/models/concerns/email_confirmation_handler.rb)
return if confirmation_instructions_missing_and_handled?(user)
set_flash_message(:notice, :success, kind: scheme.description) if is_navigational_format?
sign_in_and_redirect user, event: :authentication
else
flash[:notice] = _('Successfully signed in')
redirect_to new_user_registration_url
end
end
# rubocop:enable Metrics/AbcSize
end
end