diff --git a/enterprise/app/controllers/enterprise/devise_overrides/passwords_controller.rb b/enterprise/app/controllers/enterprise/devise_overrides/passwords_controller.rb index e2bbb8cb6..d84ac1d71 100644 --- a/enterprise/app/controllers/enterprise/devise_overrides/passwords_controller.rb +++ b/enterprise/app/controllers/enterprise/devise_overrides/passwords_controller.rb @@ -1,19 +1,24 @@ module Enterprise::DeviseOverrides::PasswordsController def create - check_saml_user + if saml_user_attempting_password_reset? + render json: { + success: false, + errors: [I18n.t('messages.reset_password_saml_user')] + }, status: :forbidden + return + end + super - rescue CustomExceptions::Base => e - build_response(e.message, e.http_status_code) end private - def check_saml_user - return if params[:email].blank? + def saml_user_attempting_password_reset? + return false if params[:email].blank? user = User.from_email(params[:email]) - return unless user&.provider == 'saml' + return false unless user&.provider == 'saml' - raise CustomExceptions::Base.new(I18n.t('messages.reset_password_saml_user'), :forbidden) + true end end diff --git a/spec/enterprise/controllers/enterprise/devise_overrides/passwords_controller_spec.rb b/spec/enterprise/controllers/enterprise/devise_overrides/passwords_controller_spec.rb new file mode 100644 index 000000000..23b498be8 --- /dev/null +++ b/spec/enterprise/controllers/enterprise/devise_overrides/passwords_controller_spec.rb @@ -0,0 +1,36 @@ +require 'rails_helper' + +RSpec.describe 'Enterprise Passwords Controller', type: :request do + let!(:account) { create(:account) } + + describe 'POST /auth/password' do + context 'with SAML user email' do + let!(:saml_user) { create(:user, email: 'saml@example.com', provider: 'saml', account: account) } + + it 'prevents password reset and returns forbidden with custom error message' do + params = { email: saml_user.email, redirect_url: 'http://test.host' } + + post user_password_path, params: params, as: :json + + expect(response).to have_http_status(:forbidden) + json_response = JSON.parse(response.body) + expect(json_response['success']).to be(false) + expect(json_response['errors']).to include(I18n.t('messages.reset_password_saml_user')) + end + end + + context 'with non-SAML user email' do + let!(:regular_user) { create(:user, email: 'regular@example.com', provider: 'email', account: account) } + + it 'allows password reset for non-SAML users' do + params = { email: regular_user.email, redirect_url: 'http://test.host' } + + post user_password_path, params: params, as: :json + + expect(response).to have_http_status(:ok) + json_response = JSON.parse(response.body) + expect(json_response['message']).to be_present + end + end + end +end