Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/vue_shared/components/web_ide_link.vue30
-rw-r--r--app/models/oauth_access_token.rb10
-rw-r--r--config/feature_flags/development/hash_oauth_tokens.yml8
-rw-r--r--config/initializers/doorkeeper.rb2
-rw-r--r--doc/development/documentation/testing.md30
-rw-r--r--lib/gitlab/doorkeeper_secret_storing/pbkdf2_sha512.rb28
-rw-r--r--locale/gitlab.pot9
-rw-r--r--spec/frontend/blob/components/blob_header_default_actions_spec.js2
-rw-r--r--spec/frontend/blob/sketch/index_spec.js2
-rw-r--r--spec/frontend/design_management/components/delete_button_spec.js4
-rw-r--r--spec/frontend/design_management/components/design_notes/design_discussion_spec.js12
-rw-r--r--spec/frontend/design_management/components/design_notes/design_note_spec.js2
-rw-r--r--spec/frontend/design_management/components/design_notes/design_reply_form_spec.js6
-rw-r--r--spec/frontend/design_management/components/design_notes/toggle_replies_widget_spec.js8
-rw-r--r--spec/frontend/design_management/components/design_scaler_spec.js2
-rw-r--r--spec/frontend/design_management/components/design_sidebar_spec.js8
-rw-r--r--spec/frontend/design_management/components/design_todo_button_spec.js2
-rw-r--r--spec/frontend/design_management/components/image_spec.js2
-rw-r--r--spec/frontend/design_management/components/list/item_spec.js10
-rw-r--r--spec/frontend/design_management/components/toolbar/index_spec.js10
-rw-r--r--spec/frontend/design_management/components/upload/button_spec.js2
-rw-r--r--spec/frontend/design_management/components/upload/design_version_dropdown_spec.js12
-rw-r--r--spec/frontend/design_management/pages/design/index_spec.js12
-rw-r--r--spec/frontend/design_management/pages/index_spec.js8
-rw-r--r--spec/frontend/design_management/router_spec.js4
-rw-r--r--spec/frontend/diffs/components/diff_file_header_spec.js2
-rw-r--r--spec/frontend/ide/components/shared/commit_message_field_spec.js2
-rw-r--r--spec/frontend/ide/stores/actions/file_spec.js8
-rw-r--r--spec/frontend/projects/commits/components/author_select_spec.js4
-rw-r--r--spec/frontend/vue_merge_request_widget/components/states/mr_widget_wip_spec.js14
-rw-r--r--spec/frontend/vue_shared/components/confirm_modal_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/runner_instructions/runner_instructions_modal_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/web_ide_link_spec.js6
-rw-r--r--spec/lib/gitlab/auth/auth_finders_spec.rb6
-rw-r--r--spec/lib/gitlab/doorkeeper_secret_storing/pbkdf2_sha512_spec.rb36
-rw-r--r--spec/models/oauth_access_token_spec.rb47
-rw-r--r--spec/requests/api/doorkeeper_access_spec.rb6
-rw-r--r--spec/requests/api/go_proxy_spec.rb6
-rw-r--r--spec/requests/api/helpers_spec.rb2
-rw-r--r--spec/requests/api/npm_project_packages_spec.rb6
-rw-r--r--spec/requests/rack_attack_global_spec.rb12
-rw-r--r--spec/support/helpers/api_helpers.rb6
-rw-r--r--spec/support/helpers/rack_attack_spec_helpers.rb6
-rw-r--r--spec/support/shared_examples/requests/api/npm_packages_shared_examples.rb8
44 files changed, 292 insertions, 116 deletions
diff --git a/app/assets/javascripts/vue_shared/components/web_ide_link.vue b/app/assets/javascripts/vue_shared/components/web_ide_link.vue
index cac0d5a45c9..6d179b3dc92 100644
--- a/app/assets/javascripts/vue_shared/components/web_ide_link.vue
+++ b/app/assets/javascripts/vue_shared/components/web_ide_link.vue
@@ -10,6 +10,21 @@ const KEY_WEB_IDE = 'webide';
const KEY_GITPOD = 'gitpod';
const KEY_PIPELINE_EDITOR = 'pipeline_editor';
+export const i18n = {
+ modal: {
+ title: __('Enable Gitpod?'),
+ content: s__(
+ 'Gitpod|To use Gitpod you must first enable the feature in the integrations section of your %{linkStart}user preferences%{linkEnd}.',
+ ),
+ actionCancelText: __('Cancel'),
+ actionPrimaryText: __('Enable Gitpod'),
+ },
+ webIdeText: s__('WebIDE|Quickly and easily edit multiple files in your project.'),
+ webIdeTooltip: s__(
+ 'WebIDE|Quickly and easily edit multiple files in your project. Press . to open',
+ ),
+};
+
export default {
components: {
ActionsButton,
@@ -19,16 +34,7 @@ export default {
GlLink,
ConfirmForkModal,
},
- i18n: {
- modal: {
- title: __('Enable Gitpod?'),
- content: s__(
- 'Gitpod|To use Gitpod you must first enable the feature in the integrations section of your %{linkStart}user preferences%{linkEnd}.',
- ),
- actionCancelText: __('Cancel'),
- actionPrimaryText: __('Enable Gitpod'),
- },
- },
+ i18n,
props: {
isFork: {
type: Boolean,
@@ -207,8 +213,8 @@ export default {
return {
key: KEY_WEB_IDE,
text: this.webIdeActionText,
- secondaryText: __('Quickly and easily edit multiple files in your project.'),
- tooltip: '',
+ secondaryText: this.$options.i18n.webIdeText,
+ tooltip: this.$options.i18n.webIdeTooltip,
attrs: {
'data-qa-selector': 'web_ide_button',
'data-track-action': 'click_consolidated_edit_ide',
diff --git a/app/models/oauth_access_token.rb b/app/models/oauth_access_token.rb
index 87e82c04783..7d71e15d3c5 100644
--- a/app/models/oauth_access_token.rb
+++ b/app/models/oauth_access_token.rb
@@ -16,4 +16,14 @@ class OauthAccessToken < Doorkeeper::AccessToken
super
end
end
+
+ # this method overrides a shortcoming upstream, more context:
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/367888
+ def self.find_by_fallback_token(attr, plain_secret)
+ return unless fallback_secret_strategy && fallback_secret_strategy == Doorkeeper::SecretStoring::Plain
+ # token is hashed, don't allow plaintext comparison
+ return if plain_secret.starts_with?("$")
+
+ super
+ end
end
diff --git a/config/feature_flags/development/hash_oauth_tokens.yml b/config/feature_flags/development/hash_oauth_tokens.yml
new file mode 100644
index 00000000000..43cd5672fc4
--- /dev/null
+++ b/config/feature_flags/development/hash_oauth_tokens.yml
@@ -0,0 +1,8 @@
+---
+name: hash_oauth_tokens
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91501
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/367570
+milestone: '15.3'
+type: development
+group: group::authentication and authorization
+default_enabled: false
diff --git a/config/initializers/doorkeeper.rb b/config/initializers/doorkeeper.rb
index 761904009bb..867f3fd47cc 100644
--- a/config/initializers/doorkeeper.rb
+++ b/config/initializers/doorkeeper.rb
@@ -90,6 +90,8 @@ Doorkeeper.configure do
# Check out the wiki for more information on customization
access_token_methods :from_access_token_param, :from_bearer_authorization, :from_bearer_param
+ hash_token_secrets using: '::Gitlab::DoorkeeperSecretStoring::Pbkdf2Sha512', fallback: :plain
+
# Specify what grant flows are enabled in array of Strings. The valid
# strings and the flows they enable are:
#
diff --git a/doc/development/documentation/testing.md b/doc/development/documentation/testing.md
index 1a678873509..85219ec0364 100644
--- a/doc/development/documentation/testing.md
+++ b/doc/development/documentation/testing.md
@@ -81,6 +81,36 @@ This requires you to either:
### Documentation link tests
+Merge requests containing changes to Markdown (`.md`) files run a `docs-lint links`
+job, which runs two types of link checks. In both cases, links with destinations
+that begin with `http` or `https` are considered external links, and skipped:
+
+- `bundle exec nanoc check internal_links`: Tests links to internal pages.
+- `bundle exec nanoc check internal_anchors`: Tests links to subheadings (anchors) on internal pages.
+
+Failures from these tests are displayed at the end of the test results in the **Issues found!** area.
+For example, failures in the `internal_anchors` test follow this format:
+
+```plaintext
+[ ERROR ] internal_anchors - Broken anchor detected!
+ - source file `/tmp/gitlab-docs/public/ee/user/application_security/api_fuzzing/index.html`
+ - destination `/tmp/gitlab-docs/public/ee/development/code_review.html`
+ - link `../../../development/code_review.html#review-response-slo`
+ - anchor `#review-response-slo`
+```
+
+- **Source file**: The full path to the file containing the error. To find the
+ file in the `gitlab` repository, replace `/tmp/gitlab-docs/public/ee` with `doc`, and `.html` with `.md`.
+- **Destination**: The full path to the file not found by the test. To find the
+ file in the `gitlab` repository, replace `/tmp/gitlab-docs/public/ee` with `doc`, and `.html` with `.md`.
+- **Link**: The actual link the script attempted to find.
+- **Anchor**: If present, the subheading (anchor) the script attempted to find.
+
+Check for multiple instances of the same broken link on each page reporting an error.
+Even if a specific broken link appears multiple times on a page, the test reports it only once.
+
+#### Run document link tests locally
+
To execute documentation link tests locally:
1. Navigate to the [`gitlab-docs`](https://gitlab.com/gitlab-org/gitlab-docs) directory.
diff --git a/lib/gitlab/doorkeeper_secret_storing/pbkdf2_sha512.rb b/lib/gitlab/doorkeeper_secret_storing/pbkdf2_sha512.rb
new file mode 100644
index 00000000000..4bfb5f9e64c
--- /dev/null
+++ b/lib/gitlab/doorkeeper_secret_storing/pbkdf2_sha512.rb
@@ -0,0 +1,28 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module DoorkeeperSecretStoring
+ class Pbkdf2Sha512 < ::Doorkeeper::SecretStoring::Base
+ STRETCHES = 20_000
+ # An empty salt is used because we need to look tokens up solely by
+ # their hashed value. Additionally, tokens are always cryptographically
+ # pseudo-random and unique, therefore salting provides no
+ # additional security.
+ SALT = ''
+
+ def self.transform_secret(plain_secret)
+ return plain_secret unless Feature.enabled?(:hash_oauth_tokens)
+
+ Devise::Pbkdf2Encryptable::Encryptors::Pbkdf2Sha512.digest(plain_secret, STRETCHES, SALT)
+ end
+
+ ##
+ # Determines whether this strategy supports restoring
+ # secrets from the database. This allows detecting users
+ # trying to use a non-restorable strategy with +reuse_access_tokens+.
+ def self.allows_restoring_secrets?
+ false
+ end
+ end
+ end
+end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index c0b5cabf983..9f9d7c7665e 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -32068,9 +32068,6 @@ msgstr ""
msgid "Quick range"
msgstr ""
-msgid "Quickly and easily edit multiple files in your project."
-msgstr ""
-
msgid "Quota of CI/CD minutes"
msgstr ""
@@ -43720,6 +43717,12 @@ msgstr ""
msgid "WebIDE|Merge request"
msgstr ""
+msgid "WebIDE|Quickly and easily edit multiple files in your project."
+msgstr ""
+
+msgid "WebIDE|Quickly and easily edit multiple files in your project. Press . to open"
+msgstr ""
+
msgid "WebIDE|This project does not accept unsigned commits."
msgstr ""
diff --git a/spec/frontend/blob/components/blob_header_default_actions_spec.js b/spec/frontend/blob/components/blob_header_default_actions_spec.js
index 2382ac15f40..0f015715dc2 100644
--- a/spec/frontend/blob/components/blob_header_default_actions_spec.js
+++ b/spec/frontend/blob/components/blob_header_default_actions_spec.js
@@ -71,7 +71,7 @@ describe('Blob Header Default Actions', () => {
});
buttons = wrapper.findAllComponents(GlButton);
- expect(buttons.at(0).attributes('disabled')).toBeTruthy();
+ expect(buttons.at(0).attributes('disabled')).toBe('true');
});
it('does not render the copy button if a rendering error is set', () => {
diff --git a/spec/frontend/blob/sketch/index_spec.js b/spec/frontend/blob/sketch/index_spec.js
index 5e1922a24f4..e8d1f724c4b 100644
--- a/spec/frontend/blob/sketch/index_spec.js
+++ b/spec/frontend/blob/sketch/index_spec.js
@@ -69,7 +69,7 @@ describe('Sketch viewer', () => {
const img = document.querySelector('#js-sketch-viewer img');
expect(img).not.toBeNull();
- expect(img.classList.contains('img-fluid')).toBeTruthy();
+ expect(img.classList.contains('img-fluid')).toBe(true);
});
it('renders link to image', () => {
diff --git a/spec/frontend/design_management/components/delete_button_spec.js b/spec/frontend/design_management/components/delete_button_spec.js
index e3907fdbe15..cee1eec792d 100644
--- a/spec/frontend/design_management/components/delete_button_spec.js
+++ b/spec/frontend/design_management/components/delete_button_spec.js
@@ -6,8 +6,8 @@ import BatchDeleteButton from '~/design_management/components/delete_button.vue'
describe('Batch delete button component', () => {
let wrapper;
- const findButton = () => wrapper.find(GlButton);
- const findModal = () => wrapper.find(GlModal);
+ const findButton = () => wrapper.findComponent(GlButton);
+ const findModal = () => wrapper.findComponent(GlModal);
function createComponent({ isDeleting = false } = {}, { slots = {} } = {}) {
wrapper = shallowMount(BatchDeleteButton, {
diff --git a/spec/frontend/design_management/components/design_notes/design_discussion_spec.js b/spec/frontend/design_management/components/design_notes/design_discussion_spec.js
index ae2dc23a94d..2091e1e08dd 100644
--- a/spec/frontend/design_management/components/design_notes/design_discussion_spec.js
+++ b/spec/frontend/design_management/components/design_notes/design_discussion_spec.js
@@ -26,13 +26,13 @@ describe('Design discussions component', () => {
const originalGon = window.gon;
let wrapper;
- const findDesignNotes = () => wrapper.findAll(DesignNote);
- const findReplyPlaceholder = () => wrapper.find(ReplyPlaceholder);
- const findReplyForm = () => wrapper.find(DesignReplyForm);
- const findRepliesWidget = () => wrapper.find(ToggleRepliesWidget);
+ const findDesignNotes = () => wrapper.findAllComponents(DesignNote);
+ const findReplyPlaceholder = () => wrapper.findComponent(ReplyPlaceholder);
+ const findReplyForm = () => wrapper.findComponent(DesignReplyForm);
+ const findRepliesWidget = () => wrapper.findComponent(ToggleRepliesWidget);
const findResolveButton = () => wrapper.find('[data-testid="resolve-button"]');
const findResolvedMessage = () => wrapper.find('[data-testid="resolved-message"]');
- const findResolveLoadingIcon = () => wrapper.find(GlLoadingIcon);
+ const findResolveLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
const findResolveCheckbox = () => wrapper.find('[data-testid="resolve-checkbox"]');
const findApolloMutation = () => wrapper.findComponent(ApolloMutation);
@@ -307,7 +307,7 @@ describe('Design discussions component', () => {
expect(
wrapper
- .findAll(DesignNote)
+ .findAllComponents(DesignNote)
.wrappers.every((designNote) => designNote.classes('gl-bg-blue-50')),
).toBe(true);
},
diff --git a/spec/frontend/design_management/components/design_notes/design_note_spec.js b/spec/frontend/design_management/components/design_notes/design_note_spec.js
index 1f84fde9f7f..28833b4af5c 100644
--- a/spec/frontend/design_management/components/design_notes/design_note_spec.js
+++ b/spec/frontend/design_management/components/design_notes/design_note_spec.js
@@ -100,7 +100,7 @@ describe('Design note component', () => {
note,
});
- expect(wrapper.find(TimeAgoTooltip).exists()).toBe(true);
+ expect(wrapper.findComponent(TimeAgoTooltip).exists()).toBe(true);
});
it('should not render edit icon when user does not have a permission', () => {
diff --git a/spec/frontend/design_management/components/design_notes/design_reply_form_spec.js b/spec/frontend/design_management/components/design_notes/design_reply_form_spec.js
index 38dd2df01a3..f7ce742b933 100644
--- a/spec/frontend/design_management/components/design_notes/design_reply_form_spec.js
+++ b/spec/frontend/design_management/components/design_notes/design_reply_form_spec.js
@@ -15,9 +15,9 @@ describe('Design reply form component', () => {
let wrapper;
const findTextarea = () => wrapper.find('textarea');
- const findSubmitButton = () => wrapper.find({ ref: 'submitButton' });
- const findCancelButton = () => wrapper.find({ ref: 'cancelButton' });
- const findModal = () => wrapper.find({ ref: 'cancelCommentModal' });
+ const findSubmitButton = () => wrapper.findComponent({ ref: 'submitButton' });
+ const findCancelButton = () => wrapper.findComponent({ ref: 'cancelButton' });
+ const findModal = () => wrapper.findComponent({ ref: 'cancelCommentModal' });
function createComponent(props = {}, mountOptions = {}) {
wrapper = mount(DesignReplyForm, {
diff --git a/spec/frontend/design_management/components/design_notes/toggle_replies_widget_spec.js b/spec/frontend/design_management/components/design_notes/toggle_replies_widget_spec.js
index f87228663b6..41129e2b58d 100644
--- a/spec/frontend/design_management/components/design_notes/toggle_replies_widget_spec.js
+++ b/spec/frontend/design_management/components/design_notes/toggle_replies_widget_spec.js
@@ -8,10 +8,10 @@ describe('Toggle replies widget component', () => {
let wrapper;
const findToggleWrapper = () => wrapper.find('[data-testid="toggle-comments-wrapper"]');
- const findIcon = () => wrapper.find(GlIcon);
- const findButton = () => wrapper.find(GlButton);
- const findAuthorLink = () => wrapper.find(GlLink);
- const findTimeAgo = () => wrapper.find(TimeAgoTooltip);
+ const findIcon = () => wrapper.findComponent(GlIcon);
+ const findButton = () => wrapper.findComponent(GlButton);
+ const findAuthorLink = () => wrapper.findComponent(GlLink);
+ const findTimeAgo = () => wrapper.findComponent(TimeAgoTooltip);
function createComponent(props = {}) {
wrapper = shallowMount(ToggleRepliesWidget, {
diff --git a/spec/frontend/design_management/components/design_scaler_spec.js b/spec/frontend/design_management/components/design_scaler_spec.js
index a04e2ebda5b..e1a66cea329 100644
--- a/spec/frontend/design_management/components/design_scaler_spec.js
+++ b/spec/frontend/design_management/components/design_scaler_spec.js
@@ -6,7 +6,7 @@ import DesignScaler from '~/design_management/components/design_scaler.vue';
describe('Design management design scaler component', () => {
let wrapper;
- const getButtons = () => wrapper.findAll(GlButton);
+ const getButtons = () => wrapper.findAllComponents(GlButton);
const getDecreaseScaleButton = () => getButtons().at(0);
const getResetScaleButton = () => getButtons().at(1);
const getIncreaseScaleButton = () => getButtons().at(2);
diff --git a/spec/frontend/design_management/components/design_sidebar_spec.js b/spec/frontend/design_management/components/design_sidebar_spec.js
index f13796138bd..af995f75ddc 100644
--- a/spec/frontend/design_management/components/design_sidebar_spec.js
+++ b/spec/frontend/design_management/components/design_sidebar_spec.js
@@ -32,12 +32,12 @@ describe('Design management design sidebar component', () => {
const originalGon = window.gon;
let wrapper;
- const findDiscussions = () => wrapper.findAll(DesignDiscussion);
+ const findDiscussions = () => wrapper.findAllComponents(DesignDiscussion);
const findFirstDiscussion = () => findDiscussions().at(0);
const findUnresolvedDiscussions = () => wrapper.findAll('[data-testid="unresolved-discussion"]');
const findResolvedDiscussions = () => wrapper.findAll('[data-testid="resolved-discussion"]');
- const findParticipants = () => wrapper.find(Participants);
- const findResolvedCommentsToggle = () => wrapper.find(GlAccordionItem);
+ const findParticipants = () => wrapper.findComponent(Participants);
+ const findResolvedCommentsToggle = () => wrapper.findComponent(GlAccordionItem);
const findNewDiscussionDisclaimer = () =>
wrapper.find('[data-testid="new-discussion-disclaimer"]');
@@ -87,7 +87,7 @@ describe('Design management design sidebar component', () => {
it('renders To-Do button', () => {
createComponent();
- expect(wrapper.find(DesignTodoButton).exists()).toBe(true);
+ expect(wrapper.findComponent(DesignTodoButton).exists()).toBe(true);
});
describe('when has no discussions', () => {
diff --git a/spec/frontend/design_management/components/design_todo_button_spec.js b/spec/frontend/design_management/components/design_todo_button_spec.js
index 73661c9fcb0..b3afcefe1ed 100644
--- a/spec/frontend/design_management/components/design_todo_button_spec.js
+++ b/spec/frontend/design_management/components/design_todo_button_spec.js
@@ -57,7 +57,7 @@ describe('Design management design todo button', () => {
});
it('renders TodoButton component', () => {
- expect(wrapper.find(TodoButton).exists()).toBe(true);
+ expect(wrapper.findComponent(TodoButton).exists()).toBe(true);
});
describe('when design has a pending todo', () => {
diff --git a/spec/frontend/design_management/components/image_spec.js b/spec/frontend/design_management/components/image_spec.js
index 65ee0ae6238..8163cb0d87a 100644
--- a/spec/frontend/design_management/components/image_spec.js
+++ b/spec/frontend/design_management/components/image_spec.js
@@ -71,7 +71,7 @@ describe('Design management large image component', () => {
image.trigger('error');
await nextTick();
expect(image.isVisible()).toBe(false);
- expect(wrapper.find(GlIcon).element).toMatchSnapshot();
+ expect(wrapper.findComponent(GlIcon).element).toMatchSnapshot();
});
describe('zoom', () => {
diff --git a/spec/frontend/design_management/components/list/item_spec.js b/spec/frontend/design_management/components/list/item_spec.js
index e00dda2015e..66d3f883960 100644
--- a/spec/frontend/design_management/components/list/item_spec.js
+++ b/spec/frontend/design_management/components/list/item_spec.js
@@ -23,8 +23,8 @@ describe('Design management list item component', () => {
const findDesignEvent = () => wrapper.findByTestId('design-event');
const findImgFilename = (id = imgId) => wrapper.findByTestId(`design-img-filename-${id}`);
- const findEventIcon = () => findDesignEvent().find(GlIcon);
- const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
+ const findEventIcon = () => findDesignEvent().findComponent(GlIcon);
+ const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
function createComponent({
notesCount = 0,
@@ -74,7 +74,7 @@ describe('Design management list item component', () => {
beforeEach(async () => {
createComponent();
image = wrapper.find('img');
- glIntersectionObserver = wrapper.find(GlIntersectionObserver);
+ glIntersectionObserver = wrapper.findComponent(GlIntersectionObserver);
glIntersectionObserver.vm.$emit('appear');
await nextTick();
@@ -86,7 +86,7 @@ describe('Design management list item component', () => {
describe('before image is loaded', () => {
it('renders loading spinner', () => {
- expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
+ expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(true);
});
});
@@ -105,7 +105,7 @@ describe('Design management list item component', () => {
image.trigger('error');
await nextTick();
expect(image.isVisible()).toBe(false);
- expect(wrapper.find(GlIcon).element).toMatchSnapshot();
+ expect(wrapper.findComponent(GlIcon).element).toMatchSnapshot();
});
describe('when imageV432x230 and image provided', () => {
diff --git a/spec/frontend/design_management/components/toolbar/index_spec.js b/spec/frontend/design_management/components/toolbar/index_spec.js
index 412f3de911e..b6137ba2eee 100644
--- a/spec/frontend/design_management/components/toolbar/index_spec.js
+++ b/spec/frontend/design_management/components/toolbar/index_spec.js
@@ -85,35 +85,35 @@ describe('Design management toolbar component', () => {
createComponent();
await nextTick();
- expect(wrapper.find(DeleteButton).exists()).toBe(true);
+ expect(wrapper.findComponent(DeleteButton).exists()).toBe(true);
});
it('does not render delete button on non-latest version', async () => {
createComponent(false, true, { isLatestVersion: false });
await nextTick();
- expect(wrapper.find(DeleteButton).exists()).toBe(false);
+ expect(wrapper.findComponent(DeleteButton).exists()).toBe(false);
});
it('does not render delete button when user is not logged in', async () => {
createComponent(false, false);
await nextTick();
- expect(wrapper.find(DeleteButton).exists()).toBe(false);
+ expect(wrapper.findComponent(DeleteButton).exists()).toBe(false);
});
it('emits `delete` event on deleteButton `delete-selected-designs` event', async () => {
createComponent();
await nextTick();
- wrapper.find(DeleteButton).vm.$emit('delete-selected-designs');
+ wrapper.findComponent(DeleteButton).vm.$emit('delete-selected-designs');
expect(wrapper.emitted().delete).toBeTruthy();
});
it('renders download button with correct link', () => {
createComponent();
- expect(wrapper.find(GlButton).attributes('href')).toBe(
+ expect(wrapper.findComponent(GlButton).attributes('href')).toBe(
'/-/designs/306/7f747adcd4693afadbe968d7ba7d983349b9012d',
);
});
diff --git a/spec/frontend/design_management/components/upload/button_spec.js b/spec/frontend/design_management/components/upload/button_spec.js
index d123db43ce6..59821218ab8 100644
--- a/spec/frontend/design_management/components/upload/button_spec.js
+++ b/spec/frontend/design_management/components/upload/button_spec.js
@@ -34,7 +34,7 @@ describe('Design management upload button component', () => {
it('Button `loading` prop is `true`', () => {
createComponent({ isSaving: true });
- const button = wrapper.find(GlButton);
+ const button = wrapper.findComponent(GlButton);
expect(button.exists()).toBe(true);
expect(button.props('loading')).toBe(true);
});
diff --git a/spec/frontend/design_management/components/upload/design_version_dropdown_spec.js b/spec/frontend/design_management/components/upload/design_version_dropdown_spec.js
index ec5db04bb80..7c26ab9739b 100644
--- a/spec/frontend/design_management/components/upload/design_version_dropdown_spec.js
+++ b/spec/frontend/design_management/components/upload/design_version_dropdown_spec.js
@@ -46,7 +46,7 @@ describe('Design management design version dropdown component', () => {
wrapper.destroy();
});
- const findVersionLink = (index) => wrapper.findAll(GlDropdownItem).at(index);
+ const findVersionLink = (index) => wrapper.findAllComponents(GlDropdownItem).at(index);
it('renders design version dropdown button', async () => {
createComponent();
@@ -76,35 +76,35 @@ describe('Design management design version dropdown component', () => {
createComponent();
await nextTick();
- expect(wrapper.find(GlDropdown).attributes('text')).toBe('Showing latest version');
+ expect(wrapper.findComponent(GlDropdown).attributes('text')).toBe('Showing latest version');
});
it('displays latest version text when only 1 version is present', async () => {
createComponent({ maxVersions: 1 });
await nextTick();
- expect(wrapper.find(GlDropdown).attributes('text')).toBe('Showing latest version');
+ expect(wrapper.findComponent(GlDropdown).attributes('text')).toBe('Showing latest version');
});
it('displays version text when the current version is not the latest', async () => {
createComponent({ $route: designRouteFactory(PREVIOUS_VERSION_ID) });
await nextTick();
- expect(wrapper.find(GlDropdown).attributes('text')).toBe(`Showing version #1`);
+ expect(wrapper.findComponent(GlDropdown).attributes('text')).toBe(`Showing version #1`);
});
it('displays latest version text when the current version is the latest', async () => {
createComponent({ $route: designRouteFactory(LATEST_VERSION_ID) });
await nextTick();
- expect(wrapper.find(GlDropdown).attributes('text')).toBe('Showing latest version');
+ expect(wrapper.findComponent(GlDropdown).attributes('text')).toBe('Showing latest version');
});
it('should have the same length as apollo query', async () => {
createComponent();
await nextTick();
- expect(wrapper.findAll(GlDropdownItem)).toHaveLength(wrapper.vm.allVersions.length);
+ expect(wrapper.findAllComponents(GlDropdownItem)).toHaveLength(wrapper.vm.allVersions.length);
});
it('should render TimeAgo', async () => {
diff --git a/spec/frontend/design_management/pages/design/index_spec.js b/spec/frontend/design_management/pages/design/index_spec.js
index 17a299c5de1..774e37a8b21 100644
--- a/spec/frontend/design_management/pages/design/index_spec.js
+++ b/spec/frontend/design_management/pages/design/index_spec.js
@@ -85,9 +85,9 @@ describe('Design management design index page', () => {
let wrapper;
let router;
- const findDiscussionForm = () => wrapper.find(DesignReplyForm);
- const findSidebar = () => wrapper.find(DesignSidebar);
- const findDesignPresentation = () => wrapper.find(DesignPresentation);
+ const findDiscussionForm = () => wrapper.findComponent(DesignReplyForm);
+ const findSidebar = () => wrapper.findComponent(DesignSidebar);
+ const findDesignPresentation = () => wrapper.findComponent(DesignPresentation);
function createComponent(
{ loading = false } = {},
@@ -181,15 +181,15 @@ describe('Design management design index page', () => {
it('sets loading state', () => {
createComponent({ loading: true });
- expect(wrapper.find(DesignPresentation).props('isLoading')).toBe(true);
- expect(wrapper.find(DesignSidebar).props('isLoading')).toBe(true);
+ expect(wrapper.findComponent(DesignPresentation).props('isLoading')).toBe(true);
+ expect(wrapper.findComponent(DesignSidebar).props('isLoading')).toBe(true);
});
it('renders design index', () => {
createComponent({ loading: false }, { data: { design } });
expect(wrapper.element).toMatchSnapshot();
- expect(wrapper.find(GlAlert).exists()).toBe(false);
+ expect(wrapper.findComponent(GlAlert).exists()).toBe(false);
});
it('passes correct props to sidebar component', () => {
diff --git a/spec/frontend/design_management/pages/index_spec.js b/spec/frontend/design_management/pages/index_spec.js
index 321d55cbaef..f90feaadfb0 100644
--- a/spec/frontend/design_management/pages/index_spec.js
+++ b/spec/frontend/design_management/pages/index_spec.js
@@ -111,8 +111,8 @@ describe('Design management index page', () => {
const findDropzoneWrapper = () => wrapper.findByTestId('design-dropzone-wrapper');
const findFirstDropzoneWithDesign = () => wrapper.findAllComponents(DesignDropzone).at(1);
const findDesignsWrapper = () => wrapper.findByTestId('designs-root');
- const findDesigns = () => wrapper.findAll(Design);
- const draggableAttributes = () => wrapper.find(VueDraggable).vm.$attrs;
+ const findDesigns = () => wrapper.findAllComponents(Design);
+ const draggableAttributes = () => wrapper.findComponent(VueDraggable).vm.$attrs;
const findDesignUploadButton = () => wrapper.findByTestId('design-upload-button');
const findDesignToolbarWrapper = () => wrapper.findByTestId('design-toolbar-wrapper');
const findDesignUpdateAlert = () => wrapper.findByTestId('design-update-alert');
@@ -120,8 +120,8 @@ describe('Design management index page', () => {
async function moveDesigns(localWrapper) {
await waitForPromises();
- localWrapper.find(VueDraggable).vm.$emit('input', reorderedDesigns);
- localWrapper.find(VueDraggable).vm.$emit('change', {
+ localWrapper.findComponent(VueDraggable).vm.$emit('input', reorderedDesigns);
+ localWrapper.findComponent(VueDraggable).vm.$emit('change', {
moved: {
newIndex: 0,
element: designToMove,
diff --git a/spec/frontend/design_management/router_spec.js b/spec/frontend/design_management/router_spec.js
index b9c62334223..b9edde559c8 100644
--- a/spec/frontend/design_management/router_spec.js
+++ b/spec/frontend/design_management/router_spec.js
@@ -44,7 +44,7 @@ describe('Design management router', () => {
it('pushes home component', () => {
const wrapper = factory(routeArg);
- expect(wrapper.find(Designs).exists()).toBe(true);
+ expect(wrapper.findComponent(Designs).exists()).toBe(true);
});
});
@@ -55,7 +55,7 @@ describe('Design management router', () => {
const wrapper = factory(routeArg);
return nextTick().then(() => {
- const detail = wrapper.find(DesignDetail);
+ const detail = wrapper.findComponent(DesignDetail);
expect(detail.exists()).toBe(true);
expect(detail.props('id')).toEqual('1');
});
diff --git a/spec/frontend/diffs/components/diff_file_header_spec.js b/spec/frontend/diffs/components/diff_file_header_spec.js
index d90afeb6b82..92b8b2d4aa3 100644
--- a/spec/frontend/diffs/components/diff_file_header_spec.js
+++ b/spec/frontend/diffs/components/diff_file_header_spec.js
@@ -263,7 +263,7 @@ describe('DiffFileHeader component', () => {
},
},
});
- expect(findModeChangedLine().exists()).toBeFalsy();
+ expect(findModeChangedLine().exists()).toBe(false);
},
);
diff --git a/spec/frontend/ide/components/shared/commit_message_field_spec.js b/spec/frontend/ide/components/shared/commit_message_field_spec.js
index f4f9b95b233..94da06f4cb2 100644
--- a/spec/frontend/ide/components/shared/commit_message_field_spec.js
+++ b/spec/frontend/ide/components/shared/commit_message_field_spec.js
@@ -79,7 +79,7 @@ describe('CommitMessageField', () => {
await fillText(text);
expect(findHighlightsText().text()).toEqual(text);
- expect(findHighlightsMark().text()).toBeFalsy();
+ expect(findHighlightsMark().text()).toBe('');
});
it('highlights characters over 50 length', async () => {
diff --git a/spec/frontend/ide/stores/actions/file_spec.js b/spec/frontend/ide/stores/actions/file_spec.js
index 6c1dee1e5ca..d1c31cd412b 100644
--- a/spec/frontend/ide/stores/actions/file_spec.js
+++ b/spec/frontend/ide/stores/actions/file_spec.js
@@ -60,8 +60,8 @@ describe('IDE store file actions', () => {
it('closes open files', () => {
return store.dispatch('closeFile', localFile).then(() => {
- expect(localFile.opened).toBeFalsy();
- expect(localFile.active).toBeFalsy();
+ expect(localFile.opened).toBe(false);
+ expect(localFile.active).toBe(false);
expect(store.state.openFiles.length).toBe(0);
});
});
@@ -269,7 +269,7 @@ describe('IDE store file actions', () => {
it('sets the file as active', () => {
return store.dispatch('getFileData', { path: localFile.path }).then(() => {
- expect(localFile.active).toBeTruthy();
+ expect(localFile.active).toBe(true);
});
});
@@ -277,7 +277,7 @@ describe('IDE store file actions', () => {
return store
.dispatch('getFileData', { path: localFile.path, makeFileActive: false })
.then(() => {
- expect(localFile.active).toBeFalsy();
+ expect(localFile.active).toBe(false);
});
});
diff --git a/spec/frontend/projects/commits/components/author_select_spec.js b/spec/frontend/projects/commits/components/author_select_spec.js
index 436262ff461..57e5ef0ed1d 100644
--- a/spec/frontend/projects/commits/components/author_select_spec.js
+++ b/spec/frontend/projects/commits/components/author_select_spec.js
@@ -71,7 +71,7 @@ describe('Author Select', () => {
wrapper.setData({ hasSearchParam: true });
await nextTick();
- expect(findDropdownContainer().attributes('disabled')).toBe(undefined);
+ expect(findDropdownContainer().attributes('disabled')).toBeUndefined();
});
it('has correct tooltip message', async () => {
@@ -91,7 +91,7 @@ describe('Author Select', () => {
wrapper.setData({ hasSearchParam: false });
await nextTick();
- expect(findDropdown().attributes('disabled')).toBe(undefined);
+ expect(findDropdown().attributes('disabled')).toBeUndefined();
});
it('hasSearchParam if user types a truthy string', () => {
diff --git a/spec/frontend/vue_merge_request_widget/components/states/mr_widget_wip_spec.js b/spec/frontend/vue_merge_request_widget/components/states/mr_widget_wip_spec.js
index e4ffa37a84d..af52901f508 100644
--- a/spec/frontend/vue_merge_request_widget/components/states/mr_widget_wip_spec.js
+++ b/spec/frontend/vue_merge_request_widget/components/states/mr_widget_wip_spec.js
@@ -26,11 +26,11 @@ describe('Wip', () => {
it('should have props', () => {
const { mr, service } = WorkInProgress.props;
- expect(mr.type instanceof Object).toBeTruthy();
- expect(mr.required).toBeTruthy();
+ expect(mr.type instanceof Object).toBe(true);
+ expect(mr.required).toBe(true);
- expect(service.type instanceof Object).toBeTruthy();
- expect(service.required).toBeTruthy();
+ expect(service.type instanceof Object).toBe(true);
+ expect(service.required).toBe(true);
});
});
@@ -64,7 +64,7 @@ describe('Wip', () => {
await waitForPromises();
- expect(vm.isMakingRequest).toBeTruthy();
+ expect(vm.isMakingRequest).toBe(true);
expect(eventHub.$emit).toHaveBeenCalledWith('UpdateWidgetData', mrObj);
expect(toast).toHaveBeenCalledWith('Marked as ready. Merging is now allowed.');
});
@@ -81,7 +81,7 @@ describe('Wip', () => {
});
it('should have correct elements', () => {
- expect(el.classList.contains('mr-widget-body')).toBeTruthy();
+ expect(el.classList.contains('mr-widget-body')).toBe(true);
expect(el.innerText).toContain(
"Merge blocked: merge request must be marked as ready. It's still marked as draft.",
);
@@ -95,7 +95,7 @@ describe('Wip', () => {
await nextTick();
- expect(el.querySelector('.js-remove-draft')).toEqual(null);
+ expect(el.querySelector('.js-remove-draft')).toBeNull();
});
});
});
diff --git a/spec/frontend/vue_shared/components/confirm_modal_spec.js b/spec/frontend/vue_shared/components/confirm_modal_spec.js
index 0af789c78df..c1e682a1aae 100644
--- a/spec/frontend/vue_shared/components/confirm_modal_spec.js
+++ b/spec/frontend/vue_shared/components/confirm_modal_spec.js
@@ -104,7 +104,7 @@ describe('vue_shared/components/confirm_modal', () => {
});
it('renders GlModal with data', () => {
- expect(findModal().exists()).toBeTruthy();
+ expect(findModal().exists()).toBe(true);
expect(findModal().attributes()).toEqual(
expect.objectContaining({
oktitle: MOCK_MODAL_DATA.modalAttributes.okTitle,
diff --git a/spec/frontend/vue_shared/components/runner_instructions/runner_instructions_modal_spec.js b/spec/frontend/vue_shared/components/runner_instructions/runner_instructions_modal_spec.js
index 112a0e67a0f..7c5fc63856a 100644
--- a/spec/frontend/vue_shared/components/runner_instructions/runner_instructions_modal_spec.js
+++ b/spec/frontend/vue_shared/components/runner_instructions/runner_instructions_modal_spec.js
@@ -234,14 +234,14 @@ describe('RunnerInstructionsModal component', () => {
MockResizeObserver.mockResize('xs');
await nextTick();
- expect(findPlatformButtonGroup().attributes('vertical')).toBeTruthy();
+ expect(findPlatformButtonGroup().attributes('vertical')).toEqual('true');
});
it('to a non-xs viewport', async () => {
MockResizeObserver.mockResize('sm');
await nextTick();
- expect(findPlatformButtonGroup().props('vertical')).toBeFalsy();
+ expect(findPlatformButtonGroup().props('vertical')).toBeUndefined();
});
});
});
diff --git a/spec/frontend/vue_shared/components/web_ide_link_spec.js b/spec/frontend/vue_shared/components/web_ide_link_spec.js
index 41163aef320..a0b868d1d52 100644
--- a/spec/frontend/vue_shared/components/web_ide_link_spec.js
+++ b/spec/frontend/vue_shared/components/web_ide_link_spec.js
@@ -3,7 +3,7 @@ import { nextTick } from 'vue';
import ActionsButton from '~/vue_shared/components/actions_button.vue';
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
-import WebIdeLink from '~/vue_shared/components/web_ide_link.vue';
+import WebIdeLink, { i18n } from '~/vue_shared/components/web_ide_link.vue';
import ConfirmForkModal from '~/vue_shared/components/confirm_fork_modal.vue';
import { stubComponent } from 'helpers/stub_component';
@@ -37,8 +37,8 @@ const ACTION_EDIT_CONFIRM_FORK = {
const ACTION_WEB_IDE = {
href: TEST_WEB_IDE_URL,
key: 'webide',
- secondaryText: 'Quickly and easily edit multiple files in your project.',
- tooltip: '',
+ secondaryText: i18n.webIdeText,
+ tooltip: i18n.webIdeTooltip,
text: 'Web IDE',
attrs: {
'data-qa-selector': 'web_ide_button',
diff --git a/spec/lib/gitlab/auth/auth_finders_spec.rb b/spec/lib/gitlab/auth/auth_finders_spec.rb
index e985f66bfe9..d0b44135a2f 100644
--- a/spec/lib/gitlab/auth/auth_finders_spec.rb
+++ b/spec/lib/gitlab/auth/auth_finders_spec.rb
@@ -127,7 +127,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do
let(:doorkeeper_access_token) { Doorkeeper::AccessToken.create!(application_id: application.id, resource_owner_id: user.id, scopes: 'api') }
before do
- set_bearer_token(doorkeeper_access_token.token)
+ set_bearer_token(doorkeeper_access_token.plaintext_token)
end
it { is_expected.to eq user }
@@ -577,7 +577,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do
context 'passed as header' do
before do
- set_bearer_token(doorkeeper_access_token.token)
+ set_bearer_token(doorkeeper_access_token.plaintext_token)
end
it 'returns token if valid oauth_access_token' do
@@ -587,7 +587,7 @@ RSpec.describe Gitlab::Auth::AuthFinders do
context 'passed as param' do
it 'returns user if valid oauth_access_token' do
- set_param(:access_token, doorkeeper_access_token.token)
+ set_param(:access_token, doorkeeper_access_token.plaintext_token)
expect(find_oauth_access_token.token).to eq doorkeeper_access_token.token
end
diff --git a/spec/lib/gitlab/doorkeeper_secret_storing/pbkdf2_sha512_spec.rb b/spec/lib/gitlab/doorkeeper_secret_storing/pbkdf2_sha512_spec.rb
new file mode 100644
index 00000000000..e953733c997
--- /dev/null
+++ b/spec/lib/gitlab/doorkeeper_secret_storing/pbkdf2_sha512_spec.rb
@@ -0,0 +1,36 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::DoorkeeperSecretStoring::Pbkdf2Sha512 do
+ describe '.transform_secret' do
+ let(:plaintext_token) { 'CzOBzBfU9F-HvsqfTaTXF4ivuuxYZuv3BoAK4pnvmyw' }
+
+ it 'generates a PBKDF2+SHA512 hashed value in the correct format' do
+ expect(described_class.transform_secret(plaintext_token))
+ .to eq("$pbkdf2-sha512$20000$$.c0G5XJVEew1TyeJk5TrkvB0VyOaTmDzPrsdNRED9vVeZlSyuG3G90F0ow23zUCiWKAVwmNnR/ceh.nJG3MdpQ") # rubocop:disable Layout/LineLength
+ end
+
+ context 'when hash_oauth_tokens is disabled' do
+ before do
+ stub_feature_flags(hash_oauth_tokens: false)
+ end
+
+ it 'returns a plaintext token' do
+ expect(described_class.transform_secret(plaintext_token)).to eq(plaintext_token)
+ end
+ end
+ end
+
+ describe 'STRETCHES' do
+ it 'is 20_000' do
+ expect(described_class::STRETCHES).to eq(20_000)
+ end
+ end
+
+ describe 'SALT' do
+ it 'is empty' do
+ expect(described_class::SALT).to be_empty
+ end
+ end
+end
diff --git a/spec/models/oauth_access_token_spec.rb b/spec/models/oauth_access_token_spec.rb
index 2d617e0c7b3..544f6643712 100644
--- a/spec/models/oauth_access_token_spec.rb
+++ b/spec/models/oauth_access_token_spec.rb
@@ -22,4 +22,51 @@ RSpec.describe OauthAccessToken do
end
end
end
+
+ describe 'Doorkeeper secret storing' do
+ it 'stores the token in hashed format' do
+ expect(token.token).not_to eq(token.plaintext_token)
+ end
+
+ it 'does not allow falling back to plaintext token comparison' do
+ expect(described_class.by_token(token.token)).to be_nil
+ end
+
+ it 'finds a token by plaintext token' do
+ expect(described_class.by_token(token.plaintext_token)).to be_a(OauthAccessToken)
+ end
+
+ context 'when the token is stored in plaintext' do
+ let(:plaintext_token) { Devise.friendly_token(20) }
+
+ before do
+ token.update_column(:token, plaintext_token)
+ end
+
+ it 'falls back to plaintext token comparison' do
+ expect(described_class.by_token(plaintext_token)).to be_a(OauthAccessToken)
+ end
+ end
+
+ context 'when hash_oauth_secrets is disabled' do
+ let(:hashed_token) { create(:oauth_access_token, application_id: app_one.id) }
+
+ before do
+ hashed_token
+ stub_feature_flags(hash_oauth_tokens: false)
+ end
+
+ it 'stores the token in plaintext' do
+ expect(token.token).to eq(token.plaintext_token)
+ end
+
+ it 'finds a token by plaintext token' do
+ expect(described_class.by_token(token.plaintext_token)).to be_a(OauthAccessToken)
+ end
+
+ it 'does not find a token that was previously stored as hashed' do
+ expect(described_class.by_token(hashed_token.plaintext_token)).to be_nil
+ end
+ end
+ end
end
diff --git a/spec/requests/api/doorkeeper_access_spec.rb b/spec/requests/api/doorkeeper_access_spec.rb
index 77f1dadff46..14da9a600cd 100644
--- a/spec/requests/api/doorkeeper_access_spec.rb
+++ b/spec/requests/api/doorkeeper_access_spec.rb
@@ -9,13 +9,13 @@ RSpec.describe 'doorkeeper access' do
describe "unauthenticated" do
it "returns authentication success" do
- get api("/user"), params: { access_token: token.token }
+ get api("/user"), params: { access_token: token.plaintext_token }
expect(response).to have_gitlab_http_status(:ok)
end
include_examples 'user login request with unique ip limit' do
def request
- get api('/user'), params: { access_token: token.token }
+ get api('/user'), params: { access_token: token.plaintext_token }
end
end
end
@@ -42,7 +42,7 @@ RSpec.describe 'doorkeeper access' do
shared_examples 'forbidden request' do
it 'returns 403 response' do
- get api("/user"), params: { access_token: token.token }
+ get api("/user"), params: { access_token: token.plaintext_token }
expect(response).to have_gitlab_http_status(:forbidden)
end
diff --git a/spec/requests/api/go_proxy_spec.rb b/spec/requests/api/go_proxy_spec.rb
index 2b1250320ce..7c44fddc303 100644
--- a/spec/requests/api/go_proxy_spec.rb
+++ b/spec/requests/api/go_proxy_spec.rb
@@ -376,7 +376,7 @@ RSpec.describe API::GoProxy do
end
it 'returns ok with a job token' do
- get_resource(oauth_access_token: job)
+ get_resource(access_token: job)
expect(response).to have_gitlab_http_status(:ok)
end
@@ -395,7 +395,7 @@ RSpec.describe API::GoProxy do
it 'returns unauthorized with a failed job token' do
job.update!(status: :failed)
- get_resource(oauth_access_token: job)
+ get_resource(access_token: job)
expect(response).to have_gitlab_http_status(:unauthorized)
end
@@ -445,7 +445,7 @@ RSpec.describe API::GoProxy do
end
it 'returns not found with a job token' do
- get_resource(oauth_access_token: job)
+ get_resource(access_token: job)
expect(response).to have_gitlab_http_status(:not_found)
end
diff --git a/spec/requests/api/helpers_spec.rb b/spec/requests/api/helpers_spec.rb
index c961fd9cfc8..e29e5c31a34 100644
--- a/spec/requests/api/helpers_spec.rb
+++ b/spec/requests/api/helpers_spec.rb
@@ -539,7 +539,7 @@ RSpec.describe API::Helpers do
let(:token) { create(:oauth_access_token) }
before do
- env['HTTP_AUTHORIZATION'] = "Bearer #{token.token}"
+ env['HTTP_AUTHORIZATION'] = "Bearer #{token.plaintext_token}"
end
it_behaves_like 'sudo'
diff --git a/spec/requests/api/npm_project_packages_spec.rb b/spec/requests/api/npm_project_packages_spec.rb
index 6061b3ba965..3bcffac2760 100644
--- a/spec/requests/api/npm_project_packages_spec.rb
+++ b/spec/requests/api/npm_project_packages_spec.rb
@@ -59,7 +59,7 @@ RSpec.describe API::NpmProjectPackages do
end
context 'with access token' do
- let(:headers) { build_token_auth_header(token.token) }
+ let(:headers) { build_token_auth_header(token.plaintext_token) }
it_behaves_like 'successfully downloads the file'
it_behaves_like 'a package tracking event', 'API::NpmPackages', 'pull_package'
@@ -95,7 +95,7 @@ RSpec.describe API::NpmProjectPackages do
it_behaves_like 'a package file that requires auth'
context 'with guest' do
- let(:headers) { build_token_auth_header(token.token) }
+ let(:headers) { build_token_auth_header(token.plaintext_token) }
it 'denies download when not enough permissions' do
project.add_guest(user)
@@ -356,7 +356,7 @@ RSpec.describe API::NpmProjectPackages do
end
def upload_with_token(package_name, params = {})
- upload_package(package_name, params.merge(access_token: token.token))
+ upload_package(package_name, params.merge(access_token: token.plaintext_token))
end
def upload_with_job_token(package_name, params = {})
diff --git a/spec/requests/rack_attack_global_spec.rb b/spec/requests/rack_attack_global_spec.rb
index 115f78a5600..f6b9bc527ac 100644
--- a/spec/requests/rack_attack_global_spec.rb
+++ b/spec/requests/rack_attack_global_spec.rb
@@ -104,8 +104,8 @@ RSpec.describe 'Rack Attack global throttles', :use_clean_rails_memory_store_cac
end
context 'with the token in the OAuth headers' do
- let(:request_args) { api_get_args_with_token_headers(api_partial_url, oauth_token_headers(token)) }
- let(:other_user_request_args) { api_get_args_with_token_headers(api_partial_url, oauth_token_headers(other_user_token)) }
+ let(:request_args) { api_get_args_with_token_headers(api_partial_url, bearer_headers(token)) }
+ let(:other_user_request_args) { api_get_args_with_token_headers(api_partial_url, bearer_headers(other_user_token)) }
it_behaves_like 'rate-limited user based token-authenticated requests'
end
@@ -131,8 +131,8 @@ RSpec.describe 'Rack Attack global throttles', :use_clean_rails_memory_store_cac
end
context 'with the token in the OAuth headers' do
- let(:request_args) { api_get_args_with_token_headers(api_partial_url, oauth_token_headers(token)) }
- let(:other_user_request_args) { api_get_args_with_token_headers(api_partial_url, oauth_token_headers(other_user_token)) }
+ let(:request_args) { api_get_args_with_token_headers(api_partial_url, bearer_headers(token)) }
+ let(:other_user_request_args) { api_get_args_with_token_headers(api_partial_url, bearer_headers(other_user_token)) }
it_behaves_like 'rate-limited user based token-authenticated requests'
end
@@ -1189,7 +1189,7 @@ RSpec.describe 'Rack Attack global throttles', :use_clean_rails_memory_store_cac
it 'request is authenticated by token in the OAuth headers' do
expect_authenticated_request
- get url, headers: oauth_token_headers(personal_access_token)
+ get url, headers: bearer_headers(personal_access_token)
end
it 'request is authenticated by token in basic auth' do
@@ -1206,7 +1206,7 @@ RSpec.describe 'Rack Attack global throttles', :use_clean_rails_memory_store_cac
it 'request is authenticated by token in query string' do
expect_authenticated_request
- get url, params: { access_token: oauth_token.token }
+ get url, params: { access_token: oauth_token.plaintext_token }
end
it 'request is authenticated by token in the headers' do
diff --git a/spec/support/helpers/api_helpers.rb b/spec/support/helpers/api_helpers.rb
index b084508be9a..62bb9576695 100644
--- a/spec/support/helpers/api_helpers.rb
+++ b/spec/support/helpers/api_helpers.rb
@@ -19,15 +19,17 @@ module ApiHelpers
# => "/api/v2/issues?foo=bar&private_token=..."
#
# Returns the relative path to the requested API resource
- def api(path, user = nil, version: API::API.version, personal_access_token: nil, oauth_access_token: nil, job_token: nil)
+ def api(path, user = nil, version: API::API.version, personal_access_token: nil, oauth_access_token: nil, job_token: nil, access_token: nil)
full_path = "/api/#{version}#{path}"
if oauth_access_token
- query_string = "access_token=#{oauth_access_token.token}"
+ query_string = "access_token=#{oauth_access_token.plaintext_token}"
elsif personal_access_token
query_string = "private_token=#{personal_access_token.token}"
elsif job_token
query_string = "job_token=#{job_token}"
+ elsif access_token
+ query_string = "access_token=#{access_token.token}"
elsif user
personal_access_token = create(:personal_access_token, user: user)
query_string = "private_token=#{personal_access_token.token}"
diff --git a/spec/support/helpers/rack_attack_spec_helpers.rb b/spec/support/helpers/rack_attack_spec_helpers.rb
index 6c06781df03..2502889e17c 100644
--- a/spec/support/helpers/rack_attack_spec_helpers.rb
+++ b/spec/support/helpers/rack_attack_spec_helpers.rb
@@ -17,8 +17,12 @@ module RackAttackSpecHelpers
{ Gitlab::Auth::AuthFinders::PRIVATE_TOKEN_HEADER => personal_access_token.token }
end
+ def bearer_headers(token)
+ { 'AUTHORIZATION' => "Bearer #{token.token}" }
+ end
+
def oauth_token_headers(oauth_access_token)
- { 'AUTHORIZATION' => "Bearer #{oauth_access_token.token}" }
+ { 'AUTHORIZATION' => "Bearer #{oauth_access_token.plaintext_token}" }
end
def basic_auth_headers(user, personal_access_token)
diff --git a/spec/support/shared_examples/requests/api/npm_packages_shared_examples.rb b/spec/support/shared_examples/requests/api/npm_packages_shared_examples.rb
index 8d6d85732be..b651ffc8996 100644
--- a/spec/support/shared_examples/requests/api/npm_packages_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/npm_packages_shared_examples.rb
@@ -244,7 +244,7 @@ RSpec.shared_examples 'handling get metadata requests' do |scope: :project|
let(:headers) do
case auth
when :oauth
- build_token_auth_header(token.token)
+ build_token_auth_header(token.plaintext_token)
when :personal_access_token
build_token_auth_header(personal_access_token.token)
when :job_token
@@ -404,7 +404,7 @@ RSpec.shared_examples 'handling get dist tags requests' do |scope: :project|
shared_examples 'handling all conditions' do
context 'with oauth token' do
- let(:headers) { build_token_auth_header(token.token) }
+ let(:headers) { build_token_auth_header(token.plaintext_token) }
it_behaves_like 'handling different package names, visibilities and user roles'
end
@@ -514,7 +514,7 @@ RSpec.shared_examples 'handling create dist tag requests' do |scope: :project|
shared_examples 'handling all conditions' do
context 'with oauth token' do
- let(:headers) { build_token_auth_header(token.token) }
+ let(:headers) { build_token_auth_header(token.plaintext_token) }
it_behaves_like 'handling different package names, visibilities and user roles'
end
@@ -622,7 +622,7 @@ RSpec.shared_examples 'handling delete dist tag requests' do |scope: :project|
shared_examples 'handling all conditions' do
context 'with oauth token' do
- let(:headers) { build_token_auth_header(token.token) }
+ let(:headers) { build_token_auth_header(token.plaintext_token) }
it_behaves_like 'handling different package names, visibilities and user roles'
end