diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-17 18:10:27 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-05-17 18:10:27 +0300 |
commit | 30785cadee10a5deaa45ada13def96bcfa6663b0 (patch) | |
tree | 5c00df23827cba5b50177698923313a5e38d1c89 | |
parent | 43771438e9ccf20d1b6cf12b690e63844d7c3d49 (diff) |
Add latest changes from gitlab-org/gitlab@master
27 files changed, 329 insertions, 55 deletions
diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml index 8a730970d9e..e6ad520ccca 100644 --- a/.gitlab/ci/rules.gitlab-ci.yml +++ b/.gitlab/ci/rules.gitlab-ci.yml @@ -856,6 +856,9 @@ .build-images:rules:build-qa-image-as-if-foss: rules: - !reference [".build-images:rules:build-qa-image-merge-requests", "rules"] + - <<: *if-default-branch-schedule-nightly + variables: + ARCH: amd64,arm64 # We want to rebuild the master image when the full e2e test pipeline runs. Currently this happens on a 2 hour schedule. .build-images:rules:build-qa-on-gdk-master-image: diff --git a/app/assets/javascripts/work_items/components/work_item_detail.vue b/app/assets/javascripts/work_items/components/work_item_detail.vue index 0f1af44e8a1..f20ca1ce69a 100644 --- a/app/assets/javascripts/work_items/components/work_item_detail.vue +++ b/app/assets/javascripts/work_items/components/work_item_detail.vue @@ -279,7 +279,7 @@ export default { // Once more types are moved to have Work Items involved // we need to handle this properly. if (this.parentWorkItemType === WORK_ITEM_TYPE_VALUE_ISSUE) { - return `../../issues/${this.parentWorkItem?.iid}`; + return `../../-/issues/${this.parentWorkItem?.iid}`; } return this.parentWorkItem?.webUrl; }, diff --git a/app/assets/stylesheets/framework/mixins.scss b/app/assets/stylesheets/framework/mixins.scss index dd1989aa5e1..529f6acaf04 100644 --- a/app/assets/stylesheets/framework/mixins.scss +++ b/app/assets/stylesheets/framework/mixins.scss @@ -436,8 +436,7 @@ &:last-child { &::after { - content: ''; - padding: 0; + display: none; } } } diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index ad3b79b604c..97b625d1ae2 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -613,8 +613,7 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo Feature.enabled?(:summarize_my_code_review, current_user) && namespace.group_namespace? && namespace.licensed_feature_available?(:summarize_my_mr_code_review) && - Gitlab::Llm::StageCheck.available?(namespace, :summarize_my_mr_code_review) && - merge_request.send_to_ai? + Gitlab::Llm::StageCheck.available?(namespace, :summarize_my_mr_code_review) end end diff --git a/app/views/projects/tags/show.html.haml b/app/views/projects/tags/show.html.haml index 3124f47c832..5127972c406 100644 --- a/app/views/projects/tags/show.html.haml +++ b/app/views/projects/tags/show.html.haml @@ -1,6 +1,6 @@ - user = user_email = nil -- if @tag.tagger - - user_email = @tag.tagger.email +- if @tag.user_email + - user_email = @tag.user_email - user = User.find_by_any_email(user_email) - add_to_breadcrumbs s_('TagsPage|Tags'), project_tags_path(@project) - breadcrumb_title @tag.name diff --git a/config/feature_flags/development/adapt_deprecated_approvals.yml b/config/feature_flags/development/adapt_deprecated_approvals.yml index 697f7e21025..0f2ba559033 100644 --- a/config/feature_flags/development/adapt_deprecated_approvals.yml +++ b/config/feature_flags/development/adapt_deprecated_approvals.yml @@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/409686 milestone: '16.0' type: development group: group::source code -default_enabled: false +default_enabled: true diff --git a/data/removals/16_0/16-0-ttl-days-removal.yml b/data/removals/16_0/16-0-ttl-days-removal.yml new file mode 100644 index 00000000000..213e58017c4 --- /dev/null +++ b/data/removals/16_0/16-0-ttl-days-removal.yml @@ -0,0 +1,16 @@ +- title: "Default value of `ttl_days` now 30 days" + announcement_milestone: "15.4" # (required) The milestone when this feature was deprecated. + removal_milestone: "16.0" # (required) The milestone when this feature is being removed. + breaking_change: true # (required) Change to false if this is not a breaking change. + reporter: tlinz + stage: create # (required) String value of the stage that the feature was created in. e.g., Growth + issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/369122 # (required) Link to the deprecation issue in GitLab + body: | # (required) Do not modify this line, instead modify the lines below. + From GitLab 16.0, any personal, project, or group access token [must have an expiration date](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96594). If you create a personal access token with the GitLab Shell command `personal_access_token` without specifying `ttl_days`, a default value of 30 days is now applied. +# +# OPTIONAL FIELDS +# + tiers: [Core, Premium, Ultimate] + documentation_url: https://docs.gitlab.com/ee/user/profile/personal_access_tokens.html + image_url: + video_url: diff --git a/doc/.vale/gitlab/spelling-exceptions.txt b/doc/.vale/gitlab/spelling-exceptions.txt index 476b1eebf84..4bed441ba9d 100644 --- a/doc/.vale/gitlab/spelling-exceptions.txt +++ b/doc/.vale/gitlab/spelling-exceptions.txt @@ -309,6 +309,7 @@ dput Dreamweaver DRIs DSLs +DSN Dynatrace Ecto eden diff --git a/doc/api/project_job_token_scopes.md b/doc/api/project_job_token_scopes.md new file mode 100644 index 00000000000..9120428998a --- /dev/null +++ b/doc/api/project_job_token_scopes.md @@ -0,0 +1,71 @@ +--- +stage: Verify +group: Pipeline Security +info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments" +--- + +# Project job token scope API **(FREE)** + +NOTE: + +- Every calls to the project token scope API must be authenticated, for example, with a personal access token. +- The authenticated user (personal access token) needs to have at least Maintainer role for the project. +- Depending on the usage, the personal access token requires read access (scope `read_api`) or read/write access (scope `api`) to the API. + +## Get a project job token scope + +Fetch CI_JOB_TOKEN access settings (job token scope) of a project. + +```plaintext +GET /projects/:id/job_token_scope +``` + +Parameters + +| Attribute | Type | Required | Description | +|-----------|----------------|------------------------|-------------| +| `id` | integer/string | **{check-circle}** Yes | ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding) owned by the authenticated user. | + +Example of request + +```shell +curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/1/job_token_scope" +``` + +Example of response + +```json +{ + "inbound_enabled": true, + "outbound_enabled": false +} +``` + +## Patch a project job token scope + +Patch CI_JOB_TOKEN access settings of a project. + +```plaintext +PATCH /projects/:id/job_token_scope +``` + +Parameters + +| Attribute | Type | Required | Description | +|-----------|----------------|-------------------------|-------------| +| `id` | integer/string | **{check-circle}** Yes | ID or [URL-encoded path of the project](rest/index.md#namespaced-path-encoding) owned by the authenticated user. | +| `enabled` | boolean | **{dotted-circle}** Yes | Indicates CI/CD job tokens generated in other projects have restricted access to this project. | + +Example of request + +```shell +curl --request PATCH \ + --url "https://gitlab.example.com/api/v4/projects/7/job_token_scope" \ + --header 'PRIVATE-TOKEN: <your_access_token>' \ + --header 'Content-Type: application/json' \ + --data '{ "enabled": false }' +``` + +Example of response + +There is no response body. diff --git a/doc/update/removals.md b/doc/update/removals.md index e371e2f0fb0..4f048c9277d 100644 --- a/doc/update/removals.md +++ b/doc/update/removals.md @@ -162,6 +162,16 @@ Instead, use the [new variable names](https://docs.gitlab.com/ee/user/applicatio - `CS_REGISTRY_USER` - `CS_DOCKERFILE_PATH` +### Default value of `ttl_days` now 30 days + +<div class="deprecation-notes"> +- Announced in: GitLab <span class="milestone">15.4</span> +- This is a [breaking change](https://docs.gitlab.com/ee/development/deprecation_guidelines/). Review the details carefully before upgrading. +- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/369122). +</div> + +From GitLab 16.0, any personal, project, or group access token [must have an expiration date](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96594). If you create a personal access token with the GitLab Shell command `personal_access_token` without specifying `ttl_days`, a default value of 30 days is now applied. + ### Dependency Scanning ends support for Java 13, 14, 15, and 16 <div class="deprecation-notes"> diff --git a/doc/user/group/value_stream_analytics/index.md b/doc/user/group/value_stream_analytics/index.md index bc48c1050fb..f6df7eb33a2 100644 --- a/doc/user/group/value_stream_analytics/index.md +++ b/doc/user/group/value_stream_analytics/index.md @@ -51,6 +51,9 @@ Value stream analytics offers different features at the project and group level |Date filter behavior|Filters items [finished within the date range](https://gitlab.com/groups/gitlab-org/-/epics/6046)|Filters items by creation date.|Filters items by creation date.| |Authorization|At least reporter|At least reporter|Can be public| +NOTE: +Feature parity of project-level with group-level value stream analytics is achieved by using the new record `ProjectNamespace`. For details about this consolidation initiative, see the [Organization documentation](../../../development/organization/index.md). + ## How value stream analytics works Value stream analytics calculates the duration of every stage of your software development process. diff --git a/lib/api/project_job_token_scope.rb b/lib/api/project_job_token_scope.rb index 7fd288491ef..5073d20be56 100644 --- a/lib/api/project_job_token_scope.rb +++ b/lib/api/project_job_token_scope.rb @@ -22,6 +22,35 @@ module API present user_project, with: Entities::ProjectJobTokenScope end + + desc 'Patch CI_JOB_TOKEN access settings.' do + failure [ + { code: 400, message: 'Bad Request' }, + { code: 401, message: 'Unauthorized' }, + { code: 403, message: 'Forbidden' }, + { code: 404, message: 'Not found' } + ] + success code: 204 + tags %w[projects_job_token_scope] + end + params do + requires :enabled, + type: Boolean, + as: :ci_inbound_job_token_scope_enabled, + allow_blank: false, + desc: "Indicates CI/CD job tokens generated in other projects have restricted access to this project." + end + + patch ':id/job_token_scope' do + authorize_admin_project + + job_token_scope_params = declared_params(include_missing: false) + result = ::Projects::UpdateService.new(user_project, current_user, job_token_scope_params).execute + + break bad_request!(result[:message]) if result[:status] == :error + + no_content! + end end end end diff --git a/lib/gitlab/ci/templates/Kaniko.gitlab-ci.yml b/lib/gitlab/ci/templates/Kaniko.gitlab-ci.yml index d46ac97ad1b..d7a6104082d 100644 --- a/lib/gitlab/ci/templates/Kaniko.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Kaniko.gitlab-ci.yml @@ -32,11 +32,11 @@ kaniko-build: VERSION="latest" elif [ -n "$CI_COMMIT_TAG" ];then NOSLASH=$(echo "$CI_COMMIT_TAG" | tr -s / - ) - SANITIZED="${NOSLASH//[^a-zA-Z0-9\-\.]/}" + SANITIZED="${NOSLASH//[^a-zA-Z0-9.-]/}" VERSION="$SANITIZED" else \ NOSLASH=$(echo "$CI_COMMIT_REF_NAME" | tr -s / - ) - SANITIZED="${NOSLASH//[^a-zA-Z0-9\-]/}" + SANITIZED="${NOSLASH//[^a-zA-Z0-9-]/}" VERSION="branch-$SANITIZED" fi export IMAGE_TAG=$CI_REGISTRY_IMAGE:$VERSION diff --git a/lib/gitlab/dependency_linker/requirements_txt_linker.rb b/lib/gitlab/dependency_linker/requirements_txt_linker.rb index f630c13b760..dc654964e0b 100644 --- a/lib/gitlab/dependency_linker/requirements_txt_linker.rb +++ b/lib/gitlab/dependency_linker/requirements_txt_linker.rb @@ -9,7 +9,7 @@ module Gitlab def link_dependencies link_regex(/^(?<name>(?![a-z+]+:)[^#.-][^ ><=~!;\[]+)/) do |name| - "https://pypi.python.org/pypi/#{name}" + "https://pypi.org/project/#{name}/" end link_regex(%r{^(?<name>https?://[^ ]+)}, &:itself) diff --git a/lib/gitlab/git/tag.rb b/lib/gitlab/git/tag.rb index 37977a1dfb6..5b54ba472d9 100644 --- a/lib/gitlab/git/tag.rb +++ b/lib/gitlab/git/tag.rb @@ -76,8 +76,16 @@ module Gitlab encode! @message end - def tagger - @raw_tag.tagger + def user_name + encode! tagger.name if tagger + end + + def user_email + encode! tagger.email if tagger + end + + def date + Time.at(tagger.date.seconds).utc if tagger end def has_signature? @@ -105,6 +113,10 @@ module Gitlab private + def tagger + @raw_tag.tagger + end + def message_from_gitaly_tag return @raw_tag.message.dup if full_message_fetched_from_gitaly? diff --git a/lib/gitlab/x509/tag.rb b/lib/gitlab/x509/tag.rb index cf24e6f62bd..b9a3b11ac34 100644 --- a/lib/gitlab/x509/tag.rb +++ b/lib/gitlab/x509/tag.rb @@ -11,7 +11,7 @@ module Gitlab strong_memoize(:signature) do super - signature = X509::Signature.new(signature_text, signed_text, @tag.tagger.email, Time.at(@tag.tagger.date.seconds)) + signature = X509::Signature.new(signature_text, signed_text, @tag.user_email, @tag.date) signature unless signature.verified_signature.nil? end end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 6f2d5b8456a..78bc8b447b9 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -1862,7 +1862,7 @@ msgstr "" msgid "AISummary|Experiment" msgstr "" -msgid "AISummary|Generates a summary of all public comments" +msgid "AISummary|Generates a summary of all comments" msgstr "" msgid "AISummary|See summary" diff --git a/package.json b/package.json index fed66bb53c5..5f798734b0d 100644 --- a/package.json +++ b/package.json @@ -182,7 +182,7 @@ "rehype-raw": "^6.1.1", "remark-frontmatter": "^4.0.1", "remark-gfm": "^3.0.1", - "remark-parse": "^10.0.1", + "remark-parse": "^10.0.2", "remark-rehype": "^10.1.0", "scrollparent": "^2.0.1", "semver": "^7.3.4", diff --git a/qa/lib/gitlab/page/group/settings/billing.rb b/qa/lib/gitlab/page/group/settings/billing.rb index 1cb31c995f6..45a67526682 100644 --- a/qa/lib/gitlab/page/group/settings/billing.rb +++ b/qa/lib/gitlab/page/group/settings/billing.rb @@ -34,7 +34,9 @@ module Gitlab # # @param subscription_plan [String] def wait_for_subscription(subscription_plan, page:) - ::QA::Support::Waiter.wait_until(max_duration: 30, sleep_interval: 3, reload_page: page) do + ::QA::Support::Waiter.wait_until( + max_duration: ::QA::Support::Helpers::Zuora::ZUORA_TIMEOUT, sleep_interval: 2, reload_page: page, + message: "Subscription plan '#{subscription_plan}' failed to appear") do billing_plan_header.match?(/currently using the #{subscription_plan} saas plan/i) end end diff --git a/qa/lib/gitlab/page/group/settings/usage_quotas.rb b/qa/lib/gitlab/page/group/settings/usage_quotas.rb index a6d9cfa7846..ce540b5ee56 100644 --- a/qa/lib/gitlab/page/group/settings/usage_quotas.rb +++ b/qa/lib/gitlab/page/group/settings/usage_quotas.rb @@ -50,6 +50,12 @@ module Gitlab additional_ci_minutes[/(\d+){2}/] end + def additional_ci_minutes_added? + # When opening the Usage quotas page, Seats quota tab is opened briefly even when url is to a different tab + ::QA::Support::WaitForRequests.wait_for_requests + additional_ci_minutes? + end + # Waits and Checks if storage available alert presents on the page # # @return [Boolean] True if the alert presents, false if not after 5 second wait @@ -76,12 +82,6 @@ module Gitlab purchased_usage_total[/(\d+){2}.\d+/].to_f end - - def additional_ci_minutes_added? - # When opening the Usage quotas page, Seats quota tab is opened briefly even when url is to a different tab - ::QA::Support::WaitForRequests.wait_for_requests - additional_ci_minutes? - end end end end diff --git a/qa/qa/flow/purchase.rb b/qa/qa/flow/purchase.rb index 32c4f469207..2eee15b874c 100644 --- a/qa/qa/flow/purchase.rb +++ b/qa/qa/flow/purchase.rb @@ -3,7 +3,7 @@ module QA module Flow module Purchase - include QA::Support::Helpers::Plan + include Support::Helpers::Plan extend self diff --git a/qa/qa/support/helpers/zuora.rb b/qa/qa/support/helpers/zuora.rb new file mode 100644 index 00000000000..0f75d9bb1e6 --- /dev/null +++ b/qa/qa/support/helpers/zuora.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module QA + module Support + module Helpers + module Zuora + ZUORA_TIMEOUT = 60 + end + end + end +end diff --git a/spec/frontend/work_items/components/work_item_detail_spec.js b/spec/frontend/work_items/components/work_item_detail_spec.js index 557ae07969e..1b6ea8186bd 100644 --- a/spec/frontend/work_items/components/work_item_detail_spec.js +++ b/spec/frontend/work_items/components/work_item_detail_spec.js @@ -437,7 +437,7 @@ describe('WorkItemDetail component', () => { }); it('sets the parent breadcrumb URL pointing to issue page when parent type is `Issue`', () => { - expect(findParentButton().attributes().href).toBe('../../issues/5'); + expect(findParentButton().attributes().href).toBe('../../-/issues/5'); }); it('sets the parent breadcrumb URL based on parent webUrl when parent type is not `Issue`', async () => { diff --git a/spec/lib/gitlab/dependency_linker/requirements_txt_linker_spec.rb b/spec/lib/gitlab/dependency_linker/requirements_txt_linker_spec.rb index e59756cb7bc..86ebddc9681 100644 --- a/spec/lib/gitlab/dependency_linker/requirements_txt_linker_spec.rb +++ b/spec/lib/gitlab/dependency_linker/requirements_txt_linker_spec.rb @@ -68,22 +68,22 @@ RSpec.describe Gitlab::DependencyLinker::RequirementsTxtLinker do end it 'links dependencies' do - expect(subject).to include(link('nose', 'https://pypi.python.org/pypi/nose')) - expect(subject).to include(link('nose-cov', 'https://pypi.python.org/pypi/nose-cov')) - expect(subject).to include(link('beautifulsoup4', 'https://pypi.python.org/pypi/beautifulsoup4')) - expect(subject).to include(link('docopt', 'https://pypi.python.org/pypi/docopt')) - expect(subject).to include(link('keyring', 'https://pypi.python.org/pypi/keyring')) - expect(subject).to include(link('coverage', 'https://pypi.python.org/pypi/coverage')) - expect(subject).to include(link('Mopidy-Dirble', 'https://pypi.python.org/pypi/Mopidy-Dirble')) - expect(subject).to include(link('rejected', 'https://pypi.python.org/pypi/rejected')) - expect(subject).to include(link('green', 'https://pypi.python.org/pypi/green')) - expect(subject).to include(link('Jinja2', 'https://pypi.python.org/pypi/Jinja2')) - expect(subject).to include(link('Pygments', 'https://pypi.python.org/pypi/Pygments')) - expect(subject).to include(link('Sphinx', 'https://pypi.python.org/pypi/Sphinx')) - expect(subject).to include(link('docutils', 'https://pypi.python.org/pypi/docutils')) - expect(subject).to include(link('markupsafe', 'https://pypi.python.org/pypi/markupsafe')) - expect(subject).to include(link('pytest', 'https://pypi.python.org/pypi/pytest')) - expect(subject).to include(link('foop', 'https://pypi.python.org/pypi/foop')) + expect(subject).to include(link('nose', 'https://pypi.org/project/nose/')) + expect(subject).to include(link('nose-cov', 'https://pypi.org/project/nose-cov/')) + expect(subject).to include(link('beautifulsoup4', 'https://pypi.org/project/beautifulsoup4/')) + expect(subject).to include(link('docopt', 'https://pypi.org/project/docopt/')) + expect(subject).to include(link('keyring', 'https://pypi.org/project/keyring/')) + expect(subject).to include(link('coverage', 'https://pypi.org/project/coverage/')) + expect(subject).to include(link('Mopidy-Dirble', 'https://pypi.org/project/Mopidy-Dirble/')) + expect(subject).to include(link('rejected', 'https://pypi.org/project/rejected/')) + expect(subject).to include(link('green', 'https://pypi.org/project/green/')) + expect(subject).to include(link('Jinja2', 'https://pypi.org/project/Jinja2/')) + expect(subject).to include(link('Pygments', 'https://pypi.org/project/Pygments/')) + expect(subject).to include(link('Sphinx', 'https://pypi.org/project/Sphinx/')) + expect(subject).to include(link('docutils', 'https://pypi.org/project/docutils/')) + expect(subject).to include(link('markupsafe', 'https://pypi.org/project/markupsafe/')) + expect(subject).to include(link('pytest', 'https://pypi.org/project/pytest/')) + expect(subject).to include(link('foop', 'https://pypi.org/project/foop/')) end it 'links URLs' do @@ -91,7 +91,7 @@ RSpec.describe Gitlab::DependencyLinker::RequirementsTxtLinker do end it 'does not contain link with a newline as package name' do - expect(subject).not_to include(link("\n", "https://pypi.python.org/pypi/\n")) + expect(subject).not_to include(link("\n", "https://pypi.org/project/\n")) end end end diff --git a/spec/lib/gitlab/git/tag_spec.rb b/spec/lib/gitlab/git/tag_spec.rb index 240cf6ed46f..a15c74a058d 100644 --- a/spec/lib/gitlab/git/tag_spec.rb +++ b/spec/lib/gitlab/git/tag_spec.rb @@ -2,7 +2,7 @@ require "spec_helper" -RSpec.describe Gitlab::Git::Tag do +RSpec.describe Gitlab::Git::Tag, feature_category: :source_code_management do let_it_be(:project) { create(:project, :repository) } let_it_be(:repository) { project.repository.raw } @@ -17,10 +17,9 @@ RSpec.describe Gitlab::Git::Tag do it { expect(tag.has_signature?).to be_falsey } it { expect(tag.signature_type).to eq(:NONE) } it { expect(tag.signature).to be_nil } - it { expect(tag.tagger.name).to eq("Dmitriy Zaporozhets") } - it { expect(tag.tagger.email).to eq("dmitriy.zaporozhets@gmail.com") } - it { expect(tag.tagger.date).to eq(Google::Protobuf::Timestamp.new(seconds: 1393491299)) } - it { expect(tag.tagger.timezone).to eq("+0200") } + it { expect(tag.user_name).to eq("Dmitriy Zaporozhets") } + it { expect(tag.user_email).to eq("dmitriy.zaporozhets@gmail.com") } + it { expect(tag.date).to eq(Time.at(1393491299).utc) } end describe 'signed tag' do @@ -33,10 +32,9 @@ RSpec.describe Gitlab::Git::Tag do it { expect(tag.has_signature?).to be_truthy } it { expect(tag.signature_type).to eq(:X509) } it { expect(tag.signature).not_to be_nil } - it { expect(tag.tagger.name).to eq("Roger Meier") } - it { expect(tag.tagger.email).to eq("r.meier@siemens.com") } - it { expect(tag.tagger.date).to eq(Google::Protobuf::Timestamp.new(seconds: 1574261780)) } - it { expect(tag.tagger.timezone).to eq("+0100") } + it { expect(tag.user_name).to eq("Roger Meier") } + it { expect(tag.user_email).to eq("r.meier@siemens.com") } + it { expect(tag.date).to eq(Time.at(1574261780).utc) } end it { expect(repository.tags.size).to be > 0 } diff --git a/spec/requests/api/project_job_token_scope_spec.rb b/spec/requests/api/project_job_token_scope_spec.rb index df210a00012..c070e4daf01 100644 --- a/spec/requests/api/project_job_token_scope_spec.rb +++ b/spec/requests/api/project_job_token_scope_spec.rb @@ -73,4 +73,124 @@ RSpec.describe API::ProjectJobTokenScope, feature_category: :secrets_management end end end + + describe 'PATCH /projects/:id/job_token_scope' do + let_it_be(:project) { create(:project, :public) } + let_it_be(:user) { create(:user) } + + let(:patch_job_token_scope_path) { "/projects/#{project.id}/job_token_scope" } + let(:patch_job_token_scope_params) do + { enabled: false } + end + + subject { patch api(patch_job_token_scope_path, user), params: patch_job_token_scope_params } + + context 'when unauthenticated user (missing user)' do + context 'for public project' do + it 'does not return ci cd settings of job token' do + project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) + + patch api(patch_job_token_scope_path), params: patch_job_token_scope_params + + expect(response).to have_gitlab_http_status(:unauthorized) + end + end + end + + context 'when authenticated user as maintainer' do + before_all { project.add_maintainer(user) } + + it 'returns unauthorized and blank response when invalid auth credentials are given' do + invalid_personal_access_token = build(:personal_access_token, user: user) + + patch api(patch_job_token_scope_path, user, personal_access_token: invalid_personal_access_token), + params: patch_job_token_scope_params + + expect(response).to have_gitlab_http_status(:unauthorized) + end + + it 'returns no content and updates the ci cd setting `ci_inbound_job_token_scope_enabled`' do + subject + + expect(response).to have_gitlab_http_status(:no_content) + expect(response.body).to be_blank + + project.reload + + expect(project.reload.ci_inbound_job_token_scope_enabled?).to be_falsey + expect(project.reload.ci_outbound_job_token_scope_enabled?).to be_falsey + end + + it 'returns bad_request when ::Projects::UpdateService fails' do + project_update_service_result = { status: :error, message: "any_internal_error_message" } + project_update_service = instance_double(Projects::UpdateService, execute: project_update_service_result) + allow(::Projects::UpdateService).to receive(:new).and_return(project_update_service) + + subject + + expect(response).to have_gitlab_http_status(:bad_request) + expect(json_response).to be_present + end + + it 'returns bad_request when invalid value for parameter is given' do + patch api(patch_job_token_scope_path, user), params: {} + + expect(response).to have_gitlab_http_status(:bad_request) + end + + it 'returns bad_request when invalid parameter given, e.g. truthy value' do + patch api(patch_job_token_scope_path, user), params: { enabled: 123 } + + expect(response).to have_gitlab_http_status(:bad_request) + end + + it 'returns bad_request when invalid parameter given, e.g. `nil`' do + patch api(patch_job_token_scope_path, user), params: { enabled: nil } + + expect(response).to have_gitlab_http_status(:bad_request) + end + + it 'returns bad_request and leaves it untouched when unpermitted parameter given' do + expect do + patch api(patch_job_token_scope_path, user), + params: { + irrelevant_parameter_boolean: true, + irrelevant_parameter_number: 12.34 + } + end.not_to change { project.reload.updated_at } + + expect(response).to have_gitlab_http_status(:bad_request) + + project_reloaded = Project.find(project.id) + expect(project_reloaded.ci_inbound_job_token_scope_enabled?).to eq project.ci_inbound_job_token_scope_enabled? + expect(project_reloaded.ci_outbound_job_token_scope_enabled?).to eq project.ci_outbound_job_token_scope_enabled? + end + + # We intend to deprecate the possibility to enable the outbound job token scope until gitlab release `v17.0` . + it 'returns bad_request when param `outbound_scope_enabled` given' do + patch api(patch_job_token_scope_path, user), params: { outbound_scope_enabled: true } + + expect(response).to have_gitlab_http_status(:bad_request) + + project.reload + + expect(project.reload.ci_inbound_job_token_scope_enabled?).to be_truthy + expect(project.reload.ci_outbound_job_token_scope_enabled?).to be_falsey + end + end + + context 'when authenticated user as developer' do + before do + project.add_developer(user) + end + + it 'returns forbidden and no ci cd settings for public project' do + project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) + + subject + + expect(response).to have_gitlab_http_status(:forbidden) + end + end + end end diff --git a/yarn.lock b/yarn.lock index 645a7f2b97f..134e383cc4c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10877,10 +10877,10 @@ remark-gfm@^3.0.1: micromark-extension-gfm "^2.0.0" unified "^10.0.0" -remark-parse@^10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-10.0.1.tgz#6f60ae53edbf0cf38ea223fe643db64d112e0775" - integrity sha512-1fUyHr2jLsVOkhbvPRBJ5zTKZZyD6yZzYaWCS6BPBdQ8vEMBCH+9zNCDA6tET/zHCi/jLqjCWtlJZUPk+DbnFw== +remark-parse@^10.0.2: + version "10.0.2" + resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-10.0.2.tgz#ca241fde8751c2158933f031a4e3efbaeb8bc262" + integrity sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw== dependencies: "@types/mdast" "^3.0.0" mdast-util-from-markdown "^1.0.0" |