From d22ac7d346a700fce6466cad97a8943c383f8372 Mon Sep 17 00:00:00 2001 From: Jeremy Evans Date: Sat, 16 Nov 2024 17:25:16 -0800 Subject: [PATCH] Add normalize_login configuration method for normalizing submitted login parameters This returns the submitted value by default, but allows for user provided normalization. --- CHANGELOG | 2 ++ doc/base.rdoc | 1 + lib/rodauth/features/base.rb | 10 ++++++++++ lib/rodauth/features/change_login.rb | 2 +- lib/rodauth/features/create_account.rb | 2 +- lib/rodauth/features/email_auth.rb | 2 +- lib/rodauth/features/internal_request.rb | 8 ++++---- lib/rodauth/features/lockout.rb | 2 +- lib/rodauth/features/login.rb | 2 +- lib/rodauth/features/reset_password.rb | 2 +- lib/rodauth/features/verify_account.rb | 4 ++-- lib/rodauth/features/webauthn_login.rb | 2 +- 12 files changed, 26 insertions(+), 13 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index ad744ac3..4d5eae47 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,7 @@ === master +* Add normalize_login configuration method for normalizing submitted login parameters (jeremyevans) (#451) + * Add login_confirmation_matches? configuration method to allow for case-sensitive login confirmation (jeremyevans) (#451) * Perform a case-insensitive login confirmation by default (jeremyevans) (#451) diff --git a/doc/base.rdoc b/doc/base.rdoc index 10cb5b6d..f4c664de 100644 --- a/doc/base.rdoc +++ b/doc/base.rdoc @@ -105,6 +105,7 @@ csrf_tag(path=request.path) :: The HTML fragment containing the CSRF tag to use, function_name(name) :: The name of the database function to call. It's passed either :rodauth_get_salt or :rodauth_valid_password_hash. logged_in? :: Whether the current session is logged in. login_required :: Action to take when a login is required to access the page and the user is not logged in. +normalize_login(login) :: How to normalize the submitted login parameter value, returns the argument by default. null_byte_parameter_value(key, value) :: The value to use for the parameter if the parameter includes an ASCII NUL byte ("\0"), nil by default to ignore the parameter. open_account? :: Whether the current account is an open account (not closed or unverified). over_max_bytesize_param_value(key, value) :: The value to use for the parameter if the parameter is over the maximum allowed bytesize, nil by default to ignore the parameter. diff --git a/lib/rodauth/features/base.rb b/lib/rodauth/features/base.rb index 41c895d5..bb74e367 100644 --- a/lib/rodauth/features/base.rb +++ b/lib/rodauth/features/base.rb @@ -98,6 +98,7 @@ module Rodauth :inputmode_for_field?, :logged_in?, :login_required, + :normalize_login, :null_byte_parameter_value, :open_account?, :over_max_bytesize_param_value, @@ -505,6 +506,15 @@ def over_max_bytesize_param_value(key, value) nil end + # The normalized value of the login parameter + def login_param_value + normalize_login(param(login_param)) + end + + def normalize_login(login) + login + end + # Return nil by default for values with null bytes def null_byte_parameter_value(key, value) nil diff --git a/lib/rodauth/features/change_login.rb b/lib/rodauth/features/change_login.rb index c07dafd1..a8069ea2 100644 --- a/lib/rodauth/features/change_login.rb +++ b/lib/rodauth/features/change_login.rb @@ -36,7 +36,7 @@ module Rodauth throw_error_reason(:invalid_password, invalid_password_error_status, password_param, invalid_password_message) end - login = param(login_param) + login = login_param_value unless login_meets_requirements?(login) throw_error_status(invalid_field_error_status, login_param, login_does_not_meet_requirements_message) end diff --git a/lib/rodauth/features/create_account.rb b/lib/rodauth/features/create_account.rb index 5236ba4b..e8cf76cc 100644 --- a/lib/rodauth/features/create_account.rb +++ b/lib/rodauth/features/create_account.rb @@ -40,7 +40,7 @@ module Rodauth end r.post do - login = param(login_param) + login = login_param_value password = param(password_param) new_account(login) diff --git a/lib/rodauth/features/email_auth.rb b/lib/rodauth/features/email_auth.rb index a2c8f018..46b5f518 100644 --- a/lib/rodauth/features/email_auth.rb +++ b/lib/rodauth/features/email_auth.rb @@ -56,7 +56,7 @@ module Rodauth before_email_auth_request_route r.post do - if account_from_login(param(login_param)) && open_account? + if account_from_login(login_param_value) && open_account? _email_auth_request end diff --git a/lib/rodauth/features/internal_request.rb b/lib/rodauth/features/internal_request.rb index e2a92471..c7224a0d 100644 --- a/lib/rodauth/features/internal_request.rb +++ b/lib/rodauth/features/internal_request.rb @@ -223,14 +223,14 @@ def _handle_internal_request_eval(_) end def _handle_account_id_for_login(_) - raise InternalRequestError, "no login provided" unless login = param_or_nil(login_param) - raise InternalRequestError, "no account for login" unless account = account_from_login(login) + raise InternalRequestError, "no login provided" unless param_or_nil(login_param) + raise InternalRequestError, "no account for login" unless account = account_from_login(login_param_value) _return_from_internal_request(account[account_id_column]) end def _handle_account_exists?(_) - raise InternalRequestError, "no login provided" unless login = param_or_nil(login_param) - _return_from_internal_request(!!account_from_login(login)) + raise InternalRequestError, "no login provided" unless param_or_nil(login_param) + _return_from_internal_request(!!account_from_login(login_param_value)) end def _handle_lock_account(_) diff --git a/lib/rodauth/features/lockout.rb b/lib/rodauth/features/lockout.rb index d09db59f..9c89dc10 100644 --- a/lib/rodauth/features/lockout.rb +++ b/lib/rodauth/features/lockout.rb @@ -70,7 +70,7 @@ module Rodauth before_unlock_account_request_route r.post do - if account_from_login(param(login_param)) && get_unlock_account_key + if account_from_login(login_param_value) && get_unlock_account_key if unlock_account_email_recently_sent? set_redirect_error_flash unlock_account_email_recently_sent_error_flash redirect unlock_account_email_recently_sent_redirect diff --git a/lib/rodauth/features/login.rb b/lib/rodauth/features/login.rb index 1e250ab2..2236a560 100644 --- a/lib/rodauth/features/login.rb +++ b/lib/rodauth/features/login.rb @@ -45,7 +45,7 @@ module Rodauth view = :login_view catch_error do - unless account_from_login(param(login_param)) + unless account_from_login(login_param_value) throw_error_reason(:no_matching_login, no_matching_login_error_status, login_param, no_matching_login_message) end diff --git a/lib/rodauth/features/reset_password.rb b/lib/rodauth/features/reset_password.rb index 31d4e2d1..cabea529 100644 --- a/lib/rodauth/features/reset_password.rb +++ b/lib/rodauth/features/reset_password.rb @@ -69,7 +69,7 @@ module Rodauth r.post do catch_error do - unless account_from_login(param(login_param)) + unless account_from_login(login_param_value) throw_error_reason(:no_matching_login, no_matching_login_error_status, login_param, no_matching_login_message) end diff --git a/lib/rodauth/features/verify_account.rb b/lib/rodauth/features/verify_account.rb index 73067c73..a27b857a 100644 --- a/lib/rodauth/features/verify_account.rb +++ b/lib/rodauth/features/verify_account.rb @@ -71,7 +71,7 @@ module Rodauth end r.post do - if account_from_login(param(login_param)) && allow_resending_verify_account_email? + if account_from_login(login_param_value) && allow_resending_verify_account_email? if verify_account_email_recently_sent? set_redirect_error_flash verify_account_email_recently_sent_error_flash redirect verify_account_email_recently_sent_redirect @@ -244,7 +244,7 @@ def setup_account_verification def _login_form_footer_links links = super - if !param_or_nil(login_param) || ((account || account_from_login(param(login_param))) && allow_resending_verify_account_email?) + if !param_or_nil(login_param) || ((account || account_from_login(login_param_value)) && allow_resending_verify_account_email?) links << [30, verify_account_resend_path, verify_account_resend_link_text] end links diff --git a/lib/rodauth/features/webauthn_login.rb b/lib/rodauth/features/webauthn_login.rb index 26353aa3..6d8a0986 100644 --- a/lib/rodauth/features/webauthn_login.rb +++ b/lib/rodauth/features/webauthn_login.rb @@ -74,7 +74,7 @@ def webauthn_login_verification_factor?(webauthn_credential) end def account_from_webauthn_login - account_from_login(param(login_param)) + account_from_login(login_param_value) end def webauthn_login_options?