diff --git a/app/services/saml_request_validator.rb b/app/services/saml_request_validator.rb index d055f00c766..3364854d94e 100644 --- a/app/services/saml_request_validator.rb +++ b/app/services/saml_request_validator.rb @@ -3,8 +3,9 @@ class SamlRequestValidator include ActiveModel::Model - validate :cert_exists + validate :request_cert_exists validate :authorized_service_provider + validate :registered_cert_exists validate :authorized_authn_context validate :parsable_vtr validate :authorized_email_nameid_format @@ -72,7 +73,18 @@ def parsable_vtr end end - def cert_exists + def registered_cert_exists + # if there is no service provider, this error has already been added + return if service_provider.blank? + return if service_provider.certs.present? + + errors.add( + :service_provider, :no_cert_registered, + type: :no_cert_registered + ) + end + + def request_cert_exists if @blank_cert errors.add(:service_provider, :blank_cert_element_req, type: :blank_cert_element_req) end diff --git a/config/locales/en.yml b/config/locales/en.yml index 7593fbd2ff2..2080c957568 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -765,6 +765,7 @@ errors.messages.invalid_recaptcha_token: We’re sorry, but your computer or net errors.messages.invalid_sms_number: The phone number entered doesn’t support text messaging. Try the Phone call option. errors.messages.invalid_voice_number: Invalid phone number. Check that you’ve entered the correct country code or area code. errors.messages.missing_field: Please fill in this field. +errors.messages.no_cert_registered: Your service provider does not have a certificate registered. errors.messages.no_pending_profile: No profile is waiting for verification errors.messages.not_a_number: is not a number errors.messages.otp_format: Enter your entire one-time code without spaces or special characters diff --git a/config/locales/es.yml b/config/locales/es.yml index baffc5ec289..054aee76076 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -776,6 +776,7 @@ errors.messages.invalid_recaptcha_token: Lo sentimos, pero es posible que tu com errors.messages.invalid_sms_number: El número de teléfono ingresado no admite mensajes de texto. Intente la opción de llamada telefónica. errors.messages.invalid_voice_number: Número de teléfono no válido. Verifique haber ingresado el código de país o de área correcto. errors.messages.missing_field: Llene este campo. +errors.messages.no_cert_registered: No podemos detectar un certificado en su solicitud. errors.messages.no_pending_profile: No hay ningún perfil en espera de verificación errors.messages.not_a_number: no es un número errors.messages.otp_format: Ingrese su código de un solo uso completo, sin espacios ni caracteres especiales. diff --git a/config/locales/fr.yml b/config/locales/fr.yml index dc2ae99a5ed..3c1c53bd8a2 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -765,6 +765,7 @@ errors.messages.invalid_recaptcha_token: Désolé, il est possible que votre ord errors.messages.invalid_sms_number: Le numéro de téléphone saisi ne prend pas en charge les messages texte. Veuillez essayer l’option d’appel téléphonique. errors.messages.invalid_voice_number: Numéro de téléphone non valide. Vérifiez que vous avez entré le bon indicatif international ou régional. errors.messages.missing_field: Veuillez remplir ce champ. +errors.messages.no_cert_registered: Nous ne pouvons pas détecter un certificat sur votre demande. errors.messages.no_pending_profile: Aucun profil en attente de vérification errors.messages.not_a_number: n’est pas un chiffre errors.messages.otp_format: Saisissez l’intégralité de votre code à usage unique sans espaces ni caractères spéciaux diff --git a/config/locales/zh.yml b/config/locales/zh.yml index ea75d8f839a..d6068d37407 100644 --- a/config/locales/zh.yml +++ b/config/locales/zh.yml @@ -776,6 +776,7 @@ errors.messages.invalid_recaptcha_token: 你必须完成预防滥发邮件测验 errors.messages.invalid_sms_number: 输入的电话号码不支持短信。尝试接听电话选项。 errors.messages.invalid_voice_number: 电话号码有误。检查一下你是否输入了正确的国家代码或区域代码。 errors.messages.missing_field: 请填写这一字段。 +errors.messages.no_cert_registered: 我们在你的请求中探查不到证书。 errors.messages.no_pending_profile: 没有等待验证的用户资料 errors.messages.not_a_number: 不是数字 errors.messages.otp_format: 输入你完整的一次性代码(没有空白或特殊字符) diff --git a/spec/controllers/saml_idp_controller_spec.rb b/spec/controllers/saml_idp_controller_spec.rb index c2f6cacea8d..b5ad4de18da 100644 --- a/spec/controllers/saml_idp_controller_spec.rb +++ b/spec/controllers/saml_idp_controller_spec.rb @@ -1334,6 +1334,39 @@ def name_id_version(format_urn) end end + context 'when service provider has no certs' do + let(:service_provider) do + create( + :service_provider, + certs: [], + active: true, + ) + end + + let(:settings) do + saml_settings.tap do |settings| + settings.issuer = service_provider.issuer + end + end + + it 'returns an error page' do + user = create(:user, :fully_registered) + stub_analytics + + generate_saml_response(user, settings) + + expect(response.body).to include(t('errors.messages.no_cert_registered')) + expect(@analytics).to have_logged_event( + 'SAML Auth', + hash_including( + success: false, + errors: { service_provider: [t('errors.messages.no_cert_registered')] }, + error_details: { service_provider: { no_cert_registered: true } }, + ), + ) + end + end + context 'service provider has multiple certs' do let(:service_provider) do create( diff --git a/spec/services/saml_request_validator_spec.rb b/spec/services/saml_request_validator_spec.rb index bf530ff771d..c6c3e512a7a 100644 --- a/spec/services/saml_request_validator_spec.rb +++ b/spec/services/saml_request_validator_spec.rb @@ -49,6 +49,29 @@ end end + context 'when the sp has no certs registered' do + before { sp.update!(certs: nil) } + let(:errors) do + { + service_provider: [t('errors.messages.no_cert_registered')], + } + end + let(:error_details) do + { + service_provider: { + no_cert_registered: true, + }, + } + end + + it 'returns an error' do + expect(response.to_h).to include( + errors:, + error_details:, + ) + end + end + context 'ialmax authncontext and ialmax provider' do let(:authn_context) { [Saml::Idp::Constants::IALMAX_AUTHN_CONTEXT_CLASSREF] }