From 732d05c26ffc62e1eb63c814c0c94966a51ea2b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Lled=C3=B3?= Date: Thu, 5 Feb 2026 09:59:17 +0100 Subject: [PATCH 01/19] Remove strong passwords setting --- app/controllers/admin/api/settings_controller.rb | 6 +++--- app/models/user.rb | 8 -------- app/representers/settings_representer.rb | 1 - app/views/sites/usage_rules/edit.html.slim | 4 ---- config/locales/en.yml | 2 -- doc/active_docs/account_management_api.json | 4 ---- 6 files changed, 3 insertions(+), 22 deletions(-) diff --git a/app/controllers/admin/api/settings_controller.rb b/app/controllers/admin/api/settings_controller.rb index a90b2d3e3e..21a6149e10 100644 --- a/app/controllers/admin/api/settings_controller.rb +++ b/app/controllers/admin/api/settings_controller.rb @@ -12,9 +12,9 @@ class Admin::Api::SettingsController < Admin::Api::BaseController before_action :validate_enforcing_sso_allowed, only: [:update] ALLOWED_PARAMS = %i[ - useraccountarea_enabled hide_service signups_enabled account_approval_required strong_passwords_enabled - public_search account_plans_ui_visible change_account_plan_permission service_plans_ui_visible - change_service_plan_permission enforce_sso + useraccountarea_enabled hide_service signups_enabled account_approval_required public_search + account_plans_ui_visible change_account_plan_permission service_plans_ui_visible change_service_plan_permission + enforce_sso ].freeze # Settings Read diff --git a/app/models/user.rb b/app/models/user.rb index ed6e1fe2e6..20ba4e784d 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -344,14 +344,6 @@ def provider_id_for_audits account.try!(:provider_id_for_audits) || provider_account.try!(:provider_id_for_audits) end - def provider_requires_strong_passwords? - # use fields definitons source (instance variable) as backup when creating new record - # and there is no provider account (its still new record and not set through association.build) - if source = fields_definitions_source_root - source.settings.strong_passwords_enabled? - end - end - protected def account_for_sphinx diff --git a/app/representers/settings_representer.rb b/app/representers/settings_representer.rb index c16ab4ee4f..20b078e569 100644 --- a/app/representers/settings_representer.rb +++ b/app/representers/settings_representer.rb @@ -9,7 +9,6 @@ module SettingsRepresenter property :hide_service property :signups_enabled property :account_approval_required - property :strong_passwords_enabled property :public_search property :account_plans_ui_visible property :change_account_plan_permission diff --git a/app/views/sites/usage_rules/edit.html.slim b/app/views/sites/usage_rules/edit.html.slim index f8a9145ad2..7ffe223eb2 100644 --- a/app/views/sites/usage_rules/edit.html.slim +++ b/app/views/sites/usage_rules/edit.html.slim @@ -27,10 +27,6 @@ div class="pf-c-card" input_html: { disabled: settings.approval_required_disabled? }, hint: account_approval_required_hint(current_account) - = form.inputs 'Users' - = form.input :strong_passwords_enabled, as: :patternfly_checkbox, - hint: t("formtastic.hints.settings.strong_passwords_enabled", strong_password_definition: strong_password_definition) - = form.inputs 'Search' = form.input :public_search, as: :patternfly_checkbox diff --git a/config/locales/en.yml b/config/locales/en.yml index 97033e219b..f2091c2b7e 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -2216,7 +2216,6 @@ en: approval_required_referer: "Set per account plan from %{link}." account_approval_required: "Approval is required by you before developer accounts are activated." useraccountarea_enabled: 'Only disable this if you provide another way to manage this information (e.g. via the User Management API).' - strong_passwords_enabled: "Require strong passwords from your users: %{strong_password_definition} Existing passwords will still work." public_search: > Allow anyone to search on your Developer Portal. If you have Restricted Pages your Developer Portal we advise you not to change this setting. @@ -2356,7 +2355,6 @@ en: hide_service: 'Used a default service plan' signups_enabled: 'Developers are allowed sign up themselves' cas_server_url: 'CAS Server URL' - strong_passwords_enabled: 'Strong passwords' public_search: 'Enable public search on Developer Portal' cms_escape_draft_html: 'Use Automatic Escaping for draft content' cms_escape_published_html: 'Use Automatic Escaping for published content' diff --git a/doc/active_docs/account_management_api.json b/doc/active_docs/account_management_api.json index d8c0c7a296..625f7a29ee 100644 --- a/doc/active_docs/account_management_api.json +++ b/doc/active_docs/account_management_api.json @@ -9973,10 +9973,6 @@ "type": "boolean", "description": "Approval is required by you before developer accounts are activated." }, - "strong_passwords_enabled": { - "type": "boolean", - "description": "Require strong passwords from your users: Password must be at least 8 characters long, and contain both upper and lowercase letters, a digit and one special character of -+=><_$#.:;!?@&*()~][}{|. Existing passwords will still work. " - }, "public_search": { "type": "boolean", "description": "Enables public search on Developer Portal" From f1ddee2eee5775b0a5fa3f263c1fad96b9512879 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Lled=C3=B3?= Date: Thu, 5 Feb 2026 10:22:39 +0100 Subject: [PATCH 02/19] Add strong passwords setting to `settings.yml` --- config/examples/settings.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/examples/settings.yml b/config/examples/settings.yml index 83cfbdcc78..25be6d8a51 100644 --- a/config/examples/settings.yml +++ b/config/examples/settings.yml @@ -53,6 +53,7 @@ development: force_ssl: false report_traffic: false secure_cookie: false + strong_passwords_disabled: true test: <<: *default @@ -61,6 +62,7 @@ test: readonly_custom_domains_settings: true report_traffic: false secure_cookie: false + strong_passwords_disabled: true production: <<: *default From 0eb58cc781a9704fee5ea58a80e4afc01024b551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Lled=C3=B3?= Date: Thu, 5 Feb 2026 09:44:38 +0100 Subject: [PATCH 03/19] Make strong passwords mandatory --- app/lib/authentication/by_password.rb | 36 +++++++++---------- lib/developer_portal/lib/liquid/drops/user.rb | 2 +- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/app/lib/authentication/by_password.rb b/app/lib/authentication/by_password.rb index b919170f7b..25f19230ec 100644 --- a/app/lib/authentication/by_password.rb +++ b/app/lib/authentication/by_password.rb @@ -4,31 +4,22 @@ module ByPassword extend ActiveSupport::Concern # strong passwords - SPECIAL_CHARACTERS = '-+=><_$#.:;!?@&*()~][}{|' - RE_STRONG_PASSWORD = / - \A - (?=.*\d) # number - (?=.*[a-z]) # lowercase - (?=.*[A-Z]) # uppercase - (?=.*[#{Regexp.escape(SPECIAL_CHARACTERS)}]) # special char - (?!.*\s) # does not end with space - .{8,} # at least 8 characters - \z - /x - STRONG_PASSWORD_FAIL_MSG = "Password must be at least 8 characters long, and contain both upper and lowercase letters, a digit and one special character of #{SPECIAL_CHARACTERS}.".freeze + STRONG_PASSWORD_MIN_SIZE = 16 + # All printable characters in ASCII, from 'space' (32) to ~ (126) + # at least STRONG_PASSWORD_MIN_SIZE characters + RE_STRONG_PASSWORD = /\A[ -~]{#{STRONG_PASSWORD_MIN_SIZE},64}\z/ + STRONG_PASSWORD_FAIL_MSG = "Password must be at least #{STRONG_PASSWORD_MIN_SIZE} characters long, and contain only valid characters.".freeze included do # We only need length validations as they are already set in Authentication::ByPassword has_secure_password validations: false - validates_presence_of :password, if: :password_required? + validates_presence_of :password, if: :validate_password? validates_confirmation_of :password, allow_blank: true validates :password, format: { :with => RE_STRONG_PASSWORD, :message => STRONG_PASSWORD_FAIL_MSG, - if: -> { password_required? && provider_requires_strong_passwords? } } - validates :password, length: { minimum: 6, allow_blank: true, - if: -> { password_required? && !provider_requires_strong_passwords? } } + if: -> { validate_strong_password? } } validates :lost_password_token, :password_digest, length: { maximum: 255 } @@ -45,8 +36,15 @@ def find_with_valid_password_token(token) end end - def password_required? - signup.by_user? && (password_digest.blank? || password_digest_changed?) + def validate_password? + password_digest_changed? || (signup.by_user? && password_digest.blank?) + end + + def validate_strong_password? + return false if Rails.configuration.three_scale.strong_passwords_disabled + return false if signup.sample_data? + + validate_password? end def just_changed_password? @@ -82,7 +80,7 @@ def update_password(new_password, new_password_confirmation) end def using_password? - password_digest.present? + password_digest_in_database.present? end def can_set_password? diff --git a/lib/developer_portal/lib/liquid/drops/user.rb b/lib/developer_portal/lib/liquid/drops/user.rb index 6ca03850fb..997dc11a8c 100644 --- a/lib/developer_portal/lib/liquid/drops/user.rb +++ b/lib/developer_portal/lib/liquid/drops/user.rb @@ -109,7 +109,7 @@ def using_password? {{ endif }} } def password_required? - @user.password_required? + @user.signup.by_user? end desc "Returns the list of sections the user has access to." From 3eb95d5d9100aeb47c3e483a065832cb9fb642c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Lled=C3=B3?= Date: Thu, 5 Feb 2026 10:38:50 +0100 Subject: [PATCH 04/19] Fix UI problems in admin portal: - Validate strong passwords in React forms - Some forms treat the password field as clear text. - Make password fields required only when they are actually required. - `Current password` field visible and required only when it should. - Password can be set for all users, no matter how did they signup. - SSO Users: don't see the toast to change password. It can be changed from the same form This fixes https://issues.redhat.com/browse/THREESCALE-11548 - When enforce SSO is enabled, passwords can still be set or changed. --- app/javascript/src/Login/utils/validations.ts | 9 ++++++++- app/views/buyers/accounts/new.html.erb | 2 +- app/views/buyers/users/edit.html.erb | 4 ++-- .../admin/account/users/_form.html.erb | 4 ++-- .../admin/user/personal_details/edit.html.slim | 18 +++++------------- config/locales/en.yml | 3 +-- 6 files changed, 19 insertions(+), 21 deletions(-) diff --git a/app/javascript/src/Login/utils/validations.ts b/app/javascript/src/Login/utils/validations.ts index b098d82f7a..949ee32302 100644 --- a/app/javascript/src/Login/utils/validations.ts +++ b/app/javascript/src/Login/utils/validations.ts @@ -1,5 +1,12 @@ import validate from 'validate.js' +// IMPORTANT: These STRONG_PASSWORD_* constants are duplicated from the backend. +// The source of truth is app/lib/authentication/by_password.rb. If those constants change in Ruby, +// you must update them here as well. Do not modify these without updating the backend first. +const STRONG_PASSWORD_MIN_SIZE = 16 +const RE_STRONG_PASSWORD = new RegExp(`^[ -~]{${STRONG_PASSWORD_MIN_SIZE},64}$`) +const STRONG_PASSWORD_FAIL_MSG = `Password must be at least ${STRONG_PASSWORD_MIN_SIZE} characters long, and contain only valid characters.` + const loginConstraints = { username: { presence: { allowEmpty: false, message: 'Email or username is mandatory' } }, password: { presence: { allowEmpty: false, message: 'Password is mandatory' } } @@ -12,7 +19,7 @@ function validateLogin (fields: Record): const changePasswordConstraints = { password: { presence: { allowEmpty: false, message: 'Password is mandatory' }, - length: { minimum: 6 } + format: { pattern: RE_STRONG_PASSWORD, message: STRONG_PASSWORD_FAIL_MSG } }, passwordConfirmation: { presence: { allowEmpty: false, message: 'Password confirmation is mandatory' }, diff --git a/app/views/buyers/accounts/new.html.erb b/app/views/buyers/accounts/new.html.erb index dd799314cd..ea453297ac 100644 --- a/app/views/buyers/accounts/new.html.erb +++ b/app/views/buyers/accounts/new.html.erb @@ -21,7 +21,7 @@ <%= form.fields_for [:user, @user ] do |user| %> <%= user.user_defined_form %> - <%= user.input :password, as: :patternfly_input, required: true %> + <%= user.input :password, as: :patternfly_input, input_html: { type: 'password' }, required: true %> <% end %> diff --git a/app/views/buyers/users/edit.html.erb b/app/views/buyers/users/edit.html.erb index febbfa54dc..6bfff0e050 100644 --- a/app/views/buyers/users/edit.html.erb +++ b/app/views/buyers/users/edit.html.erb @@ -13,8 +13,8 @@ <% end %> <%= form.inputs :name => "Change Password" do %> - <%= form.input :password, required: true, input_html: { autocomplete: 'off' } %> - <%= form.input :password_confirmation, required: true, input_html: { autocomplete: 'off' } %> + <%= form.input :password, required: false, input_html: { autocomplete: 'off' } %> + <%= form.input :password_confirmation, required: false, input_html: { autocomplete: 'off' } %> <% end -%> <% if can? :update_role, @user %> diff --git a/app/views/provider/admin/account/users/_form.html.erb b/app/views/provider/admin/account/users/_form.html.erb index 8d371e6d9c..09f45e5d50 100644 --- a/app/views/provider/admin/account/users/_form.html.erb +++ b/app/views/provider/admin/account/users/_form.html.erb @@ -3,8 +3,8 @@ <% end %> <%= form.inputs :name => "Change Password" do %> - <%= form.input :password, :required => true %> - <%= form.input :password_confirmation, :required => true %> + <%= form.input :password, :required => false %> + <%= form.input :password_confirmation, :required => false %> <% end -%> <% if can? :update_role, @user %> diff --git a/app/views/provider/admin/user/personal_details/edit.html.slim b/app/views/provider/admin/user/personal_details/edit.html.slim index 2cfa540206..68b3803228 100644 --- a/app/views/provider/admin/user/personal_details/edit.html.slim +++ b/app/views/provider/admin/user/personal_details/edit.html.slim @@ -3,13 +3,6 @@ - content_for :javascripts do = stylesheet_packs_chunks_tag 'pf_form' -- if current_user.can_set_password? && !current_account.settings.enforce_sso? - - content_for :page_header_alert do - br - = pf_inline_alert t('.set_password_html', href: new_provider_password_path), variant: :info - -- using_password = current_user.using_password? - div class="pf-c-card" div class="pf-c-card__body" = semantic_form_for current_user, builder: Fields::PatternflyFormBuilder, @@ -20,13 +13,12 @@ div class="pf-c-card" = form.inputs 'User Information' do = form.user_defined_form - - if using_password - = form.input :password, as: :patternfly_input, - label: t('.new_password_label'), - required: current_user.password_required?, - input_html: { value: '', required: current_user.password_required? } + = form.input :password, as: :patternfly_input, + label: t('.new_password_label'), + required: false, + input_html: { value: '', type: 'password', required: false } - - if using_password + - if current_user.using_password? = form.inputs "Provide your current password and update your personal details" do = form.input :current_password, as: :patternfly_input, required: true, diff --git a/config/locales/en.yml b/config/locales/en.yml index f2091c2b7e..6f4b0f7bae 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -452,7 +452,7 @@ en: invitee_signups: create: - error: There are some errors:\n%{errors} + error: "There are some errors:\n%{errors}" success: Thanks for signing up! You can now sign in already_logged_in: You are already signed up. Log out if you want to sign up again @@ -897,7 +897,6 @@ en: edit: header_title: Personal Details submit_button_label: Update Details - set_password_html: You have no password set. If you'd like to set one use the password reset form. new_password_label: New password update: success: User was successfully updated From c87be43d2c5b63b6e8c9df1f2edbf57e312b0951 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Lled=C3=B3?= Date: Thu, 5 Feb 2026 10:27:46 +0100 Subject: [PATCH 05/19] New signup_type: ``:sample_data` This is to exclude John Doe from strong passwords validation Co-Authored-By: Claude --- app/lib/logic/provider_signup.rb | 2 +- app/lib/signup/developer_account_manager.rb | 2 +- app/lib/signup/result.rb | 2 +- app/models/user.rb | 7 ++++++- app/models/user/states.rb | 4 ++-- 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/app/lib/logic/provider_signup.rb b/app/lib/logic/provider_signup.rb index 6d4aebfb0a..d0061a3e98 100644 --- a/app/lib/logic/provider_signup.rb +++ b/app/lib/logic/provider_signup.rb @@ -64,7 +64,7 @@ def ensure_users(count) def signup_user email_part = email.split('@') user_attributes = { email: "#{email_part[0]}+test@#{email_part[1]}", username: 'john', first_name: 'John', - last_name: 'Doe', password: '123456', password_confirmation: '123456', signup_type: :minimal} + last_name: 'Doe', password: '123456', password_confirmation: '123456', signup_type: :sample_data} signup_params = ::Signup::SignupParams.new(plans: [], user_attributes: user_attributes, account_attributes: { org_name: 'Developer' }) ::Signup::DeveloperAccountManager.new(@provider).create(signup_params) end diff --git a/app/lib/signup/developer_account_manager.rb b/app/lib/signup/developer_account_manager.rb index 9ec9e685e3..216ab6d6b9 100644 --- a/app/lib/signup/developer_account_manager.rb +++ b/app/lib/signup/developer_account_manager.rb @@ -15,7 +15,7 @@ def persist!(result, plans, defaults) # TODO: Temporary here. A new object should have the responsability to activate and approve when needed # As part of THREESCALE-1317 - result.user_activate! if result.user_activate_on_minimal_signup? + result.user_activate! if result.user_activate_on_minimal_or_sample_data? end end end diff --git a/app/lib/signup/result.rb b/app/lib/signup/result.rb index 5955b299d0..b86d62d745 100644 --- a/app/lib/signup/result.rb +++ b/app/lib/signup/result.rb @@ -20,7 +20,7 @@ def local_initialize; end attr_reader :user, :account delegate :approve, :approve!, :approved?, :approval_required?, :make_pending!, to: :account, prefix: true - delegate :activate, :activate!, :active?, :activate_on_minimal_signup?, to: :user, prefix: true + delegate :activate, :activate!, :active?, :activate_on_minimal_or_sample_data?, to: :user, prefix: true delegate :id, to: :account def valid? diff --git a/app/models/user.rb b/app/models/user.rb index 20ba4e784d..29cd3dd4a1 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -428,6 +428,11 @@ def minimal? signup_type == :minimal end + def sample_data? + # This is true only for John Doe + signup_type == :sample_data + end + def api? signup_type == :api end @@ -449,7 +454,7 @@ def cas? end def machine? - minimal? || api? || created_by_provider? || open_id? || cas? || oauth2? + minimal? || sample_data? || api? || created_by_provider? || open_id? || cas? || oauth2? end def by_user? diff --git a/app/models/user/states.rb b/app/models/user/states.rb index 78e8f44d13..115a45050a 100644 --- a/app/models/user/states.rb +++ b/app/models/user/states.rb @@ -75,8 +75,8 @@ def make_activation_code self.activation_code = self.class.make_token end - def activate_on_minimal_signup? - minimal_signup? && password.present? && !account.try!(:bought_account_plan).try!(:approval_required?) + def activate_on_minimal_or_sample_data? + (minimal_signup? || signup.sample_data?) && password.present? && !account.try!(:bought_account_plan).try!(:approval_required?) end def generate_email_verification_token From fbd2a2000972ffda463fd686e08799577de8dd2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Lled=C3=B3?= Date: Thu, 5 Feb 2026 10:24:50 +0100 Subject: [PATCH 06/19] Partners, allow `password` field to be empty --- app/controllers/partners/providers_controller.rb | 2 +- app/controllers/partners/users_controller.rb | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/controllers/partners/providers_controller.rb b/app/controllers/partners/providers_controller.rb index b9a7300d23..74b3bbad5a 100644 --- a/app/controllers/partners/providers_controller.rb +++ b/app/controllers/partners/providers_controller.rb @@ -56,7 +56,7 @@ def account_params def user_params { signup_type: partner.signup_type, - password: permitted_params[:password].presence || SecureRandom.hex, + password: permitted_params[:password].presence, email: permitted_params[:email], first_name: permitted_params[:first_name], last_name: permitted_params[:last_name], diff --git a/app/controllers/partners/users_controller.rb b/app/controllers/partners/users_controller.rb index c404f1a9c1..c140736e89 100644 --- a/app/controllers/partners/users_controller.rb +++ b/app/controllers/partners/users_controller.rb @@ -22,7 +22,7 @@ def destroy def create @user = @account.users.build @user.email = params[:email] - @user.password = SecureRandom.hex + @user.password = params[:password].presence @user.first_name = params[:first_name].presence @user.last_name = params[:last_name].presence @user.open_id = params[:open_id].presence @@ -30,11 +30,11 @@ def create @user.signup_type = :partner @user.role = :admin @user.activate! - if @user.save - render json: {id: @user.id, success: true} - else - render json: {errors: @user.errors, success: false} - end + @user.save! + + render json: {id: @user.id, success: true} + rescue StandardError + render json: {errors: @user.errors, success: false}, status: :unprocessable_entity end private From ff3f13b30d2ef63cb04e21ca3562313be58202da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Lled=C3=B3?= Date: Thu, 5 Feb 2026 10:29:03 +0100 Subject: [PATCH 07/19] Make provider user update accept password from API --- app/controllers/admin/api/buyers_users_controller.rb | 2 +- app/lib/authentication/by_password.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/api/buyers_users_controller.rb b/app/controllers/admin/api/buyers_users_controller.rb index 208841aa97..b8b6c98ad4 100644 --- a/app/controllers/admin/api/buyers_users_controller.rb +++ b/app/controllers/admin/api/buyers_users_controller.rb @@ -37,7 +37,7 @@ def show def update authorize! :update, user - user.update_with_flattened_attributes(flat_params) + user.update_with_flattened_attributes(flat_params, as: current_user.try(:role)) respond_with(user) end diff --git a/app/lib/authentication/by_password.rb b/app/lib/authentication/by_password.rb index 25f19230ec..9054c4c8ac 100644 --- a/app/lib/authentication/by_password.rb +++ b/app/lib/authentication/by_password.rb @@ -23,7 +23,7 @@ module ByPassword validates :lost_password_token, :password_digest, length: { maximum: 255 } - attr_accessible :password, :password_confirmation + attr_accessible :password, :password_confirmation, as: %i[default member admin] scope :with_valid_password_token, -> { where { lost_password_token_generated_at >= 24.hours.ago } } From 35acc2b33d92fb6cc1bccfebf342144bbdbc1e83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Lled=C3=B3?= Date: Thu, 5 Feb 2026 10:54:45 +0100 Subject: [PATCH 08/19] Fix tests Co-Authored-By: Claude --- .gitleaks.toml | 8 + .../old/accounts/personal_details.feature | 5 +- features/old/providers/settings.feature | 11 - features/old/signup/strong_passwords.feature | 27 +- features/old/signup/with_invitation.feature | 6 +- .../admin/account/invitations.feature | 4 +- features/provider/password/reset.feature | 16 +- features/step_definitions/settings_steps.rb | 4 - .../strong_passwords_steps.rb | 5 +- .../Login/components/SignupForm.spec.tsx | 231 ++++++++++-------- .../Login/utils/validations.spec.ts | 34 ++- .../buyers/users_controller_test.rb | 30 +++ .../partners/providers_controller_test.rb | 42 ++++ .../partners/users_controller_test.rb | 63 +++++ .../user/personal_details_controller_test.rb | 102 ++++++++ .../admin/api/buyers_users_controller_test.rb | 29 +++ .../admin/api/settings_controller_test.rb | 1 - .../invitation_signup_test.rb | 4 +- .../developer_portal/signup_test.rb | 43 ++++ .../admin/account/users_controller_test.rb | 18 ++ .../signups_controller_integration_test.rb | 49 ++++ .../user-management-api/users_test.rb | 21 ++ .../by_has_secure_password_test.rb | 12 - test/unit/authentication/by_password_test.rb | 219 +++++++++++++++++ test/unit/liquid/drops/user_drop_test.rb | 28 +++ test/unit/logic/provider_signup_test.rb | 46 ++++ test/unit/signup/account_manager_test.rb | 12 +- test/unit/user/signup_type_test.rb | 22 +- test/unit/user/states_test.rb | 41 ++++ test/unit/user_test.rb | 118 --------- 30 files changed, 970 insertions(+), 281 deletions(-) create mode 100644 .gitleaks.toml delete mode 100644 test/unit/authentication/by_has_secure_password_test.rb create mode 100644 test/unit/authentication/by_password_test.rb create mode 100644 test/unit/logic/provider_signup_test.rb diff --git a/.gitleaks.toml b/.gitleaks.toml new file mode 100644 index 0000000000..73eed77c41 --- /dev/null +++ b/.gitleaks.toml @@ -0,0 +1,8 @@ +[allowlist] +description = "Global Allowlist" + +# Ignore based on any subset of the file path +paths = [ + '''test/unit/authentication/by_password_test.rb''', + '''test/integration/admin/api/buyers_users_controller_test.rb''' +] diff --git a/features/old/accounts/personal_details.feature b/features/old/accounts/personal_details.feature index 00ed55a992..d78530bfdc 100644 --- a/features/old/accounts/personal_details.feature +++ b/features/old/accounts/personal_details.feature @@ -81,10 +81,11 @@ Feature: Personal Details And the "User extra required" field should contain "whatever" Scenario: Update own password when the user was signed up with password - Given the user was signed up with password + Given Strong passwords are enabled + And the user was signed up with password When I navigate to the Account Settings And I go to the provider personal details page And I fill in "New password" with "hi" And I fill in "Current password" with "supersecret" And I press "Update Details" - Then field "New password" has inline error "is too short (minimum is 6 characters)" + Then field "New password" has inline error "Password must be at least 16 characters long, and contain only valid characters" diff --git a/features/old/providers/settings.feature b/features/old/providers/settings.feature index f5e4b27d17..97eabc9c84 100644 --- a/features/old/providers/settings.feature +++ b/features/old/providers/settings.feature @@ -7,17 +7,6 @@ Feature: Settings management Background: Given a provider is logged in - Scenario: Strong password setting - And I go to the usage rules settings page - When I check "Strong passwords" - And I press "Update settings" - Then they should see a toast alert with text "Settings updated" - And the provider should have strong passwords enabled - When I uncheck "Strong passwords" - And I press "Update settings" - Then they should see a toast alert with text "Settings updated" - And the provider should have strong passwords disabled - Scenario: Account approval required checkbox is enabled Given the provider has 1 account plan When I go to the usage rules settings page diff --git a/features/old/signup/strong_passwords.feature b/features/old/signup/strong_passwords.feature index 35c09bd04a..9615cbeef4 100644 --- a/features/old/signup/strong_passwords.feature +++ b/features/old/signup/strong_passwords.feature @@ -13,7 +13,7 @@ Feature: Signup with strong passwords Scenario: Strong password is required - Given provider "foo.3scale.localhost" is requiring strong passwords + Given Strong passwords are enabled When I go to the sign up page And I fill in the following: | Email | bender@planet.ex | @@ -24,3 +24,28 @@ Feature: Signup with strong passwords And I press "Sign up" Then I should see the error that the password is too weak + + Scenario: Strong password is accepted + Given Strong passwords are enabled + When I go to the sign up page + And I fill in the following: + | Email | bender@planet.ex | + | Username | bender | + | Password | superSecret1234# | + | Password confirmation | superSecret1234# | + | Organization/Group Name | Planet eXpress | + + And I press "Sign up" + Then I should see "Thank you" + + Scenario: Weak password is accepted when strong passwords are disabled + When I go to the sign up page + And I fill in the following: + | Email | bender@planet.ex | + | Username | bender | + | Password | weakpwd | + | Password confirmation | weakpwd | + | Organization/Group Name | Planet eXpress | + + And I press "Sign up" + Then I should see "Thank you" diff --git a/features/old/signup/with_invitation.feature b/features/old/signup/with_invitation.feature index 85e52c1379..3674dd73cb 100644 --- a/features/old/signup/with_invitation.feature +++ b/features/old/signup/with_invitation.feature @@ -22,13 +22,13 @@ Feature: Signup with invitation When I fill in "Username" with "bob" And I fill in "First name" with "bob" And I fill in "Last name" with "dole" - And I fill in "Password" with "monkey" - And I fill in "Password confirmation" with "monkey" + And I fill in "Password" with "superSecret1234#" + And I fill in "Password confirmation" with "superSecret1234#" And I press "Sign up" Then I should see "Thanks for signing up! You can now sign in" And the current domain should be the admin domain of provider "foo.3scale.localhost" But "bob@foo.3scale.localhost" should receive no email with subject "Account Activation" When I fill in "Username" with "bob" - And I fill in "Password" with "monkey" + And I fill in "Password" with "superSecret1234#" And I press "Sign in" Then I should be logged in as "bob" diff --git a/features/provider/admin/account/invitations.feature b/features/provider/admin/account/invitations.feature index 3ee1e04f9c..58b807251d 100644 --- a/features/provider/admin/account/invitations.feature +++ b/features/provider/admin/account/invitations.feature @@ -82,8 +82,8 @@ Feature: Provider Account Settings User Invitations And the form is submitted with: | Email | peter@example.com | | Username | peter | - | Password | 123456 | - | Password confirmation | 123456 | + | Password | superSecret1234# | + | Password confirmation | superSecret1234# | And they log out When the provider logs in And they go to the provider users page diff --git a/features/provider/password/reset.feature b/features/provider/password/reset.feature index 50b06abb17..4674f7bdb8 100644 --- a/features/provider/password/reset.feature +++ b/features/provider/password/reset.feature @@ -51,22 +51,22 @@ Feature: Provider password reset Scenario: Set a new password Given the user has requested a new password And follow the link found in the provider password reset email send to "pepe@example.com" - And they fill in "Password" with "monkey" - And they fill in "Password confirmation" with "monkey" + And they fill in "Password" with "superSecret1234#" + And they fill in "Password confirmation" with "superSecret1234#" And press "Change Password" Then they should see "The password has been changed" And the current page is the provider login page - And the user is now able to sign in with password "monkey" + And the user is now able to sign in with password "superSecret1234#" Scenario: New password form validation Given the user has requested a new password And follow the link found in the provider password reset email send to "pepe@example.com" - And they fill in "Password" with "monkey" + And they fill in "Password" with "superSecret1234#" And they fill in "Password confirmation" with "" Then the submit button is disabled - When they fill in "Password confirmation" with "donkey" + When they fill in "Password confirmation" with "superSecret1234#5" Then the submit button is disabled - When they fill in "Password confirmation" with "monkey" + When they fill in "Password confirmation" with "superSecret1234#" Then the submit button is enabled Scenario: Invalid password reset token @@ -83,8 +83,8 @@ Feature: Provider password reset Scenario: Reuse a password reset token Given the user has requested a new password And follow the link found in the provider password reset email send to "pepe@example.com" - And they fill in "Password" with "monkey" - And they fill in "Password confirmation" with "monkey" + And they fill in "Password" with "superSecret1234#" + And they fill in "Password confirmation" with "superSecret1234#" When press "Change Password" Then they should see "The password has been changed" When follow the link found in the provider password reset email send to "pepe@example.com" diff --git a/features/step_definitions/settings_steps.rb b/features/step_definitions/settings_steps.rb index 4ce0328f89..5129c9f923 100644 --- a/features/step_definitions/settings_steps.rb +++ b/features/step_definitions/settings_steps.rb @@ -11,10 +11,6 @@ account.settings.update!(attributes) end -Then "{provider} should have strong passwords {enabled}" do |provider, enabled| - assert provider.settings.reload.strong_passwords_enabled == enabled -end - Given "{provider} has {count} account plan(s)" do |provider, count| current_size = provider.account_plans.size if count > current_size diff --git a/features/step_definitions/strong_passwords_steps.rb b/features/step_definitions/strong_passwords_steps.rb index 651b8b7cc8..0f259c0185 100644 --- a/features/step_definitions/strong_passwords_steps.rb +++ b/features/step_definitions/strong_passwords_steps.rb @@ -1,7 +1,8 @@ # frozen_string_literal: true -Given "{provider} is requiring strong passwords" do |provider| - provider.settings.update_attribute :strong_passwords_enabled, true +# When RAILS_ENV=test, strong passwords are disabled by default +Given "Strong passwords are enabled" do + Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) end Then /^I should see the error that the password is too weak$/ do diff --git a/spec/javascripts/Login/components/SignupForm.spec.tsx b/spec/javascripts/Login/components/SignupForm.spec.tsx index bb53f15617..5ebc3d5d48 100644 --- a/spec/javascripts/Login/components/SignupForm.spec.tsx +++ b/spec/javascripts/Login/components/SignupForm.spec.tsx @@ -18,8 +18,24 @@ const defaultProps: Props = { path: 'bikini-bottom' } +const validPassword = 'superSecret1234#' + const mountWrapper = (props: Partial = {}) => mount() +const fillPasswordFields = (wrapper: ReturnType) => { + act(() => { + wrapper.find('input#user_password').props().onChange!({ + currentTarget: { required: true, name: 'user[password]', value: validPassword, type: 'password' } + } as FormEvent) + }) + + act(() => { + wrapper.find('input#user_password_confirmation').props().onChange!({ + currentTarget: { required: true, name: 'user[password_confirmation]', value: validPassword, type: 'password' } + } as FormEvent) + }) +} + it('should render itself', () => { const wrapper = mountWrapper() expect(wrapper.exists('#signup_form')).toEqual(true) @@ -31,6 +47,17 @@ it('should render six Form Groups', () => { }) describe('validation', () => { + let wrapper: ReturnType + + beforeEach(() => { + wrapper = mountWrapper() + fillPasswordFields(wrapper) + }) + + it('should enable the button when all required fields are valid', () => { + expect(isSubmitDisabled(wrapper)).toEqual(false) + }) + it('should set username and validation state to true', () => { const event = { currentTarget: { @@ -41,9 +68,8 @@ describe('validation', () => { } } as FormEvent - const wrapper = mountWrapper() act(() => { wrapper.find('input#user_username').props().onChange!(event) }) - expect(isSubmitDisabled(wrapper)).toEqual(true) + expect(isSubmitDisabled(wrapper)).toEqual(false) }) it('should set validation state to false when username is invalid', () => { @@ -56,7 +82,6 @@ describe('validation', () => { } } as FormEvent - const wrapper = mountWrapper() act(() => { wrapper.find('input#user_username').props().onChange!(event) }) expect(isSubmitDisabled(wrapper)).toEqual(true) }) @@ -71,9 +96,8 @@ describe('validation', () => { } } as FormEvent - const wrapper = mountWrapper() act(() => { wrapper.find('input#user_email').props().onChange!(event) }) - expect(isSubmitDisabled(wrapper)).toEqual(true) + expect(isSubmitDisabled(wrapper)).toEqual(false) }) it('should set validation state to false when email is invalid', () => { @@ -86,8 +110,7 @@ describe('validation', () => { } } as FormEvent - const wrapper = mountWrapper() - act(() => { wrapper.find('input#user_email').props().onChange!(event) }) + act(() => { wrapper.find('input#user_email').props().onChange!(event) }) expect(isSubmitDisabled(wrapper)).toEqual(true) }) @@ -100,9 +123,8 @@ describe('validation', () => { } } as FormEvent - const wrapper = mountWrapper() act(() => { wrapper.find('input#user_first_name').props().onChange!(event) }) - expect(isSubmitDisabled(wrapper)).toEqual(true) + expect(isSubmitDisabled(wrapper)).toEqual(false) }) it('should have validation state set to true even with no First name', () => { @@ -114,9 +136,8 @@ describe('validation', () => { } } as FormEvent - const wrapper = mountWrapper() act(() => { wrapper.find('input#user_first_name').props().onChange!(event) }) - expect(isSubmitDisabled(wrapper)).toEqual(true) + expect(isSubmitDisabled(wrapper)).toEqual(false) }) it('should set lastname and validation state to true', () => { @@ -128,9 +149,8 @@ describe('validation', () => { } } as FormEvent - const wrapper = mountWrapper() act(() => { wrapper.find('input#user_last_name').props().onChange!(event) }) - expect(isSubmitDisabled(wrapper)).toEqual(true) + expect(isSubmitDisabled(wrapper)).toEqual(false) }) it('should have validation state true even with no Last name', () => { @@ -142,13 +162,36 @@ describe('validation', () => { } } as FormEvent - const wrapper = mountWrapper() - act(() => { wrapper.find('input#user_first_name').props().onChange!(event) }) - expect(isSubmitDisabled(wrapper)).toEqual(true) + act(() => { wrapper.find('input#user_last_name').props().onChange!(event) }) + expect(isSubmitDisabled(wrapper)).toEqual(false) }) it('should set password and validation state to true', () => { - const event = { + const passwordEvent = { + currentTarget: { + required: true, + name: 'user[password]', + value: validPassword, + type: 'password' + } + } as FormEvent + + const confirmationEvent = { + currentTarget: { + required: true, + name: 'user[password_confirmation]', + value: validPassword, + type: 'password' + } + } as FormEvent + + act(() => { wrapper.find('input#user_password').props().onChange!(passwordEvent) }) + act(() => { wrapper.find('input#user_password_confirmation').props().onChange!(confirmationEvent) }) + expect(isSubmitDisabled(wrapper)).toEqual(false) + }) + + it('should set validation state to false when password is weak', () => { + const passwordEvent = { currentTarget: { required: true, name: 'user[password]', @@ -157,13 +200,22 @@ describe('validation', () => { } } as FormEvent - const wrapper = mountWrapper() - act(() => { wrapper.find('input#user_password').props().onChange!(event) }) + const confirmationEvent = { + currentTarget: { + required: true, + name: 'user[password_confirmation]', + value: 'gary1234', + type: 'password' + } + } as FormEvent + + act(() => { wrapper.find('input#user_password').props().onChange!(passwordEvent) }) + act(() => { wrapper.find('input#user_password_confirmation').props().onChange!(confirmationEvent) }) expect(isSubmitDisabled(wrapper)).toEqual(true) }) - it('should set validation state to false when password is invalid', () => { - const event = { + it('should set validation state to false when password is empty', () => { + const passwordEvent = { currentTarget: { required: true, name: 'user[password]', @@ -172,28 +224,55 @@ describe('validation', () => { } } as FormEvent - const wrapper = mountWrapper() - act(() => { wrapper.find('input#user_password').props().onChange!(event) }) + const confirmationEvent = { + currentTarget: { + required: true, + name: 'user[password_confirmation]', + value: '', + type: 'password' + } + } as FormEvent + + act(() => { wrapper.find('input#user_password').props().onChange!(passwordEvent) }) + act(() => { wrapper.find('input#user_password_confirmation').props().onChange!(confirmationEvent) }) expect(isSubmitDisabled(wrapper)).toEqual(true) }) it('should set passwordConfirmation and validation state to true', () => { - const event = { + const passwordEvent = { + currentTarget: { + required: true, + name: 'user[password]', + value: validPassword, + type: 'password' + } + } as FormEvent + + const confirmationEvent = { currentTarget: { required: true, name: 'user[password_confirmation]', - value: 'gary1234', + value: validPassword, type: 'password' } } as FormEvent - const wrapper = mountWrapper() - act(() => { wrapper.find('input#user_password_confirmation').props().onChange!(event) }) - expect(isSubmitDisabled(wrapper)).toEqual(true) + act(() => { wrapper.find('input#user_password').props().onChange!(passwordEvent) }) + act(() => { wrapper.find('input#user_password_confirmation').props().onChange!(confirmationEvent) }) + expect(isSubmitDisabled(wrapper)).toEqual(false) }) - it('should set validation state to false when password confirmation is invalid', () => { - const event = { + it('should set validation state to false when password confirmation is empty', () => { + const passwordEvent = { + currentTarget: { + required: true, + name: 'user[password]', + value: validPassword, + type: 'password' + } + } as FormEvent + + const confirmationEvent = { currentTarget: { required: true, name: 'user[password_confirmation]', @@ -202,83 +281,35 @@ describe('validation', () => { } } as FormEvent - const wrapper = mountWrapper() - act(() => { wrapper.find('input#user_password_confirmation').props().onChange!(event) }) + act(() => { wrapper.find('input#user_password').props().onChange!(passwordEvent) }) + act(() => { wrapper.find('input#user_password_confirmation').props().onChange!(confirmationEvent) }) expect(isSubmitDisabled(wrapper)).toEqual(true) }) - it('should enable the button after filling up required fields', () => { - const wrapper = mountWrapper() - - act(() => { - wrapper.find('input#user_username').props().onChange!({ - currentTarget: { - required: true, - name: 'user[username]', - value: 'Sandy', - type: 'text' - } - } as FormEvent) - }) - expect(isSubmitDisabled(wrapper)).toEqual(true) + it('should set validation state to false when password and confirmation do not match', () => { + const anotherValidPassword = 'anotherSecret1234#' - act(() => { - wrapper.find('input#user_email').props().onChange!({ - currentTarget: { - required: true, - name: 'user[email]', - value: 'bob@sponge.com', - type: 'email' - } - } as FormEvent) - }) - expect(isSubmitDisabled(wrapper)).toEqual(true) - - act(() => { - wrapper.find('input#user_first_name').props().onChange!({ - currentTarget: { - name: 'user[first_name]', - value: '', - type: 'text' - } - } as FormEvent) - }) - expect(isSubmitDisabled(wrapper)).toEqual(true) + const passwordEvent = { + currentTarget: { + required: true, + name: 'user[password]', + value: validPassword, + type: 'password' + } + } as FormEvent - act(() => { - wrapper.find('input#user_first_name').props().onChange!({ - currentTarget: { - name: 'user[last_name]', - value: '', - type: 'text' - } - } as FormEvent) - }) - expect(isSubmitDisabled(wrapper)).toEqual(true) + const confirmationEvent = { + currentTarget: { + required: true, + name: 'user[password_confirmation]', + value: anotherValidPassword, + type: 'password' + } + } as FormEvent - act(() => { - wrapper.find('input#user_password').props().onChange!({ - currentTarget: { - required: true, - name: 'user[password]', - value: 'gary1234', - type: 'password' - } - } as FormEvent) - }) + act(() => { wrapper.find('input#user_password').props().onChange!(passwordEvent) }) + act(() => { wrapper.find('input#user_password_confirmation').props().onChange!(confirmationEvent) }) expect(isSubmitDisabled(wrapper)).toEqual(true) - - act(() => { - wrapper.find('input#user_password_confirmation').props().onChange!({ - currentTarget: { - required: true, - name: 'user[password_confirmation]', - value: 'gary1234', - type: 'password' - } - } as FormEvent) - }) - expect(isSubmitDisabled(wrapper)).toEqual(false) }) }) diff --git a/spec/javascripts/Login/utils/validations.spec.ts b/spec/javascripts/Login/utils/validations.spec.ts index a675c5ee81..ad7a3f38ee 100644 --- a/spec/javascripts/Login/utils/validations.spec.ts +++ b/spec/javascripts/Login/utils/validations.spec.ts @@ -37,23 +37,33 @@ describe('#validateChangePassword', () => { })).not.toBeUndefined() expect(validateChangePassword({ - password: 'aaa', + password: 'aaaaaa', passwordConfirmation: '' })).not.toBeUndefined() expect(validateChangePassword({ password: '', - passwordConfirmation: 'aaa' + passwordConfirmation: 'aaaaaa' })).not.toBeUndefined() expect(validateChangePassword({ - password: 'aaa', - passwordConfirmation: 'aaa' + password: 'aaaaaa', + passwordConfirmation: 'aaaaaa' })).not.toBeUndefined() expect(validateChangePassword({ - password: 'aaaaaa', - passwordConfirmation: 'aaaaaa' + password: 'superSecret1234#', + passwordConfirmation: '' + })).not.toBeUndefined() + + expect(validateChangePassword({ + password: '', + passwordConfirmation: 'superSecret1234#' + })).not.toBeUndefined() + + expect(validateChangePassword({ + password: 'superSecret1234#', + passwordConfirmation: 'superSecret1234#' })).toBeUndefined() }) }) @@ -74,8 +84,8 @@ describe('#validateSignup', () => { firstName: '', lastName: '', email: 'pepe@example.com', - password: '******', - passwordConfirmation: '******' + password: 'superSecret1234#', + passwordConfirmation: 'superSecret1234#' })).not.toBeUndefined() expect(validateSignup({ @@ -83,8 +93,8 @@ describe('#validateSignup', () => { firstName: '', lastName: '', email: '', - password: '******', - passwordConfirmation: '******' + password: 'superSecret1234#', + passwordConfirmation: 'superSecret1234#' })).not.toBeUndefined() expect(validateSignup({ @@ -92,8 +102,8 @@ describe('#validateSignup', () => { firstName: '', lastName: '', email: 'pepe@example.com', - password: '******', - passwordConfirmation: '******' + password: 'superSecret1234#', + passwordConfirmation: 'superSecret1234#' })).toBeUndefined() }) }) diff --git a/test/functional/buyers/users_controller_test.rb b/test/functional/buyers/users_controller_test.rb index ef1040c7ba..7f492679e1 100644 --- a/test/functional/buyers/users_controller_test.rb +++ b/test/functional/buyers/users_controller_test.rb @@ -73,4 +73,34 @@ def setup assert_response :redirect end + + class EditPagePasswordFieldsTest < ActionController::TestCase + tests Buyers::UsersController + + def setup + @provider = FactoryBot.create(:provider_account) + @buyer = FactoryBot.create(:buyer_account, provider_account: @provider) + @user = @buyer.admins.first + host! @provider.internal_admin_domain + login_provider @provider + end + + test 'edit page shows password fields for user with password' do + get :edit, params: { account_id: @buyer.id, id: @user.id } + + assert_response :success + assert_select 'input[name="user[password]"]' + assert_select 'input[name="user[password_confirmation]"]' + end + + test 'edit page shows password fields for SSO user without password' do + @user.update_columns(password_digest: nil, authentication_id: 'sso-user-id') + + get :edit, params: { account_id: @buyer.id, id: @user.id } + + assert_response :success + assert_select 'input[name="user[password]"]' + assert_select 'input[name="user[password_confirmation]"]' + end + end end diff --git a/test/functional/partners/providers_controller_test.rb b/test/functional/partners/providers_controller_test.rb index 93fade581c..a0f22e86b5 100644 --- a/test/functional/partners/providers_controller_test.rb +++ b/test/functional/partners/providers_controller_test.rb @@ -86,6 +86,48 @@ def provider_params assert_equal body['success'], true end + test 'post without password creates user with no password' do + prepare_master_account + post :create, params: provider_params + + assert_response :success + user = assigns(:user) + assert user.valid? + assert_nil user.password_digest, 'User should have no password when not provided' + assert_not user.using_password?, 'User should not be using password' + + body = JSON.parse(response.body) + assert_equal true, body['success'] + end + + test 'post with weak password rejected when strong passwords enabled' do + prepare_master_account + Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) + + post :create, params: provider_params.merge(password: 'weakpwd') + + assert_response :unprocessable_entity + body = JSON.parse(response.body) + + refute body['success'] + assert body['errors']['user']['password'].present? + end + + test 'post with strong password accepted when strong passwords enabled' do + prepare_master_account + Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) + + post :create, params: provider_params.merge(password: 'superSecret1234#') + + assert_response :success + user = assigns(:user) + assert user.valid? + assert user.authenticated?('superSecret1234#') + + body = JSON.parse(response.body) + assert_equal true, body['success'] + end + test 'post with an invalid email' do prepare_master_account post :create, params: provider_params.merge(email: 'invalid') diff --git a/test/functional/partners/users_controller_test.rb b/test/functional/partners/users_controller_test.rb index 02652cdfa4..180cc383ad 100644 --- a/test/functional/partners/users_controller_test.rb +++ b/test/functional/partners/users_controller_test.rb @@ -54,5 +54,68 @@ def setup assert JSON.parse(response.body) end + test 'create user without password but with open_id' do + post :create, params: { provider_id: @account.id, api_key: @partner.api_key, email: "foo@example.net", username: "aaron", open_id: "sso-id" } + assert_response :success + user = assigns(:user) + + assert user.valid? + assert_nil user.password_digest, 'User should have no password when not provided' + assert_not user.using_password?, 'User should not be using password' + assert_equal "sso-id", user.open_id + + body = JSON.parse(response.body) + assert body['success'] + end + + test 'create user with password' do + post :create, params: { provider_id: @account.id, api_key: @partner.api_key, email: "foo@example.net", username: "aaron", password: "secretpass123" } + + assert_response :success + user = assigns(:user) + + assert user.valid? + assert user.authenticated?("secretpass123"), 'User should authenticate with provided password' + + body = JSON.parse(response.body) + assert body['success'] + end + + test 'create user with invalid params returns 422' do + post :create, params: { provider_id: @account.id, api_key: @partner.api_key, email: "invalid-email", username: "aaron" } + + assert_response :unprocessable_entity + body = JSON.parse(response.body) + + assert_not body['success'] + assert body['errors'].present? + end + + test 'create user with weak password rejected when strong passwords enabled' do + Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) + + post :create, params: { provider_id: @account.id, api_key: @partner.api_key, email: "foo@example.net", username: "aaron", password: "weakpwd" } + + assert_response :unprocessable_entity + body = JSON.parse(response.body) + + assert_not body['success'] + assert body['errors']['password'].present? + end + + test 'create user with strong password accepted when strong passwords enabled' do + Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) + + post :create, params: { provider_id: @account.id, api_key: @partner.api_key, email: "foo@example.net", username: "aaron", password: "superSecret1234#" } + + assert_response :success + user = assigns(:user) + + assert user.valid? + assert user.authenticated?("superSecret1234#") + + body = JSON.parse(response.body) + assert body['success'] + end end diff --git a/test/functional/provider/admin/user/personal_details_controller_test.rb b/test/functional/provider/admin/user/personal_details_controller_test.rb index c65d307bc3..186118e435 100644 --- a/test/functional/provider/admin/user/personal_details_controller_test.rb +++ b/test/functional/provider/admin/user/personal_details_controller_test.rb @@ -43,4 +43,106 @@ def setup put :update, params: { user: {current_password: 'wrong_password', password: 'new_password', password_confirmation: 'new_password'} } end + class SSOUserWithoutPasswordTest < ActionController::TestCase + tests Provider::Admin::User::PersonalDetailsController + + def setup + @provider = FactoryBot.create(:provider_account) + @user = @provider.admins.first + # Simulate an SSO user: no password and has authentication_id (makes oauth2? return true) + @user.update_columns(password_digest: nil, authentication_id: 'sso-user-id') + host! @provider.external_admin_domain + login_as @user + end + + test 'edit page shows password field for SSO user without password' do + get :edit + + assert_response :success + assert_select 'input[name="user[password]"]' + end + + test 'edit page does not show current password field for SSO user without password' do + get :edit + + assert_response :success + assert_select 'input[name="user[current_password]"]', false + end + + test 'SSO user can set password without providing current password' do + put :update, params: { user: { password: 'superSecret1234#', password_confirmation: 'superSecret1234#' } } + + assert_redirected_to edit_provider_admin_user_personal_details_path + assert @user.reload.authenticated?('superSecret1234#') + end + + test 'SSO user can update other fields without providing current password' do + put :update, params: { user: { username: 'newusername', email: 'newemail@example.com' } } + + assert_redirected_to edit_provider_admin_user_personal_details_path + assert_equal 'newusername', @user.reload.username + end + end + + class UserWithPasswordTest < ActionController::TestCase + tests Provider::Admin::User::PersonalDetailsController + + def setup + @provider = FactoryBot.create(:provider_account) + @user = @provider.admins.first + host! @provider.external_admin_domain + login_as @user + end + + test 'edit page shows current password field for user with password' do + get :edit + + assert_response :success + assert_select 'input[name="user[current_password]"]' + end + + test 'user with password must provide current password to update' do + put :update, params: { user: { username: 'newusername' } } + + assert_response :success + assert_template 'edit' + assert_match(/incorrect/i, flash[:danger]) + end + + test 'user with password can update when providing correct current password' do + put :update, params: { user: { current_password: 'supersecret', username: 'newusername' } } + + assert_redirected_to edit_provider_admin_user_personal_details_path + assert_equal 'newusername', @user.reload.username + end + end + + class EnforceSSOEnabledTest < ActionController::TestCase + tests Provider::Admin::User::PersonalDetailsController + + def setup + @provider = FactoryBot.create(:provider_account) + @provider.settings.update!(enforce_sso: true) + @user = @provider.admins.first + host! @provider.external_admin_domain + login_as @user + end + + test 'user can change password when enforce SSO is enabled' do + put :update, params: { user: { current_password: 'supersecret', password: 'superSecret1234#', password_confirmation: 'superSecret1234#' } } + + assert_redirected_to edit_provider_admin_user_personal_details_path + assert @user.reload.authenticated?('superSecret1234#') + end + + test 'SSO user without password can set password when enforce SSO is enabled' do + # Simulate an SSO user: no password and has authentication_id (makes oauth2? return true) + @user.update_columns(password_digest: nil, authentication_id: 'sso-user-id') + + put :update, params: { user: { password: 'superSecret1234#', password_confirmation: 'superSecret1234#' } } + + assert_redirected_to edit_provider_admin_user_personal_details_path + assert @user.reload.authenticated?('superSecret1234#') + end + end end diff --git a/test/integration/admin/api/buyers_users_controller_test.rb b/test/integration/admin/api/buyers_users_controller_test.rb index ce08f5355f..6247792b9a 100644 --- a/test/integration/admin/api/buyers_users_controller_test.rb +++ b/test/integration/admin/api/buyers_users_controller_test.rb @@ -24,6 +24,35 @@ def setup end end + test 'updates a buyer user with password' do + user = FactoryBot.create(:simple_user, account: buyer) + + put admin_api_account_user_path(buyer, user), params: { access_token: token_value, password: 'newPassword1234#' } + + assert_response :success + assert user.reload.authenticated?('newPassword1234#'), 'User should authenticate with new password' + end + + test 'update with weak password rejected when strong passwords enabled' do + user = FactoryBot.create(:simple_user, account: buyer) + Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) + + put admin_api_account_user_path(buyer, user), params: { access_token: token_value, password: 'weakpwd' } + + assert_response :unprocessable_entity + assert_match User::STRONG_PASSWORD_FAIL_MSG, response.body + end + + test 'update with strong password accepted when strong passwords enabled' do + user = FactoryBot.create(:simple_user, account: buyer) + Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) + + put admin_api_account_user_path(buyer, user), params: { access_token: token_value, password: 'superSecret1234#' } + + assert_response :success + assert user.reload.authenticated?('superSecret1234#'), 'User should authenticate with new password' + end + private def params diff --git a/test/integration/admin/api/settings_controller_test.rb b/test/integration/admin/api/settings_controller_test.rb index a2811bf48f..221f79c721 100644 --- a/test/integration/admin/api/settings_controller_test.rb +++ b/test/integration/admin/api/settings_controller_test.rb @@ -19,7 +19,6 @@ def setup useraccountarea_enabled: true, signups_enabled: true, account_approval_required: false, - strong_passwords_enabled: false, public_search: false, account_plans_ui_visible: true, change_account_plan_permission: 'request', diff --git a/test/integration/developer_portal/invitation_signup_test.rb b/test/integration/developer_portal/invitation_signup_test.rb index e2dc521a4e..285e33d700 100644 --- a/test/integration/developer_portal/invitation_signup_test.rb +++ b/test/integration/developer_portal/invitation_signup_test.rb @@ -19,7 +19,7 @@ def test_show # and therefore, user password should be required get invitee_signup_path(invitation_token: @invitation.token) assert_response :success - assert assigns(:user).password_required? + assert assigns(:user).validate_password? # sso attributes do exist, sso authorization object should be built # and therefore, user password should not be required @@ -29,7 +29,7 @@ def test_show assert_response :success get invitee_signup_path(invitation_token: @invitation.token) assert_response :success - refute assigns(:user).password_required? + refute assigns(:user).validate_password? sso_authorization = assigns(:user).sso_authorizations.first assert_equal '12345', sso_authorization.uid assert_equal @auth_provider.id, sso_authorization.authentication_provider_id diff --git a/test/integration/developer_portal/signup_test.rb b/test/integration/developer_portal/signup_test.rb index f980ba1211..5d22fbc624 100644 --- a/test/integration/developer_portal/signup_test.rb +++ b/test/integration/developer_portal/signup_test.rb @@ -81,6 +81,49 @@ def setup end end + class StrongPasswordsTest < DeveloperPortal::SignupTest + STRONG_PASSWORD = 'superSecret1234#' + WEAK_PASSWORD = 'weakpwd' + + def account_params(password) + { + account: { + org_name: 'alaska', + user: { + email: 'foo@example.edu', + username: 'supertramp', + password: password + } + } + } + end + + def test_weak_password_rejected_when_strong_passwords_enabled + Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) + + post signup_path, params: account_params(WEAK_PASSWORD) + + assert_response :success + assert_match User::STRONG_PASSWORD_FAIL_MSG, response.body + end + + def test_strong_password_accepted_when_strong_passwords_enabled + Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) + + post signup_path, params: account_params(STRONG_PASSWORD) + + assert_response :redirect + end + + def test_weak_password_accepted_when_strong_passwords_disabled + Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(true) + + post signup_path, params: account_params(WEAK_PASSWORD) + + assert_response :redirect + end + end + class Show < DeveloperPortal::SignupTest def test_show get signup_path diff --git a/test/integration/provider/admin/account/users_controller_test.rb b/test/integration/provider/admin/account/users_controller_test.rb index b6e47ffa00..86d1208309 100644 --- a/test/integration/provider/admin/account/users_controller_test.rb +++ b/test/integration/provider/admin/account/users_controller_test.rb @@ -99,4 +99,22 @@ def test_update_blank_member_permission_ids assert user.reload.admin? end + + test 'edit page shows password fields for user with password' do + get edit_provider_admin_account_user_path(@user) + + assert_response :success + assert_select 'input[name="user[password]"]' + assert_select 'input[name="user[password_confirmation]"]' + end + + test 'edit page shows password fields for SSO user without password' do + @user.update_columns(password_digest: nil, authentication_id: 'sso-user-id') + + get edit_provider_admin_account_user_path(@user) + + assert_response :success + assert_select 'input[name="user[password]"]' + assert_select 'input[name="user[password_confirmation]"]' + end end diff --git a/test/integration/provider/signups_controller_integration_test.rb b/test/integration/provider/signups_controller_integration_test.rb index 8a8088cd0a..72e8fb562e 100644 --- a/test/integration/provider/signups_controller_integration_test.rb +++ b/test/integration/provider/signups_controller_integration_test.rb @@ -85,3 +85,52 @@ def create_params(extra_params = {}) }.deep_merge(extra_params) end end + +class Provider::SignupsControllerStrongPasswordsTest < ActionDispatch::IntegrationTest + STRONG_PASSWORD = 'superSecret1234#' + WEAK_PASSWORD = 'weakpwd' + + def setup + host! master_account.external_admin_domain + end + + def signup_params(password) + { + account: { + name: 'organization name', + user: { email: 'email@example.com', password: password } + } + } + end + + def test_weak_password_rejected_when_strong_passwords_enabled + Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) + + assert_no_difference(master_account.buyer_accounts.method(:count)) do + post provider_signup_path, params: signup_params(WEAK_PASSWORD) + end + + assert_response :success + assert_match User::STRONG_PASSWORD_FAIL_MSG, response.body + end + + def test_strong_password_accepted_when_strong_passwords_enabled + Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) + + assert_difference(master_account.buyer_accounts.method(:count)) do + post provider_signup_path, params: signup_params(STRONG_PASSWORD) + end + + assert_redirected_to success_provider_signup_path + end + + def test_weak_password_accepted_when_strong_passwords_disabled + Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(true) + + assert_difference(master_account.buyer_accounts.method(:count)) do + post provider_signup_path, params: signup_params(WEAK_PASSWORD) + end + + assert_redirected_to success_provider_signup_path + end +end diff --git a/test/integration/user-management-api/users_test.rb b/test/integration/user-management-api/users_test.rb index d3403c028a..688187ea6b 100644 --- a/test/integration/user-management-api/users_test.rb +++ b/test/integration/user-management-api/users_test.rb @@ -399,6 +399,27 @@ def setup assert chuck.authenticated?('updated-password') end + test 'update with weak password rejected when strong passwords enabled' do + chuck = FactoryBot.create(:user, account: @provider, role: 'member') + Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) + + put admin_api_user_path(format: :xml, id: chuck.id, password: "weakpwd", password_confirmation: "weakpwd"), params: { provider_key: @provider.api_key } + + assert_response :unprocessable_entity + assert_match User::STRONG_PASSWORD_FAIL_MSG, response.body + end + + test 'update with strong password accepted when strong passwords enabled' do + chuck = FactoryBot.create(:user, account: @provider, role: 'member') + Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) + + put admin_api_user_path(format: :xml, id: chuck.id, password: "superSecret1234#", password_confirmation: "superSecret1234#"), params: { provider_key: @provider.api_key } + + chuck.reload + assert_response :success + assert chuck.authenticated?('superSecret1234#') + end + test 'update does not updates state nor role' do chuck = FactoryBot.create(:user, account: @provider, role: 'member') assert chuck.pending? diff --git a/test/unit/authentication/by_has_secure_password_test.rb b/test/unit/authentication/by_has_secure_password_test.rb deleted file mode 100644 index d08a757e8d..0000000000 --- a/test/unit/authentication/by_has_secure_password_test.rb +++ /dev/null @@ -1,12 +0,0 @@ -require 'test_helper' -class Authentication::ByHasSecurePasswordTest < ActiveSupport::TestCase - - def setup - @user = FactoryBot.create(:simple_user, account: nil) - end - - test 'new user with password_digest' do - assert @user.authenticate('supersecret') - assert @user.authenticated?('supersecret') - end -end diff --git a/test/unit/authentication/by_password_test.rb b/test/unit/authentication/by_password_test.rb new file mode 100644 index 0000000000..2bbc7fd1c9 --- /dev/null +++ b/test/unit/authentication/by_password_test.rb @@ -0,0 +1,219 @@ +require 'test_helper' +class Authentication::ByPasswordTest < ActiveSupport::TestCase + + setup do + provider = FactoryBot.create(:simple_provider) + @buyer = FactoryBot.create(:buyer_account, provider_account: provider) + @user_with_password = ->(password) do + @buyer.users.new username: 'user', email: 'user@example.com', password: password, password_confirmation: password + end + end + + attr_reader :user_with_password + + class HasSecurePasswordTest < Authentication::ByPasswordTest + test 'new user with password_digest' do + user = user_with_password.call('superSecret1234#') + + assert user.authenticated?('superSecret1234#') + end + end + + class WeakPasswordTest < Authentication::ByPasswordTest + test 'should by default allow weak ones' do + user = user_with_password.call('weakpassword') + + assert user.valid? + assert user.errors[:password].blank? + end + + test 'weak password must be present' do + user = user_with_password.call('') + + assert_not user.valid? + assert_equal "can't be blank", user.errors.messages[:password].first + end + end + + class StrongPasswordsTest < Authentication::ByPasswordTest + setup do + Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) + end + + class ExistingUsersTest < StrongPasswordsTest + setup do + @user = @buyer.users.first + @user.reload + end + + test 'should be valid if not updating the password' do + @user.last_name = "not updating password" + + @user.valid? + assert @user.errors[:password].blank? + end + + test 'should be invalid if updating the password' do + @user.password = "nononono" + @user.valid? + + assert_equal User::STRONG_PASSWORD_FAIL_MSG, @user.errors[:password].first + end + + test 'password is not validated when user is sample data' do + @user.password = "nononono" + @user.signup_type = :sample_data + + assert @user.valid? + assert @user.errors[:password].blank? + end + end + + class ValidationsTest < StrongPasswordsTest + test 'should be valid with ASCII printable characters and longer than 16 characters' do + user = @buyer.users.new password: "StrongPass123-+_!$#.@", password_confirmation: "StrongPass123-+_!$#.@" + user.valid? + + assert user.errors[:password].blank? + end + + test 'should be invalid if shorter than 16 characters' do + user = user_with_password.call('Pas$123') + user.valid? + + assert_equal User::STRONG_PASSWORD_FAIL_MSG, user.errors[:password].first + end + + test 'should be invalid if has strange characters' do + user = user_with_password.call('StrongPass|') + user.valid? + + assert_equal User::STRONG_PASSWORD_FAIL_MSG, user.errors[:password].first + end + + test 'should be invalid if password and password confirmation do not match' do + @user = @buyer.users.first + + assert_not @buyer.users.first.update password: "superSecret1234#", password_confirmation: "superSecret12345#" + end + end + end + + class MethodsTest < Authentication::ByPasswordTest + class ValidatePasswordTest < MethodsTest + setup do + @user = @buyer.users.first + @user.reload + end + + test 'returns true when password has changed but not persisted' do + @user.password = 'newpassword12345' + + assert @user.validate_password? + end + + test 'returns true when password has not changed but user signed up by_user and has no password' do + @user.password_digest = nil + @user.signup_type = :new_signup + + assert @user.signup.by_user? + assert @user.validate_password? + end + + test 'returns false when password has not changed and user signup was by machine' do + @user.signup_type = :minimal + + assert @user.signup.machine? + assert_not @user.validate_password? + end + + test 'returns false when password has not changed and user signed up by_user but already has a password' do + @user.signup_type = :new_signup + + assert @user.signup.by_user? + assert @user.password_digest.present? + assert_not @user.validate_password? + end + + test 'returns true when password has changed and user signup is sample data' do + @user.password = 'newpassword12345' + @user.signup_type = :sample_data + + assert @user.signup.sample_data? + assert @user.validate_password? + end + + test 'returns false when password has not changed and user has existing password regardless of signup type' do + %i[new_signup minimal api created_by_provider].each do |signup_type| + @user.signup_type = signup_type + @user.reload + + assert @user.password_digest.present? + assert_not @user.validate_password?, "Expected validate_password? to be false for signup_type: #{signup_type}" + end + end + end + + class ValidateStrongPasswordTest < MethodsTest + setup do + @user = @buyer.users.first + @user.reload + end + + test 'returns false when strong_passwords_disabled is true' do + @user.password = 'newpassword12345' + + assert_not @user.validate_strong_password? + end + + test 'returns false when user signup is sample_data' do + @user.password = 'newpassword12345' + @user.signup_type = :sample_data + + assert_not @user.validate_strong_password? + end + + test 'returns true when strong_passwords_disabled is false and not sample_data and validate_password? is true' do + Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) + @user.password = 'newpassword12345' + @user.signup_type = :new_signup + + assert @user.validate_password? + assert @user.validate_strong_password? + end + + test 'returns false when strong_passwords_disabled is false and not sample_data but validate_password? is false' do + Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) + @user.signup_type = :new_signup + + assert_not @user.validate_password? + assert_not @user.validate_strong_password? + end + end + + class UsingPasswordTest < MethodsTest + setup do + @user = @buyer.users.first + @user.reload + end + + test 'returns true when password is persisted in database' do + assert @user.password_digest_in_database.present? + assert @user.using_password? + end + + test 'returns false when password_digest is nil in database' do + @user.update_column(:password_digest, nil) + + assert_not @user.using_password? + end + + test 'returns false when password is set but not yet persisted' do + new_user = @buyer.users.build(username: 'newuser', email: 'new@example.com', password: 'testpassword', password_confirmation: 'testpassword') + + assert new_user.password_digest.present? + assert_not new_user.using_password? + end + end + end +end diff --git a/test/unit/liquid/drops/user_drop_test.rb b/test/unit/liquid/drops/user_drop_test.rb index efb9126a3c..3ab1f0c044 100644 --- a/test/unit/liquid/drops/user_drop_test.rb +++ b/test/unit/liquid/drops/user_drop_test.rb @@ -56,6 +56,34 @@ def test_oauth2 without_password_drop = Drops::User.new(FactoryBot.create(:user, account: @buyer, password_digest: nil)) assert_not without_password_drop.using_password? end + + test '#using_password? returns false when password is set but not persisted' do + new_user = @buyer.users.build(username: 'newuser', email: 'new@example.com', password: 'testpassword', password_confirmation: 'testpassword') + new_user_drop = Drops::User.new(new_user) + + assert_not new_user_drop.using_password? + end + + test '#password_required? returns true when signup is by_user' do + @user.signup_type = :new_signup + + assert @user.signup.by_user? + assert @drop.password_required? + end + + test '#password_required? returns false when signup is machine' do + @user.signup_type = :minimal + + assert @user.signup.machine? + assert_not @drop.password_required? + end + + test '#password_required? returns false for sample_data signup' do + @user.signup_type = :sample_data + + assert @user.signup.sample_data? + assert_not @drop.password_required? + end end class BuyerUserTest < Liquid::Drops::UserDropTest diff --git a/test/unit/logic/provider_signup_test.rb b/test/unit/logic/provider_signup_test.rb new file mode 100644 index 0000000000..0658d2eb96 --- /dev/null +++ b/test/unit/logic/provider_signup_test.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require 'test_helper' + +class Logic::ProviderSignupTest < ActiveSupport::TestCase + class SampleDataTest < ActiveSupport::TestCase + def setup + @provider = FactoryBot.create(:provider_account) + end + + test 'John Doe user is created with weak password when strong passwords enabled' do + Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) + + sample_data = Logic::ProviderSignup::SampleData.new(@provider) + sample_data.create! + + john_doe = @provider.buyer_users.find_by(username: 'john') + assert john_doe.present?, 'John Doe user should be created' + assert john_doe.authenticated?('123456'), 'John Doe should have weak password 123456' + end + + test 'John Doe signup.machine? returns true' do + sample_data = Logic::ProviderSignup::SampleData.new(@provider) + sample_data.create! + + john_doe = @provider.buyer_users.find_by(username: 'john') + assert john_doe.signup.machine?, 'John Doe should be considered a machine signup' + end + + test 'John Doe signup.sample_data? returns true' do + sample_data = Logic::ProviderSignup::SampleData.new(@provider) + sample_data.create! + + john_doe = @provider.buyer_users.find_by(username: 'john') + assert john_doe.signup.sample_data?, 'John Doe should have sample_data? return true' + end + + test 'John Doe is active after creation' do + sample_data = Logic::ProviderSignup::SampleData.new(@provider) + sample_data.create! + + john_doe = @provider.buyer_users.find_by(username: 'john') + assert john_doe.active?, 'John Doe should be active after creation' + end + end +end \ No newline at end of file diff --git a/test/unit/signup/account_manager_test.rb b/test/unit/signup/account_manager_test.rb index b9139162ce..b5dc1d7e1a 100644 --- a/test/unit/signup/account_manager_test.rb +++ b/test/unit/signup/account_manager_test.rb @@ -234,8 +234,18 @@ class DeveloperAccountManagerTest < Signup::AccountManagerTest assert signup_result.account_approved? end + test 'create developer without account plan approval required and sample_data signup' do + @account_plan.update_attribute(:approval_required, false) + signup_result = signup_account_manager.create(signup_params(different_user_params: {signup_type: :sample_data})) + + # the user is active and the account is approved + assert signup_result.persisted? + assert signup_result.user_active? + assert signup_result.account_approved? + end + test 'create developer with account plan approval required and minimal signup' do - # The only difference is result.user_activate_on_minimal_signup? should return false, and it only happens if the contract_plans goes before this + # The only difference is result.user_activate_on_minimal_or_sample_data? should return false, and it only happens if the contract_plans goes before this @account_plan.update_attribute(:approval_required, true) signup_result = signup_account_manager.create(signup_params(different_user_params: {signup_type: :minimal})) account = signup_result.account diff --git a/test/unit/user/signup_type_test.rb b/test/unit/user/signup_type_test.rb index e90ab0968b..c1c6b9f37f 100644 --- a/test/unit/user/signup_type_test.rb +++ b/test/unit/user/signup_type_test.rb @@ -4,7 +4,7 @@ class User::SignupTypeTest < ActiveSupport::TestCase def test_partner assert signup_type(type: 'partner').partner? - refute signup_type(type: 'new_signup').partner? + assert_not signup_type(type: 'new_signup').partner? end test 'open_id' do @@ -12,9 +12,27 @@ def test_partner assert signup_type(open_id: 'foo').machine? end + test 'sample_data? returns true for sample_data signup_type' do + assert signup_type(type: 'sample_data').sample_data? + end + + test 'sample_data? returns false for other signup_types' do + assert_not signup_type(type: 'new_signup').sample_data? + assert_not signup_type(type: 'minimal').sample_data? + assert_not signup_type(type: 'api').sample_data? + end + + test 'machine? returns true for sample_data signup_type' do + assert signup_type(type: 'sample_data').machine? + end + + test 'by_user? returns false for sample_data signup_type' do + assert_not signup_type(type: 'sample_data').by_user? + end + private def signup_type(type: '', open_id: nil) - User::SignupType.new(stub(signup_type: type.to_sym, open_id: open_id)) + User::SignupType.new(stub(signup_type: type.to_sym, open_id: open_id, any_sso_authorizations?: false, authentication_id: nil, cas_identifier: nil)) end end diff --git a/test/unit/user/states_test.rb b/test/unit/user/states_test.rb index 371d42e91e..cb6926d0f3 100644 --- a/test/unit/user/states_test.rb +++ b/test/unit/user/states_test.rb @@ -91,5 +91,46 @@ class User::StatesTest < ActiveSupport::TestCase user.activate! end end + + class ActivateOnMinimalOrSampleDataTest < ActiveSupport::TestCase + def setup + @provider = FactoryBot.create(:simple_provider) + @buyer = FactoryBot.create(:simple_buyer, provider_account: @provider) + @user = FactoryBot.create(:pending_user, account: @buyer, password: '123456', password_confirmation: '123456') + end + + test 'returns true for minimal signup with password and no approval required' do + @user.signup_type = :minimal + + assert @user.activate_on_minimal_or_sample_data? + end + + test 'returns true for sample_data signup with password and no approval required' do + @user.signup_type = :sample_data + + assert @user.activate_on_minimal_or_sample_data? + end + + test 'returns false for sample_data signup without password' do + @user.signup_type = :sample_data + @user.password = nil + + assert_not @user.activate_on_minimal_or_sample_data? + end + + test 'returns false for sample_data signup when approval required' do + @user.signup_type = :sample_data + account_plan = FactoryBot.create(:account_plan, issuer: @provider, approval_required: true) + @buyer.buy!(account_plan) + + assert_not @user.activate_on_minimal_or_sample_data? + end + + test 'returns false for new_signup even with password' do + @user.signup_type = :new_signup + + assert_not @user.activate_on_minimal_or_sample_data? + end + end end diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb index 576574e3ad..de41ba3ea1 100644 --- a/test/unit/user_test.rb +++ b/test/unit/user_test.rb @@ -750,124 +750,6 @@ class WebhookTest < ActiveSupport::TestCase assert_equal @user.sections, [@section] end - class PasswordStrengthTest < ActiveSupport::TestCase - setup do - provider = FactoryBot.create(:simple_provider) - @buyer = FactoryBot.create(:buyer_account, provider_account: provider) - @user_with_password = ->(password) do - @buyer.users.new username: 'user', email: 'user@example.com', password: password, password_confirmation: password - end - end - - attr_reader :user_with_password - - class WeakPasswordTest < PasswordStrengthTest - setup do - @buyer.provider_account.settings.update_attribute(:strong_passwords_enabled, false) # rubocop:disable Rails/SkipsModelValidations - end - - test 'should by default allow weak ones' do - user = user_with_password.call('weakpassword') - - assert user.valid? - assert user.errors[:password].blank? - end - - test 'weak password must be 6 chars at least when password is required' do - user = user_with_password.call('weak') - - assert_not user.valid? - assert_equal "is too short (minimum is 6 characters)", user.errors.messages[:password].first - end - - test 'password is not validated when not required' do - user = user_with_password.call('weak') - user.signup_type = :api - - assert user.valid? - assert user.errors[:password].blank? - end - end - - class StrongPasswordsTest < PasswordStrengthTest - setup do - @buyer.provider_account.settings - .update_attribute(:strong_passwords_enabled, true) # rubocop:disable Rails/SkipsModelValidations - end - - class ExistingUsersTest < StrongPasswordsTest - setup do - @user = @buyer.users.first - @user.reload - end - - test 'should be valid if not updating the password' do - @user.last_name = "not updating password" - - @user.valid? - assert @user.errors[:password].blank? - end - - test 'should be invalid if updating the password' do - @user.password = "nononono" - @user.valid? - - assert_equal User::STRONG_PASSWORD_FAIL_MSG, @user.errors[:password].first - end - end - - class ValidationsTest < StrongPasswordsTest - test 'should be valid with Uppercases, lowercases, digits and weird characters -+_!$#.@ and longer than 8 characters' do - user = @buyer.users.new password: "StrongPass123-+_!$#.@", password_confirmation: "StrongPass123-+_!$#.@" - user.valid? - - assert user.errors[:password].blank? - end - - test 'should be invalid if shorter than 8 characters' do - user = @buyer.users.new password: "Pas$123", password_confirmation: "Pas$123" - user.valid? - - assert_equal User::STRONG_PASSWORD_FAIL_MSG, user.errors[:password].first - end - - test 'should be invalid if without digits' do - user = @buyer.users.new password: "StrongPass-+_!$#.@", password_confirmation: "StrongPass-+_!$#.@" - user.valid? - - assert_equal User::STRONG_PASSWORD_FAIL_MSG, user.errors[:password].first - end - - test 'should be invalid if without uppercases' do - user = @buyer.users.new password: "strongpass123-+_!$#.@", password_confirmation: "strongpass123-+_!$#.@" - user.valid? - - assert_equal User::STRONG_PASSWORD_FAIL_MSG, user.errors[:password].first - end - - test 'should be invalid if without lowercases' do - user = @buyer.users.new password: "STRONGPASS-+_!$#.@", password_confirmation: "STRONGPASS-+_!$#.@" - user.valid? - - assert_equal User::STRONG_PASSWORD_FAIL_MSG, user.errors[:password].first - end - - test 'should be invalid if has strange characters' do - user = @buyer.users.new password: "StrongPass|", password_confirmation: "StrongPass|" - user.valid? - - assert_equal User::STRONG_PASSWORD_FAIL_MSG, user.errors[:password].first - end - - test 'when created from provider should be invalid if password and password confirmation do not match' do - @user = @buyer.users.first - @user.stubs(:password_required?).returns(false) #simulate created by provider - assert_not @buyer.users.first.update password: "hola12", password_confirmation: "hola123" - end - end - end - end - test 'destroys its invitation' do invitation = FactoryBot.create(:invitation, email: "invited@example.com", account: FactoryBot.create(:provider_account)) user = invitation.make_user username: "username", password: "password" From 02b270b9eae457279b2bf77210218adf8f26f724 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Lled=C3=B3?= Date: Wed, 11 Feb 2026 09:51:03 +0100 Subject: [PATCH 09/19] Remove the max password size requirement. --- app/javascript/src/Login/utils/validations.ts | 2 +- app/lib/authentication/by_password.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/javascript/src/Login/utils/validations.ts b/app/javascript/src/Login/utils/validations.ts index 949ee32302..f0ae45842d 100644 --- a/app/javascript/src/Login/utils/validations.ts +++ b/app/javascript/src/Login/utils/validations.ts @@ -4,7 +4,7 @@ import validate from 'validate.js' // The source of truth is app/lib/authentication/by_password.rb. If those constants change in Ruby, // you must update them here as well. Do not modify these without updating the backend first. const STRONG_PASSWORD_MIN_SIZE = 16 -const RE_STRONG_PASSWORD = new RegExp(`^[ -~]{${STRONG_PASSWORD_MIN_SIZE},64}$`) +const RE_STRONG_PASSWORD = new RegExp(`^[ -~]{${STRONG_PASSWORD_MIN_SIZE},}$`) const STRONG_PASSWORD_FAIL_MSG = `Password must be at least ${STRONG_PASSWORD_MIN_SIZE} characters long, and contain only valid characters.` const loginConstraints = { diff --git a/app/lib/authentication/by_password.rb b/app/lib/authentication/by_password.rb index 9054c4c8ac..e7a46d8e30 100644 --- a/app/lib/authentication/by_password.rb +++ b/app/lib/authentication/by_password.rb @@ -7,7 +7,7 @@ module ByPassword STRONG_PASSWORD_MIN_SIZE = 16 # All printable characters in ASCII, from 'space' (32) to ~ (126) # at least STRONG_PASSWORD_MIN_SIZE characters - RE_STRONG_PASSWORD = /\A[ -~]{#{STRONG_PASSWORD_MIN_SIZE},64}\z/ + RE_STRONG_PASSWORD = /\A[ -~]{#{STRONG_PASSWORD_MIN_SIZE},}\z/ STRONG_PASSWORD_FAIL_MSG = "Password must be at least #{STRONG_PASSWORD_MIN_SIZE} characters long, and contain only valid characters.".freeze included do From b986bea541e98d83e87ccba6517240aba343eae0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Lled=C3=B3?= Date: Wed, 11 Feb 2026 09:53:37 +0100 Subject: [PATCH 10/19] Set min pass size to 15 --- app/javascript/src/Login/utils/validations.ts | 2 +- app/lib/authentication/by_password.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/javascript/src/Login/utils/validations.ts b/app/javascript/src/Login/utils/validations.ts index f0ae45842d..00cd37ca70 100644 --- a/app/javascript/src/Login/utils/validations.ts +++ b/app/javascript/src/Login/utils/validations.ts @@ -3,7 +3,7 @@ import validate from 'validate.js' // IMPORTANT: These STRONG_PASSWORD_* constants are duplicated from the backend. // The source of truth is app/lib/authentication/by_password.rb. If those constants change in Ruby, // you must update them here as well. Do not modify these without updating the backend first. -const STRONG_PASSWORD_MIN_SIZE = 16 +const STRONG_PASSWORD_MIN_SIZE = 15 const RE_STRONG_PASSWORD = new RegExp(`^[ -~]{${STRONG_PASSWORD_MIN_SIZE},}$`) const STRONG_PASSWORD_FAIL_MSG = `Password must be at least ${STRONG_PASSWORD_MIN_SIZE} characters long, and contain only valid characters.` diff --git a/app/lib/authentication/by_password.rb b/app/lib/authentication/by_password.rb index e7a46d8e30..6c824b6468 100644 --- a/app/lib/authentication/by_password.rb +++ b/app/lib/authentication/by_password.rb @@ -4,7 +4,7 @@ module ByPassword extend ActiveSupport::Concern # strong passwords - STRONG_PASSWORD_MIN_SIZE = 16 + STRONG_PASSWORD_MIN_SIZE = 15 # All printable characters in ASCII, from 'space' (32) to ~ (126) # at least STRONG_PASSWORD_MIN_SIZE characters RE_STRONG_PASSWORD = /\A[ -~]{#{STRONG_PASSWORD_MIN_SIZE},}\z/ From e69ed9ea90d93a866a3ff7a481c4ab843694d471 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Lled=C3=B3?= Date: Wed, 11 Feb 2026 10:49:21 +0100 Subject: [PATCH 11/19] Fix tests after updating password requirements --- features/old/accounts/personal_details.feature | 2 +- test/unit/authentication/by_password_test.rb | 4 ++-- test/unit/logic/provider_signup_test.rb | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/features/old/accounts/personal_details.feature b/features/old/accounts/personal_details.feature index d78530bfdc..eeea1cf622 100644 --- a/features/old/accounts/personal_details.feature +++ b/features/old/accounts/personal_details.feature @@ -88,4 +88,4 @@ Feature: Personal Details And I fill in "New password" with "hi" And I fill in "Current password" with "supersecret" And I press "Update Details" - Then field "New password" has inline error "Password must be at least 16 characters long, and contain only valid characters" + Then field "New password" has inline error "Password must be at least 15 characters long, and contain only valid characters" diff --git a/test/unit/authentication/by_password_test.rb b/test/unit/authentication/by_password_test.rb index 2bbc7fd1c9..beee285379 100644 --- a/test/unit/authentication/by_password_test.rb +++ b/test/unit/authentication/by_password_test.rb @@ -70,14 +70,14 @@ class ExistingUsersTest < StrongPasswordsTest end class ValidationsTest < StrongPasswordsTest - test 'should be valid with ASCII printable characters and longer than 16 characters' do + test 'should be valid with ASCII printable characters and longer than 15 characters' do user = @buyer.users.new password: "StrongPass123-+_!$#.@", password_confirmation: "StrongPass123-+_!$#.@" user.valid? assert user.errors[:password].blank? end - test 'should be invalid if shorter than 16 characters' do + test 'should be invalid if shorter than 15 characters' do user = user_with_password.call('Pas$123') user.valid? diff --git a/test/unit/logic/provider_signup_test.rb b/test/unit/logic/provider_signup_test.rb index 0658d2eb96..1f437ee11b 100644 --- a/test/unit/logic/provider_signup_test.rb +++ b/test/unit/logic/provider_signup_test.rb @@ -43,4 +43,4 @@ def setup assert john_doe.active?, 'John Doe should be active after creation' end end -end \ No newline at end of file +end From 485d40f3d471727222fe3a5dcf98213fdf38203f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Lled=C3=B3?= Date: Wed, 11 Feb 2026 12:41:50 +0100 Subject: [PATCH 12/19] Move password error message to I18N --- app/javascript/src/Login/utils/validations.ts | 2 ++ app/lib/authentication/by_password.rb | 2 +- config/locales/en.yml | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/javascript/src/Login/utils/validations.ts b/app/javascript/src/Login/utils/validations.ts index 00cd37ca70..309d3960e4 100644 --- a/app/javascript/src/Login/utils/validations.ts +++ b/app/javascript/src/Login/utils/validations.ts @@ -3,6 +3,8 @@ import validate from 'validate.js' // IMPORTANT: These STRONG_PASSWORD_* constants are duplicated from the backend. // The source of truth is app/lib/authentication/by_password.rb. If those constants change in Ruby, // you must update them here as well. Do not modify these without updating the backend first. +// The error message is also defined in config/locales/en.yml at: +// activerecord.errors.models.user.attributes.password.weak const STRONG_PASSWORD_MIN_SIZE = 15 const RE_STRONG_PASSWORD = new RegExp(`^[ -~]{${STRONG_PASSWORD_MIN_SIZE},}$`) const STRONG_PASSWORD_FAIL_MSG = `Password must be at least ${STRONG_PASSWORD_MIN_SIZE} characters long, and contain only valid characters.` diff --git a/app/lib/authentication/by_password.rb b/app/lib/authentication/by_password.rb index 6c824b6468..84fc6017e2 100644 --- a/app/lib/authentication/by_password.rb +++ b/app/lib/authentication/by_password.rb @@ -8,7 +8,7 @@ module ByPassword # All printable characters in ASCII, from 'space' (32) to ~ (126) # at least STRONG_PASSWORD_MIN_SIZE characters RE_STRONG_PASSWORD = /\A[ -~]{#{STRONG_PASSWORD_MIN_SIZE},}\z/ - STRONG_PASSWORD_FAIL_MSG = "Password must be at least #{STRONG_PASSWORD_MIN_SIZE} characters long, and contain only valid characters.".freeze + STRONG_PASSWORD_FAIL_MSG = I18n.t('activerecord.errors.models.user.attributes.password.weak', min_size: STRONG_PASSWORD_MIN_SIZE) included do # We only need length validations as they are already set in Authentication::ByPassword diff --git a/config/locales/en.yml b/config/locales/en.yml index 6f4b0f7bae..23a88e5299 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1929,6 +1929,7 @@ en: blank: "can't be blank" password: blank: "can't be blank" + weak: "Password must be at least %{min_size} characters long, and contain only valid characters." current_password_incorrect: "is incorrect" last_admin: "Can't delete last admin" From 9f6458860e10887a311c31785d48089047bac405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Lled=C3=B3?= Date: Wed, 11 Feb 2026 13:58:39 +0100 Subject: [PATCH 13/19] `generate_lost_password_token`: Run callbacks - But skip validation --- app/lib/authentication/by_password.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/lib/authentication/by_password.rb b/app/lib/authentication/by_password.rb index 84fc6017e2..2a8dbf6799 100644 --- a/app/lib/authentication/by_password.rb +++ b/app/lib/authentication/by_password.rb @@ -57,9 +57,10 @@ def expire_password_token def generate_lost_password_token token = SecureRandom.hex(32) - return unless update_columns(lost_password_token: token, lost_password_token_generated_at: Time.current) + self.lost_password_token = token + self.lost_password_token_generated_at = Time.current - token + token if save(validate: false) end def generate_lost_password_token! From 59aa2f7d89f646096d2432c8da4476ad5b8642a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Lled=C3=B3?= Date: Thu, 12 Feb 2026 13:05:27 +0100 Subject: [PATCH 14/19] Remove role param from buyer user controller --- app/controllers/admin/api/buyers_users_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admin/api/buyers_users_controller.rb b/app/controllers/admin/api/buyers_users_controller.rb index b8b6c98ad4..208841aa97 100644 --- a/app/controllers/admin/api/buyers_users_controller.rb +++ b/app/controllers/admin/api/buyers_users_controller.rb @@ -37,7 +37,7 @@ def show def update authorize! :update, user - user.update_with_flattened_attributes(flat_params, as: current_user.try(:role)) + user.update_with_flattened_attributes(flat_params) respond_with(user) end From 9ea6e693e023e3e9a99674313f13c586e3ef7da6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Lled=C3=B3?= Date: Thu, 12 Feb 2026 13:07:30 +0100 Subject: [PATCH 15/19] Use `will_save_change_to_password_digest?` --- app/lib/authentication/by_password.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/lib/authentication/by_password.rb b/app/lib/authentication/by_password.rb index 2a8dbf6799..2559a43d87 100644 --- a/app/lib/authentication/by_password.rb +++ b/app/lib/authentication/by_password.rb @@ -37,7 +37,7 @@ def find_with_valid_password_token(token) end def validate_password? - password_digest_changed? || (signup.by_user? && password_digest.blank?) + will_save_change_to_password_digest? || (signup.by_user? && password_digest.blank?) end def validate_strong_password? From ae3d0357c6a0c14b7be348e79a912fe449a7187d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Lled=C3=B3?= Date: Thu, 12 Feb 2026 13:18:41 +0100 Subject: [PATCH 16/19] Enable strong passwords in tests by default Let tests fail to get the complete list of outdated tests --- config/examples/settings.yml | 1 - .../old/accounts/personal_details.feature | 3 +- features/old/signup/strong_passwords.feature | 2 - .../strong_passwords_steps.rb | 5 -- .../partners/providers_controller_test.rb | 2 - .../partners/users_controller_test.rb | 4 - .../admin/api/buyers_users_controller_test.rb | 2 - .../developer_portal/signup_test.rb | 4 - .../signups_controller_integration_test.rb | 4 - .../user-management-api/users_test.rb | 2 - test/unit/authentication/by_password_test.rb | 84 +++++++++---------- test/unit/logic/provider_signup_test.rb | 2 - 12 files changed, 39 insertions(+), 76 deletions(-) diff --git a/config/examples/settings.yml b/config/examples/settings.yml index 25be6d8a51..866f77c20f 100644 --- a/config/examples/settings.yml +++ b/config/examples/settings.yml @@ -62,7 +62,6 @@ test: readonly_custom_domains_settings: true report_traffic: false secure_cookie: false - strong_passwords_disabled: true production: <<: *default diff --git a/features/old/accounts/personal_details.feature b/features/old/accounts/personal_details.feature index eeea1cf622..ac3ec41ac5 100644 --- a/features/old/accounts/personal_details.feature +++ b/features/old/accounts/personal_details.feature @@ -81,8 +81,7 @@ Feature: Personal Details And the "User extra required" field should contain "whatever" Scenario: Update own password when the user was signed up with password - Given Strong passwords are enabled - And the user was signed up with password + Given the user was signed up with password When I navigate to the Account Settings And I go to the provider personal details page And I fill in "New password" with "hi" diff --git a/features/old/signup/strong_passwords.feature b/features/old/signup/strong_passwords.feature index 9615cbeef4..e3814d7484 100644 --- a/features/old/signup/strong_passwords.feature +++ b/features/old/signup/strong_passwords.feature @@ -13,7 +13,6 @@ Feature: Signup with strong passwords Scenario: Strong password is required - Given Strong passwords are enabled When I go to the sign up page And I fill in the following: | Email | bender@planet.ex | @@ -26,7 +25,6 @@ Feature: Signup with strong passwords Then I should see the error that the password is too weak Scenario: Strong password is accepted - Given Strong passwords are enabled When I go to the sign up page And I fill in the following: | Email | bender@planet.ex | diff --git a/features/step_definitions/strong_passwords_steps.rb b/features/step_definitions/strong_passwords_steps.rb index 0f259c0185..2c92a97ee0 100644 --- a/features/step_definitions/strong_passwords_steps.rb +++ b/features/step_definitions/strong_passwords_steps.rb @@ -1,10 +1,5 @@ # frozen_string_literal: true -# When RAILS_ENV=test, strong passwords are disabled by default -Given "Strong passwords are enabled" do - Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) -end - Then /^I should see the error that the password is too weak$/ do assert has_content? User::STRONG_PASSWORD_FAIL_MSG end diff --git a/test/functional/partners/providers_controller_test.rb b/test/functional/partners/providers_controller_test.rb index a0f22e86b5..ef78ccd884 100644 --- a/test/functional/partners/providers_controller_test.rb +++ b/test/functional/partners/providers_controller_test.rb @@ -102,7 +102,6 @@ def provider_params test 'post with weak password rejected when strong passwords enabled' do prepare_master_account - Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) post :create, params: provider_params.merge(password: 'weakpwd') @@ -115,7 +114,6 @@ def provider_params test 'post with strong password accepted when strong passwords enabled' do prepare_master_account - Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) post :create, params: provider_params.merge(password: 'superSecret1234#') diff --git a/test/functional/partners/users_controller_test.rb b/test/functional/partners/users_controller_test.rb index 180cc383ad..83732e7dc4 100644 --- a/test/functional/partners/users_controller_test.rb +++ b/test/functional/partners/users_controller_test.rb @@ -93,8 +93,6 @@ def setup end test 'create user with weak password rejected when strong passwords enabled' do - Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) - post :create, params: { provider_id: @account.id, api_key: @partner.api_key, email: "foo@example.net", username: "aaron", password: "weakpwd" } assert_response :unprocessable_entity @@ -105,8 +103,6 @@ def setup end test 'create user with strong password accepted when strong passwords enabled' do - Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) - post :create, params: { provider_id: @account.id, api_key: @partner.api_key, email: "foo@example.net", username: "aaron", password: "superSecret1234#" } assert_response :success diff --git a/test/integration/admin/api/buyers_users_controller_test.rb b/test/integration/admin/api/buyers_users_controller_test.rb index 6247792b9a..ca2152607c 100644 --- a/test/integration/admin/api/buyers_users_controller_test.rb +++ b/test/integration/admin/api/buyers_users_controller_test.rb @@ -35,7 +35,6 @@ def setup test 'update with weak password rejected when strong passwords enabled' do user = FactoryBot.create(:simple_user, account: buyer) - Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) put admin_api_account_user_path(buyer, user), params: { access_token: token_value, password: 'weakpwd' } @@ -45,7 +44,6 @@ def setup test 'update with strong password accepted when strong passwords enabled' do user = FactoryBot.create(:simple_user, account: buyer) - Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) put admin_api_account_user_path(buyer, user), params: { access_token: token_value, password: 'superSecret1234#' } diff --git a/test/integration/developer_portal/signup_test.rb b/test/integration/developer_portal/signup_test.rb index 5d22fbc624..49d072ff89 100644 --- a/test/integration/developer_portal/signup_test.rb +++ b/test/integration/developer_portal/signup_test.rb @@ -99,8 +99,6 @@ def account_params(password) end def test_weak_password_rejected_when_strong_passwords_enabled - Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) - post signup_path, params: account_params(WEAK_PASSWORD) assert_response :success @@ -108,8 +106,6 @@ def test_weak_password_rejected_when_strong_passwords_enabled end def test_strong_password_accepted_when_strong_passwords_enabled - Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) - post signup_path, params: account_params(STRONG_PASSWORD) assert_response :redirect diff --git a/test/integration/provider/signups_controller_integration_test.rb b/test/integration/provider/signups_controller_integration_test.rb index 72e8fb562e..44fe526b45 100644 --- a/test/integration/provider/signups_controller_integration_test.rb +++ b/test/integration/provider/signups_controller_integration_test.rb @@ -104,8 +104,6 @@ def signup_params(password) end def test_weak_password_rejected_when_strong_passwords_enabled - Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) - assert_no_difference(master_account.buyer_accounts.method(:count)) do post provider_signup_path, params: signup_params(WEAK_PASSWORD) end @@ -115,8 +113,6 @@ def test_weak_password_rejected_when_strong_passwords_enabled end def test_strong_password_accepted_when_strong_passwords_enabled - Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) - assert_difference(master_account.buyer_accounts.method(:count)) do post provider_signup_path, params: signup_params(STRONG_PASSWORD) end diff --git a/test/integration/user-management-api/users_test.rb b/test/integration/user-management-api/users_test.rb index 688187ea6b..d0ff21d42a 100644 --- a/test/integration/user-management-api/users_test.rb +++ b/test/integration/user-management-api/users_test.rb @@ -401,7 +401,6 @@ def setup test 'update with weak password rejected when strong passwords enabled' do chuck = FactoryBot.create(:user, account: @provider, role: 'member') - Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) put admin_api_user_path(format: :xml, id: chuck.id, password: "weakpwd", password_confirmation: "weakpwd"), params: { provider_key: @provider.api_key } @@ -411,7 +410,6 @@ def setup test 'update with strong password accepted when strong passwords enabled' do chuck = FactoryBot.create(:user, account: @provider, role: 'member') - Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) put admin_api_user_path(format: :xml, id: chuck.id, password: "superSecret1234#", password_confirmation: "superSecret1234#"), params: { provider_key: @provider.api_key } diff --git a/test/unit/authentication/by_password_test.rb b/test/unit/authentication/by_password_test.rb index beee285379..9d7a7f8251 100644 --- a/test/unit/authentication/by_password_test.rb +++ b/test/unit/authentication/by_password_test.rb @@ -35,67 +35,61 @@ class WeakPasswordTest < Authentication::ByPasswordTest end end - class StrongPasswordsTest < Authentication::ByPasswordTest + class ExistingUsersTest < Authentication::ByPasswordTest setup do - Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) + @user = @buyer.users.first + @user.reload end - class ExistingUsersTest < StrongPasswordsTest - setup do - @user = @buyer.users.first - @user.reload - end - - test 'should be valid if not updating the password' do - @user.last_name = "not updating password" + test 'should be valid if not updating the password' do + @user.last_name = "not updating password" - @user.valid? - assert @user.errors[:password].blank? - end + @user.valid? + assert @user.errors[:password].blank? + end - test 'should be invalid if updating the password' do - @user.password = "nononono" - @user.valid? + test 'should be invalid if updating the password' do + @user.password = "nononono" + @user.valid? - assert_equal User::STRONG_PASSWORD_FAIL_MSG, @user.errors[:password].first - end + assert_equal User::STRONG_PASSWORD_FAIL_MSG, @user.errors[:password].first + end - test 'password is not validated when user is sample data' do - @user.password = "nononono" - @user.signup_type = :sample_data + test 'password is not validated when user is sample data' do + @user.password = "nononono" + @user.signup_type = :sample_data - assert @user.valid? - assert @user.errors[:password].blank? - end + assert @user.valid? + assert @user.errors[:password].blank? end + end - class ValidationsTest < StrongPasswordsTest - test 'should be valid with ASCII printable characters and longer than 15 characters' do - user = @buyer.users.new password: "StrongPass123-+_!$#.@", password_confirmation: "StrongPass123-+_!$#.@" - user.valid? + class ValidationsTest < Authentication::ByPasswordTest + test 'should be valid with ASCII printable characters and longer than 15 characters' do + user = @buyer.users.new password: "StrongPass123-+_!$#.@", password_confirmation: "StrongPass123-+_!$#.@" + user.valid? - assert user.errors[:password].blank? - end + assert user.errors[:password].blank? + end - test 'should be invalid if shorter than 15 characters' do - user = user_with_password.call('Pas$123') - user.valid? + test 'should be invalid if shorter than 15 characters' do + user = user_with_password.call('Pas$123') + user.valid? - assert_equal User::STRONG_PASSWORD_FAIL_MSG, user.errors[:password].first - end + assert_equal User::STRONG_PASSWORD_FAIL_MSG, user.errors[:password].first + end - test 'should be invalid if has strange characters' do - user = user_with_password.call('StrongPass|') - user.valid? + test 'should be invalid if has strange characters' do + user = user_with_password.call('StrongPass|') + user.valid? - assert_equal User::STRONG_PASSWORD_FAIL_MSG, user.errors[:password].first - end + assert_equal User::STRONG_PASSWORD_FAIL_MSG, user.errors[:password].first + end - test 'should be invalid if password and password confirmation do not match' do - @user = @buyer.users.first + test 'should be invalid if password and password confirmation do not match' do + @user = @buyer.users.first - assert_not @buyer.users.first.update password: "superSecret1234#", password_confirmation: "superSecret12345#" - end + assert_not @buyer.users.first.update password: "superSecret1234#", password_confirmation: "superSecret12345#" end end @@ -174,7 +168,6 @@ class ValidateStrongPasswordTest < MethodsTest end test 'returns true when strong_passwords_disabled is false and not sample_data and validate_password? is true' do - Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) @user.password = 'newpassword12345' @user.signup_type = :new_signup @@ -183,7 +176,6 @@ class ValidateStrongPasswordTest < MethodsTest end test 'returns false when strong_passwords_disabled is false and not sample_data but validate_password? is false' do - Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) @user.signup_type = :new_signup assert_not @user.validate_password? diff --git a/test/unit/logic/provider_signup_test.rb b/test/unit/logic/provider_signup_test.rb index 1f437ee11b..6adb113234 100644 --- a/test/unit/logic/provider_signup_test.rb +++ b/test/unit/logic/provider_signup_test.rb @@ -9,8 +9,6 @@ def setup end test 'John Doe user is created with weak password when strong passwords enabled' do - Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(false) - sample_data = Logic::ProviderSignup::SampleData.new(@provider) sample_data.create! From f2fa4589b6351668093b48fbfa82e9a51a048e12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Lled=C3=B3?= Date: Thu, 12 Feb 2026 14:32:28 +0100 Subject: [PATCH 17/19] First attempt to fix all tests... --- features/master/applications/keys.feature | 4 +- features/old/accounts/accounts.feature | 2 +- features/old/accounts/password_change.feature | 2 +- .../old/accounts/personal_details.feature | 25 ++++++++---- features/step_definitions/buyer_steps.rb | 2 +- .../admin/account/personal_details_steps.rb | 4 +- features/step_definitions/liquid_steps.rb | 2 +- features/step_definitions/provider_steps.rb | 8 ++-- features/step_definitions/session_steps.rb | 36 ++++++++--------- features/step_definitions/signup_steps.rb | 12 +++--- test/factories/simple.rb | 2 +- test/factories/user.rb | 2 +- .../personal_details_controller_test.rb | 4 +- .../user/personal_details_controller_test.rb | 12 +++--- .../admin/api/buyers_users_controller_test.rb | 2 +- test/integration/buyers/routes_test.rb | 2 +- test/integration/cms/toolbar_test.rb | 2 +- .../invitee_signups_controller_test.rb | 2 +- .../invitation_signup_test.rb | 2 +- test/integration/messages_test.rb | 2 +- .../payment_details_integration_test.rb | 2 +- .../payment_gateways/authorize_net_test.rb | 6 +-- .../payment_gateways/braintree_blue_test.rb | 7 ++-- .../payment_gateways/stripe_test.rb | 2 +- ...tee_signups_controller_integration_test.rb | 2 +- .../signups_controller_integration_test.rb | 2 +- test/integration/sessions_test.rb | 40 +++++++++---------- .../stats/api/applications_test.rb | 2 +- test/integration/stats/services_test.rb | 2 +- .../user-management-api/buyers_users_test.rb | 2 +- .../user-management-api/users_test.rb | 2 +- test/integration/utilization_test.rb | 2 +- test/test_helpers/authentication.rb | 4 +- test/unit/authentication/by_password_test.rb | 16 +++----- test/unit/sudo_test.rb | 6 +-- test/unit/user_test.rb | 20 +++++----- 36 files changed, 125 insertions(+), 121 deletions(-) diff --git a/features/master/applications/keys.feature b/features/master/applications/keys.feature index 2f50d12fb1..2e200ef7f7 100644 --- a/features/master/applications/keys.feature +++ b/features/master/applications/keys.feature @@ -14,7 +14,7 @@ Feature: Application Keys management Given they are reviewing the provider's application details When follow "Regenerate" And confirm the dialog - And fill in "Current password" with "supersecret" + And fill in "Current password" with "superSecret1234#" And press "Confirm Password" And should see "You are now in super-user mode! Retry the action, please" And follow "Regenerate" @@ -24,7 +24,7 @@ Feature: Application Keys management Scenario: Set a custom app key Given they are reviewing the provider's application details When follow "Set a custom User Key" within the API Credentials card - And fill in "Current password" with "supersecret" + And fill in "Current password" with "superSecret1234#" And press "Confirm Password" And fill in "User key" with "new-valid-key" And press "Save" diff --git a/features/old/accounts/accounts.feature b/features/old/accounts/accounts.feature index b2f6853ed7..a5725ee7b4 100644 --- a/features/old/accounts/accounts.feature +++ b/features/old/accounts/accounts.feature @@ -70,7 +70,7 @@ Feature: Account management And I navigate to the Account Settings And I go to the provider personal details page When I fill in "Email" with "invalid" - And I fill in "Current password" with "supersecret" + And I fill in "Current password" with "superSecret1234#" And I press "Update Details" Then I should see "should look like an email address" diff --git a/features/old/accounts/password_change.feature b/features/old/accounts/password_change.feature index a3b56b5f24..41b1699e38 100644 --- a/features/old/accounts/password_change.feature +++ b/features/old/accounts/password_change.feature @@ -8,7 +8,7 @@ Feature: Password change Given a provider is logged in And I go to the provider personal details page And I fill in "New password" with "monkey" - And I fill in "Current password" with "supersecret" + And I fill in "Current password" with "superSecret1234#" And I press "Update Details" And I log out And I go to the provider login page diff --git a/features/old/accounts/personal_details.feature b/features/old/accounts/personal_details.feature index ac3ec41ac5..b05d6ee0cc 100644 --- a/features/old/accounts/personal_details.feature +++ b/features/old/accounts/personal_details.feature @@ -12,7 +12,7 @@ Feature: Personal Details When I navigate to the Account Settings And I go to the provider personal details page And I fill in "Email" with "john.doe@foo.3scale.localhost" - And I fill in "Current password" with "supersecret" + And I fill in "Current password" with "superSecret1234#" And I press "Update Details" Then I should see "User was successfully updated" And I should be on the provider personal details page @@ -23,15 +23,15 @@ Feature: Personal Details And I follow "foo.3scale.localhost" Then I should be on the provider personal details page When I fill in "Email" with "john.doe@foo.3scale.localhost" - And I fill in "Current password" with "supersecret" + And I fill in "Current password" with "superSecret1234#" And I press "Update Details" Then I should be on the provider users page When I follow "foo.3scale.localhost" within the table And I fill in "Email" with "" - And I fill in "Current password" with "supersecret" + And I fill in "Current password" with "superSecret1234#" And I press "Update Details" And I fill in "Email" with "john.doe@foo.3scale.localhost" - And I fill in "Current password" with "supersecret" + And I fill in "Current password" with "superSecret1234#" And I press "Update Details" Then I should be on the provider users page And I should see the flash message "User was successfully updated" @@ -40,7 +40,7 @@ Feature: Personal Details When I navigate to the Account Settings And I go to the provider personal details page And I fill in "Username" with "u" - And I fill in "Current password" with "supersecret" + And I fill in "Current password" with "superSecret1234#" And I press "Update Details" Then field "Username" has inline error "is too short (minimum is 3 characters)" @@ -74,17 +74,26 @@ Feature: Personal Details | User extra required | When I fill in "First name" with "dude" And I fill in "User extra required" with "whatever" - And I fill in "Current password" with "supersecret" + And I fill in "Current password" with "superSecret1234#" And I press "Update Details" Then I should see "User was successfully updated" Then the "First name" field should contain "dude" And the "User extra required" field should contain "whatever" Scenario: Update own password when the user was signed up with password + Given the user was signed up with password + When I navigate to the Account Settings + And I go to the provider personal details page + And I fill in "New password" with "superSecret1234!" + And I fill in "Current password" with "superSecret1234#" + And I press "Update Details" + Then I should see "User was successfully updated" + + Scenario: Update own password to a weak password Given the user was signed up with password When I navigate to the Account Settings And I go to the provider personal details page And I fill in "New password" with "hi" - And I fill in "Current password" with "supersecret" + And I fill in "Current password" with "superSecret1234#" And I press "Update Details" - Then field "New password" has inline error "Password must be at least 15 characters long, and contain only valid characters" + Then I should see the error that the password is too weak \ No newline at end of file diff --git a/features/step_definitions/buyer_steps.rb b/features/step_definitions/buyer_steps.rb index 132d8e2f0f..faf232d5de 100644 --- a/features/step_definitions/buyer_steps.rb +++ b/features/step_definitions/buyer_steps.rb @@ -204,7 +204,7 @@ def login_form set_current_domain("foo.3scale.localhost") visit path_to('the login page') fill_in('Username or Email', with: username) - fill_in('Password', with: "supersecret") + fill_in('Password', with: "superSecret1234#") click_button('Sign in') end diff --git a/features/step_definitions/developer_portal/admin/account/personal_details_steps.rb b/features/step_definitions/developer_portal/admin/account/personal_details_steps.rb index 356050ea29..ba17fc75bb 100644 --- a/features/step_definitions/developer_portal/admin/account/personal_details_steps.rb +++ b/features/step_definitions/developer_portal/admin/account/personal_details_steps.rb @@ -4,7 +4,7 @@ fill_in('user[username]', with: 'Alfred') fill_in('user[email]', with: 'alfred@batcave.com') # password defined in test/factories/user.rb - fill_in('user[current_password]', with: 'supersecret') if has_css?('input[name="user[current_password]"]') + fill_in('user[current_password]', with: 'superSecret1234#') if has_css?('input[name="user[current_password]"]') end And "they change their password" do @@ -48,7 +48,7 @@ fill_in('user[first_name]', with: 'Alfred') fill_in('user[user_extra_required]', with: 'Butler') # password defined in test/factories/user.rb - fill_in('user[current_password]', with: 'supersecret') if has_css?('input[name="user[current_password]"]') + fill_in('user[current_password]', with: 'superSecret1234#') if has_css?('input[name="user[current_password]"]') end Then "they should be able to edit their custom personal details" do diff --git a/features/step_definitions/liquid_steps.rb b/features/step_definitions/liquid_steps.rb index 0001e1a744..dbb1f5ebc2 100644 --- a/features/step_definitions/liquid_steps.rb +++ b/features/step_definitions/liquid_steps.rb @@ -22,7 +22,7 @@ @account = FactoryBot.create(:buyer_account, provider_account: @provider, org_name: buyer_name) @account.buy!(@provider.account_plans.default) @account.update_attribute(:org_name, 'malicious buyer') - try_buyer_login_internal(buyer_name, 'supersecret') + try_buyer_login_internal(buyer_name, 'superSecret1234#') end When /^provider has xss protection enabled$/ do diff --git a/features/step_definitions/provider_steps.rb b/features/step_definitions/provider_steps.rb index b67fef22a0..7f985315a6 100644 --- a/features/step_definitions/provider_steps.rb +++ b/features/step_definitions/provider_steps.rb @@ -158,7 +158,7 @@ def import_simple_layout(provider) within signup_form do fill_in 'Email', with: user.email - fill_in 'Password', with: 'supersecret' + fill_in 'Password', with: 'superSecret1234#' fill_in 'Organization/Group Name', with: 'provider' fill_in 'Developer Portal', with: 'foo' @@ -177,7 +177,7 @@ def import_simple_layout(provider) within login_form do fill_in 'Email', with: user.email - fill_in 'Password', with: 'supersecret' + fill_in 'Password', with: 'superSecret1234#' click_on 'Sign in' end @@ -258,7 +258,7 @@ def setup_provider(login) return unless login - try_provider_login('foo.3scale.localhost', 'supersecret') + try_provider_login('foo.3scale.localhost', 'superSecret1234#') assert user_is_logged_in('foo.3scale.localhost') end @@ -289,7 +289,7 @@ def create_provider_with_plan(name, plan) # TODO: RENAME THIS NOWWW set_current_domain @master.external_domain stub_integration_errors_dashboard if login - try_provider_login(admin.username, 'supersecret') + try_provider_login(admin.username, 'superSecret1234#') assert user_is_logged_in(admin.username) end end diff --git a/features/step_definitions/session_steps.rb b/features/step_definitions/session_steps.rb index 230c11593f..9f49881881 100644 --- a/features/step_definitions/session_steps.rb +++ b/features/step_definitions/session_steps.rb @@ -3,7 +3,7 @@ Given "{provider} logs in" do |provider| set_current_domain(provider.external_admin_domain) username = provider.admins.first.username - try_provider_login(username, 'supersecret') + try_provider_login(username, 'superSecret1234#') assert user_is_logged_in(username) end @@ -12,21 +12,21 @@ Given "{provider} tries to log in" do |provider| set_current_domain(provider.external_admin_domain) username = provider.admins.first.username - try_provider_login(username, 'supersecret') + try_provider_login(username, 'superSecret1234#') end Given /^I am logged in as (provider )?"([^\"]*)"$/ do |provider,username| if provider - try_provider_login(username, 'supersecret') + try_provider_login(username, 'superSecret1234#') else - try_buyer_login_internal(username, 'supersecret') + try_buyer_login_internal(username, 'superSecret1234#') end assert user_is_logged_in(username) end Given /^I am logged in as provider "([^\"]*)" on its admin domain$/ do |username| set_current_domain(Account.providers.find_by(org_name: username).external_admin_domain) - try_provider_login(username, 'supersecret') + try_provider_login(username, 'superSecret1234#') assert user_is_logged_in(username) end @@ -38,9 +38,9 @@ set_current_domain(domain) if provider - try_provider_login(username, 'supersecret') + try_provider_login(username, 'superSecret1234#') else - try_buyer_login_internal(username, 'supersecret') + try_buyer_login_internal(username, 'superSecret1234#') end end @@ -55,7 +55,7 @@ master = Account.master set_current_domain(master.external_domain) username = master.admins.first.username - try_provider_login(username, 'supersecret') + try_provider_login(username, 'superSecret1234#') assert user_is_logged_in(username) end @@ -76,9 +76,9 @@ When /^I log in as (provider )?"([^"]*)"$/ do |provider,username| if provider - try_provider_login(username, 'supersecret') + try_provider_login(username, 'superSecret1234#') else - try_buyer_login_internal(username, 'supersecret') + try_buyer_login_internal(username, 'superSecret1234#') end assert user_is_logged_in(username) end @@ -86,7 +86,7 @@ When "{buyer} logs in" do |buyer| set_current_domain(buyer.provider_account.domain) user = buyer.users.first - try_buyer_login_internal(user.username, user.password || 'supersecret') + try_buyer_login_internal(user.username, user.password || 'superSecret1234#') assert user_is_logged_in(user.username) end @@ -97,21 +97,21 @@ set_current_domain(domain) if provider - try_provider_login(username, 'supersecret') + try_provider_login(username, 'superSecret1234#') else - try_buyer_login_internal(username, 'supersecret') + try_buyer_login_internal(username, 'superSecret1234#') end assert user_is_logged_in(username) end When "I log in as {string} on the admin domain of {provider}" do |username, provider| set_current_domain(provider.internal_admin_domain) - try_provider_login(username, 'supersecret') + try_provider_login(username, 'superSecret1234#') assert user_is_logged_in(username) end When "(I )(they )try to log in as (buyer ){string}" do |username| - try_buyer_login_internal(username, 'supersecret') + try_buyer_login_internal(username, 'superSecret1234#') end When "I try to log in as {string} with password {string}" do |username, password| @@ -119,7 +119,7 @@ end When "(I )(they )try to log in as provider {string}" do |username| - try_provider_login(username, 'supersecret') + try_provider_login(username, 'superSecret1234#') end When "I try to log in as provider {string} with password {string}" do |username, password| @@ -128,7 +128,7 @@ When /^I fill in the "([^"]*)" login data$/ do |username| fill_in('Username or Email', :with => username) - fill_in('Password', :with => "supersecret") + fill_in('Password', :with => "superSecret1234#") click_button('Sign in') end @@ -169,6 +169,6 @@ When "{user} logs in" do |user| log_out - try_provider_login(user.username, 'supersecret') + try_provider_login(user.username, 'superSecret1234#') assert user_is_logged_in(user.username) end diff --git a/features/step_definitions/signup_steps.rb b/features/step_definitions/signup_steps.rb index 4a192d2d38..fe9277bf2d 100644 --- a/features/step_definitions/signup_steps.rb +++ b/features/step_definitions/signup_steps.rb @@ -6,8 +6,8 @@ When /^I fill in the invitation signup as "([^"]*)"$/ do |username| fill_in("Username", :with => username) - fill_in("Password", :with => "supersecret") - fill_in("Password confirmation", :with => "supersecret") + fill_in("Password", :with => "superSecret1234#") + fill_in("Password confirmation", :with => "superSecret1234#") click_button "Sign up" end @@ -19,8 +19,8 @@ def fill_in_signup_fields_as(name) fill_in('Username', with: name) fill_in('Email', with: "#{name}@3scale.localhost") fill_in('Organization/Group Name', with: "#{name}'s stuff") - fill_in('Password', with: 'supersecret') - fill_in('Password confirmation', with: 'supersecret') + fill_in('Password', with: 'superSecret1234#') + fill_in('Password confirmation', with: 'superSecret1234#') click_on 'Sign up' end @@ -36,8 +36,8 @@ def fill_in_signup_fields_as(name) fill_in "Username", :with => email.gsub(/[^\w]/, '-') fill_in "Email", :with => email fill_in "Organization/Group Name", :with => email.gsub(/[^\w]/, '-') - fill_in "Password", :with => "supersecret" - fill_in "Password confirmation", :with => "supersecret" + fill_in "Password", :with => "superSecret1234#" + fill_in "Password confirmation", :with => "superSecret1234#" click_button "Sign up" end diff --git a/test/factories/simple.rb b/test/factories/simple.rb index 2895a1e5e8..afb193ec35 100644 --- a/test/factories/simple.rb +++ b/test/factories/simple.rb @@ -111,7 +111,7 @@ factory(:simple_user, :class => User) do sequence(:email) { |n| "simple#{n}@example.net" } sequence(:username) { |n| "simpledude#{n}" } - password { 'supersecret' } + password { 'superSecret1234#' } association(:account, :factory => :simple_provider) # TODO: maybe activate it? end diff --git a/test/factories/user.rb b/test/factories/user.rb index 96ffc22369..5cac1ade0f 100644 --- a/test/factories/user.rb +++ b/test/factories/user.rb @@ -2,7 +2,7 @@ factory(:pending_user, :class => :user) do sequence(:email) { |n| "foo#{n}@example.net" } sequence(:username) { |n| "dude#{n}" } - password { 'supersecret' } + password { 'superSecret1234#' } signup_type { 'new_signup' } # means the user signed up for a plan end diff --git a/test/functional/developer_portal/admin/account/personal_details_controller_test.rb b/test/functional/developer_portal/admin/account/personal_details_controller_test.rb index 8e9e7e1a5c..6f646c9bc3 100644 --- a/test/functional/developer_portal/admin/account/personal_details_controller_test.rb +++ b/test/functional/developer_portal/admin/account/personal_details_controller_test.rb @@ -52,7 +52,7 @@ def setup test 'update should succeed with current password' do login_as @buyer.admins.first - put :update, params: { user: {current_password: 'supersecret', username: 'test', email: 'test@example.com'}} + put :update, params: { user: {current_password: 'superSecret1234#', username: 'test', email: 'test@example.com'}} assert_redirected_to admin_account_users_path assert_equal flash[:notice], 'User was successfully updated.' end @@ -70,7 +70,7 @@ def setup assert_difference(Audited.audit_class.method(:count)) do User.with_synchronous_auditing do - put :update, params: { user: {current_password: 'supersecret', password: 'new_password', password_confirmation: 'new_password'} } + put :update, params: { user: {current_password: 'superSecret1234#', password: 'new_password_123', password_confirmation: 'new_password_123'} } end end diff --git a/test/functional/provider/admin/user/personal_details_controller_test.rb b/test/functional/provider/admin/user/personal_details_controller_test.rb index 186118e435..5750260c68 100644 --- a/test/functional/provider/admin/user/personal_details_controller_test.rb +++ b/test/functional/provider/admin/user/personal_details_controller_test.rb @@ -12,12 +12,12 @@ def setup test "put update should redirect to users" do - put :update, params: { user: {current_password: 'supersecret', username: 'test', email: 'test@example.com'}, origin: 'users' } + put :update, params: { user: {current_password: 'superSecret1234#', username: 'test', email: 'test@example.com'}, origin: 'users' } assert_redirected_to provider_admin_account_users_path end test "put update should redirect to edit personal details" do - put :update, params: { user: {current_password: 'supersecret', username: 'test', email: 'test@example.com'} } + put :update, params: { user: {current_password: 'superSecret1234#', username: 'test', email: 'test@example.com'} } assert_redirected_to edit_provider_admin_user_personal_details_path end @@ -30,7 +30,7 @@ def setup test 'changing password is audited' do assert_difference(Audited.audit_class.method(:count)) do User.with_synchronous_auditing do - put :update, params: { user: {current_password: 'supersecret', password: 'new_password', password_confirmation: 'new_password'} } + put :update, params: { user: {current_password: 'superSecret1234#', password: 'new_password_123', password_confirmation: 'new_password_123'} } end end @@ -110,7 +110,7 @@ def setup end test 'user with password can update when providing correct current password' do - put :update, params: { user: { current_password: 'supersecret', username: 'newusername' } } + put :update, params: { user: { current_password: 'superSecret1234#', username: 'newusername' } } assert_redirected_to edit_provider_admin_user_personal_details_path assert_equal 'newusername', @user.reload.username @@ -129,10 +129,10 @@ def setup end test 'user can change password when enforce SSO is enabled' do - put :update, params: { user: { current_password: 'supersecret', password: 'superSecret1234#', password_confirmation: 'superSecret1234#' } } + put :update, params: { user: { current_password: 'superSecret1234#', password: 'new_password_123', password_confirmation: 'new_password_123' } } assert_redirected_to edit_provider_admin_user_personal_details_path - assert @user.reload.authenticated?('superSecret1234#') + assert @user.reload.authenticated?('new_password_123') end test 'SSO user without password can set password when enforce SSO is enabled' do diff --git a/test/integration/admin/api/buyers_users_controller_test.rb b/test/integration/admin/api/buyers_users_controller_test.rb index ca2152607c..25d357e60f 100644 --- a/test/integration/admin/api/buyers_users_controller_test.rb +++ b/test/integration/admin/api/buyers_users_controller_test.rb @@ -58,7 +58,7 @@ def params access_token: token_value, username: 'testusername', email: 'test@example.com', - password: '123456', + password: 'superSecret1234#', first_name: 'testname', last_name: 'testsurname' } diff --git a/test/integration/buyers/routes_test.rb b/test/integration/buyers/routes_test.rb index 77b62c18f0..447d38be4e 100644 --- a/test/integration/buyers/routes_test.rb +++ b/test/integration/buyers/routes_test.rb @@ -6,7 +6,7 @@ def setup @provider = FactoryBot.create(:provider_account) @buyer = FactoryBot.create(:buyer_account, provider_account: @provider) host! @provider.internal_domain - login_with @buyer.admins.first.username, "supersecret" + login_with @buyer.admins.first.username, "superSecret1234#" end test 'redirect /p/admin/dashboard to /admin' do diff --git a/test/integration/cms/toolbar_test.rb b/test/integration/cms/toolbar_test.rb index 02de592175..68e5f24c6f 100644 --- a/test/integration/cms/toolbar_test.rb +++ b/test/integration/cms/toolbar_test.rb @@ -19,7 +19,7 @@ def setup get '/api_docs/login' assert_response :success - login_with @buyer.admins.first.username, "supersecret" + login_with @buyer.admins.first.username, "superSecret1234#" get '/admin' assert_response :success diff --git a/test/integration/developer_portal/accounts/invitee_signups_controller_test.rb b/test/integration/developer_portal/accounts/invitee_signups_controller_test.rb index d0a4e5fc8b..57e37c5a24 100644 --- a/test/integration/developer_portal/accounts/invitee_signups_controller_test.rb +++ b/test/integration/developer_portal/accounts/invitee_signups_controller_test.rb @@ -68,6 +68,6 @@ def setup private def user_params - { username: 'admin', password: 'supersecret' } + { username: 'admin', password: 'superSecret1234#' } end end diff --git a/test/integration/developer_portal/invitation_signup_test.rb b/test/integration/developer_portal/invitation_signup_test.rb index 285e33d700..030f5e8322 100644 --- a/test/integration/developer_portal/invitation_signup_test.rb +++ b/test/integration/developer_portal/invitation_signup_test.rb @@ -134,7 +134,7 @@ def user_valid_params { email: "foo_#{index}@example.net", username: "bar#{index}", - password: '123456' + password: 'superSecret1234#' } end end diff --git a/test/integration/messages_test.rb b/test/integration/messages_test.rb index 34d58c974e..c5185c1e17 100644 --- a/test/integration/messages_test.rb +++ b/test/integration/messages_test.rb @@ -6,7 +6,7 @@ def setup @provider = FactoryBot.create :provider_account @buyer = FactoryBot.create :buyer_account, :provider_account => @provider host! @provider.external_admin_domain - provider_login_with @provider.admins.first, 'supersecret' + provider_login_with @provider.admins.first, 'superSecret1234#' end test "ensure buyer domain" do diff --git a/test/integration/payment_details_integration_test.rb b/test/integration/payment_details_integration_test.rb index 3ee2d8ae6a..faca5dc2c9 100644 --- a/test/integration/payment_details_integration_test.rb +++ b/test/integration/payment_details_integration_test.rb @@ -10,7 +10,7 @@ class PaymentDetailsIntegrationTest < ActionDispatch::IntegrationTest host! provider.internal_domain assert !provider.settings.finance.visible? - login_with buyer.admins.first.username, "supersecret" + login_with buyer.admins.first.username, "superSecret1234#" get developer_portal.admin_account_stripe_path assert_response 403 diff --git a/test/integration/payment_gateways/authorize_net_test.rb b/test/integration/payment_gateways/authorize_net_test.rb index 078b3e2025..032657a961 100644 --- a/test/integration/payment_gateways/authorize_net_test.rb +++ b/test/integration/payment_gateways/authorize_net_test.rb @@ -23,7 +23,7 @@ def setup end # test "new users get AddProfile link" do - # login_with @buyer_account.admins.first.username, 'supersecret' + # login_with @buyer_account.admins.first.username, 'superSecret1234#' # @buyer_account.credit_card_auth_code = nil # @buyer_account.credit_card_authorize_net_payment_profile_token = nil @@ -33,14 +33,14 @@ def setup # end # test "old users without credit card get AddProfile link" do - # login_with @buyer_account.admins.first.username, 'supersecret' + # login_with @buyer_account.admins.first.username, 'superSecret1234#' # @buyer_account.credit_card_auth_code= 'code' # get "/admin/account/authorize_net" # assert_select('form[action=?]', "https://test.authorize.net/profile//AddPayment") # end # test "old users with credit card get editProfile link" do - # login_with @buyer_account.admins.first.username, 'supersecret' + # login_with @buyer_account.admins.first.username, 'superSecret1234#' # @buyer_account.credit_card_auth_code= 'code' # get "/admin/account/authorize_net" # assert_select('form[action=?]', "https://test.authorize.net/profile//editPayment") diff --git a/test/integration/payment_gateways/braintree_blue_test.rb b/test/integration/payment_gateways/braintree_blue_test.rb index dfc11d7b62..93c13ee835 100644 --- a/test/integration/payment_gateways/braintree_blue_test.rb +++ b/test/integration/payment_gateways/braintree_blue_test.rb @@ -13,7 +13,7 @@ def setup end test "navigate to the correct link" do - login_with @buyer_account.admins.first.username, 'supersecret' + login_with @buyer_account.admins.first.username, 'superSecret1234#' get "/admin/account/" details_url = "/admin/account/braintree_blue" @@ -26,14 +26,13 @@ def setup @provider_account.payment_gateway_options[:merchant_id] = "my-payment-gw-mid" @provider_account.payment_gateway_options[:public_key] = "AnY-pUbLiC-kEy" @provider_account.payment_gateway_options[:private_key] = "a1b2c3d4e5" - login_with @buyer_account.admins.first.username, 'supersecret' - assert_nil @buyer_account.credit_card_partial_number + assert_nil @buyer_account.credit_card_partial_number end test "credit card not stored" do # stub BrainTreeBlueCrypt.new(current_user).confirm(request) to return struct that answers false to success - login_with @buyer_account.admins.first.username, 'supersecret' + login_with @buyer_account.admins.first.username, 'superSecret1234#' PaymentGateways::BrainTreeBlueCrypt.any_instance.stubs(:confirm).returns(false) get "/admin/account/braintree_blue/hosted_success" end diff --git a/test/integration/payment_gateways/stripe_test.rb b/test/integration/payment_gateways/stripe_test.rb index 43f0ad2918..9f282eaf40 100644 --- a/test/integration/payment_gateways/stripe_test.rb +++ b/test/integration/payment_gateways/stripe_test.rb @@ -12,7 +12,7 @@ def setup end test "checks that the correct link exists" do - login_with @buyer_account.admins.first.username, 'supersecret' + login_with @buyer_account.admins.first.username, 'superSecret1234#' get "/admin/account/" details_url = "/admin/account/stripe" diff --git a/test/integration/provider/invitee_signups_controller_integration_test.rb b/test/integration/provider/invitee_signups_controller_integration_test.rb index 13de17d601..80d5c7c648 100644 --- a/test/integration/provider/invitee_signups_controller_integration_test.rb +++ b/test/integration/provider/invitee_signups_controller_integration_test.rb @@ -63,6 +63,6 @@ def setup private def user_params - { username: 'admin', password: 'supersecret' } + { username: 'admin', password: 'superSecret1234#' } end end diff --git a/test/integration/provider/signups_controller_integration_test.rb b/test/integration/provider/signups_controller_integration_test.rb index 44fe526b45..95745d8734 100644 --- a/test/integration/provider/signups_controller_integration_test.rb +++ b/test/integration/provider/signups_controller_integration_test.rb @@ -80,7 +80,7 @@ def create_params(extra_params = {}) @create_params ||= { account: { name: 'organization name', - user: {email: 'email@example.com', password: '123456'} + user: {email: 'email@example.com', password: 'superSecret1234#'} } }.deep_merge(extra_params) end diff --git a/test/integration/sessions_test.rb b/test/integration/sessions_test.rb index f47739a822..a722fe6e69 100644 --- a/test/integration/sessions_test.rb +++ b/test/integration/sessions_test.rb @@ -112,19 +112,19 @@ def setup end test 'redirect_url parameter is discarded if login is not via sso' do - user = FactoryBot.create(:user, account: @buyer, username: 'xi@example.net', password: 'wwwwww') + user = FactoryBot.create(:user, account: @buyer, username: 'xi@example.net', password: 'superSecret1234#') user.activate host! @provider.internal_domain - get developer_portal.create_session_url(username: user.username, password: 'wwwwww', redirect_url: forum_url(host: @provider.internal_domain)) + get developer_portal.create_session_url(username: user.username, password: 'superSecret1234#', redirect_url: forum_url(host: @provider.internal_domain)) follow_redirect! assert_equal root_path, path end test 'passing redirect_url with token' do - user = FactoryBot.create(:user, account: @buyer, username: 'xi@example.net', password: 'wwwwww') + user = FactoryBot.create(:user, account: @buyer, username: 'xi@example.net', password: 'superSecret1234#') user.activate Authentication::Strategy::Token.any_instance.expects(:authenticate_with_sso).with('yabadabado', '2016').returns(user) @@ -138,37 +138,37 @@ def setup end test 'passing redirect_to to login form' do - user = FactoryBot.create(:user, account: @buyer, username: 'xi@example.net', password: 'password') + user = FactoryBot.create(:user, account: @buyer, username: 'xi@example.net', password: 'superSecret1234#') user.activate host! @provider.internal_domain get developer_portal.login_path(return_to: '/some-page') - post developer_portal.session_path(username: 'xi@example.net', password: 'password') + post developer_portal.session_path(username: 'xi@example.net', password: 'superSecret1234#') assert_redirected_to '/some-page' assert_equal user, User.current end test 'passing redirect_to to outside domain' do - user = FactoryBot.create(:user, account: @buyer, username: 'xi@example.net', password: 'password') + user = FactoryBot.create(:user, account: @buyer, username: 'xi@example.net', password: 'superSecret1234#') user.activate host! @provider.internal_domain get developer_portal.login_path(return_to: 'http://example.com/some-page') - post developer_portal.session_path(username: 'xi@example.net', password: 'password') + post developer_portal.session_path(username: 'xi@example.net', password: 'superSecret1234#') assert_redirected_to "http://#{@provider.external_domain}/some-page" assert_equal user, User.current end test 'current user is not persisted across domains' do - provider_user = FactoryBot.create(:user, account: @provider, username: 'provider', password: 'provider') + provider_user = FactoryBot.create(:user, account: @provider, username: 'provider', password: 'superSecret1234#') provider_user.activate! open_session do |session| session.host! @provider.external_admin_domain - session.post provider_sessions_path(username: 'provider', password: 'provider') + session.post provider_sessions_path(username: 'provider', password: 'superSecret1234#') session.assert_response :redirect session.assert_equal provider_user, User.current @@ -184,10 +184,10 @@ def setup end test 'mixpanel event properties are not persisted across requests' do - provider_user = FactoryBot.create(:user, account: @provider, username: 'provider', password: 'provider') + provider_user = FactoryBot.create(:user, account: @provider, username: 'provider', password: 'superSecret1234#') provider_user.activate! - other_provider_user = FactoryBot.create(:user, account: @provider, username: 'other_provider', password: 'provider') + other_provider_user = FactoryBot.create(:user, account: @provider, username: 'other_provider', password: 'superSecret1234#') other_provider_user.activate! analytics = sequence('analytics calls') @@ -201,7 +201,7 @@ def setup .with { |params| params[:user_id] == provider_user.id } session.host! @provider.external_admin_domain - session.post provider_sessions_path(username: 'provider', password: 'provider') + session.post provider_sessions_path(username: 'provider', password: 'superSecret1234#') session.assert_response :redirect end @@ -213,7 +213,7 @@ def setup .with { |params| params[:user_id] == other_provider_user.id } session.host! @provider.external_admin_domain - session.post provider_sessions_path(username: 'other_provider', password: 'provider') + session.post provider_sessions_path(username: 'other_provider', password: 'superSecret1234#') session.assert_response :redirect end @@ -223,7 +223,7 @@ def setup host! @provider.external_admin_domain user = @provider.admins.first - provider_login_with user.username, 'supersecret' + provider_login_with user.username, 'superSecret1234#' assert_equal 1, user.user_sessions.count assert_no_difference '@provider.reload.updated_at' do @@ -244,11 +244,11 @@ def setup user.user_sessions.create host! @provider.external_admin_domain - provider_login_with user.username, 'supersecret' + provider_login_with user.username, 'superSecret1234#' assert_equal 2, user.user_sessions.count put provider_admin_user_personal_details_path, params: { user: { - current_password: 'supersecret', - password: 'newpwd', + current_password: 'superSecret1234#', + password: 'new_password_123', username: 'test', email: 'test2@example.com' } } @@ -261,11 +261,11 @@ def setup user.user_sessions.create host! @provider.internal_domain - login_with user.username, 'supersecret' + login_with user.username, 'superSecret1234#' assert_equal 2, user.user_sessions.count put System::UrlHelpers.cms_url_helpers.admin_account_personal_details_path, params: { user: { - current_password: 'supersecret', - password: 'newpwd', + current_password: 'superSecret1234#', + password: 'new_password_123', username: 'test', email: 'test2@example.com' } } diff --git a/test/integration/stats/api/applications_test.rb b/test/integration/stats/api/applications_test.rb index f9437b4768..b080362afd 100644 --- a/test/integration/stats/api/applications_test.rb +++ b/test/integration/stats/api/applications_test.rb @@ -10,7 +10,7 @@ def setup end test 'usage_response_code with no data as json' do - provider_login_with @admin, 'supersecret' + provider_login_with @admin, 'superSecret1234#' get usage_response_code_stats_api_applications_path(@cinstance, format: :json), params: { period: 'day', response_code: 200, timezone: 'Madrid', skip_change: false } diff --git a/test/integration/stats/services_test.rb b/test/integration/stats/services_test.rb index 37c75ed09c..ca543762f5 100644 --- a/test/integration/stats/services_test.rb +++ b/test/integration/stats/services_test.rb @@ -11,7 +11,7 @@ def setup Stats::Base.storage.flushdb host! @provider_account.internal_admin_domain - provider_login_with @provider_account.admins.first.username, 'supersecret' + provider_login_with @provider_account.admins.first.username, 'superSecret1234#' end test 'usage_response_code with no data as json' do diff --git a/test/integration/user-management-api/buyers_users_test.rb b/test/integration/user-management-api/buyers_users_test.rb index d6fa3d7e4c..92be8f9af5 100644 --- a/test/integration/user-management-api/buyers_users_test.rb +++ b/test/integration/user-management-api/buyers_users_test.rb @@ -369,7 +369,7 @@ def setup test 'update also updates password' do chuck = FactoryBot.create(:user, account: @buyer, role: "member") assert_not_empty chuck.password_digest - assert chuck.authenticate('supersecret') + assert chuck.authenticate('superSecret1234#') put admin_api_account_user_path(account_id: @buyer.id, format: :xml, id: chuck.id, diff --git a/test/integration/user-management-api/users_test.rb b/test/integration/user-management-api/users_test.rb index d0ff21d42a..cad34d053d 100644 --- a/test/integration/user-management-api/users_test.rb +++ b/test/integration/user-management-api/users_test.rb @@ -390,7 +390,7 @@ def setup test 'update also updates password' do chuck = FactoryBot.create(:user, account: @provider, role: 'member') - assert chuck.authenticated?('supersecret') + assert chuck.authenticated?('superSecret1234#') put admin_api_user_path(format: :xml, id: chuck.id, password: "updated-password", password_confirmation: "updated-password"), params: { provider_key: @provider.api_key } diff --git a/test/integration/utilization_test.rb b/test/integration/utilization_test.rb index aed31d0a5f..e55bbde999 100644 --- a/test/integration/utilization_test.rb +++ b/test/integration/utilization_test.rb @@ -14,7 +14,7 @@ class UtilizationTest < ActionDispatch::IntegrationTest @metrics = FactoryBot.create_list(:metric, 4, service: service) host! provider.external_admin_domain - provider_login_with provider.admins.first.username, 'supersecret' + provider_login_with provider.admins.first.username, 'superSecret1234#' end teardown do diff --git a/test/test_helpers/authentication.rb b/test/test_helpers/authentication.rb index c81ca23d6e..4a9597ad8a 100644 --- a/test/test_helpers/authentication.rb +++ b/test/test_helpers/authentication.rb @@ -43,7 +43,7 @@ def login_buyer(account, user: account.admins.first!) def login!(provider, user: provider.admins.first) host! provider.external_admin_domain - provider_login_with user.username, 'supersecret' + provider_login_with user.username, 'superSecret1234#' end alias_method :login_provider, :login! @@ -51,7 +51,7 @@ def login!(provider, user: provider.admins.first) def login_buyer(account) host! account.provider_account.internal_domain user = account.admins.first - login_with user.username, 'supersecret' + login_with user.username, 'superSecret1234#' end def provider_login_with(username, password) diff --git a/test/unit/authentication/by_password_test.rb b/test/unit/authentication/by_password_test.rb index 9d7a7f8251..03ffbed825 100644 --- a/test/unit/authentication/by_password_test.rb +++ b/test/unit/authentication/by_password_test.rb @@ -20,11 +20,11 @@ class HasSecurePasswordTest < Authentication::ByPasswordTest end class WeakPasswordTest < Authentication::ByPasswordTest - test 'should by default allow weak ones' do + test 'should by default forbid weak ones' do user = user_with_password.call('weakpassword') - assert user.valid? - assert user.errors[:password].blank? + assert_not user.valid? + assert_equal User::STRONG_PASSWORD_FAIL_MSG, user.errors[:password].first end test 'weak password must be present' do @@ -79,17 +79,11 @@ class ValidationsTest < Authentication::ByPasswordTest assert_equal User::STRONG_PASSWORD_FAIL_MSG, user.errors[:password].first end - test 'should be invalid if has strange characters' do - user = user_with_password.call('StrongPass|') - user.valid? - - assert_equal User::STRONG_PASSWORD_FAIL_MSG, user.errors[:password].first - end - test 'should be invalid if password and password confirmation do not match' do @user = @buyer.users.first assert_not @buyer.users.first.update password: "superSecret1234#", password_confirmation: "superSecret12345#" + assert_equal "doesn't match Password", @buyer.users.first.errors[:password_confirmation].first end end @@ -155,6 +149,8 @@ class ValidateStrongPasswordTest < MethodsTest end test 'returns false when strong_passwords_disabled is true' do + Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(true) + @user.password = 'newpassword12345' assert_not @user.validate_strong_password? diff --git a/test/unit/sudo_test.rb b/test/unit/sudo_test.rb index 3af66ba6bd..6e273bcc10 100644 --- a/test/unit/sudo_test.rb +++ b/test/unit/sudo_test.rb @@ -9,14 +9,14 @@ def setup end def test_correct_password? - refute @sudo.correct_password?('invalid-password') - assert @sudo.correct_password?('supersecret') + assert_not @sudo.correct_password?('invalid-password') + assert @sudo.correct_password?('superSecret1234#') end def test_correct_password_without_email @user.update_column :email, nil user_session = UserSession.create(user_id: @user.id) @sudo = Sudo.new(return_path: '/', user_session: user_session) - assert @sudo.correct_password?('supersecret') + assert @sudo.correct_password?('superSecret1234#') end end diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb index de41ba3ea1..03b6e40578 100644 --- a/test/unit/user_test.rb +++ b/test/unit/user_test.rb @@ -253,7 +253,7 @@ def test_accessible_services UserMailer.expects(:deliver_activation_notification).never user.username = 'liz' - user.password = 'foobar' + user.password = 'superSecret1234#' user.save! end @@ -274,12 +274,12 @@ def test_accessible_services end test 'reset password' do - user = FactoryBot.create(:simple_user, username: 'person', password: 'foobar') + user = FactoryBot.create(:simple_user, username: 'person', password: 'superSecret1234#') user.activate! - user.update(password: 'new password', password_confirmation: 'new password') + user.update(password: 'new_password_123', password_confirmation: 'new_password_123') - assert user.authenticated?('new password') + assert user.authenticated?('new_password_123') end class ExistingProviderUserTest < ActiveSupport::TestCase @@ -300,7 +300,7 @@ class ExistingProviderUserTest < ActiveSupport::TestCase @user = FactoryBot.create(:simple_user, account: account, username: 'person', email: 'person@example.org', - password: 'redpanda') + password: 'superSecret1234#') @user.activate! end @@ -308,7 +308,7 @@ class ExistingProviderUserTest < ActiveSupport::TestCase @user.update(username: 'person2') @user.reload - assert @user.authenticated?('redpanda') + assert @user.authenticated?('superSecret1234#') end test 'set remember_token' do @@ -403,7 +403,7 @@ class ExistingProviderUserTest < ActiveSupport::TestCase test 'with lost_password_token should reset lost_password_token when password is changed' do @user.generate_lost_password_token! @user = User.find(@user.id) # HACK: to reset stored passwords - @user.update_password('new_password', 'new_password') + @user.update_password('new_password_123', 'new_password_123') @user.save! assert_nil @user.lost_password_token @@ -421,7 +421,7 @@ class ExistingProviderUserTest < ActiveSupport::TestCase test 'with lost_password_token should not reset lost_password_token when user incorrectly confirms new password' do @user.generate_lost_password_token! @user = User.find(@user.id) # HACK: to reset stored passwords - @user.update_password('new_password', 'not_new_password') + @user.update_password('new_password_123', 'not_new_password_123') assert_not_nil @user.lost_password_token end end @@ -752,7 +752,7 @@ class WebhookTest < ActiveSupport::TestCase test 'destroys its invitation' do invitation = FactoryBot.create(:invitation, email: "invited@example.com", account: FactoryBot.create(:provider_account)) - user = invitation.make_user username: "username", password: "password" + user = invitation.make_user username: "username", password: "superSecret1234#" user.save! user.destroy @@ -765,7 +765,7 @@ class WebhookTest < ActiveSupport::TestCase Invitation.any_instance.stubs(:destroy).returns(false) invitation = FactoryBot.create(:invitation) - user = invitation.make_user username: "username", password: "password" + user = invitation.make_user username: "username", password: "superSecret1234#" user.save! assert_not user.destroy From 899cff09e728c3157b7e2ee4d754335c4a1674f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Lled=C3=B3?= Date: Thu, 12 Feb 2026 17:35:41 +0100 Subject: [PATCH 18/19] Fix more tests... --- features/buyers/accounts/new.feature | 7 +-- .../admin/account/personal_details.feature | 2 +- .../buyer_password_reset.feature | 12 ++--- features/old/accounts/password_change.feature | 4 +- features/old/authentication/internal.feature | 16 +++---- features/old/buyers/impersonate.feature | 4 +- features/old/signup/fields.feature | 4 +- .../old/signup/multiple_cinstances.feature | 6 +-- features/old/signup/providers.feature | 10 ++--- features/old/signup/strong_passwords.feature | 1 + features/provider/admin/accounts/new.feature | 8 ++-- features/step_definitions/account_steps.rb | 2 +- .../admin/account/personal_details_steps.rb | 2 +- .../strong_passwords_steps.rb | 5 +++ spec/acceptance/api/account_spec.rb | 2 +- .../developer_portal/login_controller_test.rb | 2 +- .../signup_controller_test.rb | 4 +- .../partners/users_controller_test.rb | 4 +- .../application_controller_test.rb | 10 ++--- .../buyers/accounts_controller_test.rb | 6 +-- .../developer_portal/login_test.rb | 2 +- .../passwords_controller_test.rb | 8 ++-- .../developer_portal/signup_test.rb | 2 +- .../providers_controller_integration_test.rb | 2 +- .../multitenant_enforcement_test.rb | 2 +- .../admin/accounts_controller_test.rb | 2 +- .../provider/passwords_integration_test.rb | 2 +- test/integration/signup_express_test.rb | 2 +- test/integration/sso_enforce_flow_test.rb | 4 +- test/unit/account/fields_test.rb | 2 +- .../authentication/strategy/internal_test.rb | 44 +++++++++---------- test/unit/invitation_test.rb | 2 +- test/unit/services/signup_service_test.rb | 4 +- test/unit/signup/account_manager_test.rb | 2 +- test/unit/user/roles_test.rb | 2 +- test/unit/user/states_test.rb | 2 +- 36 files changed, 101 insertions(+), 94 deletions(-) diff --git a/features/buyers/accounts/new.feature b/features/buyers/accounts/new.feature index 7cd7c6b4f3..da3bb1b969 100644 --- a/features/buyers/accounts/new.feature +++ b/features/buyers/accounts/new.feature @@ -35,9 +35,9 @@ Feature: Audience > Accounts > New Scenario: Fields validation Given they go to the new buyer account page When the form is submitted with: - | Username | u | - | Email | invalid | - | Password | p | + | Username | u | + | Email | invalid | + | Password | superSecret1234# | | Organization/Group Name | Org | Then field "Username" has inline error "is too short" And field "Email" has inline error "should look like an email address" @@ -63,6 +63,7 @@ Feature: Audience > Accounts > New | Organization/Group Name | Alice's Web Widget | | Country | Spain | | Fields with choices | option1 | + | Password | superSecret1234# | Then the current page is the buyer account page for "Alice's Web Widget" And the inverted table has the following rows within the account details card: diff --git a/features/developer_portal/admin/account/personal_details.feature b/features/developer_portal/admin/account/personal_details.feature index 7aedf94477..98f54f5c9a 100644 --- a/features/developer_portal/admin/account/personal_details.feature +++ b/features/developer_portal/admin/account/personal_details.feature @@ -62,7 +62,7 @@ Feature: Dev Portal Buyer Personal Details | User extra read only | | User extra hidden | - And fill in "Current Password" with "supersecret" + And fill in "Current Password" with "superSecret1234#" And they press "Update Personal Details" Then they should see error in fields: | errors | diff --git a/features/developer_portal/buyer_password_reset.feature b/features/developer_portal/buyer_password_reset.feature index e125fcfbc9..2973272dad 100644 --- a/features/developer_portal/buyer_password_reset.feature +++ b/features/developer_portal/buyer_password_reset.feature @@ -35,14 +35,14 @@ Feature: Buyer password reset And they press "Send instructions" Then they should see "A password reset link will be sent to zed@3scale.localhost if a user exists with this email" When they follow the link found in the password reset email send to "zed@3scale.localhost" - And they fill in "Password" with "monkey" - And they fill in "Password confirmation" with "monkey" + And they fill in "Password" with "superSecret1234#" + And they fill in "Password confirmation" with "superSecret1234#" And they press "Change Password" Then they should see "The password has been changed" When they go to the login page And they fill in "Username" with "zed@3scale.localhost" - And they fill in "Password" with "monkey" + And they fill in "Password" with "superSecret1234#" And they press "Sign in" Then they should be logged in as "zed" @@ -59,11 +59,11 @@ Feature: Buyer password reset And they fill in "Email" with "zed@3scale.localhost" And they press "Send instructions" And they follow the link found in the password reset email send to "zed@3scale.localhost" - And they fill in "Password" with "monkey" - And they fill in "Password confirmation" with "donkey" + And they fill in "Password" with "new_password_123" + And they fill in "Password confirmation" with "123_new_password" And they press "Change Password" Then they should see the password confirmation error - And the password of user "zed" should not be "monkey" + And the password of user "zed" should not be "new_password_123" Scenario: Blank passwords When they follow "Forgot password?" diff --git a/features/old/accounts/password_change.feature b/features/old/accounts/password_change.feature index 41b1699e38..bbadfab6dd 100644 --- a/features/old/accounts/password_change.feature +++ b/features/old/accounts/password_change.feature @@ -7,13 +7,13 @@ Feature: Password change Scenario: Provider password change Given a provider is logged in And I go to the provider personal details page - And I fill in "New password" with "monkey" + And I fill in "New password" with "new_password_123" And I fill in "Current password" with "superSecret1234#" And I press "Update Details" And I log out And I go to the provider login page And I should see "Log in to your account" And I fill in "Email or Username" with "foo.3scale.localhost" - And I fill in "Password" with "monkey" + And I fill in "Password" with "new_password_123" And I press "Sign in" Then I should be logged in as "foo.3scale.localhost" diff --git a/features/old/authentication/internal.feature b/features/old/authentication/internal.feature index 19af7ff170..90f6e61f61 100644 --- a/features/old/authentication/internal.feature +++ b/features/old/authentication/internal.feature @@ -20,7 +20,7 @@ Feature: Internal authentication And I go to the provider login page Then I should feel secure When I fill in "Username" with "foo.3scale.localhost" - And I fill in "Password" with "supersecret" + And I fill in "Password" with "superSecret1234#" And I press "Sign in" Then I should be logged in as "foo.3scale.localhost" And I should be on the provider dashboard @@ -32,11 +32,11 @@ Feature: Internal authentication @javascript Scenario: Redirects and keeps full url # legal terms's url url has query_string - Given the admin of account "foo.3scale.localhost" has password "foobar" + Given the admin of account "foo.3scale.localhost" has password "superSecret1234#" When current domain is the admin domain of provider "foo.3scale.localhost" And I go to the legal terms settings page And I fill in "Username" with "foo.3scale.localhost" - And I fill in "Password" with "foobar" + And I fill in "Password" with "superSecret1234#" And I press "Sign in" Then I should have the following query string: | system_name | signup_licence| @@ -44,7 +44,7 @@ Feature: Internal authentication @javascript Scenario: Failed attempt to sign in as provider with invalid password - Given the admin of account "foo.3scale.localhost" has password "foobar" + Given the admin of account "foo.3scale.localhost" has password "superSecret1234#" When current domain is the admin domain of provider "foo.3scale.localhost" And I go to the provider login page And I fill in "Username" with "foo.3scale.localhost" @@ -67,17 +67,17 @@ Feature: Internal authentication When the current domain is foo.3scale.localhost And I go to the login page And I fill in "Username" with "alice" - And I fill in "Password" with "supersecret" + And I fill in "Password" with "superSecret1234#" And I press "Sign in" Then I should be logged in as "alice" @wip @3D Scenario: Successful sign in as master account admin - Given the master account admin has username "admin" and password "supermonkey" + Given the master account admin has username "admin" and password "superSecret1234#" When current domain is the admin domain of provider "foo.3scale.localhost" And I go to the provider login page And I fill in "Username" with "admin" - And I fill in "Password" with "supermonkey" + And I fill in "Password" with "superSecret1234#" And I press "Sign in" Then I should be logged in as "admin" And I should be on the provider dashboard @@ -89,7 +89,7 @@ Feature: Internal authentication When current domain is the admin domain of provider "foo.3scale.localhost" And I go to the provider login page And I fill in "Username" with "foo.3scale.localhost" - And I fill in "Password" with "supersecret" + And I fill in "Password" with "superSecret1234#" And I press "Sign in" Then user "foo.3scale.localhost" should have last login on 8th October 2010 at 11:10 from 100.101.102.103 diff --git a/features/old/buyers/impersonate.feature b/features/old/buyers/impersonate.feature index 7a6c5a283e..c47fcc8ae3 100644 --- a/features/old/buyers/impersonate.feature +++ b/features/old/buyers/impersonate.feature @@ -1,11 +1,11 @@ @javascript Feature: Impersonate - In order to get the same user experience and posibilities as other users of the site + In order to get the same user experience and possibilities as other users of the site As a master account admin I want to impersonate them Background: - Given the master account admin has username "master" and password "supersecret" + Given the master account admin has username "master" and password "superSecret1234#" And a provider "foo.3scale.localhost" with impersonation_admin admin And a provider "bar.3scale.localhost" diff --git a/features/old/signup/fields.feature b/features/old/signup/fields.feature index 86008e49fd..b138eb70e9 100644 --- a/features/old/signup/fields.feature +++ b/features/old/signup/fields.feature @@ -58,8 +58,8 @@ Feature: Signup with defined fields When I fill in the following: | Email | bender@planet.ex | | Username | bender | - | Password | supersecret | - | Password confirmation | supersecret | + | Password | superSecret1234# | + | Password confirmation | superSecret1234# | | User extra required | MustBe | | Organization/Group Name | Planet eXpress | | Account extra required | foo | diff --git a/features/old/signup/multiple_cinstances.feature b/features/old/signup/multiple_cinstances.feature index 242d0fa6b8..4bd7122fe2 100644 --- a/features/old/signup/multiple_cinstances.feature +++ b/features/old/signup/multiple_cinstances.feature @@ -19,8 +19,8 @@ Feature: Buyer signup to service allowing multiple applications per buyer When I fill in "Username" with "hugo" And I fill in "Email" with "hugo@stuff.com" And I fill in "Organization/Group Name" with "hugo's stuff" - And I fill in "Password" with "donkey" - And I fill in "Password confirmation" with "donkey" + And I fill in "Password" with "superSecret1234#" + And I fill in "Password confirmation" with "superSecret1234#" And I press "Sign up" Then I should see "Please click the link in the email and you can directly login!" When I follow the activation link in an email sent to "hugo@stuff.com" @@ -30,7 +30,7 @@ Feature: Buyer signup to service allowing multiple applications per buyer When buyer "hugo's stuff" is approved And I fill in "Username" with "hugo" - And I fill in "Password" with "donkey" + And I fill in "Password" with "superSecret1234#" And I press "Sign in" Then I should be logged in as "hugo" diff --git a/features/old/signup/providers.feature b/features/old/signup/providers.feature index 76f1166a69..a25cbc6a0d 100644 --- a/features/old/signup/providers.feature +++ b/features/old/signup/providers.feature @@ -21,7 +21,7 @@ Scenario: Signup, activate, login, create sample data and let a buyer login | Email | tom@monsterapi.com | | First name | quentin | | Organization/Group Name | foo | - | Password | godzilla | + | Password | superSecret1234# | And I press "Sign up" Then I should see "Hi quentin, thank you for signing up" And the domain of provider "foo" should be "foo.3scale.localhost" @@ -36,7 +36,7 @@ Scenario: Signup, activate, login, create sample data and let a buyer login When I follow the activation link in an email sent to "tom@monsterapi.com" And I fill in the following: | Email or Username | tom@monsterapi.com | - | Password | godzilla | + | Password | superSecret1234# | And I press "Sign in" Then I should be logged in as "admin" And I should be on the provider onboarding wizard page @@ -69,8 +69,8 @@ Scenario: Signup, activate, login, create sample data and let a buyer login | Username | bob | | Email | bob@customer.net | | Organization/Group Name | bob's enterprise | - | Password | ie4ever | - | Password confirmation | ie4ever | + | Password | superSecret1234# | + | Password confirmation | superSecret1234# | And I press "Sign up" And I wait a moment Then I should see "Thank you" @@ -79,7 +79,7 @@ Scenario: Signup, activate, login, create sample data and let a buyer login When I follow the activation link in an email sent to "bob@customer.net" And I fill in the following: | Username or Email | bob | - | Password | ie4ever | + | Password | superSecret1234# | And I press "Sign in" Then I should see "Signed in successfully" Then I should be on the homepage diff --git a/features/old/signup/strong_passwords.feature b/features/old/signup/strong_passwords.feature index e3814d7484..af042ffcdf 100644 --- a/features/old/signup/strong_passwords.feature +++ b/features/old/signup/strong_passwords.feature @@ -37,6 +37,7 @@ Feature: Signup with strong passwords Then I should see "Thank you" Scenario: Weak password is accepted when strong passwords are disabled + Given Strong passwords are disabled When I go to the sign up page And I fill in the following: | Email | bender@planet.ex | diff --git a/features/provider/admin/accounts/new.feature b/features/provider/admin/accounts/new.feature index 57a1878fcc..62c258559c 100644 --- a/features/provider/admin/accounts/new.feature +++ b/features/provider/admin/accounts/new.feature @@ -22,8 +22,8 @@ Feature: Provider accounts management When the form is submitted with: | Username | usernamepro | | Email | provider@example.com | - | Password | 123456 | - | Password confirmation | 123456 | + | Password | superSecret1234# | + | Password confirmation | superSecret1234# | | Organization/Group Name | The Provider | Then they should see a toast alert with text "Tenant account was successfully created" And the current page is the overview page of account "The Provider" @@ -33,8 +33,8 @@ Feature: Provider accounts management When the form is submitted with: | Username | u | | Email | invalid | - | Password | 123456 | - | Password confirmation | 654321 | + | Password | superSecret1234# | + | Password confirmation | 1234superSecret# | | Organization/Group Name | Some Provider | Then field "Username" has inline error "is too short (minimum is 3 characters)" And field "Email" has inline error "should look like an email address" diff --git a/features/step_definitions/account_steps.rb b/features/step_definitions/account_steps.rb index 53c9716375..b8bb1ee185 100644 --- a/features/step_definitions/account_steps.rb +++ b/features/step_definitions/account_steps.rb @@ -38,7 +38,7 @@ Then "new accounts with {plan} will be pending for approval" do |plan| params = Signup::SignupParams.new(plans: [plan], user_attributes: { - password: 'password', + password: 'superSecret1234#', username: 'pepe', email: 'pepe@example.com' }, account_attributes: { diff --git a/features/step_definitions/developer_portal/admin/account/personal_details_steps.rb b/features/step_definitions/developer_portal/admin/account/personal_details_steps.rb index ba17fc75bb..c7a63d389c 100644 --- a/features/step_definitions/developer_portal/admin/account/personal_details_steps.rb +++ b/features/step_definitions/developer_portal/admin/account/personal_details_steps.rb @@ -8,7 +8,7 @@ end And "they change their password" do - @new_password = 'ultrasecret' + @new_password = 'ultraSecret1234#' fill_in('user[password]', with: @new_password) fill_in('user[password_confirmation]', with: @new_password) end diff --git a/features/step_definitions/strong_passwords_steps.rb b/features/step_definitions/strong_passwords_steps.rb index 2c92a97ee0..4e5ed0a685 100644 --- a/features/step_definitions/strong_passwords_steps.rb +++ b/features/step_definitions/strong_passwords_steps.rb @@ -1,5 +1,10 @@ # frozen_string_literal: true +# When RAILS_ENV=test, strong passwords are disabled by default +Given "Strong passwords are disabled" do + Rails.configuration.three_scale.stubs(:strong_passwords_disabled).returns(true) +end + Then /^I should see the error that the password is too weak$/ do assert has_content? User::STRONG_PASSWORD_FAIL_MSG end diff --git a/spec/acceptance/api/account_spec.rb b/spec/acceptance/api/account_spec.rb index 347fd7f466..6d4c0dd95c 100644 --- a/spec/acceptance/api/account_spec.rb +++ b/spec/acceptance/api/account_spec.rb @@ -106,7 +106,7 @@ parameter :email, 'Email of the admin user' parameter :password, 'Password of the admin user' - let(:password) { 'password' } + let(:password) { 'superSecret1234#' } let(:email) { 'email@example.com' } let(:username) { 'new_user' } let(:org_name) { 'New Signup' } diff --git a/test/functional/developer_portal/login_controller_test.rb b/test/functional/developer_portal/login_controller_test.rb index 8d8933e632..cd5547123b 100644 --- a/test/functional/developer_portal/login_controller_test.rb +++ b/test/functional/developer_portal/login_controller_test.rb @@ -105,7 +105,7 @@ def provider_account def create_user_and_account buyer_account = FactoryBot.create(:buyer_account, provider_account: provider_account) - FactoryBot.create(:user, account: buyer_account, password: 'kangaroo', state: 'active', authentication_id: 'oauth|1234') + FactoryBot.create(:user, account: buyer_account, password: 'superSecret1234#', state: 'active', authentication_id: 'oauth|1234') end def create_oauth2_provider_account diff --git a/test/functional/developer_portal/signup_controller_test.rb b/test/functional/developer_portal/signup_controller_test.rb index 022f705c0c..4f6130f334 100644 --- a/test/functional/developer_portal/signup_controller_test.rb +++ b/test/functional/developer_portal/signup_controller_test.rb @@ -146,8 +146,8 @@ def valid_buyer_params(hash = {}) { account: { org_name: "bar", user: { username: "foobar", email: "email@email.com", - password: "123456", - password_confirmation: "123456" } + password: "superSecret1234#", + password_confirmation: "superSecret1234#" } }}.merge(hash) end end diff --git a/test/functional/partners/users_controller_test.rb b/test/functional/partners/users_controller_test.rb index 83732e7dc4..5e615ac4d7 100644 --- a/test/functional/partners/users_controller_test.rb +++ b/test/functional/partners/users_controller_test.rb @@ -70,13 +70,13 @@ def setup end test 'create user with password' do - post :create, params: { provider_id: @account.id, api_key: @partner.api_key, email: "foo@example.net", username: "aaron", password: "secretpass123" } + post :create, params: { provider_id: @account.id, api_key: @partner.api_key, email: "foo@example.net", username: "aaron", password: "superSecret1234#" } assert_response :success user = assigns(:user) assert user.valid? - assert user.authenticated?("secretpass123"), 'User should authenticate with provided password' + assert user.authenticated?("superSecret1234#"), 'User should authenticate with provided password' body = JSON.parse(response.body) assert body['success'] diff --git a/test/integration/application_controller_test.rb b/test/integration/application_controller_test.rb index 3fa3020ddb..9a5ecbfa02 100644 --- a/test/integration/application_controller_test.rb +++ b/test/integration/application_controller_test.rb @@ -64,7 +64,7 @@ def setup post admin_buyers_accounts_path, params: { account: { org_name: 'Alaska', - user: { email: 'foo@example.com', password: '123456', username: 'hello' } + user: { email: 'foo@example.com', password: 'superSecret1234#', username: 'hello' } } } end @@ -81,7 +81,7 @@ def setup with_forgery_protection do post admin_api_signup_path(format: :json), params: { - org_name: 'Alaska', username: 'hello', email: 'foo@example.com', password: '123456' + org_name: 'Alaska', username: 'hello', email: 'foo@example.com', password: 'superSecret1234#' } end assert_response :forbidden @@ -98,7 +98,7 @@ def setup with_forgery_protection do post admin_api_signup_path(format: :json), params: { access_token: token, org_name: 'Alaska', - username: 'hello', email: 'foo@example.com', password: '123456' + username: 'hello', email: 'foo@example.com', password: 'superSecret1234#' } end assert_response :created @@ -116,7 +116,7 @@ def setup post admin_api_signup_path(format: :json), headers: { Authorization: ActionController::HttpAuthentication::Basic.encode_credentials(token, '') }, params: { - org_name: 'Alaska', username: 'hello', email: 'foo@example.com', password: '123456' + org_name: 'Alaska', username: 'hello', email: 'foo@example.com', password: 'superSecret1234#' } end assert_response :created @@ -133,7 +133,7 @@ def setup post admin_api_signup_path(format: :json), headers: { Authorization: ActionController::HttpAuthentication::Basic.encode_credentials(token, '') }, params: { - org_name: 'Alaska', username: 'hello', email: 'foo@example.com', password: '123456' + org_name: 'Alaska', username: 'hello', email: 'foo@example.com', password: 'superSecret1234#' } end assert_response :created diff --git a/test/integration/buyers/accounts_controller_test.rb b/test/integration/buyers/accounts_controller_test.rb index aaf5c75b90..f05e44f470 100644 --- a/test/integration/buyers/accounts_controller_test.rb +++ b/test/integration/buyers/accounts_controller_test.rb @@ -19,7 +19,7 @@ def setup post admin_buyers_accounts_path, params: { account: { org_name: 'Alaska', - user: { email: 'foo@example.com', extra_fields: { created_by: 'hi' }, password: '123456', username: 'hello' } + user: { email: 'foo@example.com', extra_fields: { created_by: 'hi' }, password: 'superSecret1234#', username: 'hello' } } } @@ -45,7 +45,7 @@ def setup post admin_buyers_accounts_path, params: { account: { org_name: 'hello', org_legaladdress: 'address', - user: { username: 'hello', email: 'foo@example.com', password: 'password'} + user: { username: 'hello', email: 'foo@example.com', password: 'superSecret1234#'} } } assert_equal 1, WebHookWorker.jobs.size @@ -264,7 +264,7 @@ def setup user: { username: 'johndoe', email: 'user@example.org', - password: 'secretpassword' + password: 'superSecret1234#' } } } diff --git a/test/integration/developer_portal/login_test.rb b/test/integration/developer_portal/login_test.rb index ae7d9a3ffe..85db24c680 100644 --- a/test/integration/developer_portal/login_test.rb +++ b/test/integration/developer_portal/login_test.rb @@ -127,7 +127,7 @@ def test_create_activation user: { email: 'foo2@example.com', username: 'username', - password: 'password' + password: 'superSecret1234#' } }) diff --git a/test/integration/developer_portal/passwords_controller_test.rb b/test/integration/developer_portal/passwords_controller_test.rb index aa51d81b3b..eb17942ffb 100644 --- a/test/integration/developer_portal/passwords_controller_test.rb +++ b/test/integration/developer_portal/passwords_controller_test.rb @@ -26,12 +26,12 @@ def test_password_token def test_update_password user.generate_lost_password_token - put developer_portal.admin_account_password_path(user: { password: 'password123', - password_confirmation: 'password123' }, password_reset_token: user.lost_password_token) + put developer_portal.admin_account_password_path(user: { password: 'new_password_123', + password_confirmation: 'new_password_123' }, password_reset_token: user.lost_password_token) assert_match 'password has been changed', flash[:notice] - put developer_portal.admin_account_password_path(user: { password: '123password', - password_confirmation: '123password' }, password_reset_token: user.lost_password_token) + put developer_portal.admin_account_password_path(user: { password: '123_new_password', + password_confirmation: '123_new_password' }, password_reset_token: user.lost_password_token) assert_match 'password reset token is invalid', flash[:error] end diff --git a/test/integration/developer_portal/signup_test.rb b/test/integration/developer_portal/signup_test.rb index 49d072ff89..3825b951e7 100644 --- a/test/integration/developer_portal/signup_test.rb +++ b/test/integration/developer_portal/signup_test.rb @@ -13,7 +13,7 @@ class DeveloperPortal::SignupTest < ActionDispatch::IntegrationTest user: { email: ACCOUNT_EMAIL, username: 'supertramp', - password: 'westisthebest' + password: 'superSecret1234#' } }.freeze diff --git a/test/integration/master/api/providers_controller_integration_test.rb b/test/integration/master/api/providers_controller_integration_test.rb index b376e1542d..a5326a0e59 100644 --- a/test/integration/master/api/providers_controller_integration_test.rb +++ b/test/integration/master/api/providers_controller_integration_test.rb @@ -250,7 +250,7 @@ def signup_params(different_params = {}) org_name: 'Alaska', username: 'person', email: 'person@example.com', - password: '123456', + password: 'superSecret1234#', user_extra_field: 'hi-user', account_extra_field: 'hi-account' }.merge(different_params) diff --git a/test/integration/multitenant_enforcement_test.rb b/test/integration/multitenant_enforcement_test.rb index 7459b1953f..133b3da608 100644 --- a/test/integration/multitenant_enforcement_test.rb +++ b/test/integration/multitenant_enforcement_test.rb @@ -115,7 +115,7 @@ class MultitenantEnforcementTest < ActionDispatch::IntegrationTest org_name: 'Alaska', username: 'person', email: 'person@example.com', - password: '123456', + password: 'superSecret1234#', user_extra_field: 'hi-user', account_extra_field: 'hi-account' } diff --git a/test/integration/provider/admin/accounts_controller_test.rb b/test/integration/provider/admin/accounts_controller_test.rb index ef689c4d6d..d497eb2b4d 100644 --- a/test/integration/provider/admin/accounts_controller_test.rb +++ b/test/integration/provider/admin/accounts_controller_test.rb @@ -97,7 +97,7 @@ def valid_params { account: { org_name: 'Alaska', - user: { email: 'foo@example.com', extra_fields: { created_by: 'hi' }, password: '123456', username: 'hello' } + user: { email: 'foo@example.com', extra_fields: { created_by: 'hi' }, password: 'superSecret1234#', username: 'hello' } } } end diff --git a/test/integration/provider/passwords_integration_test.rb b/test/integration/provider/passwords_integration_test.rb index 17472f9475..84e3418e6d 100644 --- a/test/integration/provider/passwords_integration_test.rb +++ b/test/integration/provider/passwords_integration_test.rb @@ -33,7 +33,7 @@ def test_user_reset_his_password assert_equal session[:password_reset_token], regenerated_token # user updates his password - put provider_password_path(user: { password: 'alaska123',password_confirmation: 'alaska123' }) + put provider_password_path(user: { password: 'new_password_123',password_confirmation: 'new_password_123' }) assert_response :redirect assert_match 'password has been changed', flash[:success] assert_nil session[:password_reset_token] diff --git a/test/integration/signup_express_test.rb b/test/integration/signup_express_test.rb index 2ba66d4ca3..7a5cb573dc 100644 --- a/test/integration/signup_express_test.rb +++ b/test/integration/signup_express_test.rb @@ -58,7 +58,7 @@ def params(custom_params = {}) org_name: 'company', username: 'quentin', email: 'quentin@example.com', - password: '12345678', + password: 'superSecret1234#', account_plan_id: @account_plan.id }.merge(custom_params) end diff --git a/test/integration/sso_enforce_flow_test.rb b/test/integration/sso_enforce_flow_test.rb index 9acd265a43..93b8cfdc36 100644 --- a/test/integration/sso_enforce_flow_test.rb +++ b/test/integration/sso_enforce_flow_test.rb @@ -4,7 +4,7 @@ class SsoEnforceFlowTest < ActionDispatch::IntegrationTest def setup @provider = FactoryBot.create(:provider_account) - @user = FactoryBot.create(:simple_admin, account: @provider, password: 'alaska1233') + @user = FactoryBot.create(:simple_admin, account: @provider, password: 'superSecret1234#') @user.activate! host! @provider.external_admin_domain @@ -17,7 +17,7 @@ def test_sso_enforce # rubocop:disable Metrics/AbcSize, Metrics/MethodLength assert_match 'id="pf-login-page-container', response.body # username & password login - post provider_sessions_path(username: @user.username, password: 'alaska1233') + post provider_sessions_path(username: @user.username, password: 'superSecret1234#') assert_match 'Signed in successfully', flash[:success] assert_not_nil User.current diff --git a/test/unit/account/fields_test.rb b/test/unit/account/fields_test.rb index fbcc2fecd3..b371efabf6 100644 --- a/test/unit/account/fields_test.rb +++ b/test/unit/account/fields_test.rb @@ -5,7 +5,7 @@ class Account::FieldsTest < ActiveSupport::TestCase class BuyerTest < Account::FieldsTest def setup - @user_attrs = { username: 'buyer', email: 'email@buyer.com', password: 'password', password_confirmation: 'password' } + @user_attrs = { username: 'buyer', email: 'email@buyer.com', password: 'superSecret1234#', password_confirmation: 'superSecret1234#' } @provider = FactoryBot.create(:simple_provider) @buyer = FactoryBot.create(:simple_buyer, provider_account: @provider, org_name: 'buyer') diff --git a/test/unit/authentication/strategy/internal_test.rb b/test/unit/authentication/strategy/internal_test.rb index acadf0acf6..99efc4fb01 100644 --- a/test/unit/authentication/strategy/internal_test.rb +++ b/test/unit/authentication/strategy/internal_test.rb @@ -16,108 +16,108 @@ def setup test 'authenticate authenticates buyer user' do buyer_account = FactoryBot.create(:buyer_account, :provider_account => @provider_account) - buyer_user = FactoryBot.create(:user, :account => buyer_account, :password => 'kangaroo') + buyer_user = FactoryBot.create(:user, :account => buyer_account, :password => 'superSecret1234#') buyer_user.activate! user = FactoryBot.create(:user, :account => @provider_account, :username => 'dave', - :password => 'kangaroo') + :password => 'superSecret1234#') user.activate! assert_equal buyer_user, @strategy.authenticate(:username => buyer_user.username, - :password => 'kangaroo') + :password => 'superSecret1234#') - assert_nil @strategy.authenticate(:username => 'dave', :password => 'kangaroo') + assert_nil @strategy.authenticate(:username => 'dave', :password => 'superSecret1234#') end test 'authenticate returns nil if the password is incorrect' do - user = FactoryBot.create(:user, :account => @provider_account, :password => 'foobar') + user = FactoryBot.create(:user, :account => @provider_account, :password => 'superSecret1234#') user.activate! assert_nil @strategy.authenticate(:username => user.username, :password => 'wrong!') end test 'authenticate returns nil if the user is pending' do - user = FactoryBot.create(:user, :account => @provider_account, :password => 'foobar') + user = FactoryBot.create(:user, :account => @provider_account, :password => 'superSecret1234#') assert_nil @strategy.authenticate(:username => user.username, - :password => 'foobar') + :password => 'superSecret1234#') end test 'authenticate returns nil if the user is suspended' do - user = FactoryBot.create(:user, :password => 'foobar') + user = FactoryBot.create(:user, :password => 'superSecret1234#') user.activate! user.suspend! assert_nil @strategy.authenticate(:username => user.username, - :password => 'foobar') + :password => 'superSecret1234#') end test 'authenticate authenticates user by username in buyer side' do buyer_account = FactoryBot.create(:buyer_account, :provider_account => @provider_account) - user = FactoryBot.create(:user, :account => buyer_account, :password => 'kangaroo') + user = FactoryBot.create(:user, :account => buyer_account, :password => 'superSecret1234#') user.activate! assert_equal user, @strategy.authenticate(:username => user.username, - :password => 'kangaroo') + :password => 'superSecret1234#') end test 'authenticate authenticates user by email in buyer domain' do buyer_account = FactoryBot.create(:buyer_account, :provider_account => @provider_account) - user = FactoryBot.create(:user, :account => buyer_account, :password => 'kangaroo') + user = FactoryBot.create(:user, :account => buyer_account, :password => 'superSecret1234#') user.activate! assert_equal user, @strategy.authenticate(:username => user.email, - :password => 'kangaroo') + :password => 'superSecret1234#') end test 'authenticate returns nil if the account of the user is pending' do account = FactoryBot.create(:account, :provider_account => @provider_account) - user = FactoryBot.create(:user, :account => account, :password => 'foobar') + user = FactoryBot.create(:user, :account => account, :password => 'superSecret1234#') user.activate! account.make_pending! assert_nil @strategy.authenticate(:username => user.username, - :password => 'foobar') + :password => 'superSecret1234#') end test 'authenticate returns nil if the account of the user is rejected' do account = FactoryBot.create(:account, :provider_account => @provider_account) - user = FactoryBot.create(:user, :account => account, :password => 'foobar') + user = FactoryBot.create(:user, :account => account, :password => 'superSecret1234#') user.activate! account.reject! assert_nil @strategy.authenticate(:username => user.username, - :password => 'foobar') + :password => 'superSecret1234#') end test 'authenticate authenticates user with approved account' do account = FactoryBot.create(:account, :provider_account => @provider_account) - user = FactoryBot.create(:user, :account => account, :password => 'foobar') + user = FactoryBot.create(:user, :account => account, :password => 'superSecret1234#') user.activate! assert_equal user, @strategy.authenticate(:username => user.username, - :password => 'foobar') + :password => 'superSecret1234#') end test 'authenticates provider side' do provider_strategy = Authentication::Strategy::Internal.new(@provider_account, true) user = FactoryBot.create(:user, :account => @provider_account, :username => 'dave', - :password => 'kangaroo') + :password => 'superSecret1234#') account = FactoryBot.create(:account, :provider_account => @provider_account) - buyer_pass = 'foobar' + buyer_pass = 'buyer_password_123' buyer_user = FactoryBot.create(:user, :account => account, :password => buyer_pass) user.activate! buyer_user.activate! - assert_equal user, provider_strategy.authenticate(:username => 'dave', :password => 'kangaroo') + assert_equal user, provider_strategy.authenticate(:username => 'dave', :password => 'superSecret1234#') assert_nil provider_strategy.authenticate(:username => buyer_user.username, :password => buyer_pass) end diff --git a/test/unit/invitation_test.rb b/test/unit/invitation_test.rb index 0f2000999a..6cde6d6872 100644 --- a/test/unit/invitation_test.rb +++ b/test/unit/invitation_test.rb @@ -107,7 +107,7 @@ def setup test 'creating invited user accepts the invitation' do invitation = @provider.invitations.create!(:email => 'bob@example.net') - user = invitation.make_user(:username => 'bob', :password => 'monkey') + user = invitation.make_user(:username => 'bob', :password => 'superSecret1234#') assert_change :of => -> { invitation.accepted? }, :from => false, :to => true do user.save! diff --git a/test/unit/services/signup_service_test.rb b/test/unit/services/signup_service_test.rb index 3ef5d4a56c..f38d3d18d0 100644 --- a/test/unit/services/signup_service_test.rb +++ b/test/unit/services/signup_service_test.rb @@ -16,7 +16,7 @@ def test_create service = new_instance_signup_service assert_difference(User.method(:count), 0) do user = service.create - refute user.persisted? + assert_not user.persisted? end service = new_instance_signup_service(valid_account_params, valid_user_params) @@ -57,6 +57,6 @@ def valid_account_params def valid_user_params index = User.maximum(:id) - { username: "Alex_#{index}", email: "foo_#{index}@example.net", password: 'wild123' } + { username: "Alex_#{index}", email: "foo_#{index}@example.net", password: 'superSecret1234#' } end end diff --git a/test/unit/signup/account_manager_test.rb b/test/unit/signup/account_manager_test.rb index b5dc1d7e1a..699232473c 100644 --- a/test/unit/signup/account_manager_test.rb +++ b/test/unit/signup/account_manager_test.rb @@ -311,7 +311,7 @@ def valid_account_params(different_account_params: {}) def valid_user_params(different_user_params: {}) { email: 'emailTest@email.com', username: 'john', first_name: 'John', last_name: 'Doe', - password: '123456', password_confirmation: '123456', signup_type: :minimal }.merge(different_user_params) + password: 'superSecret1234#', password_confirmation: 'superSecret1234#', signup_type: :minimal }.merge(different_user_params) end end end diff --git a/test/unit/user/roles_test.rb b/test/unit/user/roles_test.rb index 4509053477..85c0b9bd2a 100644 --- a/test/unit/user/roles_test.rb +++ b/test/unit/user/roles_test.rb @@ -4,7 +4,7 @@ class User::RolesTest < ActiveSupport::TestCase test 'default role is :member' do - user = User.create!(username: 'bob', email: 'bob@example.com', password: 'monkey') + user = User.create!(username: 'bob', email: 'bob@example.com', password: 'superSecret1234#') assert_equal :member, user.role end diff --git a/test/unit/user/states_test.rb b/test/unit/user/states_test.rb index cb6926d0f3..c519425f2f 100644 --- a/test/unit/user/states_test.rb +++ b/test/unit/user/states_test.rb @@ -96,7 +96,7 @@ class ActivateOnMinimalOrSampleDataTest < ActiveSupport::TestCase def setup @provider = FactoryBot.create(:simple_provider) @buyer = FactoryBot.create(:simple_buyer, provider_account: @provider) - @user = FactoryBot.create(:pending_user, account: @buyer, password: '123456', password_confirmation: '123456') + @user = FactoryBot.create(:pending_user, account: @buyer, password: 'superSecret1234#', password_confirmation: 'superSecret1234#') end test 'returns true for minimal signup with password and no approval required' do From c6ca8d7f43df6ce8aad10bc34e1152d75a72ac78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Lled=C3=B3?= Date: Thu, 12 Feb 2026 18:03:47 +0100 Subject: [PATCH 19/19] Third attempt to fix tests... --- .circleci/config.yml | 4 ++-- test/functional/partners/providers_controller_test.rb | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9ac71a8bc8..d5960b0dd8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -98,8 +98,8 @@ system-builder-ruby33: &system-builder-ruby33 ORACLE_SYSTEM_PASSWORD: threescalepass NLS_LANG: AMERICAN_AMERICA.UTF8 TZ: UTC - MASTER_PASSWORD: p - USER_PASSWORD: p + MASTER_PASSWORD: superSecret1234# + USER_PASSWORD: superSecret1234# LC_ALL: C.utf8 RAILS_ENV: test diff --git a/test/functional/partners/providers_controller_test.rb b/test/functional/partners/providers_controller_test.rb index ef78ccd884..b2603b62fc 100644 --- a/test/functional/partners/providers_controller_test.rb +++ b/test/functional/partners/providers_controller_test.rb @@ -77,11 +77,11 @@ def provider_params test 'post with specific password' do prepare_master_account - post :create, params: provider_params.merge(password: 'foobar123') + post :create, params: provider_params.merge(password: 'superSecret1234#') user = assigns(:user) account = assigns(:account) strategy = Authentication::Strategy::Internal.new(account, true) - assert strategy.authenticate(username: user.username, password: 'foobar123') + assert strategy.authenticate(username: user.username, password: 'superSecret1234#') body = JSON.parse(response.body) assert_equal body['success'], true end