diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-03-13 03:08:53 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-03-13 03:08:53 +0300 |
commit | df4e4c33e0266171016df38c0a41e8c049ee114f (patch) | |
tree | e0454da4c721f91367b09715cf46dbcf843b8a2e | |
parent | d9d098f697d8129b0dedca24fc4eccc1af1c99b8 (diff) |
Add latest changes from gitlab-org/gitlab@master
21 files changed, 82 insertions, 247 deletions
@@ -517,7 +517,7 @@ gem 'kas-grpc', '~> 0.0.2' gem 'grpc', '~> 1.42.0' -gem 'google-protobuf', '~> 3.22', '>= 3.22.1' +gem 'google-protobuf', '~> 3.22', '>= 3.22.2' gem 'toml-rb', '~> 2.2.0' diff --git a/Gemfile.checksum b/Gemfile.checksum index aed7cde551a..88bb5924fcc 100644 --- a/Gemfile.checksum +++ b/Gemfile.checksum @@ -237,15 +237,16 @@ {"name":"google-cloud-errors","version":"1.3.0","platform":"ruby","checksum":"450b681e24c089a20721a01acc4408bb4a7b0df28c175aaab488da917480d64b"}, {"name":"google-cloud-profiler-v2","version":"0.4.0","platform":"ruby","checksum":"53fc2ab175d08f54233c644310d47798feac996220916815c4fb44c937b5d3e3"}, {"name":"google-cloud-storage","version":"1.44.0","platform":"ruby","checksum":"299a1e055c9277c8120f7c10d21d37e4d8c17c7b963350c0e0bff7e9d9a570ea"}, -{"name":"google-protobuf","version":"3.22.1","platform":"arm64-darwin","checksum":"bd904af849bd1f143c4d9eb74e0622f9efca7ed20719b00baa77fcb1a5fc2aa7"}, -{"name":"google-protobuf","version":"3.22.1","platform":"java","checksum":"268359af055709c5796b1c726f839ef0fe356702c7abdb136367eb37cf9662e3"}, -{"name":"google-protobuf","version":"3.22.1","platform":"ruby","checksum":"2fc99aa4f0c2fdd33baf7c7fafb045118d1775893ca8823254658429a23ba0f2"}, -{"name":"google-protobuf","version":"3.22.1","platform":"x64-mingw-ucrt","checksum":"351cb7743ea748156fea56ace3f5613ce5a5f1c4c59b18ff28930ef7c53de5f6"}, -{"name":"google-protobuf","version":"3.22.1","platform":"x64-mingw32","checksum":"3808b954ee3240ef97d019037149dde2afa877585420b30f7ac7be37cee7bb4e"}, -{"name":"google-protobuf","version":"3.22.1","platform":"x86-linux","checksum":"6d8ee9928dbe564916b37ede264b1b3492915b818a0daf9c8b4b572eda7baa30"}, -{"name":"google-protobuf","version":"3.22.1","platform":"x86-mingw32","checksum":"a8ab1fda2a208dc238f16b2796d5a3383e6a273f8ef88a23ca90e0c2846594ee"}, -{"name":"google-protobuf","version":"3.22.1","platform":"x86_64-darwin","checksum":"a425ce701b8c4f9aeb7cac0e7f1b36496ff8f6bf86dc7fe9d06af534d25e45d8"}, -{"name":"google-protobuf","version":"3.22.1","platform":"x86_64-linux","checksum":"a62f7d472c346cea6c6141c70b1caba5b7e75319c56cf44a24b62bad6c1adf10"}, +{"name":"google-protobuf","version":"3.22.2","platform":"aarch64-linux","checksum":"21357d807fd4b7e6e423dafa98732bf9a2be2767c06ea81a8a7980e71659783a"}, +{"name":"google-protobuf","version":"3.22.2","platform":"arm64-darwin","checksum":"ee4026e3d24d2c584476dd0dd1ff4662589711709ef5a91b82d36c995bb711d1"}, +{"name":"google-protobuf","version":"3.22.2","platform":"java","checksum":"d3d5389755bcf788717f000c9de41bed64fc211c46687dd41ebf7f8545b57962"}, +{"name":"google-protobuf","version":"3.22.2","platform":"ruby","checksum":"d516c13248500fb4e1af469c2d71e8b6ecffacb6f55e9be203f01b7d0ff01eff"}, +{"name":"google-protobuf","version":"3.22.2","platform":"x64-mingw-ucrt","checksum":"c26f38dde5612793db886a19485db7d3037628edf1d35ee8b5ca1ba16c82d005"}, +{"name":"google-protobuf","version":"3.22.2","platform":"x64-mingw32","checksum":"5c36e9f519988af2ac52444f3881fc4f6f6181a6177c01bae7b8ea007c76f80b"}, +{"name":"google-protobuf","version":"3.22.2","platform":"x86-linux","checksum":"ab49eb312d414e9a7231542240a4fddc52ea8c78007b812132a2c1d9ba943e26"}, +{"name":"google-protobuf","version":"3.22.2","platform":"x86-mingw32","checksum":"7fa69f62e182bae2a32f499da9ce8e5d9412d0a5768764967a7c1d0d89492e2e"}, +{"name":"google-protobuf","version":"3.22.2","platform":"x86_64-darwin","checksum":"e716c0fc6c970d82febf2447de2c762d265c288dbc26c3043c30544c8a4d60d9"}, +{"name":"google-protobuf","version":"3.22.2","platform":"x86_64-linux","checksum":"8fd16e0115d01209494767b6182c2a9f5d257d5f3c495c513762555a46f1ab88"}, {"name":"googleapis-common-protos","version":"1.4.0","platform":"ruby","checksum":"da2380fb5ab1563580816c74e8d684ac17512c3654c829a3ee84f6d6139de382"}, {"name":"googleapis-common-protos-types","version":"1.5.0","platform":"ruby","checksum":"5769cf7376abc86ef7f5897a4aaca1d5c5a3c49ddabeddd2c251fcf8155f858b"}, {"name":"googleauth","version":"1.3.0","platform":"ruby","checksum":"51dd7362353cf1e90a2d01e1fb94321ae3926c776d4dc4a79db65230217ffcc2"}, diff --git a/Gemfile.lock b/Gemfile.lock index 40a2739b744..06b10c4867c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -684,7 +684,7 @@ GEM google-cloud-core (~> 1.6) googleauth (>= 0.16.2, < 2.a) mini_mime (~> 1.0) - google-protobuf (3.22.1) + google-protobuf (3.22.2) googleapis-common-protos (1.4.0) google-protobuf (~> 3.14) googleapis-common-protos-types (~> 1.2) @@ -1732,7 +1732,7 @@ DEPENDENCIES google-apis-serviceusage_v1 (~> 0.28.0) google-apis-sqladmin_v1beta4 (~> 0.41.0) google-cloud-storage (~> 1.44.0) - google-protobuf (~> 3.22, >= 3.22.1) + google-protobuf (~> 3.22, >= 3.22.2) gpgme (~> 2.0.22) grape (~> 1.5.2) grape-entity (~> 0.10.0) @@ -1927,4 +1927,4 @@ DEPENDENCIES yajl-ruby (~> 1.4.3) BUNDLED WITH - 2.4.7 + 2.4.8 diff --git a/app/controllers/concerns/authenticates_with_two_factor.rb b/app/controllers/concerns/authenticates_with_two_factor.rb index a073f9b5db7..f5400dcd473 100644 --- a/app/controllers/concerns/authenticates_with_two_factor.rb +++ b/app/controllers/concerns/authenticates_with_two_factor.rb @@ -25,13 +25,7 @@ module AuthenticatesWithTwoFactor session[:user_password_hash] = Digest::SHA256.hexdigest(user.encrypted_password) add_gon_variables - push_frontend_feature_flag(:webauthn) - - if Feature.enabled?(:webauthn) - setup_webauthn_authentication(user) - else - setup_u2f_authentication(user) - end + setup_webauthn_authentication(user) render 'devise/sessions/two_factor' end @@ -54,11 +48,7 @@ module AuthenticatesWithTwoFactor if user_params[:otp_attempt].present? && session[:otp_user_id] authenticate_with_two_factor_via_otp(user) elsif user_params[:device_response].present? && session[:otp_user_id] - if user.two_factor_webauthn_enabled? - authenticate_with_two_factor_via_webauthn(user) - else - authenticate_with_two_factor_via_u2f(user) - end + authenticate_with_two_factor_via_webauthn(user) elsif user && user.valid_password?(user_params[:password]) prompt_for_two_factor(user) end @@ -96,15 +86,6 @@ module AuthenticatesWithTwoFactor end end - # Authenticate using the response from a U2F (universal 2nd factor) device - def authenticate_with_two_factor_via_u2f(user) - if U2fRegistration.authenticate(user, u2f_app_id, user_params[:device_response], session[:challenge]) - handle_two_factor_success(user) - else - handle_two_factor_failure(user, 'U2F', _('Authentication via U2F device failed.')) - end - end - def authenticate_with_two_factor_via_webauthn(user) if Webauthn::AuthenticateService.new(user, user_params[:device_response], session[:challenge]).execute handle_two_factor_success(user) diff --git a/app/controllers/concerns/authenticates_with_two_factor_for_admin_mode.rb b/app/controllers/concerns/authenticates_with_two_factor_for_admin_mode.rb index 574fc6c0f37..045ccf1e5b8 100644 --- a/app/controllers/concerns/authenticates_with_two_factor_for_admin_mode.rb +++ b/app/controllers/concerns/authenticates_with_two_factor_for_admin_mode.rb @@ -11,13 +11,7 @@ module AuthenticatesWithTwoFactorForAdminMode return handle_locked_user(user) unless user.can?(:log_in) session[:otp_user_id] = user.id - push_frontend_feature_flag(:webauthn) - - if user.two_factor_webauthn_enabled? - setup_webauthn_authentication(user) - else - setup_u2f_authentication(user) - end + setup_webauthn_authentication(user) render 'admin/sessions/two_factor', layout: 'application' end @@ -30,11 +24,7 @@ module AuthenticatesWithTwoFactorForAdminMode if user_params[:otp_attempt].present? && session[:otp_user_id] admin_mode_authenticate_with_two_factor_via_otp(user) elsif user_params[:device_response].present? && session[:otp_user_id] - if user.two_factor_webauthn_enabled? - admin_mode_authenticate_with_two_factor_via_webauthn(user) - else - admin_mode_authenticate_with_two_factor_via_u2f(user) - end + admin_mode_authenticate_with_two_factor_via_webauthn(user) elsif user && user.valid_password?(user_params[:password]) admin_mode_prompt_for_two_factor(user) else @@ -56,14 +46,6 @@ module AuthenticatesWithTwoFactorForAdminMode end end - def admin_mode_authenticate_with_two_factor_via_u2f(user) - if U2fRegistration.authenticate(user, u2f_app_id, user_params[:device_response], session[:challenge]) - admin_handle_two_factor_success - else - admin_handle_two_factor_failure(user, 'U2F', _('Authentication via U2F device failed.')) - end - end - def admin_mode_authenticate_with_two_factor_via_webauthn(user) if Webauthn::AuthenticateService.new(user, user_params[:device_response], session[:challenge]).execute admin_handle_two_factor_success diff --git a/app/controllers/profiles/two_factor_auths_controller.rb b/app/controllers/profiles/two_factor_auths_controller.rb index 89151068696..8f482cf6e2f 100644 --- a/app/controllers/profiles/two_factor_auths_controller.rb +++ b/app/controllers/profiles/two_factor_auths_controller.rb @@ -8,10 +8,6 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController helper_method :current_password_required? - before_action do - push_frontend_feature_flag(:webauthn) - end - feature_category :system_access def show @@ -41,32 +37,12 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController @error = { message: _('Invalid pin code.') } @qr_code = build_qr_code @account_string = account_string - - if Feature.enabled?(:webauthn) - setup_webauthn_registration - else - setup_u2f_registration - end + setup_webauthn_registration render 'show' end end - # A U2F (universal 2nd factor) device's information is stored after successful - # registration, which is then used while 2FA authentication is taking place. - def create_u2f - @u2f_registration = U2fRegistration.register(current_user, u2f_app_id, device_registration_params, session[:challenges]) - - if @u2f_registration.persisted? - session.delete(:challenges) - redirect_to profile_two_factor_auth_path, notice: s_("Your U2F device was registered!") - else - @qr_code = build_qr_code - setup_u2f_registration - render :show - end - end - def create_webauthn @webauthn_registration = Webauthn::RegisterService.new(current_user, device_registration_params, session[:challenge]).execute @@ -175,22 +151,6 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController Gitlab.config.gitlab.host end - # Setup in preparation of communication with a U2F (universal 2nd factor) device - # Actual communication is performed using a Javascript API - def setup_u2f_registration - @u2f_registration ||= U2fRegistration.new - @registrations = u2f_registrations - u2f = U2F::U2F.new(u2f_app_id) - - registration_requests = u2f.registration_requests - sign_requests = u2f.authentication_requests(current_user.u2f_registrations.map(&:key_handle)) - session[:challenges] = registration_requests.map(&:challenge) - - gon.push(u2f: { challenges: session[:challenges], app_id: u2f_app_id, - register_requests: registration_requests, - sign_requests: sign_requests }) - end - def device_registration_params params.require(:device_registration).permit(:device_response, :name) end diff --git a/app/controllers/profiles/u2f_registrations_controller.rb b/app/controllers/profiles/u2f_registrations_controller.rb deleted file mode 100644 index 2ee0e9fe960..00000000000 --- a/app/controllers/profiles/u2f_registrations_controller.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -class Profiles::U2fRegistrationsController < Profiles::ApplicationController - feature_category :system_access - - def destroy - u2f_registration = current_user.u2f_registrations.find(params[:id]) - u2f_registration.destroy - redirect_to profile_two_factor_auth_path, status: :found, notice: _("Successfully deleted U2F device.") - end -end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 83034e3faa6..1003de314d2 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -36,9 +36,6 @@ class SessionsController < Devise::SessionsController before_action :save_failed_login, if: :action_new_and_failed_login? before_action :load_recaptcha before_action :set_invite_params, only: [:new] - before_action do - push_frontend_feature_flag(:webauthn) - end after_action :log_failed_login, if: :action_new_and_failed_login? after_action :verify_known_sign_in, only: [:create] @@ -311,10 +308,8 @@ class SessionsController < Devise::SessionsController def authentication_method if user_params[:otp_attempt] AuthenticationEvent::TWO_FACTOR - elsif user_params[:device_response] && Feature.enabled?(:webauthn) + elsif user_params[:device_response] AuthenticationEvent::TWO_FACTOR_WEBAUTHN - elsif user_params[:device_response] && !Feature.enabled?(:webauthn) - AuthenticationEvent::TWO_FACTOR_U2F else AuthenticationEvent::STANDARD end diff --git a/app/models/members_preloader.rb b/app/models/members_preloader.rb index 169ce49b4d3..f6617fa0888 100644 --- a/app/models/members_preloader.rb +++ b/app/models/members_preloader.rb @@ -8,7 +8,7 @@ class MembersPreloader end def preload_all - user_associations = [:status, :u2f_registrations] + user_associations = [:status] user_associations << :webauthn_registrations if Feature.enabled?(:webauthn) ActiveRecord::Associations::Preloader.new( diff --git a/app/models/user.rb b/app/models/user.rb index 8c34c2eb516..e0aacda8dc2 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -615,13 +615,12 @@ class User < ApplicationRecord def self.with_two_factor where(otp_required_for_login: true) - .or(where_exists(U2fRegistration.where(U2fRegistration.arel_table[:user_id].eq(arel_table[:id])))) .or(where_exists(WebauthnRegistration.where(WebauthnRegistration.arel_table[:user_id].eq(arel_table[:id])))) end def self.without_two_factor where - .missing(:u2f_registrations, :webauthn_registrations) + .missing(:webauthn_registrations) .where(otp_required_for_login: false) end @@ -1072,16 +1071,6 @@ class User < ApplicationRecord forti_token_cloud_enabled?(self) end - def two_factor_u2f_enabled? - return false if Feature.enabled?(:webauthn) - - if u2f_registrations.loaded? - u2f_registrations.any? - else - u2f_registrations.exists? - end - end - def two_factor_webauthn_enabled? return false unless Feature.enabled?(:webauthn) diff --git a/config/routes/profile.rb b/config/routes/profile.rb index 539084ce34d..2d0d3fb66f0 100644 --- a/config/routes/profile.rb +++ b/config/routes/profile.rb @@ -75,7 +75,6 @@ resource :profile, only: [:show, :update] do resource :two_factor_auth, only: [:show, :create, :destroy] do member do - post :create_u2f post :codes patch :skip post :create_webauthn diff --git a/doc/administration/gitaly/troubleshooting.md b/doc/administration/gitaly/troubleshooting.md index 722d61f587b..0937fa37f37 100644 --- a/doc/administration/gitaly/troubleshooting.md +++ b/doc/administration/gitaly/troubleshooting.md @@ -715,6 +715,10 @@ Possible solutions: - Provision larger VMs to gain access to larger network traffic allowances. - Use your cloud service's monitoring and logging to check that the Praefect nodes are not exhausting their traffic allowances. +### `gitlab-ctl reconfigure` fails with error: `STDOUT: praefect: configuration error: error reading config file: toml: cannot store TOML string into a Go int` + +This error occurs when `praefect['database_port']` or `praefect['database_direct_port']` are configured as a string instead of an integer. + ## Profiling Gitaly Gitaly exposes several of the Golang built-in performance profiling tools on the Prometheus listen port. For example, if Prometheus is listening diff --git a/doc/administration/operations/rails_console.md b/doc/administration/operations/rails_console.md index 652a4fa5497..ac550d30566 100644 --- a/doc/administration/operations/rails_console.md +++ b/doc/administration/operations/rails_console.md @@ -569,7 +569,7 @@ def disable_two_factor! end def two_factor_enabled? - two_factor_otp_enabled? || two_factor_u2f_enabled? + two_factor_otp_enabled? || two_factor_webauthn_enabled? end ``` diff --git a/doc/user/application_security/dependency_scanning/index.md b/doc/user/application_security/dependency_scanning/index.md index dd78f3b751f..c35f5942294 100644 --- a/doc/user/application_security/dependency_scanning/index.md +++ b/doc/user/application_security/dependency_scanning/index.md @@ -926,18 +926,35 @@ include: merge cyclonedx sboms: stage: merge-cyclonedx-sboms image: - name: cyclonedx/cyclonedx-cli:0.24.0 + name: cyclonedx/cyclonedx-cli:0.24.2 entrypoint: [""] script: - - find . -name "gl-sbom-*.cdx.json" -exec /cyclonedx merge --output-file gl-sbom-all.cdx.json --input-files "{}" + + - apt-get update && apt-get install -y jq + - find . -name "gl-sbom-*.cdx.json" -exec cyclonedx merge --output-file gl-sbom-all.cdx.json --input-files "{}" + + # remove duplicates from merged file. See https://github.com/CycloneDX/cyclonedx-cli/issues/188 for details. + - | + jq '. | + { + "bomFormat": .bomFormat, + "specVersion": .specVersion, + "serialNumber": .serialNumber, + "version": .version, + "metadata": { + "tools": [ + (.metadata.tools | unique[]) + ] + }, + "components": [ + (.components | unique[]) + ] + }' "gl-sbom-all.cdx.json" > gl-sbom-all.cdx.json.tmp && mv gl-sbom-all.cdx.json.tmp gl-sbom-all.cdx.json + # optional: validate the merged sbom + - cyclonedx validate --input-version v1_4 --input-file gl-sbom-all.cdx.json artifacts: paths: - gl-sbom-all.cdx.json ``` -NOTE: -Merging CycloneDX SBOM files may cause [License Scanning of CycloneDX Files](../../compliance/license_scanning_of_cyclonedx_files/index.md) to not work as the [cyclonedx-cli](https://github.com/CycloneDX/cyclonedx-cli) tool [does not remove duplicates](https://github.com/CycloneDX/cyclonedx-cli/issues/188). This causes the CycloneDX file to become invalid as duplicates are not allowed within the [official CycloneDX JSON specification](https://cyclonedx.org/docs/latest/json/#components). - GitLab uses [CycloneDX Properties](https://cyclonedx.org/use-cases/#properties--name-value-store) to store implementation-specific details in the metadata of each CycloneDX SBOM, such as the location of build and lock files. If multiple CycloneDX SBOMs are merged together, diff --git a/doc/user/application_security/secret_detection/index.md b/doc/user/application_security/secret_detection/index.md index 1df25837e4b..93d5ed0aa58 100644 --- a/doc/user/application_security/secret_detection/index.md +++ b/doc/user/application_security/secret_detection/index.md @@ -36,8 +36,8 @@ more information, see [Post-processing and revocation](post_processing.md). All identified secrets are reported in the: -- Merge request widget -- Pipelines' **Security** tab +- [Merge request widget](../index.md#view-security-scan-information-in-merge-requests) +- [Pipeline security report](../vulnerability_report/pipeline.md) - [Vulnerability Report](../vulnerability_report/index.md) ![Secret Detection in merge request widget](img/secret_detection_v13_2.png) diff --git a/doc/user/project/import/bitbucket_server.md b/doc/user/project/import/bitbucket_server.md index e6d2e3e00b6..9937ea956c4 100644 --- a/doc/user/project/import/bitbucket_server.md +++ b/doc/user/project/import/bitbucket_server.md @@ -120,6 +120,16 @@ If the project import completes but LFS objects can't be downloaded or cloned, y password or personal access token containing special characters. For more information, see [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/337769). +### Pull requests are missing + +Importing large projects spawns a process that can consume a lot of memory. Sometimes you can see messages such as `Sidekiq worker RSS out of range` in the +[Sidekiq logs](../../../administration/logs/index.md#sidekiq-logs). This can mean that MemoryKiller is interrupting the `RepositoryImportWorker` because it's using +too much memory. + +To resolve this problem, temporarily increase the `SIDEKIQ_MEMORY_KILLER_MAX_RSS` environment variable using +[custom environment variables](https://docs.gitlab.com/omnibus/settings/environment-variables.html) from the default `2000000` value to a larger value like `3000000`. +Consider memory constraints on the system before deciding to increase `SIDEKIQ_MEMORY_KILLER_MAX_RSS`. + ## Related topics For information on automating user, group, and project import API calls, see diff --git a/lib/api/users.rb b/lib/api/users.rb index 297306fa6d7..63f838c8962 100644 --- a/lib/api/users.rb +++ b/lib/api/users.rb @@ -156,7 +156,7 @@ module API entity = current_user&.can_read_all_resources? ? Entities::UserWithAdmin : Entities::UserBasic if entity == Entities::UserWithAdmin - users = users.preload(:identities, :u2f_registrations, :webauthn_registrations, :namespace, :followers, :followees, :user_preference) + users = users.preload(:identities, :webauthn_registrations, :namespace, :followers, :followees, :user_preference) end users, options = with_custom_attributes(users, { with: entity, current_user: current_user }) diff --git a/locale/gitlab.pot b/locale/gitlab.pot index ac9ac545feb..6ca1caa6115 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -6056,9 +6056,6 @@ msgstr "" msgid "Authentication method updated" msgstr "" -msgid "Authentication via U2F device failed." -msgstr "" - msgid "Authentication via WebAuthn device failed." msgstr "" @@ -42096,9 +42093,6 @@ msgstr "" msgid "Successfully deactivated" msgstr "" -msgid "Successfully deleted U2F device." -msgstr "" - msgid "Successfully deleted WebAuthn device." msgstr "" @@ -50208,9 +50202,6 @@ msgstr "" msgid "Your U2F device did not send a valid JSON response." msgstr "" -msgid "Your U2F device was registered!" -msgstr "" - msgid "Your WebAuthn device did not send a valid JSON response." msgstr "" diff --git a/spec/controllers/admin/sessions_controller_spec.rb b/spec/controllers/admin/sessions_controller_spec.rb index e0890f4d160..07088eed6d4 100644 --- a/spec/controllers/admin/sessions_controller_spec.rb +++ b/spec/controllers/admin/sessions_controller_spec.rb @@ -220,7 +220,9 @@ RSpec.describe Admin::SessionsController, :do_not_mock_admin_mode do end end - shared_examples 'when using two-factor authentication via hardware device' do + context 'when using two-factor authentication via WebAuthn' do + let(:user) { create(:admin, :two_factor_via_webauthn) } + def authenticate_2fa(user_params) post(:create, params: { user: user_params }, session: { otp_user_id: user.id }) end @@ -237,10 +239,6 @@ RSpec.describe Admin::SessionsController, :do_not_mock_admin_mode do end it 'can login with valid auth' do - # we can stub both without an differentiation between webauthn / u2f - # as these not interfere with each other und this saves us passing aroud - # parameters - allow(U2fRegistration).to receive(:authenticate).and_return(true) allow_any_instance_of(Webauthn::AuthenticateService).to receive(:execute).and_return(true) expect(controller.current_user_mode.admin_mode?).to be(false) @@ -255,7 +253,6 @@ RSpec.describe Admin::SessionsController, :do_not_mock_admin_mode do end it 'cannot login with invalid auth' do - allow(U2fRegistration).to receive(:authenticate).and_return(false) allow_any_instance_of(Webauthn::AuthenticateService).to receive(:execute).and_return(false) expect(controller.current_user_mode.admin_mode?).to be(false) @@ -267,12 +264,6 @@ RSpec.describe Admin::SessionsController, :do_not_mock_admin_mode do expect(controller.current_user_mode.admin_mode?).to be(false) end end - - context 'when using two-factor authentication via WebAuthn' do - it_behaves_like 'when using two-factor authentication via hardware device' do - let(:user) { create(:admin, :two_factor_via_webauthn) } - end - end end end diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb index 77ec72e72dd..80856512bba 100644 --- a/spec/controllers/sessions_controller_spec.rb +++ b/spec/controllers/sessions_controller_spec.rb @@ -493,51 +493,49 @@ RSpec.describe SessionsController do end end - context 'when using two-factor authentication via U2F device' do - let(:user) { create(:user, :two_factor) } + context 'when using two-factor authentication via WebAuthn device' do + let(:user) { create(:user, :two_factor_via_webauthn) } - def authenticate_2fa_u2f(user_params) + def authenticate_2fa(user_params) post(:create, params: { user: user_params }, session: { otp_user_id: user.id }) end - before do - stub_feature_flags(webauthn: false) - end - context 'remember_me field' do it 'sets a remember_user_token cookie when enabled' do - allow(U2fRegistration).to receive(:authenticate).and_return(true) + allow_any_instance_of(Webauthn::AuthenticateService).to receive(:execute).and_return(true) allow(controller).to receive(:find_user).and_return(user) - expect(controller) - .to receive(:remember_me).with(user).and_call_original + expect(controller).to receive(:remember_me).with(user).and_call_original - authenticate_2fa_u2f(remember_me: '1', login: user.username, device_response: "{}") + authenticate_2fa(remember_me: '1', login: user.username, device_response: "{}") expect(response.cookies['remember_user_token']).to be_present end it 'does nothing when disabled' do - allow(U2fRegistration).to receive(:authenticate).and_return(true) + allow_any_instance_of(Webauthn::AuthenticateService).to receive(:execute).and_return(true) allow(controller).to receive(:find_user).and_return(user) expect(controller).not_to receive(:remember_me) - authenticate_2fa_u2f(remember_me: '0', login: user.username, device_response: "{}") + authenticate_2fa(remember_me: '0', login: user.username, device_response: "{}") expect(response.cookies['remember_user_token']).to be_nil end end it "creates an audit log record" do - allow(U2fRegistration).to receive(:authenticate).and_return(true) - expect { authenticate_2fa_u2f(login: user.username, device_response: "{}") }.to change { AuditEvent.count }.by(1) - expect(AuditEvent.last.details[:with]).to eq("two-factor-via-u2f-device") + allow_any_instance_of(Webauthn::AuthenticateService).to receive(:execute).and_return(true) + + expect { authenticate_2fa(login: user.username, device_response: "{}") }.to( + change { AuditEvent.count }.by(1)) + expect(AuditEvent.last.details[:with]).to eq("two-factor-via-webauthn-device") end it "creates an authentication event record" do - allow(U2fRegistration).to receive(:authenticate).and_return(true) + allow_any_instance_of(Webauthn::AuthenticateService).to receive(:execute).and_return(true) - expect { authenticate_2fa_u2f(login: user.username, device_response: "{}") }.to change { AuthenticationEvent.count }.by(1) - expect(AuthenticationEvent.last.provider).to eq("two-factor-via-u2f-device") + expect { authenticate_2fa(login: user.username, device_response: "{}") }.to( + change { AuthenticationEvent.count }.by(1)) + expect(AuthenticationEvent.last.provider).to eq("two-factor-via-webauthn-device") end end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index eab0771fe83..96aee0e48e9 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -984,10 +984,6 @@ RSpec.describe User, feature_category: :user_profile do end end - describe 'and U2F' do - it_behaves_like "returns the right users", :two_factor_via_u2f - end - describe 'and WebAuthn' do it_behaves_like "returns the right users", :two_factor_via_webauthn end @@ -1003,26 +999,6 @@ RSpec.describe User, feature_category: :user_profile do expect(users_without_two_factor).not_to include(user_with_2fa.id) end - describe 'and u2f' do - it 'excludes users with 2fa enabled via U2F' do - user_with_2fa = create(:user, :two_factor_via_u2f) - user_without_2fa = create(:user) - users_without_two_factor = described_class.without_two_factor.pluck(:id) - - expect(users_without_two_factor).to include(user_without_2fa.id) - expect(users_without_two_factor).not_to include(user_with_2fa.id) - end - - it 'excludes users with 2fa enabled via OTP and U2F' do - user_with_2fa = create(:user, :two_factor_via_otp, :two_factor_via_u2f) - user_without_2fa = create(:user) - users_without_two_factor = described_class.without_two_factor.pluck(:id) - - expect(users_without_two_factor).to include(user_without_2fa.id) - expect(users_without_two_factor).not_to include(user_with_2fa.id) - end - end - describe 'and webauthn' do it 'excludes users with 2fa enabled via WebAuthn' do user_with_2fa = create(:user, :two_factor_via_webauthn) @@ -2213,54 +2189,6 @@ RSpec.describe User, feature_category: :user_profile do end end - context 'two_factor_u2f_enabled?' do - let_it_be(:user) { create(:user, :two_factor) } - - context 'when webauthn feature flag is enabled' do - context 'user has no U2F registration' do - it { expect(user.two_factor_u2f_enabled?).to eq(false) } - end - - context 'user has existing U2F registration' do - it 'returns false' do - device = U2F::FakeU2F.new(FFaker::BaconIpsum.characters(5)) - create(:u2f_registration, - name: 'my u2f device', - user: user, - certificate: Base64.strict_encode64(device.cert_raw), - key_handle: U2F.urlsafe_encode64(device.key_handle_raw), - public_key: Base64.strict_encode64(device.origin_public_key_raw)) - - expect(user.two_factor_u2f_enabled?).to eq(false) - end - end - end - - context 'when webauthn feature flag is disabled' do - before do - stub_feature_flags(webauthn: false) - end - - context 'user has no U2F registration' do - it { expect(user.two_factor_u2f_enabled?).to eq(false) } - end - - context 'user has existing U2F registration' do - it 'returns true' do - device = U2F::FakeU2F.new(FFaker::BaconIpsum.characters(5)) - create(:u2f_registration, - name: 'my u2f device', - user: user, - certificate: Base64.strict_encode64(device.cert_raw), - key_handle: U2F.urlsafe_encode64(device.key_handle_raw), - public_key: Base64.strict_encode64(device.origin_public_key_raw)) - - expect(user.two_factor_u2f_enabled?).to eq(true) - end - end - end - end - describe 'needs_new_otp_secret?', :freeze_time do let(:user) { create(:user) } |