about summary refs log tree commit diff
path: root/app/controllers/auth
diff options
context:
space:
mode:
Diffstat (limited to 'app/controllers/auth')
-rw-r--r--app/controllers/auth/confirmations_controller.rb44
-rw-r--r--app/controllers/auth/omniauth_callbacks_controller.rb2
-rw-r--r--app/controllers/auth/passwords_controller.rb1
-rw-r--r--app/controllers/auth/registrations_controller.rb9
-rw-r--r--app/controllers/auth/sessions_controller.rb44
5 files changed, 66 insertions, 34 deletions
diff --git a/app/controllers/auth/confirmations_controller.rb b/app/controllers/auth/confirmations_controller.rb
index 0b5a2f3c9..17ad56fa8 100644
--- a/app/controllers/auth/confirmations_controller.rb
+++ b/app/controllers/auth/confirmations_controller.rb
@@ -1,12 +1,18 @@
 # frozen_string_literal: true
 
 class Auth::ConfirmationsController < Devise::ConfirmationsController
+  include CaptchaConcern
+
   layout 'auth'
 
   before_action :set_body_classes
   before_action :set_pack
+  before_action :set_confirmation_user!, only: [:show, :confirm_captcha]
   before_action :require_unconfirmed!
 
+  before_action :extend_csp_for_captcha!, only: [:show, :confirm_captcha]
+  before_action :require_captcha_if_needed!, only: [:show]
+
   skip_before_action :require_functional!
 
   def new
@@ -15,8 +21,46 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController
     resource.email = current_user.unconfirmed_email || current_user.email if user_signed_in?
   end
 
+  def show
+    old_session_values = session.to_hash
+    reset_session
+    session.update old_session_values.except('session_id')
+
+    super
+  end
+
+  def confirm_captcha
+    check_captcha! do |message|
+      flash.now[:alert] = message
+      render :captcha
+      return
+    end
+
+    show
+  end
+
   private
 
+  def require_captcha_if_needed!
+    render :captcha if captcha_required?
+  end
+
+  def set_confirmation_user!
+    # We need to reimplement looking up the user because
+    # Devise::ConfirmationsController#show looks up and confirms in one
+    # step.
+    confirmation_token = params[:confirmation_token]
+    return if confirmation_token.nil?
+    @confirmation_user = User.find_first_by_auth_conditions(confirmation_token: confirmation_token)
+  end
+
+  def captcha_user_bypass?
+    return true if @confirmation_user.nil? || @confirmation_user.confirmed?
+
+    invite = Invite.find(@confirmation_user.invite_id) if @confirmation_user.invite_id.present?
+    invite.present? && !invite.max_uses.nil?
+  end
+
   def set_pack
     use_pack 'auth'
   end
diff --git a/app/controllers/auth/omniauth_callbacks_controller.rb b/app/controllers/auth/omniauth_callbacks_controller.rb
index 7925e23cb..991a50b03 100644
--- a/app/controllers/auth/omniauth_callbacks_controller.rb
+++ b/app/controllers/auth/omniauth_callbacks_controller.rb
@@ -11,7 +11,7 @@ class Auth::OmniauthCallbacksController < Devise::OmniauthCallbacksController
 
       if @user.persisted?
         LoginActivity.create(
-          user: user,
+          user: @user,
           success: true,
           authentication_method: :omniauth,
           provider: provider,
diff --git a/app/controllers/auth/passwords_controller.rb b/app/controllers/auth/passwords_controller.rb
index 42534f8ce..609220eb1 100644
--- a/app/controllers/auth/passwords_controller.rb
+++ b/app/controllers/auth/passwords_controller.rb
@@ -11,7 +11,6 @@ class Auth::PasswordsController < Devise::PasswordsController
     super do |resource|
       if resource.errors.empty?
         resource.session_activations.destroy_all
-        resource.forget_me!
       end
     end
   end
diff --git a/app/controllers/auth/registrations_controller.rb b/app/controllers/auth/registrations_controller.rb
index 6429bd969..6b1f3fa82 100644
--- a/app/controllers/auth/registrations_controller.rb
+++ b/app/controllers/auth/registrations_controller.rb
@@ -1,7 +1,6 @@
 # frozen_string_literal: true
 
 class Auth::RegistrationsController < Devise::RegistrationsController
-  include Devise::Controllers::Rememberable
   include RegistrationSpamConcern
 
   layout :determine_layout
@@ -31,8 +30,6 @@ class Auth::RegistrationsController < Devise::RegistrationsController
     super do |resource|
       if resource.saved_change_to_encrypted_password?
         resource.clear_other_sessions(current_session.session_id)
-        resource.forget_me!
-        remember_me(resource)
       end
     end
   end
@@ -85,13 +82,17 @@ class Auth::RegistrationsController < Devise::RegistrationsController
   end
 
   def check_enabled_registrations
-    redirect_to root_path if single_user_mode? || !allowed_registrations?
+    redirect_to root_path if single_user_mode? || omniauth_only? || !allowed_registrations?
   end
 
   def allowed_registrations?
     Setting.registrations_mode != 'none' || @invite&.valid_for_use?
   end
 
+  def omniauth_only?
+    ENV['OMNIAUTH_ONLY'] == 'true'
+  end
+
   def invite_code
     if params[:user]
       params[:user][:invite_code]
diff --git a/app/controllers/auth/sessions_controller.rb b/app/controllers/auth/sessions_controller.rb
index f07f38075..8607077f7 100644
--- a/app/controllers/auth/sessions_controller.rb
+++ b/app/controllers/auth/sessions_controller.rb
@@ -1,8 +1,6 @@
 # frozen_string_literal: true
 
 class Auth::SessionsController < Devise::SessionsController
-  include Devise::Controllers::Rememberable
-
   layout 'auth'
 
   skip_before_action :require_no_authentication, only: [:create]
@@ -17,14 +15,6 @@ class Auth::SessionsController < Devise::SessionsController
   before_action :set_instance_presenter, only: [:new]
   before_action :set_body_classes
 
-  def new
-    Devise.omniauth_configs.each do |provider, config|
-      return redirect_to(omniauth_authorize_path(resource_name, provider)) if config.strategy.redirect_at_sign_in
-    end
-
-    super
-  end
-
   def create
     super do |resource|
       # We only need to call this if this hasn't already been
@@ -44,10 +34,13 @@ class Auth::SessionsController < Devise::SessionsController
   end
 
   def webauthn_options
-    user = find_user
+    user = User.find_by(id: session[:attempt_user_id])
 
     if user&.webauthn_enabled?
-      options_for_get = WebAuthn::Credential.options_for_get(allow: user.webauthn_credentials.pluck(:external_id))
+      options_for_get = WebAuthn::Credential.options_for_get(
+        allow: user.webauthn_credentials.pluck(:external_id),
+        user_verification: 'discouraged'
+      )
 
       session[:webauthn_challenge] = options_for_get.challenge
 
@@ -60,16 +53,20 @@ class Auth::SessionsController < Devise::SessionsController
   protected
 
   def find_user
-    if session[:attempt_user_id]
+    if user_params[:email].present?
+      find_user_from_params
+    elsif session[:attempt_user_id]
       User.find_by(id: session[:attempt_user_id])
-    else
-      user   = User.authenticate_with_ldap(user_params) if Devise.ldap_authentication
-      user ||= User.authenticate_with_pam(user_params) if Devise.pam_authentication
-      user ||= User.find_for_authentication(email: user_params[:email])
-      user
     end
   end
 
+  def find_user_from_params
+    user   = User.authenticate_with_ldap(user_params) if Devise.ldap_authentication
+    user ||= User.authenticate_with_pam(user_params) if Devise.pam_authentication
+    user ||= User.find_for_authentication(email: user_params[:email])
+    user
+  end
+
   def user_params
     params.require(:user).permit(:email, :password, :otp_attempt, :sign_in_token_attempt, credential: {})
   end
@@ -84,14 +81,6 @@ class Auth::SessionsController < Devise::SessionsController
     end
   end
 
-  def after_sign_out_path_for(_resource_or_scope)
-    Devise.omniauth_configs.each_value do |config|
-      return root_path if config.strategy.redirect_at_sign_in
-    end
-
-    super
-  end
-
   def require_no_authentication
     super
 
@@ -148,8 +137,7 @@ class Auth::SessionsController < Devise::SessionsController
 
     clear_attempt_from_session
 
-    user.update_sign_in!(request, new_sign_in: true)
-    remember_me(user)
+    user.update_sign_in!(new_sign_in: true)
     sign_in(user)
     flash.delete(:notice)