mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-12-25 17:24:51 +08:00
Add support of Okta SSO provider [SCI-6184]
This commit is contained in:
parent
6dea5f17ff
commit
47b8347ce6
9 changed files with 94 additions and 4 deletions
1
Gemfile
1
Gemfile
|
@ -25,6 +25,7 @@ gem 'doorkeeper', '>= 4.6'
|
||||||
gem 'omniauth'
|
gem 'omniauth'
|
||||||
gem 'omniauth-azure-activedirectory'
|
gem 'omniauth-azure-activedirectory'
|
||||||
gem 'omniauth-linkedin-oauth2'
|
gem 'omniauth-linkedin-oauth2'
|
||||||
|
gem 'omniauth-okta'
|
||||||
|
|
||||||
# TODO: remove this when omniauth gem resolves CVE issues
|
# TODO: remove this when omniauth gem resolves CVE issues
|
||||||
# Prevents CVE-2015-9284 (https://github.com/omniauth/omniauth/wiki/FAQ#cve-2015-9284-warnings)
|
# Prevents CVE-2015-9284 (https://github.com/omniauth/omniauth/wiki/FAQ#cve-2015-9284-warnings)
|
||||||
|
|
|
@ -407,6 +407,9 @@ GEM
|
||||||
omniauth-oauth2 (1.7.1)
|
omniauth-oauth2 (1.7.1)
|
||||||
oauth2 (~> 1.4)
|
oauth2 (~> 1.4)
|
||||||
omniauth (>= 1.9, < 3)
|
omniauth (>= 1.9, < 3)
|
||||||
|
omniauth-okta (0.1.3)
|
||||||
|
omniauth (~> 1.5)
|
||||||
|
omniauth-oauth2 (>= 1.6.0, < 2.0)
|
||||||
omniauth-rails_csrf_protection (0.1.2)
|
omniauth-rails_csrf_protection (0.1.2)
|
||||||
actionpack (>= 4.2)
|
actionpack (>= 4.2)
|
||||||
omniauth (>= 1.3.1)
|
omniauth (>= 1.3.1)
|
||||||
|
@ -692,6 +695,7 @@ DEPENDENCIES
|
||||||
omniauth
|
omniauth
|
||||||
omniauth-azure-activedirectory
|
omniauth-azure-activedirectory
|
||||||
omniauth-linkedin-oauth2
|
omniauth-linkedin-oauth2
|
||||||
|
omniauth-okta
|
||||||
omniauth-rails_csrf_protection (~> 0.1)
|
omniauth-rails_csrf_protection (~> 0.1)
|
||||||
overcommit
|
overcommit
|
||||||
pg (~> 1.1)
|
pg (~> 1.1)
|
||||||
|
|
|
@ -401,6 +401,16 @@ a[data-toggle="tooltip"] {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.okta-sign-in-actions {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
margin-top: 10px;
|
||||||
|
|
||||||
|
.btn-okta {
|
||||||
|
background-color: #00297a;
|
||||||
|
color: $color-white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.navbar-secondary {
|
.navbar-secondary {
|
||||||
transition: .4s $timing-function-sharp;
|
transition: .4s $timing-function-sharp;
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,11 +127,50 @@ module Users
|
||||||
redirect_to after_omniauth_failure_path_for(resource_name) and return
|
redirect_to after_omniauth_failure_path_for(resource_name) and return
|
||||||
end
|
end
|
||||||
# Confirm user
|
# Confirm user
|
||||||
@user.update_column(:confirmed_at, @user.created_at)
|
@user.update!(confirmed_at: @user.created_at)
|
||||||
redirect_to users_sign_up_provider_path(user: @user)
|
redirect_to users_sign_up_provider_path(user: @user)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def okta
|
||||||
|
auth = request.env['omniauth.auth']
|
||||||
|
user = User.from_omniauth(auth)
|
||||||
|
# User found in database so just signing in
|
||||||
|
return sign_in_and_redirect(user) if user.present?
|
||||||
|
|
||||||
|
user = User.find_by(email: auth.info.email.downcase)
|
||||||
|
|
||||||
|
if user.blank?
|
||||||
|
# Create new user and identity
|
||||||
|
user = User.new(full_name: auth.info.name,
|
||||||
|
initials: generate_initials(auth.info.name),
|
||||||
|
email: auth.info.email,
|
||||||
|
password: generate_user_password)
|
||||||
|
User.transaction do
|
||||||
|
user.save!
|
||||||
|
user.user_identities.create!(provider: auth.provider, uid: auth.uid)
|
||||||
|
user.update!(confirmed_at: user.created_at)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
# Link to existing local account
|
||||||
|
user.user_identities.create!(provider: auth.provider, uid: auth.uid)
|
||||||
|
user.update!(confirmed_at: user.created_at) if user.confirmed_at.blank?
|
||||||
|
end
|
||||||
|
sign_in_and_redirect(user)
|
||||||
|
rescue StandardError => e
|
||||||
|
Rails.logger.error e.message
|
||||||
|
Rails.logger.error e.backtrace.join("\n")
|
||||||
|
error_message = I18n.t('devise.okta.errors.failed_to_save') if e.is_a?(ActiveRecord::RecordInvalid)
|
||||||
|
error_message ||= I18n.t('devise.okta.errors.generic')
|
||||||
|
redirect_to after_omniauth_failure_path_for(resource_name)
|
||||||
|
ensure
|
||||||
|
if error_message
|
||||||
|
set_flash_message(:alert, :failure, kind: I18n.t('devise.okta.provider_name'), reason: error_message)
|
||||||
|
else
|
||||||
|
set_flash_message(:notice, :success, kind: I18n.t('devise.okta.provider_name'))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# More info at:
|
# More info at:
|
||||||
# https://github.com/plataformatec/devise#omniauth
|
# https://github.com/plataformatec/devise#omniauth
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,14 @@
|
||||||
<div data-hook="omniauth-sign-in-links"></div>
|
<div data-hook="omniauth-sign-in-links"></div>
|
||||||
<% end -%>
|
<% end -%>
|
||||||
|
|
||||||
|
<%- if devise_mapping.omniauthable? && Devise.omniauth_configs[:okta].present? %>
|
||||||
|
<div class="okta-sign-in-actions">
|
||||||
|
<%= form_tag omniauth_authorize_path(resource_name, :okta), method: :post do %>
|
||||||
|
<%= submit_tag t('devise.okta.sign_in_label'), class: 'btn btn-okta' %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<%- unless defined?(linkedin_skip) %>
|
<%- unless defined?(linkedin_skip) %>
|
||||||
<%- if Rails.configuration.x.enable_user_registration && Rails.configuration.x.linkedin_signin_enabled && @oauth_authorize != true %>
|
<%- if Rails.configuration.x.enable_user_registration && Rails.configuration.x.linkedin_signin_enabled && @oauth_authorize != true %>
|
||||||
<%= render partial: "users/shared/linkedin_sign_in_links", locals: { resource_name: resource_name } %>
|
<%= render partial: "users/shared/linkedin_sign_in_links", locals: { resource_name: resource_name } %>
|
||||||
|
|
|
@ -295,6 +295,23 @@ Devise.setup do |config|
|
||||||
config.omniauth :linkedin, ENV['LINKEDIN_KEY'], ENV['LINKEDIN_SECRET'], scope: 'r_liteprofile r_emailaddress'
|
config.omniauth :linkedin, ENV['LINKEDIN_KEY'], ENV['LINKEDIN_SECRET'], scope: 'r_liteprofile r_emailaddress'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if [ENV['OKTA_CLIENT_ID'], ENV['OKTA_CLIENT_SECRET'], ENV['OKTA_DOMAIN'], ENV['OKTA_AUTH_SERVER_ID']].all?
|
||||||
|
config.omniauth(
|
||||||
|
:okta,
|
||||||
|
ENV['OKTA_CLIENT_ID'],
|
||||||
|
ENV['OKTA_CLIENT_SECRET'],
|
||||||
|
scope: 'openid profile email',
|
||||||
|
fields: %w(profile email),
|
||||||
|
client_options: {
|
||||||
|
site: "https://#{ENV['OKTA_DOMAIN']}",
|
||||||
|
authorize_url: "https://#{ENV['OKTA_DOMAIN']}/oauth2/#{ENV['OKTA_AUTH_SERVER_ID']}/v1/authorize",
|
||||||
|
token_url: "https://#{ENV['OKTA_DOMAIN']}/oauth2/#{ENV['OKTA_AUTH_SERVER_ID']}/v1/token",
|
||||||
|
user_info_url: "https://#{ENV['OKTA_DOMAIN']}/oauth2/#{ENV['OKTA_AUTH_SERVER_ID']}/v1/userinfo"
|
||||||
|
},
|
||||||
|
strategy_class: OmniAuth::Strategies::Okta
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
# ==> Warden configuration
|
# ==> Warden configuration
|
||||||
# If you want to use other strategies, that are not supported by Devise, or
|
# If you want to use other strategies, that are not supported by Devise, or
|
||||||
# change the failure app, you can configure them inside the config.warden block.
|
# change the failure app, you can configure them inside the config.warden block.
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# Extends class holds the arrays for the models enum fields
|
# Extends class holds the arrays for the models enum fields
|
||||||
# so that can be extended in sub modules.
|
# so that can be extended in sub modules.
|
||||||
|
|
||||||
|
# rubocop:disable Style/MutableConstant
|
||||||
|
|
||||||
class Extends
|
class Extends
|
||||||
# To extend the enum fields in the engine you have to put in
|
# To extend the enum fields in the engine you have to put in
|
||||||
# lib/engine_name/engine.rb file as in the example:
|
# lib/engine_name/engine.rb file as in the example:
|
||||||
|
@ -109,7 +111,7 @@ class Extends
|
||||||
'RepositoryAssetValue' => 'file',
|
'RepositoryAssetValue' => 'file',
|
||||||
'RepositoryStatusValue' => 'status' }
|
'RepositoryStatusValue' => 'status' }
|
||||||
|
|
||||||
OMNIAUTH_PROVIDERS = [:linkedin, :customazureactivedirectory]
|
OMNIAUTH_PROVIDERS = %i(linkedin customazureactivedirectory okta)
|
||||||
|
|
||||||
INITIAL_USER_OPTIONS = {}
|
INITIAL_USER_OPTIONS = {}
|
||||||
|
|
||||||
|
@ -395,3 +397,5 @@ class Extends
|
||||||
change_user_role_on_my_module
|
change_user_role_on_my_module
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# rubocop:enable Style/MutableConstant
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
require 'omniauth/strategies/custom_azure_active_directory'
|
require 'omniauth/strategies/custom_azure_active_directory'
|
||||||
|
|
||||||
SETUP_PROC = lambda do |env|
|
AZURE_SETUP_PROC = lambda do |env|
|
||||||
providers = Rails.configuration.x.azure_ad_apps.select { |_, v| v[:enable_sign_in] == true }
|
providers = Rails.configuration.x.azure_ad_apps.select { |_, v| v[:enable_sign_in] == true }
|
||||||
raise StandardError, 'No Azure AD config available for sign in' if providers.blank?
|
raise StandardError, 'No Azure AD config available for sign in' if providers.blank?
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ SETUP_PROC = lambda do |env|
|
||||||
end
|
end
|
||||||
|
|
||||||
Rails.application.config.middleware.use OmniAuth::Builder do
|
Rails.application.config.middleware.use OmniAuth::Builder do
|
||||||
provider OmniAuth::Strategies::CustomAzureActiveDirectory, setup: SETUP_PROC
|
provider OmniAuth::Strategies::CustomAzureActiveDirectory, setup: AZURE_SETUP_PROC
|
||||||
end
|
end
|
||||||
|
|
||||||
OmniAuth.config.logger = Rails.logger
|
OmniAuth.config.logger = Rails.logger
|
||||||
|
|
|
@ -74,6 +74,13 @@ en:
|
||||||
no_local_user_map: "No local user record found"
|
no_local_user_map: "No local user record found"
|
||||||
no_email: "Email is missing in auth token"
|
no_email: "Email is missing in auth token"
|
||||||
failed_to_save: "Failed to create new user"
|
failed_to_save: "Failed to create new user"
|
||||||
|
okta:
|
||||||
|
provider_name: "Okta"
|
||||||
|
sign_in_label: "Sign in with Okta"
|
||||||
|
errors:
|
||||||
|
generic: "Failed to sign in user"
|
||||||
|
no_local_user_map: "No local user record found"
|
||||||
|
failed_to_save: "Failed to create new user"
|
||||||
|
|
||||||
doorkeeper:
|
doorkeeper:
|
||||||
errors:
|
errors:
|
||||||
|
|
Loading…
Reference in a new issue