From 6be4c220580918d9d85a3a125445df21275d59f2 Mon Sep 17 00:00:00 2001 From: kennethrioja <59597207+kennethrioja@users.noreply.github.com> Date: Thu, 9 Oct 2025 10:55:43 +0200 Subject: [PATCH 1/4] feat(oidc_only): can show only oidc login --- app/assets/stylesheets/application.scss | 10 +++++++++- app/helpers/application_helper.rb | 10 ++++++++++ app/models/user.rb | 4 +++- .../devise/sessions/_omniauth_options.html.erb | 3 ++- app/views/devise/sessions/new.html.erb | 18 +++++++++++++++++- app/views/layouts/_login_menu.html.erb | 13 ++++++++----- config/locales/en.yml | 1 + config/tess.example.yml | 5 +++-- test/controllers/static_controller_test.rb | 18 ++++++++++++++++++ test/integration/login_test.rb | 18 ++++++++++++++++++ 10 files changed, 89 insertions(+), 11 deletions(-) diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index e6f2912c9..b8b357820 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -1047,4 +1047,12 @@ td.day .calendar-text { top: 0; } } -} \ No newline at end of file +} + +.btn-oidc-only { + font-size: 36px; + padding: 4px; + margin: 12px 10px; + display: flex; + justify-content: center; +} diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index a7ca517b2..13ea4950b 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -698,4 +698,14 @@ def unverified_notice(resource) def theme_path "themes/#{params[:theme_preview] || current_space&.theme || TeSS::Config.site['default_theme'] || 'default'}" end + + def omniauth_login_link(provider, config) + link_to( + t('authentication.omniauth.log_in_with', + provider: config.options[:label] || + t("authentication.omniauth.providers.#{provider}", default: provider.to_s.titleize)), + omniauth_authorize_path('user', provider), + method: :post + ) + end end diff --git a/app/models/user.rb b/app/models/user.rb index d113186c5..44b713043 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -62,7 +62,9 @@ class User < ApplicationRecord before_save :set_username_for_invitee # Include default devise modules. Others available are: :lockable, :timeoutable - if TeSS::Config.feature['registration'] + if TeSS::Config.feature['login_through_oidc_only'] + devise :database_authenticatable, :confirmable, :trackable, :validatable, :omniauthable, :authentication_keys => [:login] + elsif TeSS::Config.feature['registration'] devise :database_authenticatable, :confirmable, :registerable, :invitable, :recoverable, :rememberable, :trackable, :validatable, :omniauthable, :authentication_keys => [:login] elsif TeSS::Config.feature['invitation'] diff --git a/app/views/devise/sessions/_omniauth_options.html.erb b/app/views/devise/sessions/_omniauth_options.html.erb index 8fa2bd23a..68745c4c7 100644 --- a/app/views/devise/sessions/_omniauth_options.html.erb +++ b/app/views/devise/sessions/_omniauth_options.html.erb @@ -1,7 +1,8 @@ <% if devise_mapping.omniauthable? -%> <% Devise.omniauth_configs.each do |provider, config| -%> <%= link_to(omniauth_authorize_path(resource_name, provider), method: :post, - class: config.options[:logo] ? '' : 'btn btn-default') do %> + class: config.options[:logo] ? '' : + TeSS::Config.feature["login_through_oidc_only"] ? 'btn btn-default btn-lg btn-oidc-only' : 'btn btn-default') do %> <% if config.options[:logo].present? %> <%= image_tag(config.options[:logo], class: "omniauth-logo omniauth-#{provider}") -%> <% else %> diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb index 61728b088..a8518c381 100644 --- a/app/views/devise/sessions/new.html.erb +++ b/app/views/devise/sessions/new.html.erb @@ -1,6 +1,8 @@
<% if resource_class.omniauth_providers.any? && devise_mapping.omniauthable? %> @@ -10,12 +12,20 @@
<% end %> + <% if TeSS::Config.feature["login_through_oidc_only"] %> +
+
+
+

+
<%= t('authentication.omniauth.admin') %>

+
+
+ <% end %> <%= simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<%= t('authentication.password.title') %>

<%= t('authentication.password.description') %>

<%= f.input :login, label: t('authentication.password.email_or_username'), autofocus: true %> <%= f.input :password, label: t('authentication.password.password'), - input_html: { autocomplete: 'off' } %> + input_html: { autocomplete: 'off' } %> <% if devise_mapping.rememberable? -%> <%= f.input :remember_me, label: t('authentication.password.remember_me'), as: :boolean %> <% end -%> @@ -23,6 +33,12 @@ <%= f.submit t('authentication.password.log_in'), :class => 'btn btn-primary' %>
<% end %> + <% if !TeSS::Config.feature["login_through_oidc_only"] %> <%= render "devise/shared/links" %> + <% else %> + +
+ + <% end %>
diff --git a/app/views/layouts/_login_menu.html.erb b/app/views/layouts/_login_menu.html.erb index ca404040b..f857983a5 100644 --- a/app/views/layouts/_login_menu.html.erb +++ b/app/views/layouts/_login_menu.html.erb @@ -1,14 +1,16 @@ +<% if TeSS::Config.feature["login_through_oidc_only"] && Devise.omniauth_configs.size == 1 %> +
  • + <% provider, config = Devise.omniauth_configs.first %> + <%= omniauth_login_link(provider, config) %> +
  • +<% else %> +<% end %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 2075e30ee..e85ca8e92 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -743,6 +743,7 @@ en: oidc: OpenID Connect oidc2: Alternative OpenID Connect log_in_with: 'Log in with %{provider}' + admin: Admin ingestion: categories: events: 'Events' diff --git a/config/tess.example.yml b/config/tess.example.yml index 103916215..ed4c8e509 100644 --- a/config/tess.example.yml +++ b/config/tess.example.yml @@ -147,13 +147,11 @@ default: &default feature: elearning_materials: false events: true - invitation: false materials: true nodes: false collections: true content_providers: true subscription: true - registration: true trainers: false workflows: true sources: false @@ -171,6 +169,9 @@ default: &default learning_paths: false collection_curation: true spaces: false + invitation: false + registration: false + login_through_oidc_only: false # when true, only the first oidc authentication will be available in TeSS, useful when you have your org SSO. Be careful! invitation and registration must be false when using this feature. restrict_content_provider_selection: false user_ingestion_methods: ['bioschemas'] placeholder: diff --git a/test/controllers/static_controller_test.rb b/test/controllers/static_controller_test.rb index f4c93039d..e51a65794 100644 --- a/test/controllers/static_controller_test.rb +++ b/test/controllers/static_controller_test.rb @@ -493,4 +493,22 @@ class StaticControllerTest < ActionController::TestCase end end end + + test 'should find log in drop down when login_through_oidc_only is disabled' do + with_settings({ feature: { login_through_oidc_only: false } }) do + get :home + assert_select 'ul.user-options.nav.navbar-nav.navbar-right' do + assert_select 'a.dropdown-toggle', count: 1 + end + end + end + + test 'should find log in button when login_through_oidc_only is enabled' do + with_settings({ feature: { login_through_oidc_only: true } }) do + get :home + assert_select 'ul.user-options.nav.navbar-nav.navbar-right' do + assert_select 'a[href="/users/auth/oidc"]', text: 'Log in', count: 1 + end + end + end end diff --git a/test/integration/login_test.rb b/test/integration/login_test.rb index 58b02aaa1..6d65ce1da 100644 --- a/test/integration/login_test.rb +++ b/test/integration/login_test.rb @@ -29,6 +29,24 @@ class LoginTest < ActionDispatch::IntegrationTest logout_user end + test 'should not see big login button and admin login when login_through_oidc_only is disabled' do + with_settings({ feature: { login_through_oidc_only: false } }) do + get '/users/sign_in' + assert_response :success + assert_select 'div.form-middle a.btn-oidc-only', false + assert_select 'dl.faq', false + end + end + + test 'should see big login button and admin login when login_through_oidc_only is enabled' do + with_settings({ feature: { login_through_oidc_only: true } }) do + get '/users/sign_in' + assert_response :success + assert_select 'div.form-middle a.btn-oidc-only' + assert_select 'dl.faq' + end + end + private def login_user(username, identifier, password) From 71d29b8fdc0a806d2bdcfe7e59c7c51ba06c26d7 Mon Sep 17 00:00:00 2001 From: kennethrioja <59597207+kennethrioja@users.noreply.github.com> Date: Fri, 14 Nov 2025 16:19:38 +0100 Subject: [PATCH 2/4] fixtest(oidc_only): added Devise.stub for omniauth_configs --- test/controllers/static_controller_test.rb | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/test/controllers/static_controller_test.rb b/test/controllers/static_controller_test.rb index e51a65794..cab7b7fea 100644 --- a/test/controllers/static_controller_test.rb +++ b/test/controllers/static_controller_test.rb @@ -504,10 +504,13 @@ class StaticControllerTest < ActionController::TestCase end test 'should find log in button when login_through_oidc_only is enabled' do - with_settings({ feature: { login_through_oidc_only: true } }) do - get :home - assert_select 'ul.user-options.nav.navbar-nav.navbar-right' do - assert_select 'a[href="/users/auth/oidc"]', text: 'Log in', count: 1 + Devise.stub( :omniauth_configs, { oidc: OpenStruct.new(options: { label: "OIDC" }) } + ) do + with_settings({ feature: { login_through_oidc_only: true } }) do + get :home + assert_select 'ul.user-options.nav.navbar-nav.navbar-right' do + assert_select 'a[href="/users/auth/oidc"]', text: 'Log in', count: 1 + end end end end From f0c3adca6c5551ebfe318dc0816596f72fa58742 Mon Sep 17 00:00:00 2001 From: kennethrioja <59597207+kennethrioja@users.noreply.github.com> Date: Fri, 19 Dec 2025 09:41:47 +0100 Subject: [PATCH 3/4] chore(tess_example.yml): set registration to true --- config/tess.example.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/tess.example.yml b/config/tess.example.yml index ed4c8e509..fb40dd153 100644 --- a/config/tess.example.yml +++ b/config/tess.example.yml @@ -170,7 +170,7 @@ default: &default collection_curation: true spaces: false invitation: false - registration: false + registration: true login_through_oidc_only: false # when true, only the first oidc authentication will be available in TeSS, useful when you have your org SSO. Be careful! invitation and registration must be false when using this feature. restrict_content_provider_selection: false user_ingestion_methods: ['bioschemas'] From 81710ec3f6677e3e9647b990aa9cd4ba016630ec Mon Sep 17 00:00:00 2001 From: kennethrioja <59597207+kennethrioja@users.noreply.github.com> Date: Fri, 19 Dec 2025 12:54:54 +0100 Subject: [PATCH 4/4] test(static_controller_test.rb): fixed --- test/controllers/static_controller_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/controllers/static_controller_test.rb b/test/controllers/static_controller_test.rb index cab7b7fea..13b254422 100644 --- a/test/controllers/static_controller_test.rb +++ b/test/controllers/static_controller_test.rb @@ -509,7 +509,7 @@ class StaticControllerTest < ActionController::TestCase with_settings({ feature: { login_through_oidc_only: true } }) do get :home assert_select 'ul.user-options.nav.navbar-nav.navbar-right' do - assert_select 'a[href="/users/auth/oidc"]', text: 'Log in', count: 1 + assert_select 'a[href="/users/auth/oidc"]', count: 1 end end end