diff --git a/app/assets/javascripts/notes/components/discussion_filter_note.vue b/app/assets/javascripts/notes/components/discussion_filter_note.vue index 83326279423..61af0b06535 100644 --- a/app/assets/javascripts/notes/components/discussion_filter_note.vue +++ b/app/assets/javascripts/notes/components/discussion_filter_note.vue @@ -39,8 +39,8 @@ export default { -
- +
+ {{ __('Show all activity') }} diff --git a/app/models/terraform/state.rb b/app/models/terraform/state.rb index 4d17a4d332c..59f7d852ce6 100644 --- a/app/models/terraform/state.rb +++ b/app/models/terraform/state.rb @@ -3,6 +3,7 @@ module Terraform class State < ApplicationRecord include UsageStatistics + include AfterCommitQueue HEX_REGEXP = %r{\A\h+\z}.freeze UUID_LENGTH = 32 diff --git a/app/services/terraform/states/trigger_destroy_service.rb b/app/services/terraform/states/trigger_destroy_service.rb index 3669bdcf716..3347d429bb4 100644 --- a/app/services/terraform/states/trigger_destroy_service.rb +++ b/app/services/terraform/states/trigger_destroy_service.rb @@ -12,9 +12,11 @@ module Terraform return unauthorized_response unless can_destroy_state? return state_locked_response if state.locked? - state.update!(deleted_at: Time.current) + state.run_after_commit do + Terraform::States::DestroyWorker.perform_async(id) + end - Terraform::States::DestroyWorker.perform_async(state.id) + state.update!(deleted_at: Time.current) ServiceResponse.success end diff --git a/doc/ci/environments/index.md b/doc/ci/environments/index.md index b13bd041d46..f995d4790c0 100644 --- a/doc/ci/environments/index.md +++ b/doc/ci/environments/index.md @@ -642,6 +642,18 @@ To delete a stopped environment in the GitLab UI: 1. Next to the environment you want to delete, select **Delete environment**. 1. On the confirmation dialog box, select **Delete environment**. +#### Delete an active environment without running a stop job + +> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/225794) in GitLab 15.1. + +You can delete an active environment without running a stop job. +This is useful when you have an active environment, but the corresponding `action: stop` job can't run or succeed for some reason. + +To delete an active environment: + +1. Execute the [Stop an environment API](../../api/environments.md#stop-an-environment) while specifying `force=true`. +1. Execute the [Delete an environment API](../../api/environments.md#delete-an-environment). + ### Access an environment for preparation or verification purposes > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/208655) in GitLab 13.2. diff --git a/doc/user/application_security/sast/index.md b/doc/user/application_security/sast/index.md index d4dd8059c6a..3c6ca020a13 100644 --- a/doc/user/application_security/sast/index.md +++ b/doc/user/application_security/sast/index.md @@ -74,41 +74,42 @@ GitLab SAST supports a variety of languages, package managers, and frameworks. O You can also [view our language roadmap](https://about.gitlab.com/direction/secure/static-analysis/sast/#language-support) and [request other language support by opening an issue](https://gitlab.com/groups/gitlab-org/-/epics/297). -| Language (package managers) / framework | Scan tool | Introduced in GitLab Version | -|---------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------| -| .NET Core | [Security Code Scan](https://security-code-scan.github.io) | 11.0 | -| .NET Framework | [Security Code Scan](https://security-code-scan.github.io) | 13.0 | -| Apex (Salesforce) | [PMD](https://pmd.github.io/pmd/index.html) | 12.1 | -| C | [Semgrep](https://semgrep.dev) | 14.2 | -| C/C++ | [Flawfinder](https://github.com/david-a-wheeler/flawfinder) | 10.7 | -| Elixir (Phoenix) | [Sobelow](https://github.com/nccgroup/sobelow) | 11.1 | -| Go | [Gosec](https://github.com/securego/gosec) | 10.7 | -| Go | [Semgrep](https://semgrep.dev) | 14.4 | -| Groovy ([Ant](https://ant.apache.org/), [Gradle](https://gradle.org/), [Maven](https://maven.apache.org/), and [SBT](https://www.scala-sbt.org/)) | [SpotBugs](https://spotbugs.github.io/) with the [find-sec-bugs](https://find-sec-bugs.github.io/) plugin | 11.3 (Gradle) & 11.9 (Ant, Maven, SBT) | -| Helm Charts | [Kubesec](https://github.com/controlplaneio/kubesec) | 13.1 | -| Java (any build system) | [Semgrep](https://semgrep.dev) | 14.10 | -| Java ([Ant](https://ant.apache.org/), [Gradle](https://gradle.org/), [Maven](https://maven.apache.org/), and [SBT](https://www.scala-sbt.org/)) | [SpotBugs](https://spotbugs.github.io/) with the [find-sec-bugs](https://find-sec-bugs.github.io/) plugin | 10.6 (Maven), 10.8 (Gradle) & 11.9 (Ant, SBT) | -| Java (Android) | [MobSF (beta)](https://github.com/MobSF/Mobile-Security-Framework-MobSF) | 13.5 | -| JavaScript | [ESLint security plugin](https://github.com/nodesecurity/eslint-plugin-security) | 11.8 | -| JavaScript | [Semgrep](https://semgrep.dev) | 13.10 | -| Kotlin (Android) | [MobSF (beta)](https://github.com/MobSF/Mobile-Security-Framework-MobSF) | 13.5 | -| Kotlin (General) | [SpotBugs](https://spotbugs.github.io/) with the [find-sec-bugs](https://find-sec-bugs.github.io/) plugin | 13.11 | -| Kubernetes manifests | [Kubesec](https://github.com/controlplaneio/kubesec) | 12.6 | -| Node.js | [NodeJsScan](https://github.com/ajinabraham/NodeJsScan) | 11.1 | -| Objective-C (iOS) | [MobSF (beta)](https://github.com/MobSF/Mobile-Security-Framework-MobSF) | 13.5 | -| PHP | [phpcs-security-audit](https://github.com/FloeDesignTechnologies/phpcs-security-audit) | 10.8 | -| Python ([pip](https://pip.pypa.io/en/stable/)) | [bandit](https://github.com/PyCQA/bandit) | 10.3 | -| Python | [Semgrep](https://semgrep.dev) | 13.9 | -| React | [ESLint react plugin](https://github.com/yannickcr/eslint-plugin-react) | 12.5 | -| React | [Semgrep](https://semgrep.dev) | 13.10 | -| Ruby | [brakeman](https://brakemanscanner.org) | 13.9 | -| Ruby on Rails | [brakeman](https://brakemanscanner.org) | 10.3 | -| Scala ([Ant](https://ant.apache.org/), [Gradle](https://gradle.org/), [Maven](https://maven.apache.org/), and [SBT](https://www.scala-sbt.org/)) | [SpotBugs](https://spotbugs.github.io/) with the [find-sec-bugs](https://find-sec-bugs.github.io/) plugin | 11.0 (SBT) & 11.9 (Ant, Gradle, Maven) | -| Swift (iOS) | [MobSF (beta)](https://github.com/MobSF/Mobile-Security-Framework-MobSF) | 13.5 | -| TypeScript | [ESLint security plugin](https://github.com/nodesecurity/eslint-plugin-security) | 11.9, [merged](https://gitlab.com/gitlab-org/gitlab/-/issues/36059) with ESLint in 13.2 | -| TypeScript | [Semgrep](https://semgrep.dev) | 13.10 | +| Language (package managers) / framework | Scan tool | Introduced in GitLab Version | +|------------------------------------------------|-----------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------| +| .NET Core | [Security Code Scan](https://security-code-scan.github.io) | 11.0 | +| .NET Framework1 | [Security Code Scan](https://security-code-scan.github.io) | 13.0 | +| Apex (Salesforce) | [PMD](https://pmd.github.io/pmd/index.html) | 12.1 | +| C | [Semgrep](https://semgrep.dev) | 14.2 | +| C/C++ | [Flawfinder](https://github.com/david-a-wheeler/flawfinder) | 10.7 | +| Elixir (Phoenix) | [Sobelow](https://github.com/nccgroup/sobelow) | 11.1 | +| Go | [Gosec](https://github.com/securego/gosec) | 10.7 | +| Go | [Semgrep](https://semgrep.dev) | 14.4 | +| Groovy2 | [SpotBugs](https://spotbugs.github.io/) with the [find-sec-bugs](https://find-sec-bugs.github.io/) plugin | 11.3 (Gradle) & 11.9 (Ant, Maven, SBT) | +| Helm Charts | [Kubesec](https://github.com/controlplaneio/kubesec) | 13.1 | +| Java (any build system) | [Semgrep](https://semgrep.dev) | 14.10 | +| Java2 | [SpotBugs](https://spotbugs.github.io/) with the [find-sec-bugs](https://find-sec-bugs.github.io/) plugin | 10.6 (Maven), 10.8 (Gradle) & 11.9 (Ant, SBT) | +| Java (Android) | [MobSF (beta)](https://github.com/MobSF/Mobile-Security-Framework-MobSF) | 13.5 | +| JavaScript | [ESLint security plugin](https://github.com/nodesecurity/eslint-plugin-security) | 11.8 | +| JavaScript | [Semgrep](https://semgrep.dev) | 13.10 | +| Kotlin (Android) | [MobSF (beta)](https://github.com/MobSF/Mobile-Security-Framework-MobSF) | 13.5 | +| Kotlin (General)2 | [SpotBugs](https://spotbugs.github.io/) with the [find-sec-bugs](https://find-sec-bugs.github.io/) plugin | 13.11 | +| Kubernetes manifests | [Kubesec](https://github.com/controlplaneio/kubesec) | 12.6 | +| Node.js | [NodeJsScan](https://github.com/ajinabraham/NodeJsScan) | 11.1 | +| Objective-C (iOS) | [MobSF (beta)](https://github.com/MobSF/Mobile-Security-Framework-MobSF) | 13.5 | +| PHP | [phpcs-security-audit](https://github.com/FloeDesignTechnologies/phpcs-security-audit) | 10.8 | +| Python ([pip](https://pip.pypa.io/en/stable/)) | [bandit](https://github.com/PyCQA/bandit) | 10.3 | +| Python | [Semgrep](https://semgrep.dev) | 13.9 | +| React | [ESLint react plugin](https://github.com/yannickcr/eslint-plugin-react) | 12.5 | +| React | [Semgrep](https://semgrep.dev) | 13.10 | +| Ruby | [brakeman](https://brakemanscanner.org) | 13.9 | +| Ruby on Rails | [brakeman](https://brakemanscanner.org) | 10.3 | +| Scala2 | [SpotBugs](https://spotbugs.github.io/) with the [find-sec-bugs](https://find-sec-bugs.github.io/) plugin | 11.0 (SBT) & 11.9 (Ant, Gradle, Maven) | +| Swift (iOS) | [MobSF (beta)](https://github.com/MobSF/Mobile-Security-Framework-MobSF) | 13.5 | +| TypeScript | [ESLint security plugin](https://github.com/nodesecurity/eslint-plugin-security) | 11.9, [merged](https://gitlab.com/gitlab-org/gitlab/-/issues/36059) with ESLint in 13.2 | +| TypeScript | [Semgrep](https://semgrep.dev) | 13.10 | -Note that the Java analyzers can also be used for variants like the +1. .NET 4 support is limited. The analyzer runs in a Linux container and does not have access to Windows-specific libraries or features. We currently plan to [migrate C# coverage to Semgrep-based scanning](https://gitlab.com/gitlab-org/gitlab/-/issues/347258) to make it easier to scan C# projects. +1. The SpotBugs-based analyzer supports [Ant](https://ant.apache.org/), [Gradle](https://gradle.org/), [Maven](https://maven.apache.org/), and [SBT](https://www.scala-sbt.org/). It can also be used with variants like the [Gradle wrapper](https://docs.gradle.org/current/userguide/gradle_wrapper.html), [Grails](https://grails.org/), and the [Maven wrapper](https://github.com/takari/maven-wrapper). diff --git a/lib/api/terraform/state.rb b/lib/api/terraform/state.rb index b727fbd9f65..a19919b5e76 100644 --- a/lib/api/terraform/state.rb +++ b/lib/api/terraform/state.rb @@ -81,7 +81,7 @@ module API delete do authorize! :admin_terraform_state, user_project - remote_state_handler.handle_with_lock do |state| + remote_state_handler.find_with_lock do |state| ::Terraform::States::TriggerDestroyService.new(state, current_user: current_user).execute end diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb index 5d5a431f206..6c3487c28ea 100644 --- a/lib/gitlab/auth.rb +++ b/lib/gitlab/auth.rb @@ -217,7 +217,7 @@ module Gitlab return unless valid_scoped_token?(token, all_available_scopes) if project && token.user.project_bot? - return unless token_bot_in_resource?(token.user, project) + return unless can_read_project?(token.user, project) end if token.user.can_log_in_with_non_expired_password? || token.user.project_bot? @@ -225,22 +225,8 @@ module Gitlab end end - def token_bot_in_project?(user, project) - project.bots.include?(user) - end - - # rubocop: disable CodeReuse/ActiveRecord - - # A workaround for adding group-level automation is to add the bot user of a project access token as a group member. - # In order to make project access tokens work this way during git authentication, we need to add an additional check for group membership. - # This is a temporary workaround until service accounts are implemented. - def token_bot_in_group?(user, project) - project.group && project.group.members_with_parents.where(user_id: user.id).exists? - end - # rubocop: enable CodeReuse/ActiveRecord - - def token_bot_in_resource?(user, project) - token_bot_in_project?(user, project) || token_bot_in_group?(user, project) + def can_read_project?(user, project) + user.can?(:read_project, project) end def valid_oauth_token?(token) @@ -323,7 +309,7 @@ module Gitlab return unless build.project.builds_enabled? if build.user - return unless build.user.can_log_in_with_non_expired_password? || (build.user.project_bot? && token_bot_in_resource?(build.user, build.project)) + return unless build.user.can_log_in_with_non_expired_password? || (build.user.project_bot? && can_read_project?(build.user, build.project)) # If user is assigned to build, use restricted credentials of user Gitlab::Auth::Result.new(build.user, build.project, :build, build_authentication_abilities) diff --git a/qa/qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb index c86a649f179..9ba41626d5f 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/login/2fa_recovery_spec.rb @@ -1,10 +1,13 @@ # frozen_string_literal: true module QA - RSpec.describe 'Manage', :requires_admin, :skip_live_env do + RSpec.describe 'Manage', :requires_admin, :skip_live_env, :reliable do describe '2FA' do let(:owner_user) do - Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_2fa_owner_username_1, Runtime::Env.gitlab_qa_2fa_owner_password_1) + Resource::User.fabricate_or_use( + Runtime::Env.gitlab_qa_2fa_owner_username_1, + Runtime::Env.gitlab_qa_2fa_owner_password_1 + ) end let(:developer_user) do @@ -32,7 +35,10 @@ module QA group.add_member(developer_user, Resource::Members::AccessLevel::DEVELOPER) end - it 'allows using 2FA recovery code once only', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347937' do + it( + 'allows using 2FA recovery code once only', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347937' + ) do recovery_code = enable_2fa_for_user_and_fetch_recovery_code(developer_user) Flow::Login.sign_in(as: developer_user, skip_page_validation: true) @@ -56,13 +62,6 @@ module QA expect(page).to have_text('Invalid two-factor code') end - after do - group.set_require_two_factor_authentication(value: 'false') - group.remove_via_api! - sandbox_group.remove_via_api! - developer_user.remove_via_api! - end - def admin_api_client @admin_api_client ||= Runtime::API::Client.as_admin end @@ -74,9 +73,9 @@ module QA def enable_2fa_for_user_and_fetch_recovery_code(user) Flow::Login.while_signed_in(as: user) do Page::Profile::TwoFactorAuth.perform do |two_fa_auth| - @otp = QA::Support::OTP.new(two_fa_auth.otp_secret_content) + otp = QA::Support::OTP.new(two_fa_auth.otp_secret_content) - two_fa_auth.set_pin_code(@otp.fresh_otp) + two_fa_auth.set_pin_code(otp.fresh_otp) two_fa_auth.set_current_password(user.password) two_fa_auth.click_register_2fa_app_button diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb index f5a74956174..1e869df0988 100644 --- a/spec/lib/gitlab/auth_spec.rb +++ b/spec/lib/gitlab/auth_spec.rb @@ -481,6 +481,17 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do end it_behaves_like 'with an invalid access token' + + context 'when the token belongs to a group via project share' do + let_it_be(:invited_group) { create(:group) } + + before do + invited_group.add_maintainer(project_bot_user) + create(:project_group_link, group: invited_group, project: project) + end + + it_behaves_like 'with a valid access token' + end end end end diff --git a/spec/services/terraform/states/trigger_destroy_service_spec.rb b/spec/services/terraform/states/trigger_destroy_service_spec.rb index 2e96331779c..459f4c3bdb9 100644 --- a/spec/services/terraform/states/trigger_destroy_service_spec.rb +++ b/spec/services/terraform/states/trigger_destroy_service_spec.rb @@ -9,7 +9,9 @@ RSpec.describe Terraform::States::TriggerDestroyService do describe '#execute', :aggregate_failures do let_it_be(:state) { create(:terraform_state, project: project) } - subject { described_class.new(state, current_user: user).execute } + let(:service) { described_class.new(state, current_user: user) } + + subject { service.execute } it 'marks the state as deleted and schedules a cleanup worker' do expect(Terraform::States::DestroyWorker).to receive(:perform_async).with(state.id).once @@ -18,6 +20,15 @@ RSpec.describe Terraform::States::TriggerDestroyService do expect(state.deleted_at).to be_like_time(Time.current) end + context 'within a database transaction' do + subject { state.with_lock { service.execute } } + + it 'does not raise an EnqueueFromTransactionError' do + expect { subject }.not_to raise_error + expect(state.deleted_at).to be_like_time(Time.current) + end + end + shared_examples 'unable to delete state' do it 'does not modify the state' do expect(Terraform::States::DestroyWorker).not_to receive(:perform_async)