Skip to content

Commit d645bb6

Browse files
committed
WIP Updates to sso
Adding some missing methods and start cleanup. We still need to clean up and fix the `openid_connect` method on `omniauth_callbacks_controller.rb`.
1 parent 0c21df3 commit d645bb6

File tree

8 files changed

+88
-137
lines changed

8 files changed

+88
-137
lines changed

Gemfile

+1-2
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,7 @@ gem 'omniauth-orcid'
107107
# https://nvd.nist.gov/vuln/detail/CVE-2015-9284
108108
gem 'omniauth-rails_csrf_protection'
109109

110-
#This gem provides cilogon support with devise login authentication
111-
#This is a part of omniauth
110+
# This gem provides cilogon support with devise login authentication
112111
gem 'omniauth_openid_connect'
113112

114113
# A ruby implementation of the RFC 7519 OAuth JSON Web Token (JWT) standard.

app/controllers/home_controller.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ def index
2323
else
2424
redirect_to plans_url
2525
end
26-
elsif session['devise.shibboleth_data'].present?# || session['devise.openid_connect_data'].present?
26+
elsif session['devise.shibboleth_data'].present?
2727
# NOTE: Update this to handle ORCiD as well when we enable it as a login method
2828
redirect_to new_user_registration_url
2929
end

app/controllers/users/omniauth_callbacks_controller.rb

+28-53
Original file line numberDiff line numberDiff line change
@@ -3,51 +3,33 @@
33
module Users
44
# Controller that handles callbacks from OmniAuth integrations (e.g. Shibboleth and ORCID)
55
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
6-
##
7-
# Dynamically build a handler for each omniauth provider
8-
# -------------------------------------------------------------
9-
IdentifierScheme.for_authentication.each do |scheme|
10-
define_method(scheme.name.downcase) do
11-
handle_omniauth(scheme)
12-
end
13-
end
14-
15-
16-
# def openid_connect
17-
# @user = User.from_omniauth(request.env["omniauth.auth"])
18-
19-
# if @user.present?
20-
# sign_in_and_redirect @user, event: :authentication
21-
# set_flash_message(:notice, :success, kind: "OpenID Connect") if is_navigational_format?
22-
# else
23-
# session["devise.openid_connect_data"] = request.env["omniauth.auth"]
24-
# redirect_to new_user_registration_url
25-
# end
26-
# end
27-
28-
29-
30-
31-
#This is for the OpenidConnect CILogon
32-
6+
# This is for the OpenidConnect CILogon
337
def openid_connect
348
# First or create
359
auth = request.env['omniauth.auth']
3610
user = User.from_omniauth(auth)
37-
identifier_scheme = IdentifierScheme.find_by_name(auth.provider)
3811

3912
if auth.info.email.nil? && user.nil?
40-
#If email is missing we need to request the user to register with DMP.
41-
#User email can be missing if the user email id is set to private or trusted clients only we won't get the value.
42-
#USer email id is one of the mandatory field which is must required.
43-
flash[:notice] = 'Please try sign-up with DMP assistant.'
13+
# If email is missing we need to request the user to register with DMP.
14+
# User email can be missing if the user email id is set to private or
15+
# trusted clients only we won't get the value.
16+
# User email id is one of the mandatory field which is must required.
17+
18+
flash[:notice] =
19+
"Your institution's current settings do not provide an email address, which is necessary for registration. " \
20+
'To proceed, please update your settings to make your email address visible. Alternatively, you can ' \
21+
'create an account directly on DMP Assistant.'
4422
redirect_to new_user_registration_path
45-
elsif current_user.nil?
23+
end
24+
25+
identifier_scheme = IdentifierScheme.find_by_name(auth.provider)
26+
27+
if current_user.nil?
4628
# We need to register
4729
if user.nil?
4830
# Register and sign in
4931
user = User.create_from_provider_data(auth)
50-
Identifier.create(identifier_scheme: identifier_scheme, #auth.provider, #scheme, #IdentifierScheme.last.id,
32+
Identifier.create(identifier_scheme: identifier_scheme, # auth.provider, #scheme, #IdentifierScheme.last.id,
5133
value: auth.uid,
5234
attrs: auth,
5335
identifiable: user)
@@ -59,15 +41,13 @@ def openid_connect
5941
Identifier.create(identifier_scheme: identifier_scheme,
6042
value: auth.uid,
6143
attrs: auth,
62-
identifiable: current_user)
44+
identifiable: user)
6345

6446
flash[:notice] = 'linked succesfully'
6547
redirect_to root_path
6648
end
6749
end
6850

69-
70-
7151
# Processes callbacks from an omniauth provider and directs the user to
7252
# the appropriate page:
7353
# Not logged in and uid had no match ---> Sign Up page
@@ -82,33 +62,23 @@ def openid_connect
8262
def handle_omniauth(scheme)
8363
user = if request.env['omniauth.auth'].nil?
8464
User.from_omniauth(request.env)
85-
else
86-
User.from_omniauth(request.env['rack.session'] )
65+
else
66+
User.from_omniauth(request.env['omniauth.auth'])
8767
end
8868

8969
# If the user isn't logged in
9070
if current_user.nil?
9171
# If the uid didn't have a match in the system send them to register
9272
if user.nil?
9373
session["devise.#{scheme.name.downcase}_data"] = request.env['omniauth.auth']
74+
9475
redirect_to new_user_registration_url
9576

9677
# Otherwise sign them in
9778
elsif scheme.name == 'shibboleth'
9879
# Until ORCID becomes supported as a login method
9980
set_flash_message(:notice, :success, kind: scheme.description) if is_navigational_format?
10081
sign_in_and_redirect user, event: :authentication
101-
elsif schema.name == "openid_connect"
102-
@user = User.from_omniauth(request.env["omniauth.auth"])
103-
Rails.logger.info "OmniAuth Auth Hash: #{request.env["omniauth.auth"]}"
104-
105-
if @user.persisted?
106-
sign_in_and_redirect @user, event: :authentication
107-
set_flash_message(:notice, :success, kind: "OpenID Connect") if is_navigational_format?
108-
else
109-
session["devise.openid_connect_data"] = request.env["omniauth.auth"]
110-
redirect_to new_user_registration_url
111-
end
11282
else
11383
flash[:notice] = _('Successfully signed in')
11484
redirect_to new_user_registration_url
@@ -119,13 +89,12 @@ def handle_omniauth(scheme)
11989
# If the user could not be found by that uid then attach it to their record
12090
if user.nil?
12191
if Identifier.create(identifier_scheme: scheme,
122-
value: request.env['rack.session']['omniauth.state'],#request.env['omniauth.auth'].uid,
123-
attrs: request.env['rack.session']['omniauth.nonce'],#request.env['omniauth.auth'],
92+
value: request.env['omniauth.auth'].uid,
93+
attrs: request.env['omniauth.auth'],
12494
identifiable: current_user)
12595
flash[:notice] =
12696
format(_('Your account has been successfully linked to %{scheme}.'),
12797
scheme: scheme.description)
128-
redirect_to new_user_registration_url
12998

13099
else
131100
flash[:alert] = format(_('Unable to link your account to %{scheme}.'),
@@ -145,7 +114,13 @@ def handle_omniauth(scheme)
145114
end
146115
end
147116

117+
def orcid
118+
handle_omniauth(IdentifierScheme.for_authentication.find_by(name: 'orcid'))
119+
end
148120

121+
def shibboleth
122+
handle_omniauth(IdentifierScheme.for_authentication.find_by(name: 'shibboleth'))
123+
end
149124

150125
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength
151126
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity

app/models/user.rb

+21-30
Original file line numberDiff line numberDiff line change
@@ -177,39 +177,30 @@ class User < ApplicationRecord
177177
##
178178
# Load the user based on the scheme and id provided by the Omniauth call
179179
def self.from_omniauth(auth)
180-
# byebug
181-
Identifier.by_scheme_name(auth.provider.downcase.to_s, 'User')
182-
.where(value: auth.uid)
183-
.first&.identifiable
184-
# end
185-
186-
187-
# Rails.logger.info "OmniAuth Auth Hash: #{auth.inspect}"
188-
# where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
189-
# user.provider = auth.provider
190-
# user.uid = auth.uid
191-
# user.email = auth.info.email
192-
# user.password = Devise.friendly_token[0,20]
193-
# end
194-
# # # .where(value: auth.info.eppn) #need to add a cilogon condition for this
195-
# # .first&.identifiable
196-
# # .where(value: auth.uid).first_or_create do |user|
197-
# # user.email = auth.info.email
198-
# # user.password = Devise.friendly_token[0, 20]
199-
# # user.name = auth.info.name # if the User model has a name
200-
# # end
180+
Identifier.by_scheme_name(auth.provider.downcase, 'User')
181+
.where(value: auth.uid)
182+
.first&.identifiable
201183
end
202184

185+
##
186+
# Handle user creation from provider
187+
def self.create_from_provider_data(provider_data)
188+
user = User.find_by email: provider_data.info.email
189+
190+
return user if user
191+
192+
user = User.new(
193+
firstname: provider_data.info.first_name,
194+
surname: provider_data.info.last_name,
195+
email: provider_data.info.email,
196+
# We don't know which organization to setup so we will use other
197+
org: Org.find_by(is_other: true),
198+
accept_terms: true,
199+
password: Devise.friendly_token[0, 20]
200+
)
203201

204-
# def self.from_omniauth(auth)
205-
# Rails.logger.info "OmniAuth Auth Hash: #{auth.inspect}"
206-
# where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
207-
# user.provider = auth.provider
208-
# user.uid = auth.uid
209-
# user.email = auth.info.email if !auth.info.email_verified.nil?
210-
# user.password = Devise.friendly_token[0,20]
211-
# end
212-
# end
202+
user.save!
203+
end
213204

214205
def self.to_csv(users)
215206
User::AtCsv.new(users).to_csv

app/presenters/identifier_presenter.rb

-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ def load_schemes
4040
# Shibboleth Org identifiers are only for use by installations that have
4141
# a curated list of Orgs that can use institutional login
4242
if @identifiable.is_a?(Org) &&
43-
# byebug
4443
!Rails.configuration.x.shibboleth.use_filtered_discovery_service
4544
schemes = schemes.reject { |scheme| scheme.name.casecmp('shibboleth').zero? }
4645
end

config/initializers/_dmproadmap.rb

-3
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,6 @@ class Application < Rails::Application
150150
# A super admin will also be able to associate orgs with their shibboleth entityIds if this is set to true
151151
config.x.shibboleth.use_filtered_discovery_service = false
152152

153-
154-
155153
# ------------------- #
156154
# OPENID_CONNECT/CILOGON SETTINGS #
157155
# ------------------- #
@@ -172,7 +170,6 @@ class Application < Rails::Application
172170
# A super admin will also be able to associate orgs with their CILogon entityIds if this is set to true
173171
config.x.openid_connect.use_filtered_discovery_service = true
174172

175-
176173
# ------- #
177174
# LOCALES #
178175
# ------- #

config/initializers/cookie_size.rb

-8
This file was deleted.

config/initializers/devise.rb

+37-39
Original file line numberDiff line numberDiff line change
@@ -282,8 +282,7 @@
282282
extra_fields: []
283283
}
284284

285-
286-
# XXX First attempt of the openid_connect XXX
285+
# XXX First attempt of the openid_connect XXX
287286
# config.omniauth :openid_connect, {
288287
# name: :cilogon,
289288
# issuer: 'https://cilogon.org/',
@@ -320,47 +319,46 @@
320319
# }
321320
# }
322321

323-
324322
# XXX Third attempt of the openid_connect XXX
325-
# config.omniauth :openid_connect, {
326-
# name: :cilogon,
327-
# issuer: ' https://cilogon.org/oauth2/device_authorization',
328-
# scope: [:openid, :profile, :email, 'org.cilogon.userinfo'],
329-
# uid_field: :sub,
330-
# response_type: :code,
331-
# client_options: {
332-
# identifier: ENV['CILOGON_CLIENT_ID'],
333-
# secret: ENV['CILOGON_SECRET_KEY'],
334-
# redirect_uri: "http://localhost:3000/users/auth/openid_connect/callback",
335-
# host: 'cilogon.org',
336-
# authorization_endpoint:"https://cilogon.org/authorize",
337-
# token_endpoint:"https://cilogon.org/oauth2/token",
338-
# registration_endpoint:"https://cilogon.org/oauth2/oidc-cm",
339-
# userinfo_endpoint:"https://cilogon.org/oauth2/userinfo",
340-
# # authorization_endpoint: '/oauth2/device_authorization',
341-
# # token_endpoint: '/oauth2/token',
342-
# # userinfo_endpoint: '/oauth2/userinfo'
343-
# }
344-
# }
323+
# config.omniauth :openid_connect, {
324+
# name: :cilogon,
325+
# issuer: ' https://cilogon.org/oauth2/device_authorization',
326+
# scope: [:openid, :profile, :email, 'org.cilogon.userinfo'],
327+
# uid_field: :sub,
328+
# response_type: :code,
329+
# client_options: {
330+
# identifier: ENV['CILOGON_CLIENT_ID'],
331+
# secret: ENV['CILOGON_SECRET_KEY'],
332+
# redirect_uri: "http://localhost:3000/users/auth/openid_connect/callback",
333+
# host: 'cilogon.org',
334+
# authorization_endpoint:"https://cilogon.org/authorize",
335+
# token_endpoint:"https://cilogon.org/oauth2/token",
336+
# registration_endpoint:"https://cilogon.org/oauth2/oidc-cm",
337+
# userinfo_endpoint:"https://cilogon.org/oauth2/userinfo",
338+
# # authorization_endpoint: '/oauth2/device_authorization',
339+
# # token_endpoint: '/oauth2/token',
340+
# # userinfo_endpoint: '/oauth2/userinfo'
341+
# }
342+
# }
345343

346344
# XXX the 4th attempt of this is final final XXX
347345

348-
config.omniauth :openid_connect, {
349-
name: :openid_connect,
350-
scope: [:openid], #:email], #:profile],#, :"org.cilogon.userinfo"],
351-
response_type: :code,
352-
issuer: "https://cilogon.org",
353-
discovery: true,
354-
client_options: {
355-
uid_field: "sub",
356-
port: 443,
357-
scheme: "https",
358-
host: "cilogon.org",
359-
identifier: ENV['CILOGON_CLIENT_ID'],
360-
secret: ENV['CILOGON_SECRET_KEY'],
361-
redirect_uri: "http://127.0.0.1:3000/users/auth/openid_connect/callback"
362-
},
363-
}
346+
config.omniauth :openid_connect, {
347+
name: :openid_connect,
348+
scope: %i[openid email profile org.cilogon.userinfo],
349+
response_type: :code,
350+
issuer: "https://cilogon.org",
351+
discovery: true,
352+
client_options: {
353+
uid_field: "sub",
354+
port: 443,
355+
scheme: "https",
356+
host: "cilogon.org",
357+
identifier: ENV.fetch('CILOGON_CLIENT_ID', nil),
358+
secret: ENV.fetch('CILOGON_SECRET_KEY', nil),
359+
redirect_uri: "http://127.0.0.1:3000/users/auth/openid_connect/callback"
360+
}
361+
}
364362

365363
# ==> Warden configuration
366364
# If you want to use other strategies, that are not supported by Devise, or

0 commit comments

Comments
 (0)