summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-07-04 18:09:30 +0000
committernao.hashizume <nhashizume@gitlab.com>2022-07-04 12:42:07 -0700
commitf712a0c6de61c94f48c12a25f0cdb1db6bd51c94 (patch)
tree177ced5ef7f03cd1f76e44a6f56c7cc281d06ffc
parent0af8d072b36d81d60ad817f1bda0cfc35615096e (diff)
downloadgitlab-ce-nao-test-foss-failure.tar.gz
Add latest changes from gitlab-org/gitlab@masternao-test-foss-failure
-rw-r--r--app/assets/javascripts/content_editor/components/bubble_menus/formatting.vue20
-rw-r--r--app/assets/javascripts/lib/dompurify.js1
-rw-r--r--app/assets/javascripts/vue_shared/components/notes/placeholder_note.vue24
-rw-r--r--app/models/namespace_setting.rb23
-rw-r--r--app/policies/global_policy.rb2
-rw-r--r--app/services/groups/base_service.rb4
-rw-r--r--app/services/groups/create_service.rb2
-rw-r--r--app/views/admin/application_settings/_gitpod.html.haml2
-rw-r--r--config/locales/en.yml3
-rw-r--r--data/removals/15_0/15-0-remove-background-upload-object-storage.yml31
-rw-r--r--db/migrate/20220613054349_add_unique_project_download_limit_settings_to_namespace_settings.rb12
-rw-r--r--db/schema_migrations/202206130543491
-rw-r--r--db/structure.sql2
-rw-r--r--doc/update/removals.md29
-rw-r--r--lib/gitlab/ci/runner_releases.rb2
-rw-r--r--locale/gitlab.pot48
-rw-r--r--spec/frontend/content_editor/components/bubble_menus/formatting_spec.js24
-rw-r--r--spec/frontend/lib/dompurify_spec.js23
-rw-r--r--spec/frontend/vue_shared/components/notes/__snapshots__/placeholder_note_spec.js.snap23
-rw-r--r--spec/frontend/vue_shared/components/notes/placeholder_note_spec.js12
-rw-r--r--spec/lib/gitlab/ci/runner_releases_spec.rb13
-rw-r--r--spec/policies/global_policy_spec.rb40
22 files changed, 284 insertions, 57 deletions
diff --git a/app/assets/javascripts/content_editor/components/bubble_menus/formatting.vue b/app/assets/javascripts/content_editor/components/bubble_menus/formatting.vue
index e35fbf14de5..a1e18aa52e7 100644
--- a/app/assets/javascripts/content_editor/components/bubble_menus/formatting.vue
+++ b/app/assets/javascripts/content_editor/components/bubble_menus/formatting.vue
@@ -103,6 +103,26 @@ export default {
:label="__('Insert link')"
@execute="trackToolbarControlExecution"
/>
+ <toolbar-button
+ data-testid="superscript"
+ content-type="superscript"
+ icon-name="superscript"
+ editor-command="toggleSuperscript"
+ category="tertiary"
+ size="medium"
+ :label="__('Superscript')"
+ @execute="trackToolbarControlExecution"
+ />
+ <toolbar-button
+ data-testid="subscript"
+ content-type="subscript"
+ icon-name="subscript"
+ editor-command="toggleSubscript"
+ category="tertiary"
+ size="medium"
+ :label="__('Subscript')"
+ @execute="trackToolbarControlExecution"
+ />
</gl-button-group>
</bubble-menu>
</template>
diff --git a/app/assets/javascripts/lib/dompurify.js b/app/assets/javascripts/lib/dompurify.js
index 4959550e273..a01c6df0003 100644
--- a/app/assets/javascripts/lib/dompurify.js
+++ b/app/assets/javascripts/lib/dompurify.js
@@ -8,6 +8,7 @@ const defaultConfig = {
// See https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1421
FORBID_ATTR: ['data-remote', 'data-url', 'data-type', 'data-method'],
FORBID_TAGS: ['style', 'mstyle'],
+ ALLOW_UNKNOWN_PROTOCOLS: true,
};
// Only icons urls from `gon` are allowed
diff --git a/app/assets/javascripts/vue_shared/components/notes/placeholder_note.vue b/app/assets/javascripts/vue_shared/components/notes/placeholder_note.vue
index 624dbcc6d8e..0cb4a5bc39f 100644
--- a/app/assets/javascripts/vue_shared/components/notes/placeholder_note.vue
+++ b/app/assets/javascripts/vue_shared/components/notes/placeholder_note.vue
@@ -16,17 +16,17 @@
* :note="{body: 'This is a note'}"
* />
*/
-import { GlSafeHtmlDirective as SafeHtml } from '@gitlab/ui';
+import { GlSafeHtmlDirective as SafeHtml, GlAvatarLink, GlAvatar } from '@gitlab/ui';
import { mapGetters } from 'vuex';
import { renderMarkdown } from '~/notes/utils';
import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue';
-import userAvatarLink from '../user_avatar/user_avatar_link.vue';
export default {
name: 'PlaceholderNote',
directives: { SafeHtml },
components: {
- userAvatarLink,
+ GlAvatarLink,
+ GlAvatar,
TimelineEntryItem,
},
props: {
@@ -55,7 +55,10 @@ export default {
return 24;
}
- return 40;
+ return {
+ default: 24,
+ md: 32,
+ };
},
},
};
@@ -64,11 +67,14 @@ export default {
<template>
<timeline-entry-item class="note note-wrapper being-posted fade-in-half">
<div class="timeline-icon">
- <user-avatar-link
- :link-href="getUserData.path"
- :img-src="getUserData.avatar_url"
- :img-size="avatarSize"
- />
+ <gl-avatar-link class="gl-mr-3" :href="getUserData.path">
+ <gl-avatar
+ :src="getUserData.avatar_url"
+ :entity-name="getUserData.username"
+ :alt="getUserData.name"
+ :size="avatarSize"
+ />
+ </gl-avatar-link>
</div>
<div ref="note" :class="{ discussion: !note.individual_note }" class="timeline-content">
<div class="note-header">
diff --git a/app/models/namespace_setting.rb b/app/models/namespace_setting.rb
index 504daf2662e..595e34821af 100644
--- a/app/models/namespace_setting.rb
+++ b/app/models/namespace_setting.rb
@@ -24,14 +24,27 @@ class NamespaceSetting < ApplicationRecord
chronic_duration_attr :subgroup_runner_token_expiration_interval_human_readable, :subgroup_runner_token_expiration_interval
chronic_duration_attr :project_runner_token_expiration_interval_human_readable, :project_runner_token_expiration_interval
- NAMESPACE_SETTINGS_PARAMS = [:default_branch_name, :delayed_project_removal,
- :lock_delayed_project_removal, :resource_access_token_creation_allowed,
- :prevent_sharing_groups_outside_hierarchy, :new_user_signups_cap,
- :setup_for_company, :jobs_to_be_done, :runner_token_expiration_interval, :enabled_git_access_protocol,
- :subgroup_runner_token_expiration_interval, :project_runner_token_expiration_interval].freeze
+ NAMESPACE_SETTINGS_PARAMS = %i[
+ default_branch_name
+ delayed_project_removal
+ lock_delayed_project_removal
+ resource_access_token_creation_allowed
+ prevent_sharing_groups_outside_hierarchy
+ new_user_signups_cap
+ setup_for_company
+ jobs_to_be_done
+ runner_token_expiration_interval
+ enabled_git_access_protocol
+ subgroup_runner_token_expiration_interval
+ project_runner_token_expiration_interval
+ ].freeze
self.primary_key = :namespace_id
+ def self.allowed_namespace_settings_params
+ NAMESPACE_SETTINGS_PARAMS
+ end
+
sanitizes! :default_branch_name
def prevent_sharing_groups_outside_hierarchy
diff --git a/app/policies/global_policy.rb b/app/policies/global_policy.rb
index fa7b117f3cd..406144b7a5c 100644
--- a/app/policies/global_policy.rb
+++ b/app/policies/global_policy.rb
@@ -120,6 +120,8 @@ class GlobalPolicy < BasePolicy
# We can't use `read_statistics` because the user may have different permissions for different projects
rule { admin }.enable :use_project_statistics_filters
+ rule { admin }.enable :delete_runners
+
rule { external_user }.prevent :create_snippet
end
diff --git a/app/services/groups/base_service.rb b/app/services/groups/base_service.rb
index 06136aff50e..9705f3a560d 100644
--- a/app/services/groups/base_service.rb
+++ b/app/services/groups/base_service.rb
@@ -13,11 +13,11 @@ module Groups
private
def handle_namespace_settings
- settings_params = params.slice(*::NamespaceSetting::NAMESPACE_SETTINGS_PARAMS)
+ settings_params = params.slice(*::NamespaceSetting.allowed_namespace_settings_params)
return if settings_params.empty?
- ::NamespaceSetting::NAMESPACE_SETTINGS_PARAMS.each do |nsp|
+ ::NamespaceSetting.allowed_namespace_settings_params.each do |nsp|
params.delete(nsp)
end
diff --git a/app/services/groups/create_service.rb b/app/services/groups/create_service.rb
index 639f7c68c40..35716f7742a 100644
--- a/app/services/groups/create_service.rb
+++ b/app/services/groups/create_service.rb
@@ -13,7 +13,7 @@ module Groups
remove_unallowed_params
set_visibility_level
- @group = Group.new(params.except(*::NamespaceSetting::NAMESPACE_SETTINGS_PARAMS))
+ @group = Group.new(params.except(*::NamespaceSetting.allowed_namespace_settings_params))
@group.build_namespace_settings
handle_namespace_settings
diff --git a/app/views/admin/application_settings/_gitpod.html.haml b/app/views/admin/application_settings/_gitpod.html.haml
index eb47d177701..cd4493d8016 100644
--- a/app/views/admin/application_settings/_gitpod.html.haml
+++ b/app/views/admin/application_settings/_gitpod.html.haml
@@ -13,7 +13,7 @@
.settings-content
= gitlab_ui_form_for @application_setting, url: general_admin_application_settings_path(anchor: 'js-gitpod-settings'), html: { class: 'fieldset-form', id: 'gitpod-settings' } do |f|
- = form_errors(@application_setting)
+ = form_errors(@application_setting, pajamas_alert: true)
%fieldset
.form-group
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 233dca33bb8..56df8f93113 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -10,6 +10,9 @@ en:
target: Target issue
group:
path: Group URL
+ namespace_setting:
+ unique_project_download_limit: "Number of projects"
+ unique_project_download_limit_interval_in_seconds: "Interval (seconds)"
member:
user: "The member's email address"
invite_email: "The member's email address"
diff --git a/data/removals/15_0/15-0-remove-background-upload-object-storage.yml b/data/removals/15_0/15-0-remove-background-upload-object-storage.yml
index dcfd18cf809..16aab3d14c2 100644
--- a/data/removals/15_0/15-0-remove-background-upload-object-storage.yml
+++ b/data/removals/15_0/15-0-remove-background-upload-object-storage.yml
@@ -7,17 +7,46 @@
reporter: fzimmer
body: | # Do not modify this line, instead modify the lines below.
To reduce the overall complexity and maintenance burden of GitLab's [object storage feature](https://docs.gitlab.com/ee/administration/object_storage.html), support for using `background_upload` has been removed in GitLab 15.0.
+ By default [direct upload](https://docs.gitlab.com/ee/development/uploads/index.html#direct-upload) will be used.
- This impacts a small subset of object storage providers, including but not limited to:
+ This impacts a subset of object storage providers, including but not limited to:
- **OpenStack** Customers using OpenStack need to change their configuration to use the S3 API instead of Swift.
- **RackSpace** Customers using RackSpace-based object storage need to migrate data to a different provider.
If your object storage provider does not support `background_upload`, please [migrate objects to a supported object storage provider](https://docs.gitlab.com/ee/administration/object_storage.html#migrate-objects-to-a-different-object-storage-provider).
+ #### Encrypted S3 buckets
+
Additionally, this also breaks the use of [encrypted S3 buckets](https://docs.gitlab.com/ee/administration/object_storage.html#encrypted-s3-buckets) with [storage-specific configuration form](https://docs.gitlab.com/ee/administration/object_storage.html#storage-specific-configuration).
If your S3 buckets have [SSE-S3 or SSE-KMS encryption enabled](https://docs.aws.amazon.com/kms/latest/developerguide/services-s3.html), please [migrate your configuration to use consolidated object storage form](https://docs.gitlab.com/ee/administration/object_storage.html#transition-to-consolidated-form) before upgrading to GitLab 15.0. Otherwise, you may start getting `ETag mismatch` errors during objects upload.
+
+ #### 403 errors
+
+ If you see 403 errors when uploading to object storage after
+ upgrading to GitLab 15.0, check that the [correct permissions](https://docs.gitlab.com/ee/administration/object_storage.html#iam-permissions)
+ are assigned to the bucket. Direct upload needs the ability to delete an
+ object (example: `s3:DeleteObject`), but background uploads do not.
+
+ #### `remote_directory` with a path prefix
+
+ If the object storage `remote_directory` configuration contains a slash (`/`) after the bucket (example: `gitlab/uploads`), be aware that this [was never officially supported](https://gitlab.com/gitlab-org/gitlab/-/issues/292958).
+ Some users found that they could specify a path prefix to the bucket. In direct upload mode, object storage uploads will fail if a slash is present in GitLab 15.0.
+
+ If you have set a prefix, you can use a workaround to revert to background uploads:
+
+ 1. Continue to use [storage-specific configuration](https://docs.gitlab.com/ee/administration/object_storage.html#storage-specific-configuration).
+ 1. In Omnibus GitLab, set the `GITLAB_LEGACY_BACKGROUND_UPLOADS` to re-enable background uploads:
+
+ ```ruby
+ gitlab_rails['env'] = { 'GITLAB_LEGACY_BACKGROUND_UPLOADS' => 'artifacts,external_diffs,lfs,uploads,packages,dependency_proxy,terraform_state,pages' }
+ ```
+
+ Prefixes will be supported officially in [GitLab 15.2](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91307).
+ This workaround will be dropped, so we encourage migrating to consolidated object storage.
+
+
stage: Enablement
tiers: [Core, Premium, Ultimate]
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/26600
diff --git a/db/migrate/20220613054349_add_unique_project_download_limit_settings_to_namespace_settings.rb b/db/migrate/20220613054349_add_unique_project_download_limit_settings_to_namespace_settings.rb
new file mode 100644
index 00000000000..7e821cb17a2
--- /dev/null
+++ b/db/migrate/20220613054349_add_unique_project_download_limit_settings_to_namespace_settings.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+class AddUniqueProjectDownloadLimitSettingsToNamespaceSettings < Gitlab::Database::Migration[2.0]
+ enable_lock_retries!
+
+ def change
+ add_column :namespace_settings, :unique_project_download_limit, :smallint,
+ default: 0, null: false
+ add_column :namespace_settings, :unique_project_download_limit_interval_in_seconds, :integer,
+ default: 0, null: false
+ end
+end
diff --git a/db/schema_migrations/20220613054349 b/db/schema_migrations/20220613054349
new file mode 100644
index 00000000000..1c3806a80c8
--- /dev/null
+++ b/db/schema_migrations/20220613054349
@@ -0,0 +1 @@
+4c3e4852614dd1a59d63809c40417887794bcbbcf8d3ea3a96f8846e2bd5f795 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index f697bacdfc5..2013a434bab 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -17550,6 +17550,8 @@ CREATE TABLE namespace_settings (
project_runner_token_expiration_interval integer,
exclude_from_free_user_cap boolean DEFAULT false NOT NULL,
enabled_git_access_protocol smallint DEFAULT 0 NOT NULL,
+ unique_project_download_limit smallint DEFAULT 0 NOT NULL,
+ unique_project_download_limit_interval_in_seconds integer DEFAULT 0 NOT NULL,
CONSTRAINT check_0ba93c78c7 CHECK ((char_length(default_branch_name) <= 255))
);
diff --git a/doc/update/removals.md b/doc/update/removals.md
index 32fbf851176..dc4cf874a93 100644
--- a/doc/update/removals.md
+++ b/doc/update/removals.md
@@ -66,18 +66,45 @@ This is a [breaking change](https://docs.gitlab.com/ee/development/contributing/
Review the details carefully before upgrading.
To reduce the overall complexity and maintenance burden of GitLab's [object storage feature](https://docs.gitlab.com/ee/administration/object_storage.html), support for using `background_upload` has been removed in GitLab 15.0.
+By default [direct upload](https://docs.gitlab.com/ee/development/uploads/index.html#direct-upload) will be used.
-This impacts a small subset of object storage providers, including but not limited to:
+This impacts a subset of object storage providers, including but not limited to:
- **OpenStack** Customers using OpenStack need to change their configuration to use the S3 API instead of Swift.
- **RackSpace** Customers using RackSpace-based object storage need to migrate data to a different provider.
If your object storage provider does not support `background_upload`, please [migrate objects to a supported object storage provider](https://docs.gitlab.com/ee/administration/object_storage.html#migrate-objects-to-a-different-object-storage-provider).
+#### Encrypted S3 buckets
+
Additionally, this also breaks the use of [encrypted S3 buckets](https://docs.gitlab.com/ee/administration/object_storage.html#encrypted-s3-buckets) with [storage-specific configuration form](https://docs.gitlab.com/ee/administration/object_storage.html#storage-specific-configuration).
If your S3 buckets have [SSE-S3 or SSE-KMS encryption enabled](https://docs.aws.amazon.com/kms/latest/developerguide/services-s3.html), please [migrate your configuration to use consolidated object storage form](https://docs.gitlab.com/ee/administration/object_storage.html#transition-to-consolidated-form) before upgrading to GitLab 15.0. Otherwise, you may start getting `ETag mismatch` errors during objects upload.
+#### 403 errors
+
+If you see 403 errors when uploading to object storage after
+upgrading to GitLab 15.0, check that the [correct permissions](https://docs.gitlab.com/ee/administration/object_storage.html#iam-permissions)
+are assigned to the bucket. Direct upload needs the ability to delete an
+object (example: `s3:DeleteObject`), but background uploads do not.
+
+#### `remote_directory` with a path prefix
+
+If the object storage `remote_directory` configuration contains a slash (`/`) after the bucket (example: `gitlab/uploads`), be aware that this [was never officially supported](https://gitlab.com/gitlab-org/gitlab/-/issues/292958).
+Some users found that they could specify a path prefix to the bucket. In direct upload mode, object storage uploads will fail if a slash is present in GitLab 15.0.
+
+If you have set a prefix, you can use a workaround to revert to background uploads:
+
+1. Continue to use [storage-specific configuration](https://docs.gitlab.com/ee/administration/object_storage.html#storage-specific-configuration).
+1. In Omnibus GitLab, set the `GITLAB_LEGACY_BACKGROUND_UPLOADS` to re-enable background uploads:
+
+ ```ruby
+ gitlab_rails['env'] = { 'GITLAB_LEGACY_BACKGROUND_UPLOADS' => 'artifacts,external_diffs,lfs,uploads,packages,dependency_proxy,terraform_state,pages' }
+ ```
+
+Prefixes will be supported officially in [GitLab 15.2](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91307).
+This workaround will be dropped, so we encourage migrating to consolidated object storage.
+
### Container Network and Host Security
WARNING:
diff --git a/lib/gitlab/ci/runner_releases.rb b/lib/gitlab/ci/runner_releases.rb
index 8dc6533a384..1930bc4ff75 100644
--- a/lib/gitlab/ci/runner_releases.rb
+++ b/lib/gitlab/ci/runner_releases.rb
@@ -45,7 +45,7 @@ module Gitlab
end
def parse_runner_release(release)
- ::Gitlab::VersionInfo.parse(release['name'].delete_prefix('v'))
+ ::Gitlab::VersionInfo.parse(release['name'], parse_suffix: true)
end
def next_backoff
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 88f1a0584f9..61b600d52a4 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -11484,6 +11484,9 @@ msgstr ""
msgid "DORA4Metrics|Average (last %{days}d)"
msgstr ""
+msgid "DORA4Metrics|Change failure rate"
+msgstr ""
+
msgid "DORA4Metrics|Date"
msgstr ""
@@ -11517,6 +11520,15 @@ msgstr ""
msgid "DORA4Metrics|Number of deployments"
msgstr ""
+msgid "DORA4Metrics|Number of incidents divided by the number of deployments to a production environment in the given time period."
+msgstr ""
+
+msgid "DORA4Metrics|Percentage of failed deployments"
+msgstr ""
+
+msgid "DORA4Metrics|Something went wrong while getting change failure rate data."
+msgstr ""
+
msgid "DORA4Metrics|Something went wrong while getting deployment frequency data."
msgstr ""
@@ -18002,6 +18014,9 @@ msgstr ""
msgid "Group"
msgstr ""
+msgid "Group \"%{group_name}\" was successfully updated."
+msgstr ""
+
msgid "Group %{group_name} couldn't be exported."
msgstr ""
@@ -18440,6 +18455,9 @@ msgstr ""
msgid "GroupSettings|Auto DevOps pipeline was updated for the group"
msgstr ""
+msgid "GroupSettings|Automatically ban users who download more than the specified number of projects within the specified interval."
+msgstr ""
+
msgid "GroupSettings|Available only on the top-level group. Applies to all subgroups. Groups already shared with a group outside %{group} are still shared unless removed manually."
msgstr ""
@@ -18497,9 +18515,15 @@ msgstr ""
msgid "GroupSettings|If the parent group's visibility is lower than the group's current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility."
msgstr ""
+msgid "GroupSettings|Interval (seconds)"
+msgstr ""
+
msgid "GroupSettings|Members cannot invite groups outside of %{group} and its subgroups"
msgstr ""
+msgid "GroupSettings|Number of projects"
+msgstr ""
+
msgid "GroupSettings|Organizations and contacts can be created and associated with issues."
msgstr ""
@@ -18518,9 +18542,15 @@ msgstr ""
msgid "GroupSettings|Prevent forking setting was not saved"
msgstr ""
+msgid "GroupSettings|Project download rate limit"
+msgstr ""
+
msgid "GroupSettings|Projects in %{group} cannot be shared with other groups"
msgstr ""
+msgid "GroupSettings|Reporting"
+msgstr ""
+
msgid "GroupSettings|Select a subgroup to use as the source for custom project templates for this group."
msgstr ""
@@ -18539,9 +18569,15 @@ msgstr ""
msgid "GroupSettings|Set the initial name and protections for the default branch of new repositories created in the group."
msgstr ""
+msgid "GroupSettings|Set to 0 to disable limiting."
+msgstr ""
+
msgid "GroupSettings|The Auto DevOps pipeline runs if no alternative CI configuration file is found."
msgstr ""
+msgid "GroupSettings|The maximum number of unique projects a user can download within the specified interval before they're banned. Set to 0 to disable limiting."
+msgstr ""
+
msgid "GroupSettings|The projects in this subgroup can be selected as templates for new projects created in the group. %{link_start}Learn more.%{link_end}"
msgstr ""
@@ -35846,9 +35882,6 @@ msgstr ""
msgid "Showing all issues"
msgstr ""
-msgid "Showing data for group '%{group_name}' from Nov 1, 2019 to Dec 31, 2019"
-msgstr ""
-
msgid "Showing data for workflow items created in this date range. Date range limited to %{maxDateRange} days."
msgstr ""
@@ -35864,6 +35897,9 @@ msgstr ""
msgid "Showing version #%{versionNumber}"
msgstr ""
+msgid "Shows issues and %{labels_count} labels for group '%{group_name}' from Nov 1, 2019 to Dec 31, 2019"
+msgstr ""
+
msgid "Side-by-side"
msgstr ""
@@ -37160,6 +37196,9 @@ msgstr ""
msgid "Subscribes to this %{quick_action_target}."
msgstr ""
+msgid "Subscript"
+msgstr ""
+
msgid "Subscription"
msgstr ""
@@ -37639,6 +37678,9 @@ msgstr ""
msgid "SuperSonics|past subscriptions"
msgstr ""
+msgid "Superscript"
+msgstr ""
+
msgid "Support"
msgstr ""
diff --git a/spec/frontend/content_editor/components/bubble_menus/formatting_spec.js b/spec/frontend/content_editor/components/bubble_menus/formatting_spec.js
index 6479c0ba008..fba4cf7f680 100644
--- a/spec/frontend/content_editor/components/bubble_menus/formatting_spec.js
+++ b/spec/frontend/content_editor/components/bubble_menus/formatting_spec.js
@@ -46,12 +46,14 @@ describe('content_editor/components/bubble_menus/formatting', () => {
});
describe.each`
- testId | controlProps
- ${'bold'} | ${{ contentType: 'bold', iconName: 'bold', label: 'Bold text', editorCommand: 'toggleBold', size: 'medium', category: 'tertiary' }}
- ${'italic'} | ${{ contentType: 'italic', iconName: 'italic', label: 'Italic text', editorCommand: 'toggleItalic', size: 'medium', category: 'tertiary' }}
- ${'strike'} | ${{ contentType: 'strike', iconName: 'strikethrough', label: 'Strikethrough', editorCommand: 'toggleStrike', size: 'medium', category: 'tertiary' }}
- ${'code'} | ${{ contentType: 'code', iconName: 'code', label: 'Code', editorCommand: 'toggleCode', size: 'medium', category: 'tertiary' }}
- ${'link'} | ${{ contentType: 'link', iconName: 'link', label: 'Insert link', editorCommand: 'toggleLink', editorCommandParams: { href: '' }, size: 'medium', category: 'tertiary' }}
+ testId | controlProps
+ ${'bold'} | ${{ contentType: 'bold', iconName: 'bold', label: 'Bold text', editorCommand: 'toggleBold' }}
+ ${'italic'} | ${{ contentType: 'italic', iconName: 'italic', label: 'Italic text', editorCommand: 'toggleItalic' }}
+ ${'strike'} | ${{ contentType: 'strike', iconName: 'strikethrough', label: 'Strikethrough', editorCommand: 'toggleStrike' }}
+ ${'code'} | ${{ contentType: 'code', iconName: 'code', label: 'Code', editorCommand: 'toggleCode' }}
+ ${'link'} | ${{ contentType: 'link', iconName: 'link', label: 'Insert link', editorCommand: 'toggleLink', editorCommandParams: { href: '' } }}
+ ${'superscript'} | ${{ contentType: 'superscript', iconName: 'superscript', label: 'Superscript', editorCommand: 'toggleSuperscript' }}
+ ${'subscript'} | ${{ contentType: 'subscript', iconName: 'subscript', label: 'Subscript', editorCommand: 'toggleSubscript' }}
`('given a $testId toolbar control', ({ testId, controlProps }) => {
beforeEach(() => {
buildWrapper();
@@ -60,9 +62,13 @@ describe('content_editor/components/bubble_menus/formatting', () => {
it('renders the toolbar control with the provided properties', () => {
expect(wrapper.findByTestId(testId).exists()).toBe(true);
- Object.keys(controlProps).forEach((propName) => {
- expect(wrapper.findByTestId(testId).props(propName)).toEqual(controlProps[propName]);
- });
+ expect(wrapper.findByTestId(testId).props()).toEqual(
+ expect.objectContaining({
+ ...controlProps,
+ size: 'medium',
+ category: 'tertiary',
+ }),
+ );
});
it('tracks the execution of toolbar controls', () => {
diff --git a/spec/frontend/lib/dompurify_spec.js b/spec/frontend/lib/dompurify_spec.js
index 34325dad6a1..b585c69e911 100644
--- a/spec/frontend/lib/dompurify_spec.js
+++ b/spec/frontend/lib/dompurify_spec.js
@@ -34,6 +34,17 @@ const unsafeUrls = [
`${absoluteGon.sprite_file_icons}/../../https://evil.url`,
];
+/* eslint-disable no-script-url */
+const invalidProtocolUrls = [
+ 'javascript:alert(1)',
+ 'jAvascript:alert(1)',
+ 'data:text/html,<script>alert(1);</script>',
+ ' javascript:',
+ 'javascript :',
+];
+/* eslint-enable no-script-url */
+const validProtocolUrls = ['slack://open', 'x-devonthink-item://90909', 'x-devonthink-item:90909'];
+
const forbiddenDataAttrs = ['data-remote', 'data-url', 'data-type', 'data-method'];
const acceptedDataAttrs = ['data-random', 'data-custom'];
@@ -150,4 +161,16 @@ describe('~/lib/dompurify', () => {
expect(sanitize(htmlHref)).toBe(`<a ${attrWithValue}>hello</a>`);
});
});
+
+ describe('with non-http links', () => {
+ it.each(validProtocolUrls)('should allow %s', (url) => {
+ const html = `<a href="${url}">internal link</a>`;
+ expect(sanitize(html)).toBe(`<a href="${url}">internal link</a>`);
+ });
+
+ it.each(invalidProtocolUrls)('should not allow %s', (url) => {
+ const html = `<a href="${url}">internal link</a>`;
+ expect(sanitize(html)).toBe(`<a>internal link</a>`);
+ });
+ });
});
diff --git a/spec/frontend/vue_shared/components/notes/__snapshots__/placeholder_note_spec.js.snap b/spec/frontend/vue_shared/components/notes/__snapshots__/placeholder_note_spec.js.snap
index 5e956d66b6a..bf6c8e8c704 100644
--- a/spec/frontend/vue_shared/components/notes/__snapshots__/placeholder_note_spec.js.snap
+++ b/spec/frontend/vue_shared/components/notes/__snapshots__/placeholder_note_spec.js.snap
@@ -7,16 +7,19 @@ exports[`Issue placeholder note component matches snapshot 1`] = `
<div
class="timeline-icon"
>
- <user-avatar-link-stub
- imgalt=""
- imgcssclasses=""
- imgsize="40"
- imgsrc="mock_path"
- linkhref="/root"
- tooltipplacement="top"
- tooltiptext=""
- username=""
- />
+ <gl-avatar-link-stub
+ class="gl-mr-3"
+ href="/root"
+ >
+ <gl-avatar-stub
+ alt="Root"
+ entityid="0"
+ entityname="root"
+ shape="circle"
+ size="[object Object]"
+ src="mock_path"
+ />
+ </gl-avatar-link-stub>
</div>
<div
diff --git a/spec/frontend/vue_shared/components/notes/placeholder_note_spec.js b/spec/frontend/vue_shared/components/notes/placeholder_note_spec.js
index 6881cb79740..f951cfd5cd9 100644
--- a/spec/frontend/vue_shared/components/notes/placeholder_note_spec.js
+++ b/spec/frontend/vue_shared/components/notes/placeholder_note_spec.js
@@ -1,8 +1,8 @@
import { shallowMount } from '@vue/test-utils';
+import { GlAvatar } from '@gitlab/ui';
import Vue from 'vue';
import Vuex from 'vuex';
import IssuePlaceholderNote from '~/vue_shared/components/notes/placeholder_note.vue';
-import UserAvatarLink from '~/vue_shared/components/user_avatar/user_avatar_link.vue';
import { userDataMock } from 'jest/notes/mock_data';
Vue.use(Vuex);
@@ -56,14 +56,14 @@ describe('Issue placeholder note component', () => {
describe('avatar size', () => {
it.each`
- size | line | isOverviewTab
- ${40} | ${null} | ${false}
- ${24} | ${{ line_code: '123' }} | ${false}
- ${40} | ${{ line_code: '123' }} | ${true}
+ size | line | isOverviewTab
+ ${{ default: 24, md: 32 }} | ${null} | ${false}
+ ${24} | ${{ line_code: '123' }} | ${false}
+ ${{ default: 24, md: 32 }} | ${{ line_code: '123' }} | ${true}
`('renders avatar $size for $line and $isOverviewTab', ({ size, line, isOverviewTab }) => {
createComponent(false, { line, isOverviewTab });
- expect(wrapper.findComponent(UserAvatarLink).props('imgSize')).toBe(size);
+ expect(wrapper.findComponent(GlAvatar).props('size')).toEqual(size);
});
});
});
diff --git a/spec/lib/gitlab/ci/runner_releases_spec.rb b/spec/lib/gitlab/ci/runner_releases_spec.rb
index 9e4a8739c0f..eb29629730c 100644
--- a/spec/lib/gitlab/ci/runner_releases_spec.rb
+++ b/spec/lib/gitlab/ci/runner_releases_spec.rb
@@ -85,15 +85,22 @@ RSpec.describe Gitlab::Ci::RunnerReleases do
expect(http_call_timestamp_offsets).to eq([0, 5, 15, 35, 75, 155, 315, 635, 1275, 2555, 5115, 8715])
# Finally a successful HTTP request results in releases being returned
- allow(Gitlab::HTTP).to receive(:try_get).with('the release API URL').once { mock_http_response([{ 'name' => 'v14.9.1' }]) }
+ allow(Gitlab::HTTP).to receive(:try_get)
+ .with('the release API URL')
+ .once { mock_http_response([{ 'name' => 'v14.9.1-beta1-ee' }]) }
travel 1.hour
expect(releases).not_to be_nil
end
end
context 'when response is not nil' do
- let(:response) { [{ 'name' => 'v14.9.1' }, { 'name' => 'v14.9.0' }] }
- let(:expected_result) { [Gitlab::VersionInfo.new(14, 9, 0), Gitlab::VersionInfo.new(14, 9, 1)] }
+ let(:response) { [{ 'name' => 'v14.9.1-beta1-ee' }, { 'name' => 'v14.9.0' }] }
+ let(:expected_result) do
+ [
+ Gitlab::VersionInfo.new(14, 9, 0),
+ Gitlab::VersionInfo.new(14, 9, 1, '-beta1-ee')
+ ]
+ end
it 'returns parsed and sorted Gitlab::VersionInfo objects' do
expect(releases).to eq(expected_result)
diff --git a/spec/policies/global_policy_spec.rb b/spec/policies/global_policy_spec.rb
index 04d7eca6f09..da0427420e4 100644
--- a/spec/policies/global_policy_spec.rb
+++ b/spec/policies/global_policy_spec.rb
@@ -40,7 +40,7 @@ RSpec.describe GlobalPolicy do
end
context "for an admin" do
- let(:current_user) { create(:admin) }
+ let_it_be(:current_user) { create(:admin) }
context "when the public level is restricted" do
before do
@@ -118,7 +118,7 @@ RSpec.describe GlobalPolicy do
end
context 'admin' do
- let(:current_user) { create(:user, :admin) }
+ let_it_be(:current_user) { create(:user, :admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { is_expected.to be_allowed(:read_custom_attribute) }
@@ -138,7 +138,7 @@ RSpec.describe GlobalPolicy do
end
context 'admin' do
- let(:current_user) { create(:admin) }
+ let_it_be(:current_user) { create(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { is_expected.to be_allowed(:approve_user) }
@@ -156,7 +156,7 @@ RSpec.describe GlobalPolicy do
end
context 'admin' do
- let(:current_user) { create(:admin) }
+ let_it_be(:current_user) { create(:admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { is_expected.to be_allowed(:reject_user) }
@@ -174,7 +174,7 @@ RSpec.describe GlobalPolicy do
end
context 'admin' do
- let(:current_user) { create(:user, :admin) }
+ let_it_be(:current_user) { create(:user, :admin) }
context 'when admin mode is enabled', :enable_admin_mode do
it { is_expected.to be_allowed(:use_project_statistics_filters) }
@@ -591,4 +591,34 @@ RSpec.describe GlobalPolicy do
it { is_expected.not_to be_allowed(:log_in) }
end
end
+
+ describe 'delete runners' do
+ context 'when anonymous' do
+ let(:current_user) { nil }
+
+ it { is_expected.not_to be_allowed(:delete_runners) }
+ end
+
+ context 'regular user' do
+ it { is_expected.not_to be_allowed(:delete_runners) }
+ end
+
+ context 'when external' do
+ let(:current_user) { build(:user, :external) }
+
+ it { is_expected.not_to be_allowed(:delete_runners) }
+ end
+
+ context 'admin user' do
+ let_it_be(:current_user) { create(:user, :admin) }
+
+ context 'when admin mode is enabled', :enable_admin_mode do
+ it { is_expected.to be_allowed(:delete_runners) }
+ end
+
+ context 'when admin mode is disabled' do
+ it { is_expected.to be_disallowed(:delete_runners) }
+ end
+ end
+ end
end