From 7a4117b883263c27732234546250357890fcafb9 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 30 May 2024 15:14:55 -0400 Subject: [PATCH 1/5] Use `config_for` to hold omniauth config hash --- app/controllers/application_controller.rb | 2 +- .../concerns/web_app_controller_concern.rb | 2 +- app/helpers/application_helper.rb | 2 +- app/helpers/registration_helper.rb | 2 +- app/serializers/initial_state_serializer.rb | 2 +- config/application.rb | 3 + config/initializers/3_omniauth.rb | 102 +++--------------- .../initializers/content_security_policy.rb | 2 +- config/omniauth.yml | 85 +++++++++++++++ spec/helpers/application_helper_spec.rb | 25 +++-- spec/requests/omniauth_callbacks_spec.rb | 6 +- 11 files changed, 126 insertions(+), 107 deletions(-) create mode 100644 config/omniauth.yml diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 62e3355ae62..43bf4289d09 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -79,7 +79,7 @@ class ApplicationController < ActionController::Base end def after_sign_out_path_for(_resource_or_scope) - if ENV['OMNIAUTH_ONLY'] == 'true' && ENV['OIDC_ENABLED'] == 'true' + if Rails.configuration.omniauth.only && Rails.configuration.omniauth.oidc_enabled '/auth/auth/openid_connect/logout' else new_user_session_path diff --git a/app/controllers/concerns/web_app_controller_concern.rb b/app/controllers/concerns/web_app_controller_concern.rb index b8c909877b6..fddb8f156be 100644 --- a/app/controllers/concerns/web_app_controller_concern.rb +++ b/app/controllers/concerns/web_app_controller_concern.rb @@ -11,7 +11,7 @@ module WebAppControllerConcern end def skip_csrf_meta_tags? - !(ENV['ONE_CLICK_SSO_LOGIN'] == 'true' && ENV['OMNIAUTH_ONLY'] == 'true' && Devise.omniauth_providers.length == 1) && current_user.nil? + !(ENV['ONE_CLICK_SSO_LOGIN'] == 'true' && Rails.configuration.omniauth.only && Devise.omniauth_providers.length == 1) && current_user.nil? end def set_app_body_class diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 7e9cfee3f68..6f85148b71a 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -49,7 +49,7 @@ module ApplicationHelper end def omniauth_only? - ENV['OMNIAUTH_ONLY'] == 'true' + Rails.configuration.omniauth.only end def link_to_login(name = nil, html_options = nil, &block) diff --git a/app/helpers/registration_helper.rb b/app/helpers/registration_helper.rb index ef5462ac887..596261de951 100644 --- a/app/helpers/registration_helper.rb +++ b/app/helpers/registration_helper.rb @@ -12,7 +12,7 @@ module RegistrationHelper end def omniauth_only? - ENV['OMNIAUTH_ONLY'] == 'true' + Rails.configuration.omniauth.only end def ip_blocked?(remote_ip) diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb index 13f332c95c4..d8addbd1e02 100644 --- a/app/serializers/initial_state_serializer.rb +++ b/app/serializers/initial_state_serializer.rb @@ -125,6 +125,6 @@ class InitialStateSerializer < ActiveModel::Serializer end def sso_redirect - "/auth/auth/#{Devise.omniauth_providers[0]}" if ENV['ONE_CLICK_SSO_LOGIN'] == 'true' && ENV['OMNIAUTH_ONLY'] == 'true' && Devise.omniauth_providers.length == 1 + "/auth/auth/#{Devise.omniauth_providers[0]}" if ENV['ONE_CLICK_SSO_LOGIN'] == 'true' && Rails.configuration.omniauth.only && Devise.omniauth_providers.length == 1 end end diff --git a/config/application.rb b/config/application.rb index 5aca74fd1c6..6037ffdd7b9 100644 --- a/config/application.rb +++ b/config/application.rb @@ -112,6 +112,9 @@ module Mastodon end end + # Load config/omniauth.yml settings + config.omniauth = config_for(:omniauth) + config.to_prepare do Doorkeeper::AuthorizationsController.layout 'modal' Doorkeeper::AuthorizedApplicationsController.layout 'admin' diff --git a/config/initializers/3_omniauth.rb b/config/initializers/3_omniauth.rb index aa8ba1a056e..d731c0fd5c4 100644 --- a/config/initializers/3_omniauth.rb +++ b/config/initializers/3_omniauth.rb @@ -10,98 +10,26 @@ end Devise.setup do |config| # CAS strategy - if ENV['CAS_ENABLED'] == 'true' - cas_options = {} - cas_options[:display_name] = ENV['CAS_DISPLAY_NAME'] - cas_options[:url] = ENV['CAS_URL'] if ENV['CAS_URL'] - cas_options[:host] = ENV['CAS_HOST'] if ENV['CAS_HOST'] - cas_options[:port] = ENV['CAS_PORT'] if ENV['CAS_PORT'] - cas_options[:ssl] = ENV['CAS_SSL'] == 'true' if ENV['CAS_SSL'] - cas_options[:service_validate_url] = ENV['CAS_VALIDATE_URL'] if ENV['CAS_VALIDATE_URL'] - cas_options[:callback_url] = ENV['CAS_CALLBACK_URL'] if ENV['CAS_CALLBACK_URL'] - cas_options[:logout_url] = ENV['CAS_LOGOUT_URL'] if ENV['CAS_LOGOUT_URL'] - cas_options[:login_url] = ENV['CAS_LOGIN_URL'] if ENV['CAS_LOGIN_URL'] - cas_options[:uid_field] = ENV['CAS_UID_FIELD'] || 'user' if ENV['CAS_UID_FIELD'] - cas_options[:ca_path] = ENV['CAS_CA_PATH'] if ENV['CAS_CA_PATH'] - cas_options[:disable_ssl_verification] = ENV['CAS_DISABLE_SSL_VERIFICATION'] == 'true' - cas_options[:uid_key] = ENV['CAS_UID_KEY'] || 'user' - cas_options[:name_key] = ENV['CAS_NAME_KEY'] || 'name' - cas_options[:email_key] = ENV['CAS_EMAIL_KEY'] || 'email' - cas_options[:nickname_key] = ENV['CAS_NICKNAME_KEY'] || 'nickname' - cas_options[:first_name_key] = ENV['CAS_FIRST_NAME_KEY'] || 'firstname' - cas_options[:last_name_key] = ENV['CAS_LAST_NAME_KEY'] || 'lastname' - cas_options[:location_key] = ENV['CAS_LOCATION_KEY'] || 'location' - cas_options[:image_key] = ENV['CAS_IMAGE_KEY'] || 'image' - cas_options[:phone_key] = ENV['CAS_PHONE_KEY'] || 'phone' - cas_options[:security] = {} - cas_options[:security][:assume_email_is_verified] = ENV['CAS_SECURITY_ASSUME_EMAIL_IS_VERIFIED'] == 'true' - config.omniauth :cas, cas_options + if Rails.configuration.omniauth.cas_enabled + config.omniauth( + :cas, + Rails.configuration.omniauth.cas + ) end # SAML strategy - if ENV['SAML_ENABLED'] == 'true' - saml_options = {} - saml_options[:display_name] = ENV['SAML_DISPLAY_NAME'] - saml_options[:assertion_consumer_service_url] = ENV['SAML_ACS_URL'] if ENV['SAML_ACS_URL'] - saml_options[:issuer] = ENV['SAML_ISSUER'] if ENV['SAML_ISSUER'] - saml_options[:idp_sso_target_url] = ENV['SAML_IDP_SSO_TARGET_URL'] if ENV['SAML_IDP_SSO_TARGET_URL'] - saml_options[:idp_sso_target_url_runtime_params] = ENV['SAML_IDP_SSO_TARGET_PARAMS'] if ENV['SAML_IDP_SSO_TARGET_PARAMS'] # FIXME: Should be parsable Hash - saml_options[:idp_cert] = ENV['SAML_IDP_CERT'] if ENV['SAML_IDP_CERT'] - saml_options[:idp_cert_fingerprint] = ENV['SAML_IDP_CERT_FINGERPRINT'] if ENV['SAML_IDP_CERT_FINGERPRINT'] - saml_options[:idp_cert_fingerprint_validator] = ENV['SAML_IDP_CERT_FINGERPRINT_VALIDATOR'] if ENV['SAML_IDP_CERT_FINGERPRINT_VALIDATOR'] # FIXME: Should be Lambda { |fingerprint| } - saml_options[:name_identifier_format] = ENV['SAML_NAME_IDENTIFIER_FORMAT'] if ENV['SAML_NAME_IDENTIFIER_FORMAT'] - saml_options[:request_attributes] = {} - saml_options[:certificate] = ENV['SAML_CERT'] if ENV['SAML_CERT'] - saml_options[:private_key] = ENV['SAML_PRIVATE_KEY'] if ENV['SAML_PRIVATE_KEY'] - saml_options[:security] = {} - saml_options[:security][:want_assertions_signed] = ENV['SAML_SECURITY_WANT_ASSERTION_SIGNED'] == 'true' - saml_options[:security][:want_assertions_encrypted] = ENV['SAML_SECURITY_WANT_ASSERTION_ENCRYPTED'] == 'true' - saml_options[:security][:assume_email_is_verified] = ENV['SAML_SECURITY_ASSUME_EMAIL_IS_VERIFIED'] == 'true' - saml_options[:attribute_statements] = {} - saml_options[:attribute_statements][:uid] = [ENV['SAML_ATTRIBUTES_STATEMENTS_UID']] if ENV['SAML_ATTRIBUTES_STATEMENTS_UID'] - saml_options[:attribute_statements][:email] = [ENV['SAML_ATTRIBUTES_STATEMENTS_EMAIL']] if ENV['SAML_ATTRIBUTES_STATEMENTS_EMAIL'] - saml_options[:attribute_statements][:full_name] = [ENV['SAML_ATTRIBUTES_STATEMENTS_FULL_NAME']] if ENV['SAML_ATTRIBUTES_STATEMENTS_FULL_NAME'] - saml_options[:attribute_statements][:first_name] = [ENV['SAML_ATTRIBUTES_STATEMENTS_FIRST_NAME']] if ENV['SAML_ATTRIBUTES_STATEMENTS_FIRST_NAME'] - saml_options[:attribute_statements][:last_name] = [ENV['SAML_ATTRIBUTES_STATEMENTS_LAST_NAME']] if ENV['SAML_ATTRIBUTES_STATEMENTS_LAST_NAME'] - saml_options[:attribute_statements][:verified] = [ENV['SAML_ATTRIBUTES_STATEMENTS_VERIFIED']] if ENV['SAML_ATTRIBUTES_STATEMENTS_VERIFIED'] - saml_options[:attribute_statements][:verified_email] = [ENV['SAML_ATTRIBUTES_STATEMENTS_VERIFIED_EMAIL']] if ENV['SAML_ATTRIBUTES_STATEMENTS_VERIFIED_EMAIL'] - saml_options[:uid_attribute] = ENV['SAML_UID_ATTRIBUTE'] if ENV['SAML_UID_ATTRIBUTE'] - saml_options[:allowed_clock_drift] = ENV['SAML_ALLOWED_CLOCK_DRIFT'] if ENV['SAML_ALLOWED_CLOCK_DRIFT'] - config.omniauth :saml, saml_options + if Rails.configuration.omniauth.saml_enabled + config.omniauth( + :saml, + Rails.configuration.omniauth.saml + ) end # OpenID Connect Strategy - if ENV['OIDC_ENABLED'] == 'true' - oidc_options = {} - oidc_options[:display_name] = ENV['OIDC_DISPLAY_NAME'] # OPTIONAL - oidc_options[:issuer] = ENV['OIDC_ISSUER'] if ENV['OIDC_ISSUER'] # NEED - oidc_options[:discovery] = ENV['OIDC_DISCOVERY'] == 'true' if ENV['OIDC_DISCOVERY'] # OPTIONAL (default: false) - oidc_options[:client_auth_method] = ENV['OIDC_CLIENT_AUTH_METHOD'] if ENV['OIDC_CLIENT_AUTH_METHOD'] # OPTIONAL (default: basic) - scope_string = ENV['OIDC_SCOPE'] if ENV['OIDC_SCOPE'] # NEED - scopes = scope_string.split(',') - oidc_options[:scope] = scopes.map(&:to_sym) - oidc_options[:response_type] = ENV['OIDC_RESPONSE_TYPE'] if ENV['OIDC_RESPONSE_TYPE'] # OPTIONAL (default: code) - oidc_options[:response_mode] = ENV['OIDC_RESPONSE_MODE'] if ENV['OIDC_RESPONSE_MODE'] # OPTIONAL (default: query) - oidc_options[:display] = ENV['OIDC_DISPLAY'] if ENV['OIDC_DISPLAY'] # OPTIONAL (default: page) - oidc_options[:prompt] = ENV['OIDC_PROMPT'] if ENV['OIDC_PROMPT'] # OPTIONAL - oidc_options[:send_nonce] = ENV['OIDC_SEND_NONCE'] == 'true' if ENV['OIDC_SEND_NONCE'] # OPTIONAL (default: true) - oidc_options[:send_scope_to_token_endpoint] = ENV['OIDC_SEND_SCOPE_TO_TOKEN_ENDPOINT'] == 'true' if ENV['OIDC_SEND_SCOPE_TO_TOKEN_ENDPOINT'] # OPTIONAL (default: true) - oidc_options[:post_logout_redirect_uri] = ENV['OIDC_IDP_LOGOUT_REDIRECT_URI'] if ENV['OIDC_IDP_LOGOUT_REDIRECT_URI'] # OPTIONAL - oidc_options[:uid_field] = ENV['OIDC_UID_FIELD'] if ENV['OIDC_UID_FIELD'] # NEED - oidc_options[:client_options] = {} - oidc_options[:client_options][:identifier] = ENV['OIDC_CLIENT_ID'] if ENV['OIDC_CLIENT_ID'] # NEED - oidc_options[:client_options][:secret] = ENV['OIDC_CLIENT_SECRET'] if ENV['OIDC_CLIENT_SECRET'] # NEED - oidc_options[:client_options][:redirect_uri] = ENV['OIDC_REDIRECT_URI'] if ENV['OIDC_REDIRECT_URI'] # NEED - oidc_options[:client_options][:scheme] = ENV['OIDC_HTTP_SCHEME'] if ENV['OIDC_HTTP_SCHEME'] # OPTIONAL (default: https) - oidc_options[:client_options][:host] = ENV['OIDC_HOST'] if ENV['OIDC_HOST'] # OPTIONAL - oidc_options[:client_options][:port] = ENV['OIDC_PORT'] if ENV['OIDC_PORT'] # OPTIONAL - oidc_options[:client_options][:authorization_endpoint] = ENV['OIDC_AUTH_ENDPOINT'] if ENV['OIDC_AUTH_ENDPOINT'] # NEED when discovery != true - oidc_options[:client_options][:token_endpoint] = ENV['OIDC_TOKEN_ENDPOINT'] if ENV['OIDC_TOKEN_ENDPOINT'] # NEED when discovery != true - oidc_options[:client_options][:userinfo_endpoint] = ENV['OIDC_USER_INFO_ENDPOINT'] if ENV['OIDC_USER_INFO_ENDPOINT'] # NEED when discovery != true - oidc_options[:client_options][:jwks_uri] = ENV['OIDC_JWKS_URI'] if ENV['OIDC_JWKS_URI'] # NEED when discovery != true - oidc_options[:client_options][:end_session_endpoint] = ENV['OIDC_END_SESSION_ENDPOINT'] if ENV['OIDC_END_SESSION_ENDPOINT'] # OPTIONAL - oidc_options[:security] = {} - oidc_options[:security][:assume_email_is_verified] = ENV['OIDC_SECURITY_ASSUME_EMAIL_IS_VERIFIED'] == 'true' # OPTIONAL - config.omniauth :openid_connect, oidc_options + if Rails.configuration.omniauth.oidc_enabled + config.omniauth( + :openid_connect, + Rails.configuration.omniauth.oidc + ) end end diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index e43e38786c4..b225694c68e 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -14,7 +14,7 @@ media_hosts = policy.media_hosts def sso_host return unless ENV['ONE_CLICK_SSO_LOGIN'] == 'true' - return unless ENV['OMNIAUTH_ONLY'] == 'true' + return unless Rails.configuration.omniauth.only return unless Devise.omniauth_providers.length == 1 provider = Devise.omniauth_configs[Devise.omniauth_providers[0]] diff --git a/config/omniauth.yml b/config/omniauth.yml new file mode 100644 index 00000000000..d2da207d28a --- /dev/null +++ b/config/omniauth.yml @@ -0,0 +1,85 @@ +--- +shared: + only: <%= ENV.fetch('OMNIAUTH_ONLY', 'false') == 'true' %> + cas_enabled: <%= ENV.fetch('CAS_ENABLED', 'false') == 'true' %> + oidc_enabled: <%= ENV.fetch('OIDC_ENABLED', 'false') == 'true' %> + saml_enabled: <%= ENV.fetch('SAML_ENABLED', 'false') == 'true' %> + cas: + display_name: <%= ENV.fetch('CAS_DISPLAY_NAME', nil) %> + url: <%= ENV.fetch('CAS_URL', nil) %> + host: <%= ENV.fetch('CAS_HOST', nil) %> + port: <%= ENV.fetch('CAS_PORT', nil) %> + ssl: <%= ENV.fetch('SAS_SSL', 'false') == 'true' %> + service_validate_url: <%= ENV.fetch('CAS_VALIDATE_URL', nil) %> + callback_url: <%= ENV.fetch('CAS_CALLBACK_URL', nil) %> + logout_url: <%= ENV.fetch('CAS_LOGOUT_URL', nil) %> + login_url: <%= ENV.fetch('CAS_LOGIN_URL', nil) %> + uid_field: <%= ENV.fetch('CAS_UID_FIELD', 'user') %> + ca_path: <%= ENV.fetch('CAS_CA_PATH', nil) %> + disable_ssl_verification: <%= ENV.fetch('CAS_DISABLE_SSL_VERIFICATION', 'false') == 'true' %> + uid_key: <%= ENV.fetch('CAS_UID_KEY', 'user') %> + name_key: <%= ENV.fetch('CAS_NAME_KEY', 'name') %> + email_key: <%= ENV.fetch('CAS_EMAIL_KEY', 'email') %> + nickname_key: <%= ENV.fetch('CAS_NICKNAME_KEY', 'nickname') %> + first_name_key: <%= ENV.fetch('CAS_FIRST_NAME_KEY', 'firstname') %> + last_name_key: <%= ENV.fetch('CAS_LAST_NAME_KEY', 'lastname') %> + location_key: <%= ENV.fetch('CAS_LOCATION_KEY', 'location') %> + image_key: <%= ENV.fetch('CAS_IMAGE_KEY', 'image') %> + phone_key: <%= ENV.fetch('CAS_PHONE_KEY', 'phone') %> + security: + assume_email_is_verified: <%= ENV.fetch('CAS_SECURITY_ASSUME_EMAIL_IS_VERIFIED', 'false') == 'true' %> + saml: + display_name: <%= ENV.fetch('SAML_DISPLAY_NAME', nil) %> + assertion_consumer_service_url: <%= ENV.fetch('SAML_ACS_URL', nil) %> + issuer: <%= ENV.fetch('SAML_ISSUER', nil) %> + idp_sso_target_url: <%= ENV.fetch('SAML_IDP_SSO_TARGET_URL', nil) %> + idp_sso_target_url_runtime_params: <%= ENV.fetch('SAML_IDP_SSO_TARGET_PARAMS', nil) %> # FIXME: Should be parsable Hash + idp_cert: <%= ENV.fetch('SAML_IDP_CERT', nil) %> + idp_cert_fingerprint: <%= ENV.fetch('SAML_IDP_CERT_FINGERPRINT', nil) %> + idp_cert_fingerprint_validator: <%= ENV.fetch('SAML_IDP_CERT_FINGERPRINT_VALIDATOR', nil) %> # FIXME: Should be Lambda { |fingerprint| } + name_identifier_format: <%= ENV.fetch('SAML_NAME_IDENTIFIER_FORMAT', nil) %> + request_attributes: {} + certificate: <%= ENV.fetch('SAML_CERT', nil) %> + private_key: <%= ENV.fetch('SAML_PRIVATE_KEY', nil) %> + security: + want_assertions_signed: <%= ENV.fetch('SAML_SECURITY_WANT_ASSERTION_SIGNED', 'false') == 'true' %> + want_assertions_encrypted: <%= ENV.fetch('SAML_SECURITY_WANT_ASSERTION_ENCRYPTED', 'false') == 'true' %> + assume_email_is_verified: <%= ENV.fetch('SAML_SECURITY_ASSUME_EMAIL_IS_VERIFIED', 'false') == 'true' %> + attribute_statements: + uid: <%= [ENV.fetch('SAML_ATTRIBUTES_STATEMENTS_UID', nil)] %> + email: <%= [ENV.fetch('SAML_ATTRIBUTES_STATEMENTS_EMAIL', nil)] %> + full_name: <%= [ENV.fetch('SAML_ATTRIBUTES_STATEMENTS_FULL_NAME', nil)] %> + first_name: <%= [ENV.fetch('SAML_ATTRIBUTES_STATEMENTS_FIRST_NAME', nil)] %> + last_name: <%= [ENV.fetch('SAML_ATTRIBUTES_STATEMENTS_LAST_NAME', nil)] %> + verified: <%= [ENV.fetch('SAML_ATTRIBUTES_STATEMENTS_VERIFIED', nil)] %> + verified_email: <%= [ENV.fetch('SAML_ATTRIBUTES_STATEMENTS_VERIFIED_EMAIL', nil)] %> + uid_attribute: <%= ENV.fetch('SAML_UID_ATTRIBUTE', nil) %> + allowed_clock_drift: <%= ENV.fetch('SAML_ALLOWED_CLOCK_DRIFT', nil) %> + oidc: + display_name: <%= ENV.fetch('OIDC_DISPLAY_NAME', nil) %> # OPTIONAL + issuer: <%= ENV.fetch('OIDC_ISSUER', nil) %> # NEED + discovery: <%= ENV.fetch('OIDC_DISCOVERY', 'false') == 'true' %> # OPTIONAL (default: false) + client_auth_method: <%= ENV.fetch('OIDC_CLIENT_AUTH_METHOD', nil) %> # OPTIONAL (default: basic) + scope: <%= ENV.fetch('OIDC_SCOPE', '').split(',').map(&:to_sym) %> + response_type: <%= ENV.fetch('OIDC_RESPONSE_TYPE', nil) %> # OPTIONAL (default: code) + response_mode: <%= ENV.fetch('OIDC_RESPONSE_MODE', nil) %> # OPTIONAL (default: query) + display: <%= ENV.fetch('OIDC_DISPLAY', nil) %> # OPTIONAL (default: page) + prompt: <%= ENV.fetch('OIDC_PROMPT', nil) %> # OPTIONAL + send_nonce: <%= ENV.fetch('OIDC_SEND_NONCE', 'true') == 'true' %> # OPTIONAL (default: true) + send_scope_to_token_endpoint: <%= ENV.fetch('OIDC_SEND_SCOPE_TO_TOKEN_ENDPOINT', 'true') == 'true' %> # OPTIONAL (default: true) + post_logout_redirect_uri: <%= ENV.fetch('OIDC_IDP_LOGOUT_REDIRECT_URI', nil) %> # OPTIONAL + uid_field: <%= ENV.fetch('OIDC_UID_FIELD', nil) %> # NEED + client_options: + identifier: <%= ENV.fetch('OIDC_CLIENT_ID', nil) %> # NEED + secret: <%= ENV.fetch('OIDC_CLIENT_SECRET', nil) %> # NEED + redirect_uri: <%= ENV.fetch('OIDC_REDIRECT_URI', nil) %> # NEED + scheme: <%= ENV.fetch('OIDC_HTTP_SCHEME', nil) %> # OPTIONAL (default: https) + host: <%= ENV.fetch('OIDC_HOST', nil) %> # OPTIONAL + port: <%= ENV.fetch('OIDC_PORT', nil) %> # OPTIONAL + authorization_endpoint: <%= ENV.fetch('OIDC_AUTH_ENDPOINT', nil) %> # NEED when discovery != true + token_endpoint: <%= ENV.fetch('OIDC_TOKEN_ENDPOINT', nil) %> # NEED when discovery != true + userinfo_endpoint: <%= ENV.fetch('OIDC_USER_INFO_ENDPOINT', nil) %> # NEED when discovery != true + jwks_uri: <%= ENV.fetch('OIDC_JWKS_URI', nil) %> # NEED when discovery != true + end_session_endpoint: <%= ENV.fetch('OIDC_END_SESSION_ENDPOINT', nil) %> # OPTIONAL + security: + assume_email_is_verified: <%= ENV.fetch('OIDC_SECURITY_ASSUME_EMAIL_IS_VERIFIED', 'false') == 'true' %> # OPTIONAL diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index 56974513bef..4859816d09c 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -88,9 +88,10 @@ describe ApplicationHelper do context 'when in omniauth only mode' do around do |example| - ClimateControl.modify OMNIAUTH_ONLY: 'true' do - example.run - end + original = Rails.configuration.omniauth.only + Rails.configuration.omniauth.only = true + example.run + Rails.configuration.omniauth.only = original end it 'redirects to joinmastodon site' do @@ -106,11 +107,12 @@ describe ApplicationHelper do end describe 'omniauth_only?' do - context 'when env var is set to true' do + context 'when configuration is set to true' do around do |example| - ClimateControl.modify OMNIAUTH_ONLY: 'true' do - example.run - end + original = Rails.configuration.omniauth.only + Rails.configuration.omniauth.only = true + example.run + Rails.configuration.omniauth.only = original end it 'returns true' do @@ -118,11 +120,12 @@ describe ApplicationHelper do end end - context 'when env var is not set' do + context 'when configuration is false' do around do |example| - ClimateControl.modify OMNIAUTH_ONLY: nil do - example.run - end + original = Rails.configuration.omniauth.only + Rails.configuration.omniauth.only = false + example.run + Rails.configuration.omniauth.only = original end it 'returns false' do diff --git a/spec/requests/omniauth_callbacks_spec.rb b/spec/requests/omniauth_callbacks_spec.rb index 095535e4859..403dda4640d 100644 --- a/spec/requests/omniauth_callbacks_spec.rb +++ b/spec/requests/omniauth_callbacks_spec.rb @@ -129,15 +129,15 @@ describe 'OmniAuth callbacks' do end end - describe '#openid_connect', if: ENV['OIDC_ENABLED'] == 'true' && ENV['OIDC_SCOPE'].present? do + describe '#openid_connect', if: Rails.configuration.omniauth.oidc_enabled && Rails.configuration.omniauth.oidc[:scope].present? do include_examples 'omniauth provider callbacks', :openid_connect end - describe '#cas', if: ENV['CAS_ENABLED'] == 'true' do + describe '#cas', if: Rails.configuration.omniauth.cas_enabled do include_examples 'omniauth provider callbacks', :cas end - describe '#saml', if: ENV['SAML_ENABLED'] == 'true' do + describe '#saml', if: Rails.configuration.omniauth.saml_enabled do include_examples 'omniauth provider callbacks', :saml end end From db937fcffbbdf0ee26f326aa6a5b507a2584b890 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 31 May 2024 12:36:36 -0400 Subject: [PATCH 2/5] Convert scope to symbol array outside yaml read --- config/initializers/3_omniauth.rb | 6 +++++- config/omniauth.yml | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/config/initializers/3_omniauth.rb b/config/initializers/3_omniauth.rb index d731c0fd5c4..1dc536c55ca 100644 --- a/config/initializers/3_omniauth.rb +++ b/config/initializers/3_omniauth.rb @@ -27,9 +27,13 @@ Devise.setup do |config| # OpenID Connect Strategy if Rails.configuration.omniauth.oidc_enabled + oidc_options = Rails.configuration.omniauth.oidc + config.omniauth( :openid_connect, - Rails.configuration.omniauth.oidc + oidc_options.merge( + scope: oidc_options[:scope].split(',').map(&:to_sym) # Convert scope to symbol array + ) ) end end diff --git a/config/omniauth.yml b/config/omniauth.yml index d2da207d28a..556c1ab14a0 100644 --- a/config/omniauth.yml +++ b/config/omniauth.yml @@ -60,7 +60,7 @@ shared: issuer: <%= ENV.fetch('OIDC_ISSUER', nil) %> # NEED discovery: <%= ENV.fetch('OIDC_DISCOVERY', 'false') == 'true' %> # OPTIONAL (default: false) client_auth_method: <%= ENV.fetch('OIDC_CLIENT_AUTH_METHOD', nil) %> # OPTIONAL (default: basic) - scope: <%= ENV.fetch('OIDC_SCOPE', '').split(',').map(&:to_sym) %> + scope: <%= ENV.fetch('OIDC_SCOPE', '') %> response_type: <%= ENV.fetch('OIDC_RESPONSE_TYPE', nil) %> # OPTIONAL (default: code) response_mode: <%= ENV.fetch('OIDC_RESPONSE_MODE', nil) %> # OPTIONAL (default: query) display: <%= ENV.fetch('OIDC_DISPLAY', nil) %> # OPTIONAL (default: page) From 850cc0c35c013cdd59683233711da8eade796831 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 3 Jun 2024 09:39:56 -0400 Subject: [PATCH 3/5] Update config/omniauth.yml Co-authored-by: Claire --- config/omniauth.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/omniauth.yml b/config/omniauth.yml index 556c1ab14a0..3383d511c36 100644 --- a/config/omniauth.yml +++ b/config/omniauth.yml @@ -9,7 +9,7 @@ shared: url: <%= ENV.fetch('CAS_URL', nil) %> host: <%= ENV.fetch('CAS_HOST', nil) %> port: <%= ENV.fetch('CAS_PORT', nil) %> - ssl: <%= ENV.fetch('SAS_SSL', 'false') == 'true' %> + ssl: <%= ENV.fetch('CAS_SSL', 'false') == 'true' %> service_validate_url: <%= ENV.fetch('CAS_VALIDATE_URL', nil) %> callback_url: <%= ENV.fetch('CAS_CALLBACK_URL', nil) %> logout_url: <%= ENV.fetch('CAS_LOGOUT_URL', nil) %> From 74af68e8a80c70ccf108c1cfc42d119f09f8e3ea Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Mon, 3 Jun 2024 09:52:37 -0400 Subject: [PATCH 4/5] Read oidc scope as yaml symbol array --- config/initializers/3_omniauth.rb | 6 +----- config/omniauth.yml | 4 +++- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/config/initializers/3_omniauth.rb b/config/initializers/3_omniauth.rb index 1dc536c55ca..d731c0fd5c4 100644 --- a/config/initializers/3_omniauth.rb +++ b/config/initializers/3_omniauth.rb @@ -27,13 +27,9 @@ Devise.setup do |config| # OpenID Connect Strategy if Rails.configuration.omniauth.oidc_enabled - oidc_options = Rails.configuration.omniauth.oidc - config.omniauth( :openid_connect, - oidc_options.merge( - scope: oidc_options[:scope].split(',').map(&:to_sym) # Convert scope to symbol array - ) + Rails.configuration.omniauth.oidc ) end end diff --git a/config/omniauth.yml b/config/omniauth.yml index 3383d511c36..6a98ae85166 100644 --- a/config/omniauth.yml +++ b/config/omniauth.yml @@ -60,7 +60,9 @@ shared: issuer: <%= ENV.fetch('OIDC_ISSUER', nil) %> # NEED discovery: <%= ENV.fetch('OIDC_DISCOVERY', 'false') == 'true' %> # OPTIONAL (default: false) client_auth_method: <%= ENV.fetch('OIDC_CLIENT_AUTH_METHOD', nil) %> # OPTIONAL (default: basic) - scope: <%= ENV.fetch('OIDC_SCOPE', '') %> + scope: <% ENV.fetch('OIDC_SCOPE', '').split(',').each do |value| %> + - !ruby/symbol <%= value %> + <% end %> response_type: <%= ENV.fetch('OIDC_RESPONSE_TYPE', nil) %> # OPTIONAL (default: code) response_mode: <%= ENV.fetch('OIDC_RESPONSE_MODE', nil) %> # OPTIONAL (default: query) display: <%= ENV.fetch('OIDC_DISPLAY', nil) %> # OPTIONAL (default: page) From 78e3b7776559fd0ace461a065eb43d5164c4a556 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 11 Jun 2024 10:35:18 -0400 Subject: [PATCH 5/5] Move to `x` namespace --- app/controllers/application_controller.rb | 2 +- .../concerns/web_app_controller_concern.rb | 2 +- app/helpers/application_helper.rb | 2 +- app/helpers/registration_helper.rb | 2 +- app/serializers/initial_state_serializer.rb | 2 +- config/application.rb | 2 +- config/initializers/3_omniauth.rb | 12 ++++++------ spec/helpers/application_helper_spec.rb | 18 +++++++++--------- spec/requests/omniauth_callbacks_spec.rb | 6 +++--- 9 files changed, 24 insertions(+), 24 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 43bf4289d09..d87cab84792 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -79,7 +79,7 @@ class ApplicationController < ActionController::Base end def after_sign_out_path_for(_resource_or_scope) - if Rails.configuration.omniauth.only && Rails.configuration.omniauth.oidc_enabled + if Rails.configuration.x.omniauth.only && Rails.configuration.x.omniauth.oidc_enabled '/auth/auth/openid_connect/logout' else new_user_session_path diff --git a/app/controllers/concerns/web_app_controller_concern.rb b/app/controllers/concerns/web_app_controller_concern.rb index fddb8f156be..3ef9521de0c 100644 --- a/app/controllers/concerns/web_app_controller_concern.rb +++ b/app/controllers/concerns/web_app_controller_concern.rb @@ -11,7 +11,7 @@ module WebAppControllerConcern end def skip_csrf_meta_tags? - !(ENV['ONE_CLICK_SSO_LOGIN'] == 'true' && Rails.configuration.omniauth.only && Devise.omniauth_providers.length == 1) && current_user.nil? + !(ENV['ONE_CLICK_SSO_LOGIN'] == 'true' && Rails.configuration.x.omniauth.only && Devise.omniauth_providers.length == 1) && current_user.nil? end def set_app_body_class diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 6f85148b71a..ff452854fc3 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -49,7 +49,7 @@ module ApplicationHelper end def omniauth_only? - Rails.configuration.omniauth.only + Rails.configuration.x.omniauth.only end def link_to_login(name = nil, html_options = nil, &block) diff --git a/app/helpers/registration_helper.rb b/app/helpers/registration_helper.rb index 596261de951..685c8b62e4c 100644 --- a/app/helpers/registration_helper.rb +++ b/app/helpers/registration_helper.rb @@ -12,7 +12,7 @@ module RegistrationHelper end def omniauth_only? - Rails.configuration.omniauth.only + Rails.configuration.x.omniauth.only end def ip_blocked?(remote_ip) diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb index d8addbd1e02..68d2fa90871 100644 --- a/app/serializers/initial_state_serializer.rb +++ b/app/serializers/initial_state_serializer.rb @@ -125,6 +125,6 @@ class InitialStateSerializer < ActiveModel::Serializer end def sso_redirect - "/auth/auth/#{Devise.omniauth_providers[0]}" if ENV['ONE_CLICK_SSO_LOGIN'] == 'true' && Rails.configuration.omniauth.only && Devise.omniauth_providers.length == 1 + "/auth/auth/#{Devise.omniauth_providers[0]}" if ENV['ONE_CLICK_SSO_LOGIN'] == 'true' && Rails.configuration.x.omniauth.only && Devise.omniauth_providers.length == 1 end end diff --git a/config/application.rb b/config/application.rb index 6037ffdd7b9..aff6908f6b7 100644 --- a/config/application.rb +++ b/config/application.rb @@ -113,7 +113,7 @@ module Mastodon end # Load config/omniauth.yml settings - config.omniauth = config_for(:omniauth) + config.x.omniauth = config_for(:omniauth) config.to_prepare do Doorkeeper::AuthorizationsController.layout 'modal' diff --git a/config/initializers/3_omniauth.rb b/config/initializers/3_omniauth.rb index d731c0fd5c4..d3f79c91e4a 100644 --- a/config/initializers/3_omniauth.rb +++ b/config/initializers/3_omniauth.rb @@ -10,26 +10,26 @@ end Devise.setup do |config| # CAS strategy - if Rails.configuration.omniauth.cas_enabled + if Rails.configuration.x.omniauth.cas_enabled config.omniauth( :cas, - Rails.configuration.omniauth.cas + Rails.configuration.x.omniauth.cas ) end # SAML strategy - if Rails.configuration.omniauth.saml_enabled + if Rails.configuration.x.omniauth.saml_enabled config.omniauth( :saml, - Rails.configuration.omniauth.saml + Rails.configuration.x.omniauth.saml ) end # OpenID Connect Strategy - if Rails.configuration.omniauth.oidc_enabled + if Rails.configuration.x.omniauth.oidc_enabled config.omniauth( :openid_connect, - Rails.configuration.omniauth.oidc + Rails.configuration.x.omniauth.oidc ) end end diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index 4859816d09c..0b897c012dd 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -88,10 +88,10 @@ describe ApplicationHelper do context 'when in omniauth only mode' do around do |example| - original = Rails.configuration.omniauth.only - Rails.configuration.omniauth.only = true + original = Rails.configuration.x.omniauth.only + Rails.configuration.x.omniauth.only = true example.run - Rails.configuration.omniauth.only = original + Rails.configuration.x.omniauth.only = original end it 'redirects to joinmastodon site' do @@ -109,10 +109,10 @@ describe ApplicationHelper do describe 'omniauth_only?' do context 'when configuration is set to true' do around do |example| - original = Rails.configuration.omniauth.only - Rails.configuration.omniauth.only = true + original = Rails.configuration.x.omniauth.only + Rails.configuration.x.omniauth.only = true example.run - Rails.configuration.omniauth.only = original + Rails.configuration.x.omniauth.only = original end it 'returns true' do @@ -122,10 +122,10 @@ describe ApplicationHelper do context 'when configuration is false' do around do |example| - original = Rails.configuration.omniauth.only - Rails.configuration.omniauth.only = false + original = Rails.configuration.x.omniauth.only + Rails.configuration.x.omniauth.only = false example.run - Rails.configuration.omniauth.only = original + Rails.configuration.x.omniauth.only = original end it 'returns false' do diff --git a/spec/requests/omniauth_callbacks_spec.rb b/spec/requests/omniauth_callbacks_spec.rb index 403dda4640d..2d4724af6a3 100644 --- a/spec/requests/omniauth_callbacks_spec.rb +++ b/spec/requests/omniauth_callbacks_spec.rb @@ -129,15 +129,15 @@ describe 'OmniAuth callbacks' do end end - describe '#openid_connect', if: Rails.configuration.omniauth.oidc_enabled && Rails.configuration.omniauth.oidc[:scope].present? do + describe '#openid_connect', if: Rails.configuration.x.omniauth.oidc_enabled && Rails.configuration.x.omniauth.oidc[:scope].present? do include_examples 'omniauth provider callbacks', :openid_connect end - describe '#cas', if: Rails.configuration.omniauth.cas_enabled do + describe '#cas', if: Rails.configuration.x.omniauth.cas_enabled do include_examples 'omniauth provider callbacks', :cas end - describe '#saml', if: Rails.configuration.omniauth.saml_enabled do + describe '#saml', if: Rails.configuration.x.omniauth.saml_enabled do include_examples 'omniauth provider callbacks', :saml end end