mirror of
https://github.com/we-promise/sure.git
synced 2026-04-19 12:04:08 +00:00
Add configurable multi-provider SSO, SSO-only mode, and JIT controls via auth.yml (#441)
* Add configuration and logic for dynamic SSO provider support and stricter JIT account creation - Introduced `config/auth.yml` for centralized auth configuration and documentation. - Added support for multiple SSO providers, including Google, GitHub, and OpenID Connect. - Implemented stricter JIT SSO account creation modes (`create_and_link` vs `link_only`). - Enabled optional restriction of JIT creation by allowed email domains. - Enhanced OmniAuth initializer for dynamic provider setup and better configurability. - Refined login UI to handle local login disabling and emergency super-admin override. - Updated account creation flow to respect JIT mode and domain checks. - Added tests for SSO account creation, login form visibility, and emergency overrides. # Conflicts: # app/controllers/sessions_controller.rb * remove non-translation * Refactor authentication views to use translation keys and update locale files - Extracted hardcoded strings in `oidc_accounts/link.html.erb` and `sessions/new.html.erb` into translation keys for better localization support. - Added missing translations for English and Spanish in `sessions` and `oidc_accounts` locale files. * Enhance OmniAuth provider configuration and refine local login override logic - Updated OmniAuth initializer to support dynamic provider configuration with `name` and scoped parameters for Google and GitHub. - Improved local login logic to enforce stricter handling of super-admin override when local login is disabled. - Added test for invalid super-admin override credentials. * Document Google sign-in configuration for local development and self-hosted environments --------- Co-authored-by: Josh Waldrep <joshua.waldrep5+github@gmail.com>
This commit is contained in:
@@ -2,27 +2,75 @@
|
||||
|
||||
require "omniauth/rails_csrf_protection"
|
||||
|
||||
# Configure OmniAuth for production or test environments
|
||||
# In test mode, OmniAuth will use mock data instead of real provider configuration
|
||||
required_env = %w[OIDC_ISSUER OIDC_CLIENT_ID OIDC_CLIENT_SECRET OIDC_REDIRECT_URI]
|
||||
missing = required_env.select { |k| ENV[k].blank? }
|
||||
if missing.empty? || Rails.env.test?
|
||||
Rails.application.config.middleware.use OmniAuth::Builder do
|
||||
provider :openid_connect,
|
||||
name: :openid_connect,
|
||||
scope: %i[openid email profile],
|
||||
response_type: :code,
|
||||
issuer: ENV["OIDC_ISSUER"].to_s.strip || "https://test.example.com",
|
||||
discovery: true,
|
||||
pkce: true,
|
||||
client_options: {
|
||||
identifier: ENV["OIDC_CLIENT_ID"] || "test_client_id",
|
||||
secret: ENV["OIDC_CLIENT_SECRET"] || "test_client_secret",
|
||||
redirect_uri: ENV["OIDC_REDIRECT_URI"] || "http://test.example.com/callback"
|
||||
}
|
||||
Rails.configuration.x.auth.oidc_enabled = false
|
||||
Rails.configuration.x.auth.sso_providers ||= []
|
||||
|
||||
Rails.application.config.middleware.use OmniAuth::Builder do
|
||||
(Rails.configuration.x.auth.providers || []).each do |raw_cfg|
|
||||
cfg = raw_cfg.deep_symbolize_keys
|
||||
strategy = cfg[:strategy].to_s
|
||||
name = (cfg[:name] || cfg[:id]).to_s
|
||||
|
||||
case strategy
|
||||
when "openid_connect"
|
||||
required_env = %w[OIDC_ISSUER OIDC_CLIENT_ID OIDC_CLIENT_SECRET OIDC_REDIRECT_URI]
|
||||
enabled = Rails.env.test? || required_env.all? { |k| ENV[k].present? }
|
||||
next unless enabled
|
||||
|
||||
issuer = (ENV["OIDC_ISSUER"].presence || "https://test.example.com").to_s.strip
|
||||
client_id = ENV["OIDC_CLIENT_ID"].presence || "test_client_id"
|
||||
client_secret = ENV["OIDC_CLIENT_SECRET"].presence || "test_client_secret"
|
||||
redirect_uri = ENV["OIDC_REDIRECT_URI"].presence || "http://test.example.com/callback"
|
||||
|
||||
provider :openid_connect,
|
||||
name: name.to_sym,
|
||||
scope: %i[openid email profile],
|
||||
response_type: :code,
|
||||
issuer: issuer,
|
||||
discovery: true,
|
||||
pkce: true,
|
||||
client_options: {
|
||||
identifier: client_id,
|
||||
secret: client_secret,
|
||||
redirect_uri: redirect_uri
|
||||
}
|
||||
|
||||
Rails.configuration.x.auth.oidc_enabled = true
|
||||
Rails.configuration.x.auth.sso_providers << cfg.merge(name: name)
|
||||
|
||||
when "google_oauth2"
|
||||
client_id = ENV["GOOGLE_OAUTH_CLIENT_ID"].presence || (Rails.env.test? ? "test_client_id" : nil)
|
||||
client_secret = ENV["GOOGLE_OAUTH_CLIENT_SECRET"].presence || (Rails.env.test? ? "test_client_secret" : nil)
|
||||
next unless client_id.present? && client_secret.present?
|
||||
|
||||
provider :google_oauth2,
|
||||
client_id,
|
||||
client_secret,
|
||||
{
|
||||
name: name.to_sym,
|
||||
scope: "userinfo.email,userinfo.profile"
|
||||
}
|
||||
|
||||
Rails.configuration.x.auth.sso_providers << cfg.merge(name: name)
|
||||
|
||||
when "github"
|
||||
client_id = ENV["GITHUB_CLIENT_ID"].presence || (Rails.env.test? ? "test_client_id" : nil)
|
||||
client_secret = ENV["GITHUB_CLIENT_SECRET"].presence || (Rails.env.test? ? "test_client_secret" : nil)
|
||||
next unless client_id.present? && client_secret.present?
|
||||
|
||||
provider :github,
|
||||
client_id,
|
||||
client_secret,
|
||||
{
|
||||
name: name.to_sym,
|
||||
scope: "user:email"
|
||||
}
|
||||
|
||||
Rails.configuration.x.auth.sso_providers << cfg.merge(name: name)
|
||||
end
|
||||
end
|
||||
Rails.configuration.x.auth.oidc_enabled = true
|
||||
else
|
||||
Rails.logger.warn("OIDC not enabled: missing env vars: #{missing.join(', ')}")
|
||||
Rails.configuration.x.auth.oidc_enabled = false
|
||||
end
|
||||
|
||||
if Rails.configuration.x.auth.sso_providers.empty?
|
||||
Rails.logger.warn("No SSO providers enabled; check auth.yml / ENV configuration")
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user