Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-07-06 15:08:08 +00:00
parent c1f785fe21
commit 526f1e9859
56 changed files with 759 additions and 269 deletions

View file

@ -36,10 +36,21 @@ workflow:
- if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME =~ /^release-tools\/\d+\.\d+\.\d+-rc\d+$/ && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^[\d-]+-stable(-ee)?$/ && $CI_PROJECT_PATH == "gitlab-org/gitlab"'
when: never
# For merged result pipelines, set $QA_IMAGE, since $CI_MERGE_REQUEST_SOURCE_BRANCH_SHA is only available for merged result pipelines.
- if: '$CI_MERGE_REQUEST_EVENT_TYPE == "merged_result" || $CI_MERGE_REQUEST_EVENT_TYPE == "merge_train"'
# AND
# For merge requests running exclusively in Ruby 3.0
- if: '($CI_MERGE_REQUEST_EVENT_TYPE == "merged_result" || $CI_MERGE_REQUEST_EVENT_TYPE == "merge_train") && $CI_MERGE_REQUEST_LABELS =~ /pipeline:run-in-ruby3/'
variables:
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
# Also run (detached) merge request pipelines.
RUBY_VERSION: "3.0"
# For merged result pipelines, set $QA_IMAGE, since $CI_MERGE_REQUEST_SOURCE_BRANCH_SHA is only available for merged result pipelines.
- if: '($CI_MERGE_REQUEST_EVENT_TYPE == "merged_result" || $CI_MERGE_REQUEST_EVENT_TYPE == "merge_train")'
variables:
QA_IMAGE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_MERGE_REQUEST_SOURCE_BRANCH_SHA}"
# For merge requests running exclusively in Ruby 3.0
- if: '$CI_MERGE_REQUEST_LABELS =~ /pipeline:run-in-ruby3/'
variables:
RUBY_VERSION: "3.0"
# For (detached) merge request pipelines.
- if: '$CI_MERGE_REQUEST_IID'
# For the maintenance scheduled pipelines, we set specific variables.
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH && $CI_PIPELINE_SOURCE == "schedule" && $SCHEDULE_TYPE == "maintenance"'

View file

@ -929,16 +929,18 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/app/workers/authorized_projects_worker.rb @gitlab-org/manage/authentication-and-authorization
/app/workers/personal_access_tokens/ @gitlab-org/manage/authentication-and-authorization
/config/feature_flags/development/application_settings_tokens_optional_encryption.yml @gitlab-org/manage/authentication-and-authorization
/config/feature_flags/development/async_only_project_authorizations_refresh.yml @gitlab-org/manage/authentication-and-authorization
/config/feature_flags/development/enforce_auth_checks_on_uploads.yml @gitlab-org/manage/authentication-and-authorization
/config/feature_flags/development/forti_authenticator.yml @gitlab-org/manage/authentication-and-authorization
/config/feature_flags/development/forti_token_cloud.yml @gitlab-org/manage/authentication-and-authorization
/config/feature_flags/development/groups_tokens_optional_encryption.yml @gitlab-org/manage/authentication-and-authorization
/config/feature_flags/development/omniauth_initializer_fullhost_proc.yml @gitlab-org/manage/authentication-and-authorization
/config/feature_flags/development/omniauth_login_minimal_scopes.yml @gitlab-org/manage/authentication-and-authorization
/config/feature_flags/development/personal_access_tokens_scoped_to_projects.yml @gitlab-org/manage/authentication-and-authorization
/config/feature_flags/development/projects_tokens_optional_encryption.yml @gitlab-org/manage/authentication-and-authorization
/config/feature_flags/development/refresh_authorizations_via_affected_projects_on_group_membership.yml @gitlab-org/manage/authentication-and-authorization
/config/feature_flags/development/skip_group_share_unlink_auth_refresh.yml @gitlab-org/manage/authentication-and-authorization
/config/feature_flags/development/specialized_worker_for_group_lock_update_auth_recalculation.yml @gitlab-org/manage/authentication-and-authorization
/config/feature_flags/development/update_oauth_registration_flow.yml @gitlab-org/manage/authentication-and-authorization
/config/feature_flags/development/webauthn.yml @gitlab-org/manage/authentication-and-authorization
/config/feature_flags/ops/block_password_auth_for_saml_users.yml @gitlab-org/manage/authentication-and-authorization
/config/initializers/01_secret_token.rb @gitlab-org/manage/authentication-and-authorization
@ -975,6 +977,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/ee/app/helpers/ee/access_tokens_helper.rb @gitlab-org/manage/authentication-and-authorization
/ee/app/helpers/ee/auth_helper.rb @gitlab-org/manage/authentication-and-authorization
/ee/app/helpers/ee/personal_access_tokens_helper.rb @gitlab-org/manage/authentication-and-authorization
/ee/app/models/concerns/password_complexity.rb @gitlab-org/manage/authentication-and-authorization
/ee/app/models/ee/personal_access_token.rb @gitlab-org/manage/authentication-and-authorization
/ee/app/models/ee/project_authorization.rb @gitlab-org/manage/authentication-and-authorization
/ee/app/models/scim_oauth_access_token.rb @gitlab-org/manage/authentication-and-authorization
@ -984,6 +987,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/ee/app/services/ee/resource_access_tokens/ @gitlab-org/manage/authentication-and-authorization
/ee/app/services/personal_access_tokens/ @gitlab-org/manage/authentication-and-authorization
/ee/app/services/security/token_revocation_service.rb @gitlab-org/manage/authentication-and-authorization
/ee/app/validators/password/ @gitlab-org/manage/authentication-and-authorization
/ee/app/views/admin/application_settings/_personal_access_token_expiration_policy.html.haml @gitlab-org/manage/authentication-and-authorization
/ee/app/views/credentials_inventory_mailer/personal_access_token_revoked_email.html.haml @gitlab-org/manage/authentication-and-authorization
/ee/app/views/credentials_inventory_mailer/personal_access_token_revoked_email.text.haml @gitlab-org/manage/authentication-and-authorization
@ -996,6 +1000,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/ee/app/views/shared/credentials_inventory/_project_access_tokens.html.haml @gitlab-org/manage/authentication-and-authorization
/ee/app/views/shared/credentials_inventory/personal_access_tokens/ @gitlab-org/manage/authentication-and-authorization
/ee/app/views/shared/credentials_inventory/project_access_tokens/ @gitlab-org/manage/authentication-and-authorization
/ee/app/workers/auth/ @gitlab-org/manage/authentication-and-authorization
/ee/app/workers/personal_access_tokens/ @gitlab-org/manage/authentication-and-authorization
/ee/config/routes/oauth.rb @gitlab-org/manage/authentication-and-authorization
/ee/lib/ee/gitlab/auth/ @gitlab-org/manage/authentication-and-authorization
@ -1012,6 +1017,7 @@ lib/gitlab/checks/** @proglottis @toon @zj-gitlab
/lib/api/entities/impersonation_token.rb @gitlab-org/manage/authentication-and-authorization
/lib/api/entities/impersonation_token_with_token.rb @gitlab-org/manage/authentication-and-authorization
/lib/api/entities/personal_access_token.rb @gitlab-org/manage/authentication-and-authorization
/lib/api/entities/personal_access_token_with_details.rb @gitlab-org/manage/authentication-and-authorization
/lib/api/entities/personal_access_token_with_token.rb @gitlab-org/manage/authentication-and-authorization
/lib/api/entities/resource_access_token.rb @gitlab-org/manage/authentication-and-authorization
/lib/api/entities/resource_access_token_with_token.rb @gitlab-org/manage/authentication-and-authorization

View file

@ -49,6 +49,9 @@
.if-merge-request-targeting-stable-branch: &if-merge-request-targeting-stable-branch
if: '$CI_MERGE_REQUEST_IID && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^[\d-]+-stable(-ee)?$/'
.if-merge-request-labels-run-in-ruby3: &if-merge-request-labels-run-in-ruby3
if: '$CI_MERGE_REQUEST_LABELS =~ /pipeline:run-in-ruby3/'
.if-merge-request-labels-as-if-foss: &if-merge-request-labels-as-if-foss
if: '$CI_MERGE_REQUEST_LABELS =~ /pipeline:run-as-if-foss/'
@ -1789,6 +1792,10 @@
- <<: *if-default-refs
changes: *code-backstage-patterns
.setup:rules:verify-ruby-2.7:
rules:
- <<: *if-merge-request-labels-run-in-ruby3
.setup:rules:verify-tests-yml:
rules:
- <<: *if-not-ee

View file

@ -23,13 +23,19 @@ cache gems:
- .default-retry
needs: []
dont-interrupt-me:
extends: .setup:rules:dont-interrupt-me
stage: sync
.absolutely-minimal-job:
extends:
- .minimal-job
image: ${GITLAB_DEPENDENCY_PROXY}alpine:edge
interruptible: false
variables:
GIT_STRATEGY: none
dont-interrupt-me:
extends:
- .absolutely-minimal-job
- .setup:rules:dont-interrupt-me
stage: sync
interruptible: false
script:
- echo "This jobs makes sure this pipeline won't be interrupted! See https://docs.gitlab.com/ee/ci/yaml/#interruptible."
@ -57,6 +63,15 @@ no-jh-check:
script:
- scripts/no-dir-check jh
verify-ruby-2.7:
extends:
- .absolutely-minimal-job
- .setup:rules:verify-ruby-2.7
stage: prepare
script:
- echo 'Please remove label ~"pipeline:run-in-ruby3" so we do test against Ruby 2.7 (default version) before merging the merge request'
- exit 1
verify-tests-yml:
extends:
- .setup:rules:verify-tests-yml
@ -70,8 +85,8 @@ verify-tests-yml:
verify-approvals:
extends:
- .minimal-job
- .setup:rules:jh-contribution
needs: []
script:
- source scripts/utils.sh
- install_gitlab_gem

View file

@ -1,5 +1,15 @@
<script>
import { GlForm, GlIcon, GlLink, GlButton, GlSprintf, GlAlert } from '@gitlab/ui';
import {
GlForm,
GlIcon,
GlLink,
GlButton,
GlSprintf,
GlAlert,
GlFormGroup,
GlFormInput,
GlFormSelect,
} from '@gitlab/ui';
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
import axios from '~/lib/utils/axios_utils';
import csrf from '~/lib/utils/csrf';
@ -76,9 +86,12 @@ export default {
},
components: {
GlAlert,
GlForm,
GlSprintf,
GlIcon,
GlForm,
GlFormGroup,
GlFormInput,
GlFormSelect,
GlSprintf,
GlLink,
GlButton,
MarkdownField,
@ -311,155 +324,151 @@ export default {
name="wiki[last_commit_sha]"
:value="pageInfo.lastCommitSha"
/>
<div class="form-group row">
<div class="col-sm-2 col-form-label">
<label class="control-label-full-width" for="wiki_title">{{
$options.i18n.title.label
}}</label>
</div>
<div class="col-sm-10">
<input
id="wiki_title"
v-model="title"
name="wiki[title]"
type="text"
class="form-control"
data-qa-selector="wiki_title_textbox"
:required="true"
:autofocus="!pageInfo.persisted"
:placeholder="$options.i18n.title.placeholder"
@input="updateCommitMessage"
/>
<span class="gl-display-inline-block gl-max-w-full gl-mt-2 gl-text-gray-600">
<gl-icon class="gl-mr-n1" name="bulb" />
{{ titleHelpText }}
<gl-link :href="helpPath" target="_blank">
{{ $options.i18n.title.helpText.learnMore }}
</gl-link>
</span>
</div>
</div>
<div class="form-group row">
<div class="col-sm-2 col-form-label">
<label class="control-label-full-width" for="wiki_format">{{
$options.i18n.format.label
}}</label>
</div>
<div class="col-sm-10">
<select
id="wiki_format"
v-model="format"
class="form-control"
name="wiki[format]"
:disabled="isContentEditorActive"
>
<option v-for="(key, label) of formatOptions" :key="key" :value="key">
{{ label }}
</option>
</select>
</div>
</div>
<div class="form-group row" data-testid="wiki-form-content-fieldset">
<div class="col-sm-2 col-form-label">
<label class="control-label-full-width" for="wiki_content">{{
$options.i18n.content.label
}}</label>
</div>
<div class="col-sm-10">
<div v-if="isMarkdownFormat" class="gl-display-flex gl-justify-content-end gl-mb-3">
<gl-button
data-testid="toggle-editing-mode-button"
data-qa-selector="editing_mode_button"
:data-qa-mode="toggleEditingModeButtonText"
variant="link"
@click="toggleEditingMode"
>{{ toggleEditingModeButtonText }}</gl-button
>
</div>
<local-storage-sync
storage-key="gl-wiki-content-editor-enabled"
:value="useContentEditor"
@input="setUseContentEditor"
/>
<markdown-field
v-if="!isContentEditorActive"
:markdown-preview-path="pageInfo.markdownPreviewPath"
:can-attach-file="true"
:enable-autocomplete="true"
:textarea-value="content"
:markdown-docs-path="pageInfo.markdownHelpPath"
:uploads-path="pageInfo.uploadsPath"
:enable-preview="isMarkdownFormat"
class="bordered-box"
>
<template #textarea>
<textarea
id="wiki_content"
ref="textarea"
v-model="content"
name="wiki[content]"
class="note-textarea js-gfm-input js-autosize markdown-area"
dir="auto"
data-supports-quick-actions="false"
data-qa-selector="wiki_content_textarea"
:autofocus="pageInfo.persisted"
:aria-label="$options.i18n.content.label"
:placeholder="$options.i18n.content.placeholder"
@input="handleContentChange"
>
</textarea>
<div class="row">
<div class="col-sm-9">
<gl-form-group :label="$options.i18n.title.label" label-for="wiki_title">
<template #description>
<gl-icon class="gl-mr-n1" name="bulb" />
{{ titleHelpText }}
<gl-link :href="helpPath" target="_blank">
{{ $options.i18n.title.helpText.learnMore }}
</gl-link>
</template>
</markdown-field>
<div v-if="isContentEditorActive">
<content-editor
:render-markdown="renderMarkdown"
:uploads-path="pageInfo.uploadsPath"
@initialized="loadInitialContent"
@change="handleContentEditorChange"
<gl-form-input
id="wiki_title"
v-model="title"
name="wiki[title]"
type="text"
class="form-control"
data-qa-selector="wiki_title_textbox"
:required="true"
:autofocus="!pageInfo.persisted"
:placeholder="$options.i18n.title.placeholder"
@input="updateCommitMessage"
/>
<input id="wiki_content" v-model.trim="content" type="hidden" name="wiki[content]" />
</div>
</gl-form-group>
</div>
<div class="clearfix"></div>
<div class="error-alert"></div>
<div class="col-sm-3 row-sm-10">
<gl-form-group :label="$options.i18n.format.label" label-for="wiki_format">
<gl-form-select
id="wiki_format"
v-model="format"
name="wiki[format]"
:disabled="isContentEditorActive"
class="form-control"
:value="formatOptions.Markdown"
>
<option v-for="(key, label) of formatOptions" :key="key" :value="key">
{{ label }}
</option>
</gl-form-select>
</gl-form-group>
</div>
</div>
<div class="form-text gl-text-gray-600">
<gl-sprintf v-if="displayWikiSpecificMarkdownHelp" :message="$options.i18n.linksHelpText">
<template #linkExample
><code>{{ linkExample }}</code></template
<div class="row" data-testid="wiki-form-content-fieldset">
<div class="col-sm-12 row-sm-5">
<gl-form-group>
<div v-if="isMarkdownFormat" class="gl-display-flex gl-justify-content-end gl-mb-3">
<gl-button
data-testid="toggle-editing-mode-button"
data-qa-selector="editing_mode_button"
:data-qa-mode="toggleEditingModeButtonText"
variant="link"
@click="toggleEditingMode"
>{{ toggleEditingModeButtonText }}</gl-button
>
<template
#link="// eslint-disable-next-line vue/no-template-shadow
</div>
<local-storage-sync
storage-key="gl-wiki-content-editor-enabled"
:value="useContentEditor"
@input="setUseContentEditor"
/>
<markdown-field
v-if="!isContentEditorActive"
:markdown-preview-path="pageInfo.markdownPreviewPath"
:can-attach-file="true"
:enable-autocomplete="true"
:textarea-value="content"
:markdown-docs-path="pageInfo.markdownHelpPath"
:uploads-path="pageInfo.uploadsPath"
:enable-preview="isMarkdownFormat"
class="bordered-box"
>
<template #textarea>
<textarea
id="wiki_content"
ref="textarea"
v-model="content"
name="wiki[content]"
class="note-textarea js-gfm-input js-autosize markdown-area"
dir="auto"
data-supports-quick-actions="false"
data-qa-selector="wiki_content_textarea"
:autofocus="pageInfo.persisted"
:aria-label="$options.i18n.content.label"
:placeholder="$options.i18n.content.placeholder"
@input="handleContentChange"
>
</textarea>
</template>
</markdown-field>
<div v-if="isContentEditorActive">
<content-editor
:render-markdown="renderMarkdown"
:uploads-path="pageInfo.uploadsPath"
@initialized="loadInitialContent"
@change="handleContentEditorChange"
/>
<input id="wiki_content" v-model.trim="content" type="hidden" name="wiki[content]" />
</div>
<div class="clearfix"></div>
<div class="error-alert"></div>
<div class="form-text gl-text-gray-600">
<gl-sprintf
v-if="displayWikiSpecificMarkdownHelp"
:message="$options.i18n.linksHelpText"
>
<template #linkExample>
<code>{{ linkExample }}</code>
</template>
<template
#link="// eslint-disable-next-line vue/no-template-shadow
{ content }"
><gl-link
:href="wikiSpecificMarkdownHelpPath"
target="_blank"
data-testid="wiki-markdown-help-link"
>{{ content }}</gl-link
></template
>
</gl-sprintf>
</div>
><gl-link
:href="wikiSpecificMarkdownHelpPath"
target="_blank"
data-testid="wiki-markdown-help-link"
>{{ content }}</gl-link
></template
>
</gl-sprintf>
</div>
</gl-form-group>
</div>
</div>
<div class="form-group row">
<div class="col-sm-2 col-form-label">
<label class="control-label-full-width" for="wiki_message">{{
$options.i18n.commitMessage.label
}}</label>
</div>
<div class="col-sm-10">
<input
id="wiki_message"
v-model.trim="commitMessage"
name="wiki[message]"
type="text"
class="form-control"
data-qa-selector="wiki_message_textbox"
:placeholder="$options.i18n.commitMessage.label"
/>
<div class="row">
<div class="col-sm-12 row-sm-5">
<gl-form-group :label="$options.i18n.commitMessage.label" label-for="wiki_message">
<gl-form-input
id="wiki_message"
v-model.trim="commitMessage"
name="wiki[message]"
type="text"
class="form-control"
data-qa-selector="wiki_message_textbox"
:placeholder="$options.i18n.commitMessage.label"
/>
</gl-form-group>
</div>
</div>
<div class="form-actions">
<gl-button
category="primary"

View file

@ -450,9 +450,14 @@ class Namespace < ApplicationRecord
end
def pages_virtual_domain
cache = if Feature.enabled?(:cache_pages_domain_api, root_ancestor)
::Gitlab::Pages::CacheControl.for_namespace(root_ancestor.id)
end
Pages::VirtualDomain.new(
all_projects_with_pages.includes(:route, :project_feature, pages_metadatum: :pages_deployment),
trim_prefix: full_path
projects: all_projects_with_pages.includes(:route, :project_feature, pages_metadatum: :pages_deployment),
trim_prefix: full_path,
cache: cache
)
end

View file

@ -2,8 +2,9 @@
module Pages
class VirtualDomain
def initialize(projects, trim_prefix: nil, domain: nil)
def initialize(projects:, cache: nil, trim_prefix: nil, domain: nil)
@projects = projects
@cache = cache
@trim_prefix = trim_prefix
@domain = domain
end
@ -27,8 +28,12 @@ module Pages
paths.sort_by(&:prefix).reverse
end
def cache_key
@cache_key ||= cache&.cache_key
end
private
attr_reader :projects, :trim_prefix, :domain
attr_reader :projects, :trim_prefix, :domain, :cache
end
end

View file

@ -209,7 +209,15 @@ class PagesDomain < ApplicationRecord
def pages_virtual_domain
return unless pages_deployed?
Pages::VirtualDomain.new([project], domain: self)
cache = if Feature.enabled?(:cache_pages_domain_api, project.root_namespace)
::Gitlab::Pages::CacheControl.for_project(project.id)
end
Pages::VirtualDomain.new(
projects: [project],
domain: self,
cache: cache
)
end
def clear_auto_ssl_failure

View file

@ -1,3 +1,4 @@
%p
Merge request #{merge_request_reference_link(@merge_request)}
was closed by #{sanitize_name(@updated_by.name)}
- mr_link = merge_request_reference_link(@merge_request)
- closed_by = sanitize_name(@updated_by.name)
= s_('Notify|Merge request %{mr_link} was closed by %{closed_by}').html_safe % { mr_link: mr_link, closed_by: closed_by }

View file

@ -2704,6 +2704,15 @@
:weight: 1
:idempotent: false
:tags: []
- :name: pages_invalidate_domain_cache
:worker_name: Pages::InvalidateDomainCacheWorker
:feature_category: :pages
:has_external_dependencies: false
:urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent: true
:tags: []
- :name: pages_transfer
:worker_name: PagesTransferWorker
:feature_category: :pages

View file

@ -0,0 +1,25 @@
# frozen_string_literal: true
module Pages
class InvalidateDomainCacheWorker
include Gitlab::EventStore::Subscriber
idempotent!
feature_category :pages
def handle_event(event)
if event.data[:project_id]
::Gitlab::Pages::CacheControl
.for_project(event.data[:project_id])
.clear_cache
end
if event.data[:root_namespace_id]
::Gitlab::Pages::CacheControl
.for_namespace(event.data[:root_namespace_id])
.clear_cache
end
end
end
end

View file

@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/83345
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/355909
milestone: '14.10'
type: development
group: group::adoption
group: group::acquisition
default_enabled: false

View file

@ -0,0 +1,8 @@
---
name: cache_pages_domain_api
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/88956
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/364127
milestone: '15.2'
type: development
group: group::editor
default_enabled: false

View file

@ -0,0 +1,8 @@
---
name: subgroups_approval_rules
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91598
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/366741
milestone: '15.2'
type: development
group: group::source code
default_enabled: false

View file

@ -1,8 +1,8 @@
---
name: update_oauth_registration_flow
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85871
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/363030
milestone: '15.1'
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/364342
milestone: '15.2'
type: development
group: group::adoption
group: group::acquisition
default_enabled: false

View file

@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67614
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/285533
milestone: '14.3'
type: experiment
group: group::adoption
group: group::acquisition
default_enabled: false

View file

@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70451
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/342951
milestone: '14.5'
type: experiment
group: group::expansion
group: group::acquisition
default_enabled: false

View file

@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/45840
rollout_issue_url:
milestone: '13.7'
type: experiment
group: group::adoption
group: group::acquisition
default_enabled: false

View file

@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74054
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/349799
milestone: '14.7'
type: experiment
group: group::conversion
group: group::acquisition
default_enabled: false

View file

@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70086
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340436
milestone: '14.3'
type: experiment
group: group::adoption
group: group::acquisition
default_enabled: false

View file

@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82274
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/351916
milestone: '14.9'
type: experiment
group: group::adoption
group: group::acquisition
default_enabled: false

View file

@ -327,6 +327,8 @@
- 1
- - pages_domain_verification
- 1
- - pages_invalidate_domain_cache
- 1
- - pages_transfer
- 1
- - personal_access_tokens

View file

@ -275,6 +275,19 @@ rather than from the default branch `main-jh`.
NOTE:
For now, CI will try to fetch the branch on the [GitLab JH mirror](https://gitlab.com/gitlab-org/gitlab-jh-mirrors/gitlab), so it might take some time for the new JH branch to propagate to the mirror.
## Ruby 3.0 jobs
You can add the `pipeline:run-in-ruby3` label to the merge request to switch
the Ruby version used for running the whole test suite to 3.0. When you do
this, the test suite will no longer run in Ruby 2.7 (default), and an
additional job `verify-ruby-2.7` will also run and always fail to remind us to
remove the label and run in Ruby 2.7 before merging the merge request.
This should let us:
- Test changes for Ruby 3.0
- Make sure it will not break anything when it's merged into the default branch
## `undercover` RSpec test
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74859) in GitLab 14.6.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

View file

@ -54,7 +54,15 @@ module API
virtual_domain = host.pages_virtual_domain
no_content! unless virtual_domain
present virtual_domain, with: Entities::Internal::Pages::VirtualDomain
if virtual_domain.cache_key.present?
# Cache context is not added to make it easier to expire the cache with
# Gitlab::Pages::CacheControl
present_cached virtual_domain,
cache_context: nil,
with: Entities::Internal::Pages::VirtualDomain
else
present virtual_domain, with: Entities::Internal::Pages::VirtualDomain
end
end
end
end

View file

@ -26,3 +26,14 @@ test:cargo:
script:
- rustc --version && cargo --version # Print version info for debugging
- cargo test --workspace --verbose
# Optional: Use a third party library to generate gitlab junit reports
# test:junit-report:
# script:
# Should be specified in Cargo.toml
# - cargo install junitify
# - cargo test -- --format=json -Z unstable-options --report-time | junitify --out $CI_PROJECT_DIR/tests/
# artifacts:
# when: always
# reports:
# junit: $CI_PROJECT_DIR/tests/*.xml

View file

@ -20,7 +20,10 @@ module Gitlab
::Gitlab::ErrorTracking::Processor::SidekiqProcessor,
::Gitlab::ErrorTracking::Processor::GrpcErrorProcessor,
::Gitlab::ErrorTracking::Processor::ContextPayloadProcessor,
::Gitlab::ErrorTracking::Processor::SanitizeErrorMessageProcessor
::Gitlab::ErrorTracking::Processor::SanitizeErrorMessageProcessor,
# IMPORTANT: this processor must stay at the bottom, right before
# sending the event to Sentry.
::Gitlab::ErrorTracking::Processor::SanitizerProcessor
].freeze
class << self

View file

@ -0,0 +1,48 @@
# frozen_string_literal: true
module Gitlab
module ErrorTracking
module Processor
module SanitizerProcessor
SANITIZED_HTTP_HEADERS = %w[Authorization Private-Token Job-Token].freeze
SANITIZED_ATTRIBUTES = %i[user contexts extra tags].freeze
# This processor removes sensitive fields or headers from the event
# before sending. Sentry versions above 4.0 don't support
# sanitized_fields and sanitized_http_headers anymore. The official
# document recommends using before_send instead.
#
# For more information, please visit:
# https://docs.sentry.io/platforms/ruby/guides/rails/configuration/filtering/#using-beforesend
def self.call(event)
# Raven::Event instances don't need this processing.
return event unless event.is_a?(Sentry::Event)
if event.request.present?
event.request.cookies = {}
event.request.data = {}
end
if event.request.present? && event.request.headers.is_a?(Hash)
header_filter = ActiveSupport::ParameterFilter.new(SANITIZED_HTTP_HEADERS)
event.request.headers = header_filter.filter(event.request.headers)
end
attribute_filter = ActiveSupport::ParameterFilter.new(Rails.application.config.filter_parameters)
SANITIZED_ATTRIBUTES.each do |attribute|
event.send("#{attribute}=", attribute_filter.filter(event.send(attribute))) # rubocop:disable GitlabSecurity/PublicSend
end
if event.request.present? && event.request.query_string.present?
query = Rack::Utils.parse_nested_query(event.request.query_string)
query = attribute_filter.filter(query)
query = Rack::Utils.build_nested_query(query)
event.request.query_string = query
end
event
end
end
end
end
end

View file

@ -35,6 +35,9 @@ module Gitlab
store.subscribe ::MergeRequests::UpdateHeadPipelineWorker, to: ::Ci::PipelineCreatedEvent
store.subscribe ::Namespaces::UpdateRootStatisticsWorker, to: ::Projects::ProjectDeletedEvent
store.subscribe ::Pages::InvalidateDomainCacheWorker, to: ::Pages::PageDeployedEvent
store.subscribe ::Pages::InvalidateDomainCacheWorker, to: ::Pages::PageDeletedEvent
end
private_class_method :configure!
end

View file

@ -0,0 +1,31 @@
# frozen_string_literal: true
module Gitlab
module Pages
class CacheControl
CACHE_KEY_FORMAT = 'pages_domain_for_%{type}_%{id}'
attr_reader :cache_key
class << self
def for_project(project_id)
new(type: :project, id: project_id)
end
def for_namespace(namespace_id)
new(type: :namespace, id: namespace_id)
end
end
def initialize(type:, id:)
raise(ArgumentError, "type must be :namespace or :project") unless %i[namespace project].include?(type)
@cache_key = CACHE_KEY_FORMAT % { type: type, id: id }
end
def clear_cache
Rails.cache.delete(cache_key)
end
end
end
end

View file

@ -26446,6 +26446,9 @@ msgstr ""
msgid "Notify|Merge request %{merge_request} was merged"
msgstr ""
msgid "Notify|Merge request %{mr_link} was closed by %{closed_by}"
msgstr ""
msgid "Notify|Merge request URL: %{merge_request_url}"
msgstr ""
@ -40987,9 +40990,6 @@ msgstr ""
msgid "Unable to fetch upstream and downstream pipelines."
msgstr ""
msgid "Unable to fetch vulnerable projects"
msgstr ""
msgid "Unable to find Jira project to import data from."
msgstr ""

View file

@ -1,5 +1,5 @@
import { nextTick } from 'vue';
import { GlAlert, GlButton } from '@gitlab/ui';
import { GlAlert, GlButton, GlFormInput, GlFormGroup } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
@ -107,6 +107,8 @@ describe('WikiForm', () => {
GlAlert,
GlButton,
LocalStorageSync: stubComponent(LocalStorageSync),
GlFormInput,
GlFormGroup,
},
}),
);
@ -132,7 +134,7 @@ describe('WikiForm', () => {
`(
'updates the commit message to $message when title is $title and persisted=$persisted',
async ({ title, message, persisted }) => {
createWrapper({ persisted });
createWrapper({ persisted, mountFn: mount });
await findTitle().setValue(title);
@ -141,7 +143,7 @@ describe('WikiForm', () => {
);
it('sets the commit message to "Update My page" when the page first loads when persisted', async () => {
createWrapper({ persisted: true });
createWrapper({ persisted: true, mountFn: mount });
await nextTick();
@ -161,7 +163,7 @@ describe('WikiForm', () => {
${'asciidoc'} | ${false} | ${'hides'}
${'org'} | ${false} | ${'hides'}
`('$action preview in the markdown field when format is $format', async ({ format, enabled }) => {
createWrapper();
createWrapper({ mountFn: mount });
await setFormat(format);
@ -258,7 +260,7 @@ describe('WikiForm', () => {
`(
"when title='$title', content='$content', then the button is $buttonState'",
async ({ title, content, disabledAttr }) => {
createWrapper();
createWrapper({ mountFn: mount });
await findTitle().setValue(title);
await findContent().setValue(content);
@ -295,7 +297,7 @@ describe('WikiForm', () => {
describe('toggle editing mode control', () => {
beforeEach(() => {
createWrapper();
createWrapper({ mountFn: mount });
});
it.each`

View file

@ -38,7 +38,11 @@ RSpec.describe Gitlab::DatabaseImporters::InstanceAdministrators::CreateGroup do
end
end
context 'with application settings and admin users', :do_not_mock_admin_mode_setting do
context(
'with application settings and admin users',
:do_not_mock_admin_mode_setting,
:do_not_stub_snowplow_by_default
) do
let(:group) { result[:group] }
let(:application_setting) { Gitlab::CurrentSettings.current_application_settings }

View file

@ -0,0 +1,114 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::ErrorTracking::Processor::SanitizerProcessor, :sentry do
describe '.call' do
let(:event) { Sentry.get_current_client.event_from_exception(exception) }
let(:result_hash) { described_class.call(event).to_hash }
before do
data.each do |key, value|
event.send("#{key}=", value)
end
end
after do
Sentry.get_current_scope.clear
end
context 'when event attributes contains sensitive information' do
let(:exception) { RuntimeError.new }
let(:data) do
{
contexts: {
jwt: 'abcdef',
controller: 'GraphController#execute'
},
tags: {
variables: %w[some sensitive information'],
deep_hash: {
sharedSecret: 'secret123'
}
},
user: {
email: 'a@a.com',
password: 'nobodyknows'
},
extra: {
issue_url: 'http://gitlab.com/gitlab-org/gitlab-foss/-/issues/1',
my_token: '[FILTERED]',
another_token: '[FILTERED]'
}
}
end
it 'filters sensitive attributes' do
expect_next_instance_of(ActiveSupport::ParameterFilter) do |instance|
expect(instance).to receive(:filter).exactly(4).times.and_call_original
end
expect(result_hash).to include(
contexts: {
jwt: '[FILTERED]',
controller: 'GraphController#execute'
},
tags: {
variables: '[FILTERED]',
deep_hash: {
sharedSecret: '[FILTERED]'
}
},
user: {
email: 'a@a.com',
password: '[FILTERED]'
},
extra: {
issue_url: 'http://gitlab.com/gitlab-org/gitlab-foss/-/issues/1',
my_token: '[FILTERED]',
another_token: '[FILTERED]'
}
)
end
end
context 'when request contains sensitive information' do
let(:exception) { RuntimeError.new }
let(:data) { {} }
before do
event.rack_env = {
'HTTP_AUTHORIZATION' => 'Bearer 123456',
'HTTP_PRIVATE_TOKEN' => 'abcdef',
'HTTP_JOB_TOKEN' => 'secret123',
'HTTP_GITLAB_WORKHORSE_PROXY_START' => 123456,
'HTTP_COOKIE' => 'yummy_cookie=choco; tasty_cookie=strawberry',
'QUERY_STRING' => 'token=secret&access_token=secret&job_token=secret&private_token=secret',
'Content-Type' => 'application/json',
'rack.input' => StringIO.new('{"name":"new_project", "some_token":"value"}')
}
end
it 'filters sensitive headers' do
expect(result_hash[:request][:headers]).to include(
'Authorization' => '[FILTERED]',
'Private-Token' => '[FILTERED]',
'Job-Token' => '[FILTERED]',
'Gitlab-Workhorse-Proxy-Start' => '123456'
)
end
it 'filters query string parameters' do
expect(result_hash[:request][:query_string]).not_to include('secret')
end
it 'removes cookies' do
expect(result_hash[:request][:cookies]).to be_empty
end
it 'removes data' do
expect(result_hash[:request][:data]).to be_empty
end
end
end
end

View file

@ -424,5 +424,25 @@ RSpec.describe Gitlab::ErrorTracking do
end
end
end
context 'when request contains sensitive information' do
before do
Sentry.get_current_scope.set_rack_env({
'HTTP_AUTHORIZATION' => 'Bearer 123456',
'HTTP_PRIVATE_TOKEN' => 'abcdef',
'HTTP_JOB_TOKEN' => 'secret123'
})
end
it 'filters sensitive data' do
track_exception
expect(sentry_event.to_hash[:request][:headers]).to include(
'Authorization' => '[FILTERED]',
'Private-Token' => '[FILTERED]',
'Job-Token' => '[FILTERED]'
)
end
end
end
end

View file

@ -0,0 +1,42 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::Pages::CacheControl do
it 'fails with invalid type' do
expect { described_class.new(type: :unknown, id: nil) }
.to raise_error(ArgumentError, "type must be :namespace or :project")
end
describe '.for_namespace' do
let(:subject) { described_class.for_namespace(1) }
it { expect(subject.cache_key).to eq('pages_domain_for_namespace_1') }
describe '#clear_cache' do
it 'clears the cache' do
expect(Rails.cache)
.to receive(:delete)
.with('pages_domain_for_namespace_1')
subject.clear_cache
end
end
end
describe '.for_project' do
let(:subject) { described_class.for_project(1) }
it { expect(subject.cache_key).to eq('pages_domain_for_project_1') }
describe '#clear_cache' do
it 'clears the cache' do
expect(Rails.cache)
.to receive(:delete)
.with('pages_domain_for_project_1')
subject.clear_cache
end
end
end
end

View file

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe Gitlab::Tracking::Destinations::Snowplow do
RSpec.describe Gitlab::Tracking::Destinations::Snowplow, :do_not_stub_snowplow_by_default do
let(:emitter) { SnowplowTracker::Emitter.new('localhost', buffer_size: 1) }
let(:tracker) { SnowplowTracker::Tracker.new(emitter, SnowplowTracker::Subject.new, 'namespace', 'app_id') }

View file

@ -20,7 +20,7 @@ RSpec.describe Gitlab::Tracking::IncidentManagement do
described_class.track_from_params(params)
end
context 'known params' do
context 'known params', :do_not_stub_snowplow_by_default do
known_params = described_class.tracking_keys
known_params.each do |key, values|

View file

@ -305,18 +305,20 @@ RSpec.describe ApplicationSetting do
end
end
context 'when snowplow is enabled' do
before do
setting.snowplow_enabled = true
describe 'snowplow settings', :do_not_stub_snowplow_by_default do
context 'when snowplow is enabled' do
before do
setting.snowplow_enabled = true
end
it { is_expected.not_to allow_value(nil).for(:snowplow_collector_hostname) }
it { is_expected.to allow_value("snowplow.gitlab.com").for(:snowplow_collector_hostname) }
it { is_expected.not_to allow_value('/example').for(:snowplow_collector_hostname) }
end
it { is_expected.not_to allow_value(nil).for(:snowplow_collector_hostname) }
it { is_expected.to allow_value("snowplow.gitlab.com").for(:snowplow_collector_hostname) }
it { is_expected.not_to allow_value('/example').for(:snowplow_collector_hostname) }
end
context 'when snowplow is not enabled' do
it { is_expected.to allow_value(nil).for(:snowplow_collector_hostname) }
context 'when snowplow is not enabled' do
it { is_expected.to allow_value(nil).for(:snowplow_collector_hostname) }
end
end
context 'when mailgun_events_enabled is enabled' do

View file

@ -205,7 +205,12 @@ RSpec.describe CacheableAttributes do
end
end
it 'uses RequestStore in addition to process memory cache', :request_store, :do_not_mock_admin_mode_setting do
it(
'uses RequestStore in addition to process memory cache',
:request_store,
:do_not_mock_admin_mode_setting,
:do_not_stub_snowplow_by_default
) do
# Warm up the cache
create(:application_setting).cache!

View file

@ -1885,15 +1885,29 @@ RSpec.describe Namespace do
describe '#pages_virtual_domain' do
let(:project) { create(:project, namespace: namespace) }
let(:virtual_domain) { namespace.pages_virtual_domain }
it 'returns the virual domain' do
before do
project.mark_pages_as_deployed
project.update_pages_deployment!(create(:pages_deployment, project: project))
end
virtual_domain = namespace.pages_virtual_domain
it 'returns the virual domain' do
expect(virtual_domain).to be_an_instance_of(Pages::VirtualDomain)
expect(virtual_domain.lookup_paths).not_to be_empty
expect(virtual_domain.cache_key).to eq("pages_domain_for_namespace_#{namespace.root_ancestor.id}")
end
context 'when :cache_pages_domain_api is disabled' do
before do
stub_feature_flags(cache_pages_domain_api: false)
end
it 'returns the virual domain' do
expect(virtual_domain).to be_an_instance_of(Pages::VirtualDomain)
expect(virtual_domain.lookup_paths).not_to be_empty
expect(virtual_domain.cache_key).to be_nil
end
end
end

View file

@ -7,7 +7,7 @@ RSpec.describe Pages::VirtualDomain do
let(:domain) { nil }
let(:project) { instance_double(Project) }
subject(:virtual_domain) { described_class.new([project], domain: domain) }
subject(:virtual_domain) { described_class.new(projects: [project], domain: domain) }
it 'returns nil if there is no domain provided' do
expect(virtual_domain.certificate).to be_nil
@ -35,7 +35,7 @@ RSpec.describe Pages::VirtualDomain do
context 'when there is pages domain provided' do
let(:domain) { instance_double(PagesDomain) }
subject(:virtual_domain) { described_class.new([project_a, project_b, project_c], domain: domain) }
subject(:virtual_domain) { described_class.new(projects: [project_a, project_b, project_c], domain: domain) }
it 'returns collection of projects pages lookup paths sorted by prefix in reverse' do
expect(project_a).to receive(:pages_lookup_path).with(domain: domain, trim_prefix: nil).and_return(pages_lookup_path_a)
@ -47,7 +47,7 @@ RSpec.describe Pages::VirtualDomain do
end
context 'when there is trim_prefix provided' do
subject(:virtual_domain) { described_class.new([project_a, project_b], trim_prefix: 'group/') }
subject(:virtual_domain) { described_class.new(projects: [project_a, project_b], trim_prefix: 'group/') }
it 'returns collection of projects pages lookup paths sorted by prefix in reverse' do
expect(project_a).to receive(:pages_lookup_path).with(trim_prefix: 'group/', domain: nil).and_return(pages_lookup_path_a)
@ -57,4 +57,19 @@ RSpec.describe Pages::VirtualDomain do
end
end
end
describe '#cache_key' do
it 'returns the cache key based in the given cache_control' do
cache_control = instance_double(::Gitlab::Pages::CacheControl, cache_key: 'cache_key')
virtual_domain = described_class.new(projects: [instance_double(Project)], cache: cache_control)
expect(virtual_domain.cache_key).to eq('cache_key')
end
it 'returns nil when no cache_control is given' do
virtual_domain = described_class.new(projects: [instance_double(Project)])
expect(virtual_domain.cache_key).to be_nil
end
end
end

View file

@ -544,16 +544,31 @@ RSpec.describe PagesDomain do
end
end
it 'returns the virual domain when there are pages deployed for the project' do
project.mark_pages_as_deployed
project.update_pages_deployment!(create(:pages_deployment, project: project))
context 'when there are pages deployed for the project' do
let(:virtual_domain) { pages_domain.pages_virtual_domain }
expect(Pages::VirtualDomain).to receive(:new).with([project], domain: pages_domain).and_call_original
before do
project.mark_pages_as_deployed
project.update_pages_deployment!(create(:pages_deployment, project: project))
end
virtual_domain = pages_domain.pages_virtual_domain
it 'returns the virual domain when there are pages deployed for the project' do
expect(virtual_domain).to be_an_instance_of(Pages::VirtualDomain)
expect(virtual_domain.lookup_paths).not_to be_empty
expect(virtual_domain.cache_key).to eq("pages_domain_for_project_#{project.id}")
end
expect(virtual_domain).to be_an_instance_of(Pages::VirtualDomain)
expect(virtual_domain.lookup_paths).not_to be_empty
context 'when :cache_pages_domain_api is disabled' do
before do
stub_feature_flags(cache_pages_domain_api: false)
end
it 'returns the virual domain when there are pages deployed for the project' do
expect(virtual_domain).to be_an_instance_of(Pages::VirtualDomain)
expect(virtual_domain.lookup_paths).not_to be_empty
expect(virtual_domain.cache_key).to be_nil
end
end
end
end

View file

@ -373,7 +373,7 @@ RSpec.describe API::Settings, 'Settings', :do_not_mock_admin_mode_setting do
end
end
context "snowplow tracking settings" do
context "snowplow tracking settings", :do_not_stub_snowplow_by_default do
let(:settings) do
{
snowplow_collector_hostname: "snowplow.example.com",

View file

@ -201,10 +201,12 @@ RSpec.configure do |config|
config.include SidekiqMiddleware
config.include StubActionCableConnection, type: :channel
config.include StubSpamServices
config.include SnowplowHelpers
config.include RenderedHelpers
config.include RSpec::Benchmark::Matchers, type: :benchmark
include StubFeatureFlags
include StubSnowplow
if ENV['CI'] || ENV['RETRIES']
# This includes the first try, i.e. tests will be run 4 times before failing.
@ -367,6 +369,9 @@ RSpec.configure do |config|
stub_application_setting(admin_mode: true) unless example.metadata[:do_not_mock_admin_mode_setting]
allow(Gitlab::CurrentSettings).to receive(:current_application_settings?).and_return(false)
# Ensure that Snowplow is enabled by default unless forced to the opposite
stub_snowplow unless example.metadata[:do_not_stub_snowplow_by_default]
end
config.around(:example, :quarantine) do |example|

View file

@ -2,7 +2,6 @@
# Require the provided spec helper and matchers.
require 'gitlab/experiment/rspec'
require_relative 'stub_snowplow'
RSpec.configure do |config|
config.include StubSnowplow, :experiment

View file

@ -13,7 +13,7 @@ module StubSnowplow
.and_return(SnowplowTracker::Emitter.new(host, buffer_size: buffer_size))
# rubocop:enable RSpec/AnyInstanceOf
stub_application_setting(snowplow_enabled: true)
stub_application_setting(snowplow_enabled: true, snowplow_collector_hostname: host)
allow(SnowplowTracker::SelfDescribingJson).to receive(:new).and_call_original
allow(Gitlab::Tracking).to receive(:event).and_call_original # rubocop:disable RSpec/ExpectGitlabTracking

View file

@ -15,64 +15,66 @@ RSpec.shared_examples 'setting CSP' do |rule_name|
end
end
context 'when no CSP config' do
include_context 'csp config', nil
context 'csp config and feature toggle', :do_not_stub_snowplow_by_default do
context 'when no CSP config' do
include_context 'csp config', nil
it 'does not add CSP directives' do
is_expected.to be_blank
end
end
describe "when a CSP config exists for #{rule_name}" do
include_context 'csp config', rule_name.parameterize.underscore.to_sym
context 'when feature is enabled' do
it "appends to #{rule_name}" do
is_expected.to eql("#{rule_name} #{default_csp_values} #{allowlisted_url}")
it 'does not add CSP directives' do
is_expected.to be_blank
end
end
context 'when feature is disabled' do
include_context 'disable feature'
describe "when a CSP config exists for #{rule_name}" do
include_context 'csp config', rule_name.parameterize.underscore.to_sym
it "keeps original #{rule_name}" do
is_expected.to eql("#{rule_name} #{default_csp_values}")
context 'when feature is enabled' do
it "appends to #{rule_name}" do
is_expected.to eql("#{rule_name} #{default_csp_values} #{allowlisted_url}")
end
end
end
end
describe "when a CSP config exists for default-src but not #{rule_name}" do
include_context 'csp config', :default_src
context 'when feature is disabled' do
include_context 'disable feature'
context 'when feature is enabled' do
it "uses default-src values in #{rule_name}" do
is_expected.to eql("default-src #{default_csp_values}; #{rule_name} #{default_csp_values} #{allowlisted_url}")
it "keeps original #{rule_name}" do
is_expected.to eql("#{rule_name} #{default_csp_values}")
end
end
end
context 'when feature is disabled' do
include_context 'disable feature'
describe "when a CSP config exists for default-src but not #{rule_name}" do
include_context 'csp config', :default_src
it "does not add #{rule_name}" do
is_expected.to eql("default-src #{default_csp_values}")
context 'when feature is enabled' do
it "uses default-src values in #{rule_name}" do
is_expected.to eql("default-src #{default_csp_values}; #{rule_name} #{default_csp_values} #{allowlisted_url}")
end
end
end
end
describe "when a CSP config exists for font-src but not #{rule_name}" do
include_context 'csp config', :font_src
context 'when feature is disabled' do
include_context 'disable feature'
context 'when feature is enabled' do
it "uses default-src values in #{rule_name}" do
is_expected.to eql("font-src #{default_csp_values}; #{rule_name} #{allowlisted_url}")
it "does not add #{rule_name}" do
is_expected.to eql("default-src #{default_csp_values}")
end
end
end
context 'when feature is disabled' do
include_context 'disable feature'
describe "when a CSP config exists for font-src but not #{rule_name}" do
include_context 'csp config', :font_src
it "does not add #{rule_name}" do
is_expected.to eql("font-src #{default_csp_values}")
context 'when feature is enabled' do
it "uses default-src values in #{rule_name}" do
is_expected.to eql("font-src #{default_csp_values}; #{rule_name} #{allowlisted_url}")
end
end
context 'when feature is disabled' do
include_context 'disable feature'
it "does not add #{rule_name}" do
is_expected.to eql("font-src #{default_csp_values}")
end
end
end
end

View file

@ -1,16 +0,0 @@
# frozen_string_literal: true
require_relative 'stub_snowplow'
RSpec.configure do |config|
config.include SnowplowHelpers, :snowplow
config.include StubSnowplow, :snowplow
config.before(:each, :snowplow) do
stub_snowplow
end
config.after(:each, :snowplow) do
Gitlab::Tracking.send(:tracker).send(:tracker).flush
end
end

View file

@ -0,0 +1,29 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Pages::InvalidateDomainCacheWorker do
let(:event) do
Pages::PageDeployedEvent.new(data: {
project_id: 1,
namespace_id: 2,
root_namespace_id: 3
})
end
subject { consume_event(subscriber: described_class, event: event) }
it_behaves_like 'subscribes to event'
it 'enqueues ScheduleAggregationWorker' do
expect_next_instance_of(Gitlab::Pages::CacheControl, type: :project, id: 1) do |cache_control|
expect(cache_control).to receive(:clear_cache)
end
expect_next_instance_of(Gitlab::Pages::CacheControl, type: :namespace, id: 3) do |cache_control|
expect(cache_control).to receive(:clear_cache)
end
subject
end
end

View file

@ -15,8 +15,8 @@
- '/{,ee/}lib/**/*%{keyword}*{,/**/*}'
deny:
keywords:
- '*author.*'
- '*author_*'
- '*author{,s}.*'
- '*author{,s}_*'
- '*authored*'
- '*authoring*'
- '*.png'

View file

@ -24,7 +24,7 @@ require (
github.com/rafaeljusto/redigomock/v3 v3.1.1
github.com/sebest/xff v0.0.0-20210106013422-671bd2870b3a
github.com/sirupsen/logrus v1.8.1
github.com/smartystreets/goconvey v1.6.4
github.com/smartystreets/goconvey v1.7.2
github.com/stretchr/testify v1.7.0
gitlab.com/gitlab-org/gitaly/v15 v15.1.0
gitlab.com/gitlab-org/golang-archive-zip v0.1.1
@ -93,7 +93,7 @@ require (
github.com/ryszard/goskiplist v0.0.0-20150312221310-2dfbae5fcf46 // indirect
github.com/shabbyrobe/gocovmerge v0.0.0-20190829150210-3e036491d500 // indirect
github.com/shirou/gopsutil/v3 v3.21.2 // indirect
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d // indirect
github.com/smartystreets/assertions v1.2.0 // indirect
github.com/tinylib/msgp v1.1.2 // indirect
github.com/tklauser/go-sysconf v0.3.4 // indirect
github.com/tklauser/numcpus v0.2.1 // indirect

View file

@ -1014,10 +1014,12 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg=
github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=