diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index 97836fb07d..fb2486e191 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -75,6 +75,7 @@ def update_features_enabled end Seek::Config.omniauth_enabled = string_to_boolean params[:omniauth_enabled] + Seek::Config.omniauth_skip_login_page = string_to_boolean params[:omniauth_skip_login_page] Seek::Config.standard_login_enabled = string_to_boolean params[:standard_login_enabled] Seek::Config.omniauth_user_create = string_to_boolean params[:omniauth_user_create] Seek::Config.omniauth_user_activate = string_to_boolean params[:omniauth_user_activate] diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index f823dc2024..19c6ba390c 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,6 +1,7 @@ class UsersController < ApplicationController before_action :is_current_user_auth, only: %i[edit update] before_action :is_user_admin_auth, only: %i[impersonate resend_activation_email destroy activate_other] + before_action :redirect_if_registration_disabled, only: :create skip_before_action :project_membership_required @@ -197,6 +198,13 @@ def user_params params.require(:user).permit(permitted_params) end + def redirect_if_registration_disabled + return unless Seek::Config.registration_disabled + + flash[:error] = Seek::Config.registration_disabled_description + redirect_to main_app.root_path + end + def check_registration if @user.save successful_registration diff --git a/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb index 9778ba14d5..0038654c51 100644 --- a/app/helpers/sessions_helper.rb +++ b/app/helpers/sessions_helper.rb @@ -1,4 +1,11 @@ module SessionsHelper + LOGIN_STRATEGIES = %i[password elixir_aai ldap github oidc].freeze + + # strategies with a form to fill in, rather than sending the user out to the provider + FORM_LOGIN_STRATEGIES = %i[password ldap].freeze + + REDIRECTING_LOGIN_STRATEGIES = (LOGIN_STRATEGIES - FORM_LOGIN_STRATEGIES).freeze + # a person can be logged in but not fully registered during # the registration process whilst selecting or creating a profile def logged_in_and_registered? @@ -11,13 +18,27 @@ def admin_logged_in? end def detect_default_login_strategy - return 'password' if show_standard_password_login? - return 'elixir_aai' if show_elixir_aai_login? - return 'ldap' if show_ldap_login? - return 'github' if show_github_login? - return 'oidc' if show_oidc_login? + available_login_strategies.first&.to_s + end + + # the login strategies currently available, in order of preference + def available_login_strategies + LOGIN_STRATEGIES.select { |strategy| send("show_#{strategy}_login?") } + end + + # the only way to log in, when that is a provider the user can be sent straight to + def sole_redirecting_login_strategy + strategies = available_login_strategies + strategies.first if strategies.one? && REDIRECTING_LOGIN_STRATEGIES.include?(strategies.first) + end + + # the provider to send the user straight to, skipping the login page altogether. + # the strategy and error checks stop a failed login bouncing straight back to the provider. + def auto_login_strategy + return unless Seek::Config.omniauth_skip_login_page + return if params[:strategy].present? || flash[:error].present? - nil + sole_redirecting_login_strategy end # returns true if there is somebody logged in and they are an project manager @@ -42,7 +63,7 @@ def logged_in_and_member? User.logged_in_and_member? end - def show_standard_password_login? + def show_password_login? # always show if omniauth options aren't available, regardless of standard_login_enabled setting params[:show_standard_login].present? || Seek::Config.standard_login_enabled || !show_omniauth_login? end diff --git a/app/views/admin/_omniauth.html.erb b/app/views/admin/_omniauth.html.erb index 140b03f198..3cc483c0d8 100644 --- a/app/views/admin/_omniauth.html.erb +++ b/app/views/admin/_omniauth.html.erb @@ -6,6 +6,10 @@ "Standard login enabled", "If disabled the standard username and password login will be hidden, forcing users to use an alternative provider. It is only hidden if an alternative provider has been configured and enabled below. WARNING:To avoid an administrator being locked out, the standard login option can always be displayed by including the special parameter show_standard_login=true, i.e: #{login_url(show_standard_login: true, host: Seek::Config.site_base_host)}") %> + <%= admin_checkbox_setting(:omniauth_skip_login_page, 1, Seek::Config.omniauth_skip_login_page, + "Skip the login page", "When a single provider is the only way to log in, send the user straight to it rather than + showing a login page containing one button. It has no effect while there is more than one option, or when the only + option needs credentials entering in #{Seek::Config.instance_name} (LDAP, or the standard login).") %> <%= admin_checkbox_setting(:omniauth_user_create, 1, Seek::Config.omniauth_user_create, "Omniauth user creation on login", "When a user logs in through an omniauth provider and does not exist as a #{Seek::Config.instance_name} user, they will be created using the information given by the provider.") %> <%= admin_checkbox_setting(:omniauth_user_activate, 1, Seek::Config.omniauth_user_activate, diff --git a/app/views/gadgets/_sign_in.html.erb b/app/views/gadgets/_sign_in.html.erb index d0a2f2b474..50e506b9bc 100644 --- a/app/views/gadgets/_sign_in.html.erb +++ b/app/views/gadgets/_sign_in.html.erb @@ -13,7 +13,7 @@ <%# tabs if omniauth authentication with providers is enabled %> <% if show_omniauth_login? %> diff --git a/app/views/sessions/_auto_login.html.erb b/app/views/sessions/_auto_login.html.erb new file mode 100644 index 0000000000..46387c480a --- /dev/null +++ b/app/views/sessions/_auto_login.html.erb @@ -0,0 +1,11 @@ +<% original_path ||= request.original_fullpath %> +
+

Redirecting to <%= omniauth_method_name(strategy) %>…

+ <%= form_tag omniauth_authorize_path(strategy, state: "return_to:#{original_path}"), id: 'auto-login-form' do %> + <%= submit_tag "Sign in with #{omniauth_method_name(strategy)}", class: 'btn btn-primary', id: 'auto_login_button' %> + <% end %> +
+ + diff --git a/app/views/sessions/new.html.erb b/app/views/sessions/new.html.erb index 2cc48a863b..3f93134281 100644 --- a/app/views/sessions/new.html.erb +++ b/app/views/sessions/new.html.erb @@ -4,6 +4,11 @@

<%= link_to "Sign out", logout_url %>

<% else %>
- <%= render :partial => "gadgets/sign_in", :locals => {:original_path => params[:return_to]} %> + <% if (auto_strategy = auto_login_strategy) %> + <%= render partial: 'sessions/auto_login', + locals: { strategy: auto_strategy, original_path: params[:return_to] } %> + <% else %> + <%= render :partial => "gadgets/sign_in", :locals => {:original_path => params[:return_to]} %> + <% end %>
<% end %> diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb index e9716afa6c..179e44a3be 100644 --- a/app/views/users/new.html.erb +++ b/app/views/users/new.html.erb @@ -29,7 +29,7 @@
<% if show_omniauth_login? %>