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--.rubocop_todo/layout/first_array_element_indentation.yml19
-rw-r--r--app/assets/javascripts/ide/utils.js22
-rw-r--r--app/assets/javascripts/projects/settings/branch_rules/components/edit/branch_dropdown.vue (renamed from app/assets/javascripts/projects/settings/branch_rules/components/branch_dropdown.vue)2
-rw-r--r--app/assets/javascripts/projects/settings/branch_rules/components/edit/index.vue (renamed from app/assets/javascripts/projects/settings/branch_rules/components/rule_edit.vue)0
-rw-r--r--app/assets/javascripts/projects/settings/branch_rules/components/edit/protections/index.vue (renamed from app/assets/javascripts/projects/settings/branch_rules/components/protections/index.vue)0
-rw-r--r--app/assets/javascripts/projects/settings/branch_rules/components/edit/protections/merge_protections.vue (renamed from app/assets/javascripts/projects/settings/branch_rules/components/protections/merge_protections.vue)0
-rw-r--r--app/assets/javascripts/projects/settings/branch_rules/components/edit/protections/push_protections.vue (renamed from app/assets/javascripts/projects/settings/branch_rules/components/protections/push_protections.vue)0
-rw-r--r--app/assets/javascripts/projects/settings/branch_rules/mount_branch_rules.js2
-rw-r--r--app/finders/personal_access_tokens_finder.rb42
-rw-r--r--app/models/personal_access_token.rb9
-rw-r--r--app/models/preloaders/project_root_ancestor_preloader.rb3
-rw-r--r--config/webpack.config.js48
-rw-r--r--doc/administration/merge_request_diffs.md8
-rw-r--r--doc/api/personal_access_tokens.md84
-rw-r--r--doc/raketasks/import.md12
-rw-r--r--doc/subscriptions/index.md16
-rw-r--r--doc/user/admin_area/index.md10
-rw-r--r--doc/user/profile/index.md6
-rw-r--r--doc/user/project/settings/index.md3
-rw-r--r--doc/user/project/working_with_projects.md10
-rw-r--r--jest.config.base.js2
-rw-r--r--lib/api/helpers/personal_access_tokens_helpers.rb13
-rw-r--r--lib/api/personal_access_tokens.rb10
-rw-r--r--lib/gitlab/usage/metrics/aggregates/aggregate.rb89
-rw-r--r--lib/gitlab/usage_data_counters/hll_redis_counter.rb2
-rw-r--r--lib/gitlab/usage_data_counters/known_events/common.yml24
-rw-r--r--package.json2
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_commit_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb13
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/revert/revert_commit_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb13
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb24
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb22
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb78
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb11
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb28
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_group_level_spec.rb28
-rw-r--r--qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_project_level_spec.rb20
-rw-r--r--spec/finders/personal_access_tokens_finder_spec.rb44
-rw-r--r--spec/frontend/__mocks__/monaco-editor/index.js2
-rw-r--r--spec/frontend/__mocks__/monaco-yaml/index.js4
-rw-r--r--spec/frontend/editor/source_editor_ci_schema_ext_spec.js12
-rw-r--r--spec/frontend/ide/utils_spec.js4
-rw-r--r--spec/frontend/projects/settings/branch_rules/components/edit/branch_dropdown_spec.js (renamed from spec/frontend/projects/settings/branch_rules/branch_dropdown_spec.js)2
-rw-r--r--spec/frontend/projects/settings/branch_rules/components/edit/index_spec.js (renamed from spec/frontend/projects/settings/branch_rules/rule_edit_spec.js)6
-rw-r--r--spec/frontend/projects/settings/branch_rules/components/edit/protections/index_spec.js (renamed from spec/frontend/projects/settings/branch_rules/components/protections/index_spec.js)8
-rw-r--r--spec/frontend/projects/settings/branch_rules/components/edit/protections/merge_protections_spec.js (renamed from spec/frontend/projects/settings/branch_rules/components/protections/merge_protections_spec.js)4
-rw-r--r--spec/frontend/projects/settings/branch_rules/components/edit/protections/push_protections_spec.js (renamed from spec/frontend/projects/settings/branch_rules/components/protections/push_protections_spec.js)4
-rw-r--r--spec/models/personal_access_token_spec.rb25
-rw-r--r--spec/models/preloaders/project_root_ancestor_preloader_spec.rb48
-rw-r--r--spec/requests/api/personal_access_tokens_spec.rb367
-rw-r--r--yarn.lock80
53 files changed, 920 insertions, 377 deletions
diff --git a/.rubocop_todo/layout/first_array_element_indentation.yml b/.rubocop_todo/layout/first_array_element_indentation.yml
index a30ed786e5d..b90a4621be9 100644
--- a/.rubocop_todo/layout/first_array_element_indentation.yml
+++ b/.rubocop_todo/layout/first_array_element_indentation.yml
@@ -4,25 +4,6 @@ Layout/FirstArrayElementIndentation:
Exclude:
- 'lib/gitlab/email/message/in_product_marketing/trial.rb'
- 'qa/qa/specs/features/browser_ui/2_plan/issue/custom_issue_template_spec.rb'
- - 'qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_commit_spec.rb'
- - 'qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb'
- - 'qa/qa/specs/features/browser_ui/3_create/merge_request/revert/revert_commit_spec.rb'
- - 'qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb'
- - 'qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb'
- - 'qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb'
- - 'qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb'
- - 'qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb'
- - 'qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb'
- - 'qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb'
- - 'qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_group_level_spec.rb'
- - 'qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_project_level_spec.rb'
- - 'qa/qa/specs/features/ee/api/1_manage/user/minimal_access_user_spec.rb'
- - 'qa/qa/specs/features/ee/api/9_enablement/elasticsearch/advanced_global_advanced_syntax_search_spec.rb'
- - 'qa/qa/specs/features/ee/api/9_enablement/elasticsearch/elasticsearch_api_spec.rb'
- - 'qa/qa/specs/features/ee/api/9_enablement/elasticsearch/index_tests/main_index/blob_index_spec.rb'
- - 'qa/qa/specs/features/ee/api/9_enablement/elasticsearch/nightly_elasticsearch_test_spec.rb'
- - 'qa/qa/specs/features/ee/browser_ui/3_create/repository/code_owners_with_protected_branch_and_squashed_commits_spec.rb'
- - 'qa/qa/specs/features/ee/browser_ui/4_verify/new_discussion_not_dropping_merge_trains_mr_spec.rb'
- 'spec/controllers/concerns/send_file_upload_spec.rb'
- 'spec/graphql/types/packages/tag_type_spec.rb'
- 'spec/helpers/application_settings_helper_spec.rb'
diff --git a/app/assets/javascripts/ide/utils.js b/app/assets/javascripts/ide/utils.js
index a7e6506b045..83a3d7f2ac3 100644
--- a/app/assets/javascripts/ide/utils.js
+++ b/app/assets/javascripts/ide/utils.js
@@ -1,5 +1,6 @@
import { flatten, isString } from 'lodash';
import { languages } from 'monaco-editor';
+import { setDiagnosticsOptions as yamlDiagnosticsOptions } from 'monaco-yaml';
import { performanceMarkAndMeasure } from '~/performance/utils';
import { SIDE_LEFT, SIDE_RIGHT } from './constants';
@@ -82,17 +83,16 @@ export function registerLanguages(def, ...defs) {
}
export function registerSchema(schema, options = {}) {
- const defaults = [languages.json.jsonDefaults, languages.yaml.yamlDefaults];
- defaults.forEach((d) =>
- d.setDiagnosticsOptions({
- validate: true,
- enableSchemaRequest: true,
- hover: true,
- completion: true,
- schemas: [schema],
- ...options,
- }),
- );
+ const defaultOptions = {
+ validate: true,
+ enableSchemaRequest: true,
+ hover: true,
+ completion: true,
+ schemas: [schema],
+ ...options,
+ };
+ languages.json.jsonDefaults.setDiagnosticsOptions(defaultOptions);
+ yamlDiagnosticsOptions(defaultOptions);
}
export const otherSide = (side) => (side === SIDE_RIGHT ? SIDE_LEFT : SIDE_RIGHT);
diff --git a/app/assets/javascripts/projects/settings/branch_rules/components/branch_dropdown.vue b/app/assets/javascripts/projects/settings/branch_rules/components/edit/branch_dropdown.vue
index 6ba2ef7da99..f2b1c749abc 100644
--- a/app/assets/javascripts/projects/settings/branch_rules/components/branch_dropdown.vue
+++ b/app/assets/javascripts/projects/settings/branch_rules/components/edit/branch_dropdown.vue
@@ -10,7 +10,7 @@ import {
import { createAlert } from '~/flash';
import { s__, sprintf } from '~/locale';
import { helpPagePath } from '~/helpers/help_page_helper';
-import branchesQuery from '../queries/branches.query.graphql';
+import branchesQuery from '../../queries/branches.query.graphql';
export const i18n = {
fetchBranchesError: s__('BranchRules|An error occurred while fetching branches.'),
diff --git a/app/assets/javascripts/projects/settings/branch_rules/components/rule_edit.vue b/app/assets/javascripts/projects/settings/branch_rules/components/edit/index.vue
index ad3eb7d2899..ad3eb7d2899 100644
--- a/app/assets/javascripts/projects/settings/branch_rules/components/rule_edit.vue
+++ b/app/assets/javascripts/projects/settings/branch_rules/components/edit/index.vue
diff --git a/app/assets/javascripts/projects/settings/branch_rules/components/protections/index.vue b/app/assets/javascripts/projects/settings/branch_rules/components/edit/protections/index.vue
index bcc0f64d667..bcc0f64d667 100644
--- a/app/assets/javascripts/projects/settings/branch_rules/components/protections/index.vue
+++ b/app/assets/javascripts/projects/settings/branch_rules/components/edit/protections/index.vue
diff --git a/app/assets/javascripts/projects/settings/branch_rules/components/protections/merge_protections.vue b/app/assets/javascripts/projects/settings/branch_rules/components/edit/protections/merge_protections.vue
index 85f168af4a8..85f168af4a8 100644
--- a/app/assets/javascripts/projects/settings/branch_rules/components/protections/merge_protections.vue
+++ b/app/assets/javascripts/projects/settings/branch_rules/components/edit/protections/merge_protections.vue
diff --git a/app/assets/javascripts/projects/settings/branch_rules/components/protections/push_protections.vue b/app/assets/javascripts/projects/settings/branch_rules/components/edit/protections/push_protections.vue
index 541923bb735..541923bb735 100644
--- a/app/assets/javascripts/projects/settings/branch_rules/components/protections/push_protections.vue
+++ b/app/assets/javascripts/projects/settings/branch_rules/components/edit/protections/push_protections.vue
diff --git a/app/assets/javascripts/projects/settings/branch_rules/mount_branch_rules.js b/app/assets/javascripts/projects/settings/branch_rules/mount_branch_rules.js
index 8452542540e..10de5f12757 100644
--- a/app/assets/javascripts/projects/settings/branch_rules/mount_branch_rules.js
+++ b/app/assets/javascripts/projects/settings/branch_rules/mount_branch_rules.js
@@ -1,7 +1,7 @@
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
-import RuleEdit from './components/rule_edit.vue';
+import RuleEdit from './components/edit/index.vue';
export default function mountBranchRules(el) {
if (!el) {
diff --git a/app/finders/personal_access_tokens_finder.rb b/app/finders/personal_access_tokens_finder.rb
index 7d356c1014c..8403c531945 100644
--- a/app/finders/personal_access_tokens_finder.rb
+++ b/app/finders/personal_access_tokens_finder.rb
@@ -18,6 +18,12 @@ class PersonalAccessTokensFinder
tokens = by_impersonation(tokens)
tokens = by_state(tokens)
tokens = by_owner_type(tokens)
+ tokens = by_revoked_state(tokens)
+ tokens = by_created_before(tokens)
+ tokens = by_created_after(tokens)
+ tokens = by_last_used_before(tokens)
+ tokens = by_last_used_after(tokens)
+ tokens = by_search(tokens)
sort(tokens)
end
@@ -83,4 +89,40 @@ class PersonalAccessTokensFinder
tokens
end
end
+
+ def by_revoked_state(tokens)
+ return tokens unless params.has_key?(:revoked)
+
+ params[:revoked] ? tokens.revoked : tokens.not_revoked
+ end
+
+ def by_created_before(tokens)
+ return tokens unless params[:created_before]
+
+ tokens.created_before(params[:created_before])
+ end
+
+ def by_created_after(tokens)
+ return tokens unless params[:created_after]
+
+ tokens.created_after(params[:created_after])
+ end
+
+ def by_last_used_before(tokens)
+ return tokens unless params[:last_used_before]
+
+ tokens.last_used_before(params[:last_used_before])
+ end
+
+ def by_last_used_after(tokens)
+ return tokens unless params[:last_used_after]
+
+ tokens.last_used_after(params[:last_used_after])
+ end
+
+ def by_search(tokens)
+ return tokens unless params[:search]
+
+ tokens.search(params[:search])
+ end
end
diff --git a/app/models/personal_access_token.rb b/app/models/personal_access_token.rb
index 9ed25c56ed6..f0ed1822da6 100644
--- a/app/models/personal_access_token.rb
+++ b/app/models/personal_access_token.rb
@@ -5,6 +5,8 @@ class PersonalAccessToken < ApplicationRecord
include TokenAuthenticatable
include Sortable
include EachBatch
+ include CreatedAtFilterable
+ include Gitlab::SQL::Pattern
extend ::Gitlab::Utils::Override
add_authentication_token_field :token, digest: true
@@ -24,7 +26,6 @@ class PersonalAccessToken < ApplicationRecord
scope :expiring_and_not_notified, ->(date) { where(["revoked = false AND expire_notification_delivered = false AND expires_at >= CURRENT_DATE AND expires_at <= ?", date]) }
scope :expired_today_and_not_notified, -> { where(["revoked = false AND expires_at = CURRENT_DATE AND after_expiry_notification_delivered = false"]) }
scope :inactive, -> { where("revoked = true OR expires_at < CURRENT_DATE") }
- scope :created_before, -> (date) { where("personal_access_tokens.created_at < :date", date: date) }
scope :last_used_before_or_unused, -> (date) { where("personal_access_tokens.created_at < :date AND (last_used_at < :date OR last_used_at IS NULL)", date: date) }
scope :with_impersonation, -> { where(impersonation: true) }
scope :without_impersonation, -> { where(impersonation: false) }
@@ -38,6 +39,8 @@ class PersonalAccessToken < ApplicationRecord
scope :order_expires_at_asc_id_desc, -> { reorder(expires_at: :asc, id: :desc) }
scope :project_access_token, -> { includes(:user).where(user: { user_type: :project_bot }) }
scope :owner_is_human, -> { includes(:user).where(user: { user_type: :human }) }
+ scope :last_used_before, -> (date) { where("last_used_at <= ?", date) }
+ scope :last_used_after, -> (date) { where("last_used_at >= ?", date) }
validates :scopes, presence: true
validate :validate_scopes
@@ -90,6 +93,10 @@ class PersonalAccessToken < ApplicationRecord
Gitlab::CurrentSettings.current_application_settings.personal_access_token_prefix
end
+ def self.search(query)
+ fuzzy_search(query, [:name])
+ end
+
override :format_token
def format_token(token)
"#{self.class.token_prefix}#{token}"
diff --git a/app/models/preloaders/project_root_ancestor_preloader.rb b/app/models/preloaders/project_root_ancestor_preloader.rb
index 8d04e71774c..1e935249407 100644
--- a/app/models/preloaders/project_root_ancestor_preloader.rb
+++ b/app/models/preloaders/project_root_ancestor_preloader.rb
@@ -21,7 +21,8 @@ module Preloaders
ActiveRecord::Associations::Preloader.new.preload(@projects, :namespace)
@projects.each do |project|
- project.namespace.root_ancestor = root_ancestors_by_id[project.id]&.first
+ root_ancestor = root_ancestors_by_id[project.id]&.first
+ project.namespace.root_ancestor = root_ancestor if root_ancestor.present?
end
end
diff --git a/config/webpack.config.js b/config/webpack.config.js
index 146e9b48442..5a38f278855 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -20,13 +20,13 @@ const webpack = require('webpack');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const { StatsWriterPlugin } = require('webpack-stats-plugin');
const WEBPACK_VERSION = require('webpack/package.json').version;
+const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
const createIncrementalWebpackCompiler = require('./helpers/incremental_webpack_compiler');
const IS_EE = require('./helpers/is_ee_env');
const IS_JH = require('./helpers/is_jh_env');
const vendorDllHash = require('./helpers/vendor_dll_hash');
-const MonacoWebpackPlugin = require('./plugins/monaco_webpack');
const GraphqlKnownOperationsPlugin = require('./plugins/graphql_known_operations_plugin');
const ROOT_PATH = path.resolve(__dirname, '..');
@@ -250,6 +250,20 @@ if (VENDOR_DLL && !IS_PRODUCTION) {
};
}
+const defaultJsOptions = {
+ cacheDirectory: path.join(CACHE_PATH, 'babel-loader'),
+ cacheIdentifier: [
+ process.env.BABEL_ENV || process.env.NODE_ENV || 'development',
+ webpack.version,
+ BABEL_VERSION,
+ BABEL_LOADER_VERSION,
+ // Ensure that changing supported browsers will refresh the cache
+ // in order to not pull in outdated files that import core-js
+ SUPPORTED_BROWSERS_HASH,
+ ].join('|'),
+ cacheCompression: false,
+};
+
module.exports = {
mode: IS_PRODUCTION ? 'production' : 'development',
@@ -285,18 +299,18 @@ module.exports = {
exclude: (modulePath) =>
/node_modules|vendor[\\/]assets/.test(modulePath) && !/\.vue\.js/.test(modulePath),
loader: 'babel-loader',
+ options: defaultJsOptions,
+ },
+ {
+ test: /\.js$/,
+ include: (modulePath) =>
+ /node_modules\/(monaco-worker-manager|monaco-marker-data-provider)\/index\.js/.test(
+ modulePath,
+ ) || /node_modules\/yaml/.test(modulePath),
+ loader: 'babel-loader',
options: {
- cacheDirectory: path.join(CACHE_PATH, 'babel-loader'),
- cacheIdentifier: [
- process.env.BABEL_ENV || process.env.NODE_ENV || 'development',
- webpack.version,
- BABEL_VERSION,
- BABEL_LOADER_VERSION,
- // Ensure that changing supported browsers will refresh the cache
- // in order to not pull in outdated files that import core-js
- SUPPORTED_BROWSERS_HASH,
- ].join('|'),
- cacheCompression: false,
+ plugins: ['@babel/plugin-proposal-numeric-separator'],
+ ...defaultJsOptions,
},
},
{
@@ -492,6 +506,16 @@ module.exports = {
// automatically configure monaco editor web workers
new MonacoWebpackPlugin({
filename: '[name].[contenthash:8].worker.js',
+ customLanguages: [
+ {
+ label: 'yaml',
+ entry: 'monaco-yaml',
+ worker: {
+ id: 'monaco-yaml/yamlWorker',
+ entry: 'monaco-yaml/yaml.worker',
+ },
+ },
+ ],
}),
new GraphqlKnownOperationsPlugin({ filename: 'graphql_known_operations.yml' }),
diff --git a/doc/administration/merge_request_diffs.md b/doc/administration/merge_request_diffs.md
index fe1c74b0e24..fd0991b1771 100644
--- a/doc/administration/merge_request_diffs.md
+++ b/doc/administration/merge_request_diffs.md
@@ -271,3 +271,11 @@ By default, `sudo` does not preserve existing environment variables. You should
```shell
sudo gitlab-rake gitlab:external_diffs:force_object_storage START_ID=59946109 END_ID=59946109 UPDATE_DELAY=5
```
+
+## Switching from external storage to object storage
+
+Automatic migration moves diffs stored in the database, but it does not move diffs between storage types.
+To switch from external storage to object storage:
+
+1. Move files stored on local or NFS storage to object storage manually.
+1. Run the Rake task in the [previous section](#correcting-incorrectly-migrated-diffs) to change their location in the database.
diff --git a/doc/api/personal_access_tokens.md b/doc/api/personal_access_tokens.md
index 849b5c75684..e7b491059ba 100644
--- a/doc/api/personal_access_tokens.md
+++ b/doc/api/personal_access_tokens.md
@@ -12,24 +12,56 @@ You can read more about [personal access tokens](../user/profile/personal_access
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/227264) in GitLab 13.3.
> - [Moved](https://gitlab.com/gitlab-org/gitlab/-/issues/270200) from GitLab Ultimate to GitLab Free in 13.6.
+> - `created_after`, `created_before`, `last_used_after`, `last_used_before`, `revoked`, `search` and `state` filters were [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/362248) in GitLab 15.4.
-Get a list of personal access tokens.
+Get all personal access tokens the authenticated user has access to. By default, returns an unfiltered list of:
+
+- Only personal access tokens created by the current user to a non-administrator.
+- All personal access tokens to an administrator.
+
+Administrators:
+
+- Can use the `user_id` parameter to filter by a user.
+- Can use other filters on all personal access tokens (GitLab 15.3 and later).
+
+Non-administrators:
+
+- Cannot use the `user_id` parameter to filter on any user except themselves, otherwise they receive a `401 Unauthorized` response.
+- Can only filter on their own personal access tokens (GitLab 15.3 and later).
```plaintext
GET /personal_access_tokens
+GET /personal_access_tokens?created_after=2022-01-01T00:00:00
+GET /personal_access_tokens?created_before=2022-01-01T00:00:00
+GET /personal_access_tokens?last_used_after=2022-01-01T00:00:00
+GET /personal_access_tokens?last_used_before=2022-01-01T00:00:00
+GET /personal_access_tokens?revoked=true
+GET /personal_access_tokens?search=name
+GET /personal_access_tokens?state=inactive
+GET /personal_access_tokens?user_id=1
```
-| Attribute | Type | required | Description |
-|-----------|---------|----------|---------------------|
-| `user_id` | integer/string | no | The ID of the user to filter by |
+Supported attributes:
-NOTE:
-Administrators can use the `user_id` parameter to filter by a user. Non-administrators cannot filter by any user except themselves. Attempting to do so will result in a `401 Unauthorized` response.
+| Attribute | Type | Required | Description |
+|---------------------|----------------|----------|---------------------|
+| `created_after` | datetime (ISO 8601) | **{dotted-circle}** No | Limit results to PATs created after specified time. |
+| `created_before` | datetime (ISO 8601) | **{dotted-circle}** No | Limit results to PATs created before specified time. |
+| `last_used_after` | datetime (ISO 8601) | **{dotted-circle}** No | Limit results to PATs last used after specified time. |
+| `last_used_before` | datetime (ISO 8601) | **{dotted-circle}** No | Limit results to PATs last used before specified time. |
+| `revoked` | boolean | **{dotted-circle}** No | Limit results to PATs with specified revoked state. Valid values are `true` and `false`. |
+| `search` | string | **{dotted-circle}** No | Limit results to PATs with name containing search string. |
+| `state` | string | **{dotted-circle}** No | Limit results to PATs with specified state. Valid values are `active` and `inactive`. |
+| `user_id` | integer or string | **{dotted-circle}** No | Limit results to PATs owned by specified user. |
+
+Example request:
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/personal_access_tokens"
```
+Example response:
+
```json
[
{
@@ -48,10 +80,14 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/a
]
```
+Example request:
+
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/personal_access_tokens?user_id=3"
```
+Example response:
+
```json
[
{
@@ -70,6 +106,38 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/a
]
```
+Example request:
+
+```shell
+curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/personal_access_tokens?revoked=true"
+```
+
+Example response:
+
+```json
+[
+ {
+ "id": 41,
+ "name": "Revoked Test Token",
+ "revoked": true,
+ "created_at": "2022-01-01T14:31:47.729Z",
+ "scopes": [
+ "api"
+ ],
+ "user_id": 8,
+ "last_used_at": "2022-05-18T17:58:37.550Z",
+ "active": false,
+ "expires_at": null
+ }
+]
+```
+
+You can filter by merged attributes with:
+
+```plaintext
+GET /personal_access_tokens?revoked=true&created_before=2022-01-01
+```
+
## Get single personal access token by ID
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/362239) in GitLab 15.1.
@@ -81,7 +149,7 @@ Administrators can get any token.
GET /personal_access_tokens/:id
```
-| Attribute | Type | required | Description |
+| Attribute | Type | Required | Description |
|-----------|---------|----------|---------------------|
| `id` | integer/string | yes | ID of personal access token |
@@ -116,7 +184,7 @@ Revoke a personal access token using its ID.
DELETE /personal_access_tokens/:id
```
-| Attribute | Type | required | Description |
+| Attribute | Type | Required | Description |
|-----------|---------|----------|---------------------|
| `id` | integer/string | yes | ID of personal access token |
diff --git a/doc/raketasks/import.md b/doc/raketasks/import.md
index 5c95fe2eca1..9ccf238769d 100644
--- a/doc/raketasks/import.md
+++ b/doc/raketasks/import.md
@@ -19,7 +19,8 @@ Note that:
- Existing projects are skipped.
- Projects in hashed storage may be skipped. For more information, see
[Importing bare repositories from hashed storage](#importing-bare-repositories-from-hashed-storage).
-- The existing Git repositories ware moved from disk (removed from the original path).
+- The existing Git repositories are moved from disk (removed from the original path).
+- You must manually [push Git LFS objects](#push-git-lfs-objects).
To import bare repositories into a GitLab instance:
@@ -152,3 +153,12 @@ projects (this may take a while if there are 1000s of projects in a namespace):
namespace = Namespace.find_by_full_path('gitlab-org')
namespace.send(:write_projects_repository_config)
```
+
+## Push Git LFS objects
+
+The import task doesn't import Git LFS objects. You must manually push the LFS objects to the newly
+created GitLab repository using the following command:
+
+```shell
+git lfs push --all
+```
diff --git a/doc/subscriptions/index.md b/doc/subscriptions/index.md
index e71954f1968..aedbeb8481e 100644
--- a/doc/subscriptions/index.md
+++ b/doc/subscriptions/index.md
@@ -73,26 +73,30 @@ click E "./self_managed/index.html#view-your-subscription"
With the [Customers Portal](https://customers.gitlab.com/) you can:
-- [Change your personal details](#change-your-personal-details)
+- [Change account owner information](#change-account-owner-information)
- [Change your company details](#change-your-company-details)
- [Change your payment method](#change-your-payment-method)
- [Change the linked account](#change-the-linked-account)
- [Change the namespace the subscription is linked to](#change-the-linked-namespace)
- [Change customers portal account password](#change-customers-portal-account-password)
-### Change your personal details
+### Change account owner information
-Your personal details are used on invoices. Your email address is used for the Customers Portal
-login and license-related email.
+Account owner personal details are used on invoices. The account owner email
+address is used for the Customers Portal login and license-related email.
-To change your personal details, including name, billing address, and email address:
+To change account owner information, including name, billing address, and email address:
1. Log in to the [Customers Portal](https://customers.gitlab.com/customers/sign_in).
1. Select **My account > Account details**.
1. Expand the **Personal details** section.
-1. Edit your personal details.
+1. Edit the personal details.
1. Select **Save changes**.
+If you want to transfer ownership of the Customers Portal account
+to another person, after you enter that person's personal details, you must also
+[change the Customers Portal account password](#change-customers-portal-account-password).
+
### Change your company details
To change your company details, including company name and VAT number:
diff --git a/doc/user/admin_area/index.md b/doc/user/admin_area/index.md
index 207b7e6f2d8..30849d2754b 100644
--- a/doc/user/admin_area/index.md
+++ b/doc/user/admin_area/index.md
@@ -270,10 +270,12 @@ To [Create a new group](../group/manage.md#create-a-group) select **New group**.
### Administering Topics
-> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/340920) in GitLab 14.4.
+- > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/340920) in GitLab 14.4.
+- > Merging topics [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/366884) in GitLab 15.5.
-You can administer all [topics](../project/working_with_projects.md#explore-topics) in the
-GitLab instance from the Admin Area's Topics page.
+[Topics](../project/working_with_projects.md#explore-topics) are used to categorize and find similar projects.
+
+You can administer all topics in the GitLab instance from the Admin Area's Topics page.
To access the Topics page:
@@ -295,7 +297,7 @@ insensitive and applies partial matching.
NOTE:
The assigned topics are visible only to everyone with access to the project,
-but everyone can see which topics exist at all on the GitLab instance.
+but everyone can see which topics exist on the GitLab instance.
Do not include sensitive information in the name of a topic.
### Administering Jobs
diff --git a/doc/user/profile/index.md b/doc/user/profile/index.md
index e4cf905bbce..1d88c41b554 100644
--- a/doc/user/profile/index.md
+++ b/doc/user/profile/index.md
@@ -27,6 +27,12 @@ To access your user settings:
## Change your password
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/23610) in GitLab 15.4 [with a flag](../../administration/feature_flags.md) named `block_weak_passwords`, weak passwords aren't accepted. Disabled by default.
+
+FLAG:
+On self-managed GitLab, by default blocking weak passwords is not available. To make it available, ask an administrator to [enable the feature flag](../../administration/feature_flags.md) named `block_weak_passwords`. On GitLab.com, this feature is available but can be configured by GitLab.com administrators only.
+The feature is not ready for production use.
+
To change your password:
1. On the top bar, in the top-right corner, select your avatar.
diff --git a/doc/user/project/settings/index.md b/doc/user/project/settings/index.md
index 5c2118e02cf..b42694ff1de 100644
--- a/doc/user/project/settings/index.md
+++ b/doc/user/project/settings/index.md
@@ -40,6 +40,9 @@ To assign topics to a project:
1. In the **Topics** text box, enter the project topics. Popular topics are suggested as you type.
1. Select **Save changes**.
+If you're an instance administrator, you can administer all project topics from the
+[Admin Area's Topics page](../../admin_area/index.md#administering-topics).
+
## Compliance frameworks **(PREMIUM)**
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/276221) in GitLab 13.9.
diff --git a/doc/user/project/working_with_projects.md b/doc/user/project/working_with_projects.md
index e58bf5aa557..9b52652cea2 100644
--- a/doc/user/project/working_with_projects.md
+++ b/doc/user/project/working_with_projects.md
@@ -13,6 +13,11 @@ code are saved in projects, and most features are in the scope of projects.
To view projects, on the top bar, select **Main menu > Projects > View all projects**.
+NOTE:
+The **Explore projects** tab is visible to unauthenticated users unless the
+[**Public** visibility level](../admin_area/settings/visibility_and_access_controls.md#restrict-visibility-levels)
+is restricted. Then the tab is visible only to signed-in users.
+
### Who can view the Projects page
When you select a project, the project landing page shows the project contents.
@@ -46,11 +51,6 @@ To explore project topics:
The **Explore topics** tab shows a list of topics sorted by the number of associated projects.
-NOTE:
-The **Explore projects** tab is visible to unauthenticated users unless the
-[**Public** visibility level](../admin_area/settings/visibility_and_access_controls.md#restrict-visibility-levels)
-is restricted. Then the tab is visible only to signed-in users.
-
You can assign topics to a project on the [Project Settings page](settings/index.md#assign-topics-to-a-project).
If you're an instance administrator, you can administer all project topics from the
diff --git a/jest.config.base.js b/jest.config.base.js
index d90a3b9825e..b631c2009d9 100644
--- a/jest.config.base.js
+++ b/jest.config.base.js
@@ -144,6 +144,8 @@ module.exports = (path, options = {}) => {
'three',
'monaco-editor',
'monaco-yaml',
+ 'monaco-marker-data-provider',
+ 'monaco-worker-manager',
'fast-mersenne-twister',
'prosemirror-markdown',
'marked',
diff --git a/lib/api/helpers/personal_access_tokens_helpers.rb b/lib/api/helpers/personal_access_tokens_helpers.rb
index db28daa5396..4fd72d89f4c 100644
--- a/lib/api/helpers/personal_access_tokens_helpers.rb
+++ b/lib/api/helpers/personal_access_tokens_helpers.rb
@@ -4,11 +4,14 @@ module API
module Helpers
module PersonalAccessTokensHelpers
def finder_params(current_user)
- if current_user.can_admin_all_resources?
- { user: user(params[:user_id]) }
- else
- { user: current_user, impersonation: false }
- end
+ user_param =
+ if current_user.can_admin_all_resources?
+ { user: user(params[:user_id]) }
+ else
+ { user: current_user, impersonation: false }
+ end
+
+ declared(params, include_missing: false).merge(user_param)
end
def user(user_id)
diff --git a/lib/api/personal_access_tokens.rb b/lib/api/personal_access_tokens.rb
index 1c00569bba2..a2903faa4ad 100644
--- a/lib/api/personal_access_tokens.rb
+++ b/lib/api/personal_access_tokens.rb
@@ -11,7 +11,15 @@ module API
success Entities::PersonalAccessToken
end
params do
- optional :user_id, type: Integer, desc: 'User ID'
+ optional :user_id, type: Integer, desc: 'Filter PATs by User ID'
+ optional :revoked, type: Boolean, desc: 'Filter PATs where revoked state matches parameter'
+ optional :state, type: String, desc: 'Filter PATs which are either active or not',
+ values: %w[active inactive]
+ optional :created_before, type: DateTime, desc: 'Filter PATs which were created before given datetime'
+ optional :created_after, type: DateTime, desc: 'Filter PATs which were created after given datetime'
+ optional :last_used_before, type: DateTime, desc: 'Filter PATs which were used before given datetime'
+ optional :last_used_after, type: DateTime, desc: 'Filter PATs which were used after given datetime'
+ optional :search, type: String, desc: 'Filters PATs by its name'
use :pagination
end
diff --git a/lib/gitlab/usage/metrics/aggregates/aggregate.rb b/lib/gitlab/usage/metrics/aggregates/aggregate.rb
index 11e2fd22638..d8d089c8575 100644
--- a/lib/gitlab/usage/metrics/aggregates/aggregate.rb
+++ b/lib/gitlab/usage/metrics/aggregates/aggregate.rb
@@ -13,62 +13,72 @@ module Gitlab
end
def all_time_data
- aggregated_metrics_data(start_date: nil, end_date: nil, time_frame: Gitlab::Usage::TimeFrame::ALL_TIME_TIME_FRAME_NAME)
+ aggregated_metrics_data(Gitlab::Usage::TimeFrame::ALL_TIME_TIME_FRAME_NAME)
end
def monthly_data
- aggregated_metrics_data(**monthly_time_range.merge(time_frame: Gitlab::Usage::TimeFrame::TWENTY_EIGHT_DAYS_TIME_FRAME_NAME))
+ aggregated_metrics_data(Gitlab::Usage::TimeFrame::TWENTY_EIGHT_DAYS_TIME_FRAME_NAME)
end
def weekly_data
- aggregated_metrics_data(**weekly_time_range.merge(time_frame: Gitlab::Usage::TimeFrame::SEVEN_DAYS_TIME_FRAME_NAME))
+ aggregated_metrics_data(Gitlab::Usage::TimeFrame::SEVEN_DAYS_TIME_FRAME_NAME)
end
private
attr_accessor :aggregated_metrics, :recorded_at
- def aggregated_metrics_data(start_date:, end_date:, time_frame:)
+ def aggregated_metrics_data(time_frame)
aggregated_metrics.each_with_object({}) do |aggregation, data|
next if aggregation[:feature_flag] && Feature.disabled?(aggregation[:feature_flag], type: :development)
next unless aggregation[:time_frame].include?(time_frame)
- case aggregation[:source]
- when REDIS_SOURCE
- if time_frame == Gitlab::Usage::TimeFrame::ALL_TIME_TIME_FRAME_NAME
- data[aggregation[:name]] = Gitlab::Utils::UsageData::FALLBACK
- Gitlab::ErrorTracking
- .track_and_raise_for_dev_exception(
- DisallowedAggregationTimeFrame.new("Aggregation time frame: 'all' is not allowed for aggregation with source: '#{REDIS_SOURCE}'")
- )
- else
- data[aggregation[:name]] = calculate_count_for_aggregation(aggregation: aggregation, start_date: start_date, end_date: end_date)
- end
- when DATABASE_SOURCE
- data[aggregation[:name]] = calculate_count_for_aggregation(aggregation: aggregation, start_date: start_date, end_date: end_date)
- else
- Gitlab::ErrorTracking
- .track_and_raise_for_dev_exception(UnknownAggregationSource.new("Aggregation source: '#{aggregation[:source]}' must be included in #{SOURCES.keys}"))
+ data[aggregation[:name]] = calculate_count_for_aggregation(aggregation: aggregation, time_frame: time_frame)
+ end
+ end
- data[aggregation[:name]] = Gitlab::Utils::UsageData::FALLBACK
+ def calculate_count_for_aggregation(aggregation:, time_frame:)
+ with_validate_configuration(aggregation, time_frame) do
+ source = SOURCES[aggregation[:source]]
+
+ if aggregation[:operator] == UNION_OF_AGGREGATED_METRICS
+ source.calculate_metrics_union(**time_constraints(time_frame).merge(metric_names: aggregation[:events], recorded_at: recorded_at))
+ else
+ source.calculate_metrics_intersections(**time_constraints(time_frame).merge(metric_names: aggregation[:events], recorded_at: recorded_at))
end
end
+ rescue Gitlab::UsageDataCounters::HLLRedisCounter::EventError, AggregatedMetricError => error
+ failure(error)
end
- def calculate_count_for_aggregation(aggregation:, start_date:, end_date:)
- source = SOURCES[aggregation[:source]]
-
- case aggregation[:operator]
- when UNION_OF_AGGREGATED_METRICS
- source.calculate_metrics_union(metric_names: aggregation[:events], start_date: start_date, end_date: end_date, recorded_at: recorded_at)
- when INTERSECTION_OF_AGGREGATED_METRICS
- source.calculate_metrics_intersections(metric_names: aggregation[:events], start_date: start_date, end_date: end_date, recorded_at: recorded_at)
- else
- Gitlab::ErrorTracking
- .track_and_raise_for_dev_exception(UnknownAggregationOperator.new("Events should be aggregated with one of operators #{ALLOWED_METRICS_AGGREGATIONS}"))
- Gitlab::Utils::UsageData::FALLBACK
+ def with_validate_configuration(aggregation, time_frame)
+ source = aggregation[:source]
+
+ unless ALLOWED_METRICS_AGGREGATIONS.include?(aggregation[:operator])
+ return failure(
+ UnknownAggregationOperator
+ .new("Events should be aggregated with one of operators #{ALLOWED_METRICS_AGGREGATIONS}")
+ )
end
- rescue Gitlab::UsageDataCounters::HLLRedisCounter::EventError, AggregatedMetricError => error
+
+ unless SOURCES[source]
+ return failure(
+ UnknownAggregationSource
+ .new("Aggregation source: '#{source}' must be included in #{SOURCES.keys}")
+ )
+ end
+
+ if time_frame == Gitlab::Usage::TimeFrame::ALL_TIME_TIME_FRAME_NAME && source == REDIS_SOURCE
+ return failure(
+ DisallowedAggregationTimeFrame
+ .new("Aggregation time frame: 'all' is not allowed for aggregation with source: '#{REDIS_SOURCE}'")
+ )
+ end
+
+ yield
+ end
+
+ def failure(error)
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(error)
Gitlab::Utils::UsageData::FALLBACK
end
@@ -82,6 +92,17 @@ module Gitlab
def load_yaml_from_path(path)
YAML.safe_load(File.read(path), aliases: true)&.map(&:with_indifferent_access)
end
+
+ def time_constraints(time_frame)
+ case time_frame
+ when Gitlab::Usage::TimeFrame::TWENTY_EIGHT_DAYS_TIME_FRAME_NAME
+ monthly_time_range
+ when Gitlab::Usage::TimeFrame::SEVEN_DAYS_TIME_FRAME_NAME
+ weekly_time_range
+ when Gitlab::Usage::TimeFrame::ALL_TIME_TIME_FRAME_NAME
+ { start_date: nil, end_date: nil }
+ end
+ end
end
end
end
diff --git a/lib/gitlab/usage_data_counters/hll_redis_counter.rb b/lib/gitlab/usage_data_counters/hll_redis_counter.rb
index f0cb9bcbe94..81991df2d7d 100644
--- a/lib/gitlab/usage_data_counters/hll_redis_counter.rb
+++ b/lib/gitlab/usage_data_counters/hll_redis_counter.rb
@@ -25,7 +25,6 @@ module Gitlab
error_tracking
ide_edit
incident_management
- issues_edit
pipeline_authoring
quickactions
].freeze
@@ -39,6 +38,7 @@ module Gitlab
ide_edit
importer
incident_management_alerts
+ issues_edit
kubernetes_agent
pipeline_authoring
search
diff --git a/lib/gitlab/usage_data_counters/known_events/common.yml b/lib/gitlab/usage_data_counters/known_events/common.yml
index 29b231f88f8..50033fec939 100644
--- a/lib/gitlab/usage_data_counters/known_events/common.yml
+++ b/lib/gitlab/usage_data_counters/known_events/common.yml
@@ -192,14 +192,6 @@
category: issues_edit
redis_slot: project_management
aggregation: daily
-- name: g_project_management_issue_iteration_changed
- category: issues_edit
- redis_slot: project_management
- aggregation: daily
-- name: g_project_management_issue_weight_changed
- category: issues_edit
- redis_slot: project_management
- aggregation: daily
- name: g_project_management_issue_cross_referenced
category: issues_edit
redis_slot: project_management
@@ -228,18 +220,6 @@
category: issues_edit
redis_slot: project_management
aggregation: daily
-- name: g_project_management_issue_added_to_epic
- category: issues_edit
- redis_slot: project_management
- aggregation: daily
-- name: g_project_management_issue_removed_from_epic
- category: issues_edit
- redis_slot: project_management
- aggregation: daily
-- name: g_project_management_issue_changed_epic
- category: issues_edit
- redis_slot: project_management
- aggregation: daily
- name: g_project_management_issue_designs_added
category: issues_edit
redis_slot: project_management
@@ -276,10 +256,6 @@
category: issues_edit
redis_slot: project_management
aggregation: daily
-- name: g_project_management_issue_health_status_changed
- category: issues_edit
- redis_slot: project_management
- aggregation: daily
- name: g_project_management_issue_cloned
category: issues_edit
redis_slot: project_management
diff --git a/package.json b/package.json
index 1c081319831..6cad4af99d1 100644
--- a/package.json
+++ b/package.json
@@ -143,7 +143,7 @@
"minimatch": "^3.0.4",
"monaco-editor": "^0.30.1",
"monaco-editor-webpack-plugin": "^6.0.0",
- "monaco-yaml": "3.0.0",
+ "monaco-yaml": "4.0.0",
"mousetrap": "1.6.5",
"papaparse": "^5.3.1",
"patch-package": "^6.4.7",
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_commit_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_commit_spec.rb
index a1d8b495129..d6e9c1a13df 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_commit_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/cherry_pick/cherry_pick_commit_spec.rb
@@ -18,9 +18,7 @@ module QA
commit.branch = "development"
commit.start_branch = project.default_branch
commit.commit_message = 'Add new file'
- commit.add_files([
- { file_path: file_name, content: 'pssst!' }
- ])
+ commit.add_files([{ file_path: file_name, content: 'pssst!' }])
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb
index 6ce4217f8ac..d975e18e962 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/create_merge_request_via_template_spec.rb
@@ -20,12 +20,13 @@ module QA
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = template_project
commit.commit_message = 'Add custom merge request template'
- commit.add_files([
- {
- file_path: ".gitlab/merge_request_templates/#{template_name}.md",
- content: template_content
- }
- ])
+ commit.add_files(
+ [
+ {
+ file_path: ".gitlab/merge_request_templates/#{template_name}.md",
+ content: template_content
+ }
+ ])
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/revert/revert_commit_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/revert/revert_commit_spec.rb
index 8885163b5e3..205ff12ff03 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/revert/revert_commit_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/revert/revert_commit_spec.rb
@@ -16,9 +16,7 @@ module QA
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
commit.commit_message = 'Add new file'
- commit.add_files([
- { file_path: file_name, content: 'pssst!' }
- ])
+ commit.add_files([{ file_path: file_name, content: 'pssst!' }])
end
end
diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb
index aa332a76c94..0503b1b3761 100644
--- a/qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/repository/branch_with_unusual_name_spec.rb
@@ -22,9 +22,7 @@ module QA
commit.branch = branch_name
commit.start_branch = project.default_branch
commit.commit_message = 'Add new file'
- commit.add_files([
- { file_path: 'test-folder/test-file.md', content: 'new content' }
- ])
+ commit.add_files([{ file_path: 'test-folder/test-file.md', content: 'new content' }])
end
project.visit!
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb
index 9735aa7959a..561a5a2cc1c 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/add_new_directory_in_web_ide_spec.rb
@@ -22,12 +22,13 @@ module QA
before do
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = project
- commit.add_files([
- {
- file_path: 'first_directory/test_file.txt',
- content: "Test file content"
- }
- ])
+ commit.add_files(
+ [
+ {
+ file_path: 'first_directory/test_file.txt',
+ content: "Test file content"
+ }
+ ])
end
project.visit!
diff --git a/qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb b/qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb
index fc5754e2c7a..f03c651992c 100644
--- a/qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/web_ide/open_web_ide_from_diff_tab_spec.rb
@@ -4,18 +4,18 @@ module QA
RSpec.describe 'Create' do
describe 'Open Web IDE from Diff Tab' do
files = [
- {
- file_path: 'file1',
- content: 'test1'
- },
- {
- file_path: 'file2',
- content: 'test2'
- },
- {
- file_path: 'file3',
- content: 'test3'
- }
+ {
+ file_path: 'file1',
+ content: 'test1'
+ },
+ {
+ file_path: 'file2',
+ content: 'test2'
+ },
+ {
+ file_path: 'file3',
+ content: 'test3'
+ }
]
let(:project) do
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb
index 078465770c6..222d1993bf4 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb
@@ -51,16 +51,11 @@ module QA
commit.project = package_project
commit.commit_message = 'Add .gitlab-ci.yml'
- commit.add_files([
- {
- file_path: '.gitlab-ci.yml',
- content: helm_upload_yaml
- },
- {
- file_path: 'Chart.yaml',
- content: helm_chart_yaml
- }
- ])
+ commit.add_files(
+ [
+ { file_path: '.gitlab-ci.yml', content: helm_upload_yaml },
+ { file_path: 'Chart.yaml', content: helm_chart_yaml }
+ ])
end
end
@@ -94,12 +89,7 @@ module QA
commit.project = client_project
commit.commit_message = 'Add .gitlab-ci.yml'
- commit.add_files([
- {
- file_path: '.gitlab-ci.yml',
- content: helm_install_yaml
- }
- ])
+ commit.add_files([{ file_path: '.gitlab-ci.yml', content: helm_install_yaml }])
end
end
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb
index 921b36b34af..e65607630f8 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_group_level_spec.rb
@@ -54,20 +54,12 @@ module QA
commit.project = package_project
commit.commit_message = 'Add files'
- commit.add_files([
- {
- file_path: '.gitlab-ci.yml',
- content: maven_upload_package_yaml
- },
- {
- file_path: 'pom.xml',
- content: package_pom_xml
- },
- {
- file_path: 'settings.xml',
- content: settings_xml
- }
- ])
+ commit.add_files(
+ [
+ { file_path: '.gitlab-ci.yml', content: maven_upload_package_yaml },
+ { file_path: 'pom.xml', content: package_pom_xml },
+ { file_path: 'settings.xml', content: settings_xml }
+ ])
end
end
@@ -103,20 +95,12 @@ module QA
commit.project = client_project
commit.commit_message = 'Add files'
- commit.add_files([
- {
- file_path: '.gitlab-ci.yml',
- content: maven_install_package_yaml
- },
- {
- file_path: 'pom.xml',
- content: client_pom_xml
- },
- {
- file_path: 'settings.xml',
- content: settings_xml
- }
- ])
+ commit.add_files(
+ [
+ { file_path: '.gitlab-ci.yml', content: maven_install_package_yaml },
+ { file_path: 'pom.xml', content: client_pom_xml },
+ { file_path: 'settings.xml', content: settings_xml }
+ ])
end
end
@@ -251,15 +235,15 @@ module QA
package_pom_xml = ERB.new(read_fixture('package_managers/maven', 'package_pom.xml.erb')).result(binding)
with_fixtures([
- {
- file_path: 'pom.xml',
- content: package_pom_xml
- },
- {
- file_path: 'settings.xml',
- content: settings_xml_with_pat
- }
- ]) do |dir|
+ {
+ file_path: 'pom.xml',
+ content: package_pom_xml
+ },
+ {
+ file_path: 'settings.xml',
+ content: settings_xml_with_pat
+ }
+ ]) do |dir|
Service::DockerRun::Maven.new(dir).publish!
end
@@ -281,20 +265,12 @@ module QA
commit.project = client_project
commit.commit_message = 'Add .gitlab-ci.yml'
- commit.add_files([
- {
- file_path: '.gitlab-ci.yml',
- content: maven_upload_package_yaml
- },
- {
- file_path: 'pom.xml',
- content: package_pom_xml
- },
- {
- file_path: 'settings.xml',
- content: settings_xml
- }
- ])
+ commit.add_files(
+ [
+ { file_path: '.gitlab-ci.yml', content: maven_upload_package_yaml },
+ { file_path: 'pom.xml', content: package_pom_xml },
+ { file_path: 'settings.xml', content: settings_xml }
+ ])
end
end
end
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb
index 13607ba1b41..0af315af8a5 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven/maven_project_level_spec.rb
@@ -171,11 +171,12 @@ module QA
Resource::Repository::Commit.fabricate_via_api! do |commit|
commit.project = package_project
commit.commit_message = 'Add .gitlab-ci.yml'
- commit.add_files([
- gitlab_ci_file,
- pom_file,
- settings_xml
- ])
+ commit.add_files(
+ [
+ gitlab_ci_file,
+ pom_file,
+ settings_xml
+ ])
end
end
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb
index 45693ecee41..3c8561615f9 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/maven_gradle_repository_spec.rb
@@ -39,15 +39,10 @@ module QA
commit.project = package_project
commit.commit_message = 'Add .gitlab-ci.yml'
- commit.add_files([
- {
- file_path: '.gitlab-ci.yml',
- content: gradle_upload_yaml
- },
- {
- file_path: 'build.gradle',
- content: build_upload_gradle
- }
+ commit.add_files(
+ [
+ { file_path: '.gitlab-ci.yml', content: gradle_upload_yaml },
+ { file_path: 'build.gradle', content: build_upload_gradle }
])
end
end
@@ -83,16 +78,11 @@ module QA
commit.project = client_project
commit.commit_message = 'Add files'
- commit.add_files([
- {
- file_path: '.gitlab-ci.yml',
- content: gradle_install_yaml
- },
- {
- file_path: 'build.gradle',
- content: build_install_gradle
- }
- ])
+ commit.add_files(
+ [
+ { file_path: '.gitlab-ci.yml', content: gradle_install_yaml },
+ { file_path: 'build.gradle', content: build_install_gradle }
+ ])
end
end
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_group_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_group_level_spec.rb
index f229f30facc..e2a7006249d 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_group_level_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_group_level_spec.rb
@@ -105,14 +105,7 @@ module QA
nuget_upload_yaml = ERB.new(read_fixture('package_managers/nuget', 'nuget_upload_package.yaml.erb')).result(binding)
commit.project = project
commit.commit_message = 'Add .gitlab-ci.yml'
- commit.update_files(
- [
- {
- file_path: '.gitlab-ci.yml',
- content: nuget_upload_yaml
- }
- ]
- )
+ commit.update_files([{ file_path: '.gitlab-ci.yml', content: nuget_upload_yaml }])
end
end
@@ -137,9 +130,9 @@ module QA
commit.commit_message = 'Add new csproj file'
commit.add_files(
[
- {
- file_path: 'otherdotnet.csproj',
- content: <<~EOF
+ {
+ file_path: 'otherdotnet.csproj',
+ content: <<~EOF
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
@@ -148,18 +141,11 @@ module QA
</PropertyGroup>
</Project>
- EOF
- }
- ]
- )
- commit.update_files(
- [
- {
- file_path: '.gitlab-ci.yml',
- content: nuget_install_yaml
- }
+ EOF
+ }
]
)
+ commit.update_files([{ file_path: '.gitlab-ci.yml', content: nuget_install_yaml }])
end
end
diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_project_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_project_level_spec.rb
index e70b95db1a5..620bb7e4988 100644
--- a/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_project_level_spec.rb
+++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_project_level_spec.rb
@@ -101,9 +101,9 @@ module QA
commit.commit_message = 'Add files'
commit.update_files(
[
- {
- file_path: '.gitlab-ci.yml',
- content: <<~YAML
+ {
+ file_path: '.gitlab-ci.yml',
+ content: <<~YAML
stages:
- deploy
- install
@@ -132,11 +132,11 @@ module QA
- if: '$CI_COMMIT_BRANCH == "#{project.default_branch}"'
tags:
- "runner-for-#{project.name}"
- YAML
- },
- {
- file_path: 'dotnetcore.csproj',
- content: <<~EOF
+ YAML
+ },
+ {
+ file_path: 'dotnetcore.csproj',
+ content: <<~EOF
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
@@ -145,8 +145,8 @@ module QA
</PropertyGroup>
</Project>
- EOF
- }
+ EOF
+ }
]
)
end
diff --git a/spec/finders/personal_access_tokens_finder_spec.rb b/spec/finders/personal_access_tokens_finder_spec.rb
index f22bff62082..21380cb6632 100644
--- a/spec/finders/personal_access_tokens_finder_spec.rb
+++ b/spec/finders/personal_access_tokens_finder_spec.rb
@@ -7,6 +7,50 @@ RSpec.describe PersonalAccessTokensFinder do
described_class.new(options, current_user)
end
+ describe '# searches PATs' do
+ using RSpec::Parameterized::TableSyntax
+
+ let_it_be(:time_token) do
+ create(:personal_access_token, created_at: DateTime.new(2022, 01, 02),
+ last_used_at: DateTime.new(2022, 01, 02))
+ end
+
+ let_it_be(:name_token) { create(:personal_access_token, name: 'test_1') }
+
+ let_it_be(:impersonated_token) do
+ create(:personal_access_token, :impersonation,
+ created_at: DateTime.new(2022, 01, 02),
+ last_used_at: DateTime.new(2022, 01, 02),
+ name: 'imp_token'
+ )
+ end
+
+ shared_examples 'finding tokens by user and options' do
+ subject { finder(option, user).execute }
+
+ it 'finds exactly' do
+ subject
+
+ is_expected.to contain_exactly(*result)
+ end
+ end
+
+ context 'by' do
+ where(:option, :user, :result) do
+ { created_before: DateTime.new(2022, 01, 03) } | create(:admin) | lazy { [time_token, impersonated_token] }
+ { created_after: DateTime.new(2022, 01, 01) } | create(:admin) | lazy { [time_token, name_token, impersonated_token] }
+ { last_used_before: DateTime.new(2022, 01, 03) } | create(:admin) | lazy { [time_token, impersonated_token] }
+ { last_used_before: DateTime.new(2022, 01, 03) } | create(:admin) | lazy { [time_token, impersonated_token] }
+ { impersonation: true } | create(:admin) | lazy { [impersonated_token] }
+ { search: 'test' } | create(:admin) | lazy { [name_token] }
+ end
+
+ with_them do
+ it_behaves_like 'finding tokens by user and options'
+ end
+ end
+ end
+
describe '#execute' do
let(:user) { create(:user) }
let(:params) { {} }
diff --git a/spec/frontend/__mocks__/monaco-editor/index.js b/spec/frontend/__mocks__/monaco-editor/index.js
index 384f9993150..d09672a4ecf 100644
--- a/spec/frontend/__mocks__/monaco-editor/index.js
+++ b/spec/frontend/__mocks__/monaco-editor/index.js
@@ -8,10 +8,8 @@ import 'monaco-editor/esm/vs/language/css/monaco.contribution';
import 'monaco-editor/esm/vs/language/json/monaco.contribution';
import 'monaco-editor/esm/vs/language/html/monaco.contribution';
import 'monaco-editor/esm/vs/basic-languages/monaco.contribution';
-import 'monaco-yaml/lib/esm/monaco.contribution';
// This language starts trying to spin up web workers which obviously breaks in Jest environment
jest.mock('monaco-editor/esm/vs/language/typescript/tsMode');
-jest.mock('monaco-yaml/lib/esm/yamlMode');
export * from 'monaco-editor/esm/vs/editor/editor.api';
diff --git a/spec/frontend/__mocks__/monaco-yaml/index.js b/spec/frontend/__mocks__/monaco-yaml/index.js
new file mode 100644
index 00000000000..36681854d0b
--- /dev/null
+++ b/spec/frontend/__mocks__/monaco-yaml/index.js
@@ -0,0 +1,4 @@
+const setDiagnosticsOptions = jest.fn();
+const yamlDefaults = {};
+
+export { setDiagnosticsOptions, yamlDefaults };
diff --git a/spec/frontend/editor/source_editor_ci_schema_ext_spec.js b/spec/frontend/editor/source_editor_ci_schema_ext_spec.js
index 9a14e1a55eb..21f8979f1a9 100644
--- a/spec/frontend/editor/source_editor_ci_schema_ext_spec.js
+++ b/spec/frontend/editor/source_editor_ci_schema_ext_spec.js
@@ -1,4 +1,4 @@
-import { languages } from 'monaco-editor';
+import { setDiagnosticsOptions } from 'monaco-yaml';
import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
import { TEST_HOST } from 'helpers/test_constants';
import { CiSchemaExtension } from '~/editor/extensions/source_editor_ci_schema_ext';
@@ -52,16 +52,12 @@ describe('~/editor/editor_ci_config_ext', () => {
});
describe('registerCiSchema', () => {
- beforeEach(() => {
- jest.spyOn(languages.yaml.yamlDefaults, 'setDiagnosticsOptions');
- });
-
describe('register validations options with monaco for yaml language', () => {
const mockProjectNamespace = 'namespace1';
const mockProjectPath = 'project1';
const getConfiguredYmlSchema = () => {
- return languages.yaml.yamlDefaults.setDiagnosticsOptions.mock.calls[0][0].schemas[0];
+ return setDiagnosticsOptions.mock.calls[0][0].schemas[0];
};
it('with expected basic validation configuration', () => {
@@ -77,8 +73,8 @@ describe('~/editor/editor_ci_config_ext', () => {
completion: true,
};
- expect(languages.yaml.yamlDefaults.setDiagnosticsOptions).toHaveBeenCalledTimes(1);
- expect(languages.yaml.yamlDefaults.setDiagnosticsOptions).toHaveBeenCalledWith(
+ expect(setDiagnosticsOptions).toHaveBeenCalledTimes(1);
+ expect(setDiagnosticsOptions).toHaveBeenCalledWith(
expect.objectContaining(expectedOptions),
);
});
diff --git a/spec/frontend/ide/utils_spec.js b/spec/frontend/ide/utils_spec.js
index fd9d481251d..4efc0ac6028 100644
--- a/spec/frontend/ide/utils_spec.js
+++ b/spec/frontend/ide/utils_spec.js
@@ -1,4 +1,5 @@
import { languages } from 'monaco-editor';
+import { setDiagnosticsOptions as yamlDiagnosticsOptions } from 'monaco-yaml';
import {
isTextFile,
registerLanguages,
@@ -203,7 +204,6 @@ describe('WebIDE utils', () => {
};
jest.spyOn(languages.json.jsonDefaults, 'setDiagnosticsOptions');
- jest.spyOn(languages.yaml.yamlDefaults, 'setDiagnosticsOptions');
});
it('registers the given schemas with monaco for both json and yaml languages', () => {
@@ -212,7 +212,7 @@ describe('WebIDE utils', () => {
expect(languages.json.jsonDefaults.setDiagnosticsOptions).toHaveBeenCalledWith(
expect.objectContaining({ schemas: [schema] }),
);
- expect(languages.yaml.yamlDefaults.setDiagnosticsOptions).toHaveBeenCalledWith(
+ expect(yamlDiagnosticsOptions).toHaveBeenCalledWith(
expect.objectContaining({ schemas: [schema] }),
);
});
diff --git a/spec/frontend/projects/settings/branch_rules/branch_dropdown_spec.js b/spec/frontend/projects/settings/branch_rules/components/edit/branch_dropdown_spec.js
index 79bce5a4b3f..11f219c1f90 100644
--- a/spec/frontend/projects/settings/branch_rules/branch_dropdown_spec.js
+++ b/spec/frontend/projects/settings/branch_rules/components/edit/branch_dropdown_spec.js
@@ -4,7 +4,7 @@ import { GlDropdown, GlSearchBoxByType, GlDropdownItem, GlSprintf } from '@gitla
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import BranchDropdown, {
i18n,
-} from '~/projects/settings/branch_rules/components/branch_dropdown.vue';
+} from '~/projects/settings/branch_rules/components/edit/branch_dropdown.vue';
import createMockApollo from 'helpers/mock_apollo_helper';
import branchesQuery from '~/projects/settings/branch_rules/queries/branches.query.graphql';
import waitForPromises from 'helpers/wait_for_promises';
diff --git a/spec/frontend/projects/settings/branch_rules/rule_edit_spec.js b/spec/frontend/projects/settings/branch_rules/components/edit/index_spec.js
index b0b2b9191d4..21e63fdb24d 100644
--- a/spec/frontend/projects/settings/branch_rules/rule_edit_spec.js
+++ b/spec/frontend/projects/settings/branch_rules/components/edit/index_spec.js
@@ -1,9 +1,9 @@
import { nextTick } from 'vue';
import { getParameterByName } from '~/lib/utils/url_utility';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
-import RuleEdit from '~/projects/settings/branch_rules/components/rule_edit.vue';
-import BranchDropdown from '~/projects/settings/branch_rules/components/branch_dropdown.vue';
-import Protections from '~/projects/settings/branch_rules/components/protections/index.vue';
+import RuleEdit from '~/projects/settings/branch_rules/components/edit/index.vue';
+import BranchDropdown from '~/projects/settings/branch_rules/components/edit/branch_dropdown.vue';
+import Protections from '~/projects/settings/branch_rules/components/edit/protections/index.vue';
jest.mock('~/lib/utils/url_utility', () => ({
getParameterByName: jest.fn().mockImplementation(() => 'main'),
diff --git a/spec/frontend/projects/settings/branch_rules/components/protections/index_spec.js b/spec/frontend/projects/settings/branch_rules/components/edit/protections/index_spec.js
index 3592fa50622..ee90ff8318f 100644
--- a/spec/frontend/projects/settings/branch_rules/components/protections/index_spec.js
+++ b/spec/frontend/projects/settings/branch_rules/components/edit/protections/index_spec.js
@@ -3,10 +3,10 @@ import { GlLink } from '@gitlab/ui';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import Protections, {
i18n,
-} from '~/projects/settings/branch_rules/components/protections/index.vue';
-import PushProtections from '~/projects/settings/branch_rules/components/protections/push_protections.vue';
-import MergeProtections from '~/projects/settings/branch_rules/components/protections/merge_protections.vue';
-import { protections } from '../../mock_data';
+} from '~/projects/settings/branch_rules/components/edit/protections/index.vue';
+import PushProtections from '~/projects/settings/branch_rules/components/edit/protections/push_protections.vue';
+import MergeProtections from '~/projects/settings/branch_rules/components/edit/protections/merge_protections.vue';
+import { protections } from '../../../mock_data';
describe('Branch Protections', () => {
let wrapper;
diff --git a/spec/frontend/projects/settings/branch_rules/components/protections/merge_protections_spec.js b/spec/frontend/projects/settings/branch_rules/components/edit/protections/merge_protections_spec.js
index 0e168a2ad78..b5fdc46d600 100644
--- a/spec/frontend/projects/settings/branch_rules/components/protections/merge_protections_spec.js
+++ b/spec/frontend/projects/settings/branch_rules/components/edit/protections/merge_protections_spec.js
@@ -2,8 +2,8 @@ import { GlFormGroup, GlFormCheckbox } from '@gitlab/ui';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import MergeProtections, {
i18n,
-} from '~/projects/settings/branch_rules/components/protections/merge_protections.vue';
-import { membersAllowedToMerge, requireCodeOwnersApproval } from '../../mock_data';
+} from '~/projects/settings/branch_rules/components/edit/protections/merge_protections.vue';
+import { membersAllowedToMerge, requireCodeOwnersApproval } from '../../../mock_data';
describe('Merge Protections', () => {
let wrapper;
diff --git a/spec/frontend/projects/settings/branch_rules/components/protections/push_protections_spec.js b/spec/frontend/projects/settings/branch_rules/components/edit/protections/push_protections_spec.js
index d54dad08338..60bb7a51dcb 100644
--- a/spec/frontend/projects/settings/branch_rules/components/protections/push_protections_spec.js
+++ b/spec/frontend/projects/settings/branch_rules/components/edit/protections/push_protections_spec.js
@@ -2,8 +2,8 @@ import { GlFormGroup, GlSprintf, GlFormCheckbox } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import PushProtections, {
i18n,
-} from '~/projects/settings/branch_rules/components/protections/push_protections.vue';
-import { membersAllowedToPush, allowForcePush } from '../../mock_data';
+} from '~/projects/settings/branch_rules/components/edit/protections/push_protections.vue';
+import { membersAllowedToPush, allowForcePush } from '../../../mock_data';
describe('Push Protections', () => {
let wrapper;
diff --git a/spec/models/personal_access_token_spec.rb b/spec/models/personal_access_token_spec.rb
index 5bce6a2cc3f..67e7d444d25 100644
--- a/spec/models/personal_access_token_spec.rb
+++ b/spec/models/personal_access_token_spec.rb
@@ -105,6 +105,31 @@ RSpec.describe PersonalAccessToken do
end
end
+ describe '.last_used_before' do
+ context 'last_used_*' do
+ let_it_be(:date) { DateTime.new(2022, 01, 01) }
+ let_it_be(:token) { create(:personal_access_token, last_used_at: date ) }
+ # This token should never occur in the following tests and indicates that filtering was done correctly with it
+ let_it_be(:never_used_token) { create(:personal_access_token) }
+
+ describe '.last_used_before' do
+ it 'returns personal access tokens used before the specified date only' do
+ expect(described_class.last_used_before(date + 1)).to contain_exactly(token)
+ end
+ end
+
+ it 'does not return token that is last_used_at after given date' do
+ expect(described_class.last_used_before(date + 1)).not_to contain_exactly(never_used_token)
+ end
+
+ describe '.last_used_after' do
+ it 'returns personal access tokens used after the specified date only' do
+ expect(described_class.last_used_after(date - 1)).to contain_exactly(token)
+ end
+ end
+ end
+ end
+
describe '.last_used_before_or_unused' do
let(:last_used_at) { 1.month.ago.beginning_of_hour }
let!(:unused_token) { create(:personal_access_token) }
diff --git a/spec/models/preloaders/project_root_ancestor_preloader_spec.rb b/spec/models/preloaders/project_root_ancestor_preloader_spec.rb
index 30036a6a033..bb0de24abe5 100644
--- a/spec/models/preloaders/project_root_ancestor_preloader_spec.rb
+++ b/spec/models/preloaders/project_root_ancestor_preloader_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Preloaders::ProjectRootAncestorPreloader do
let_it_be(:root_parent1) { create(:group, :private, name: 'root-1', path: 'root-1') }
- let_it_be(:root_parent2) { create(:group, :private, name: 'root-2', path: 'root-2') }
+ let_it_be(:root_parent2) { create(:group, name: 'root-2', path: 'root-2') }
let_it_be(:guest_project) { create(:project, name: 'public guest', path: 'public-guest') }
let_it_be(:private_maintainer_project) do
create(:project, :private, name: 'b private maintainer', path: 'b-private-maintainer', namespace: root_parent1)
@@ -15,7 +15,7 @@ RSpec.describe Preloaders::ProjectRootAncestorPreloader do
end
let_it_be(:public_maintainer_project) do
- create(:project, :private, name: 'a public maintainer', path: 'a-public-maintainer', namespace: root_parent2)
+ create(:project, name: 'a public maintainer', path: 'a-public-maintainer', namespace: root_parent2)
end
let(:root_query_regex) { /\ASELECT.+FROM "namespaces" WHERE "namespaces"."id" = \d+/ }
@@ -36,20 +36,20 @@ RSpec.describe Preloaders::ProjectRootAncestorPreloader do
it 'strong_memoizes the correct root_ancestor' do
pristine_projects.each do |project|
- expected_parent_id = project.root_ancestor&.id
+ preloaded_parent_id = project.root_ancestor&.id
- expect(project.parent_id).to eq(expected_parent_id)
+ expect(preloaded_parent_id).to eq(project.parent_id)
end
end
end
context 'when use_traversal_ids FF is enabled' do
context 'when the preloader is used' do
- before do
- preload_ancestors
- end
-
context 'when no additional preloads are provided' do
+ before do
+ preload_ancestors(:group)
+ end
+
it_behaves_like 'executes N matching DB queries', 0
end
@@ -57,6 +57,10 @@ RSpec.describe Preloaders::ProjectRootAncestorPreloader do
let(:additional_preloads) { [:route] }
let(:root_query_regex) { /\ASELECT.+FROM "routes" WHERE "routes"."source_id" = \d+/ }
+ before do
+ preload_ancestors
+ end
+
it_behaves_like 'executes N matching DB queries', 0, :full_path
end
end
@@ -64,6 +68,17 @@ RSpec.describe Preloaders::ProjectRootAncestorPreloader do
context 'when the preloader is not used' do
it_behaves_like 'executes N matching DB queries', 4
end
+
+ context 'when using a :group sti name and passing projects in a user namespace' do
+ let(:projects) { [private_developer_project] }
+ let(:additional_preloads) { [:ip_restrictions, :saml_provider] }
+
+ it 'does not load a nil value for root_ancestor' do
+ preload_ancestors(:group)
+
+ expect(pristine_projects.first.root_ancestor).to eq(private_developer_project.root_ancestor)
+ end
+ end
end
context 'when use_traversal_ids FF is disabled' do
@@ -91,9 +106,22 @@ RSpec.describe Preloaders::ProjectRootAncestorPreloader do
context 'when the preloader is not used' do
it_behaves_like 'executes N matching DB queries', 4
end
+
+ context 'when using a :group sti name and passing projects in a user namespace' do
+ let(:projects) { [private_developer_project] }
+ let(:additional_preloads) { [:ip_restrictions, :saml_provider] }
+
+ it 'does not load a nil value for root_ancestor' do
+ preload_ancestors(:group)
+
+ expect(pristine_projects.first.root_ancestor).to eq(private_developer_project.root_ancestor)
+ end
+ end
end
- def preload_ancestors
- described_class.new(pristine_projects, :namespace, additional_preloads).execute
+ private
+
+ def preload_ancestors(namespace_sti_name = :namespace)
+ described_class.new(pristine_projects, namespace_sti_name, additional_preloads).execute
end
end
diff --git a/spec/requests/api/personal_access_tokens_spec.rb b/spec/requests/api/personal_access_tokens_spec.rb
index 37b5a594f2a..31c4e8803e3 100644
--- a/spec/requests/api/personal_access_tokens_spec.rb
+++ b/spec/requests/api/personal_access_tokens_spec.rb
@@ -4,14 +4,34 @@ require 'spec_helper'
RSpec.describe API::PersonalAccessTokens do
let_it_be(:path) { '/personal_access_tokens' }
- let_it_be(:token1) { create(:personal_access_token) }
- let_it_be(:token2) { create(:personal_access_token) }
- let_it_be(:token_impersonated) { create(:personal_access_token, impersonation: true, user: token1.user) }
- let_it_be(:current_user) { create(:user) }
describe 'GET /personal_access_tokens' do
+ using RSpec::Parameterized::TableSyntax
+
+ def map_id(json_resonse)
+ json_response.map { |pat| pat['id'] }
+ end
+
+ shared_examples 'response as expected' do |params|
+ subject { get api(path, personal_access_token: current_users_token), params: params }
+
+ it "status, count and result as expected" do
+ subject
+
+ if status == :bad_request
+ expect(json_response).to eq(result)
+ elsif status == :ok
+ expect(map_id(json_response)).to a_collection_containing_exactly(*result)
+ end
+
+ expect(response).to have_gitlab_http_status(status)
+ expect(json_response.count).to eq(result_count)
+ end
+ end
+
context 'logged in as an Administrator' do
let_it_be(:current_user) { create(:admin) }
+ let_it_be(:current_users_token) { create(:personal_access_token, user: current_user) }
it 'returns all PATs by default' do
get api(path, current_user)
@@ -21,60 +41,348 @@ RSpec.describe API::PersonalAccessTokens do
end
context 'filtered with user_id parameter' do
+ let_it_be(:token) { create(:personal_access_token) }
+ let_it_be(:token_impersonated) { create(:personal_access_token, impersonation: true, user: token.user) }
+
it 'returns only PATs belonging to that user' do
- get api(path, current_user), params: { user_id: token1.user.id }
+ get api(path, current_user), params: { user_id: token.user.id }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.count).to eq(2)
- expect(json_response.first['user_id']).to eq(token1.user.id)
+ expect(json_response.first['user_id']).to eq(token.user.id)
expect(json_response.last['id']).to eq(token_impersonated.id)
end
end
- context 'logged in as a non-Administrator' do
- let_it_be(:current_user) { create(:user) }
+ context 'filter with revoked parameter' do
+ let_it_be(:revoked_token) { create(:personal_access_token, revoked: true) }
+ let_it_be(:not_revoked_token1) { create(:personal_access_token, revoked: false) }
+ let_it_be(:not_revoked_token2) { create(:personal_access_token, revoked: false) }
+
+ where(:revoked, :status, :result_count, :result) do
+ true | :ok | 1 | lazy { [revoked_token.id] }
+ false | :ok | 3 | lazy { [not_revoked_token1.id, not_revoked_token2.id, current_users_token.id] }
+ 'asdf' | :bad_request | 1 | { "error" => "revoked is invalid" }
+ end
+
+ with_them do
+ it_behaves_like 'response as expected', revoked: params[:revoked]
+ end
+ end
+
+ context 'filter with active parameter' do
+ let_it_be(:inactive_token1) { create(:personal_access_token, revoked: true) }
+ let_it_be(:inactive_token2) { create(:personal_access_token, expires_at: Time.new(2022, 01, 01, 00, 00, 00)) }
+ let_it_be(:active_token) { create(:personal_access_token) }
+
+ where(:state, :status, :result_count, :result) do
+ 'inactive' | :ok | 2 | lazy { [inactive_token1.id, inactive_token2.id] }
+ 'active' | :ok | 2 | lazy { [active_token.id, current_users_token.id] }
+ 'asdf' | :bad_request | 1 | { "error" => "state does not have a valid value" }
+ end
+
+ with_them do
+ it_behaves_like 'response as expected', state: params[:state]
+ end
+ end
+
+ context 'filter with created parameter' do
+ let_it_be(:token1) { create(:personal_access_token, created_at: DateTime.new(2022, 01, 01, 12, 30, 25) ) }
+
+ context 'test created_before' do
+ where(:created_at, :status, :result_count, :result) do
+ '2022-01-02' | :ok | 1 | lazy { [token1.id] }
+ '2022-01-01' | :ok | 0 | lazy { [] }
+ '2022-01-01T12:30:24' | :ok | 0 | lazy { [] }
+ '2022-01-01T12:30:25' | :ok | 1 | lazy { [token1.id] }
+ '2022-01-01T:12:30:26' | :ok | 1 | lazy { [token1.id] }
+ 'asdf' | :bad_request | 1 | { "error" => "created_before is invalid" }
+ end
+
+ with_them do
+ it_behaves_like 'response as expected', created_before: params[:created_at]
+ end
+ end
+
+ context 'test created_after' do
+ where(:created_at, :status, :result_count, :result) do
+ '2022-01-03' | :ok | 1 | lazy { [current_users_token.id] }
+ '2022-01-01' | :ok | 2 | lazy { [token1.id, current_users_token.id] }
+ '2022-01-01T12:30:25' | :ok | 2 | lazy { [token1.id, current_users_token.id] }
+ '2022-01-01T12:30:26' | :ok | 1 | lazy { [current_users_token.id] }
+ (DateTime.now + 1).to_s | :ok | 0 | lazy { [] }
+ 'asdf' | :bad_request | 1 | { "error" => "created_after is invalid" }
+ end
+
+ with_them do
+ it_behaves_like 'response as expected', created_after: params[:created_at]
+ end
+ end
+ end
+
+ context 'filter with last_used parameter' do
+ let_it_be(:token1) { create(:personal_access_token, last_used_at: DateTime.new(2022, 01, 01, 12, 30, 25) ) }
+ let_it_be(:never_used_token) { create(:personal_access_token) }
+
+ context 'test last_used_before' do
+ where(:last_used_at, :status, :result_count, :result) do
+ '2022-01-02' | :ok | 1 | lazy { [token1.id] }
+ '2022-01-01' | :ok | 0 | lazy { [] }
+ '2022-01-01T12:30:24' | :ok | 0 | lazy { [] }
+ '2022-01-01T12:30:25' | :ok | 1 | lazy { [token1.id] }
+ '2022-01-01T12:30:26' | :ok | 1 | lazy { [token1.id] }
+ 'asdf' | :bad_request | 1 | { "error" => "last_used_before is invalid" }
+ end
+
+ with_them do
+ it_behaves_like 'response as expected', last_used_before: params[:last_used_at]
+ end
+ end
+
+ context 'test last_used_after' do
+ where(:last_used_at, :status, :result_count, :result) do
+ '2022-01-03' | :ok | 1 | lazy { [current_users_token.id] }
+ '2022-01-01' | :ok | 2 | lazy { [token1.id, current_users_token.id] }
+ '2022-01-01T12:30:26' | :ok | 1 | lazy { [current_users_token.id] }
+ '2022-01-01T12:30:25' | :ok | 2 | lazy { [token1.id, current_users_token.id] }
+ (DateTime.now + 1).to_s | :ok | 0 | lazy { [] }
+ 'asdf' | :bad_request | 1 | { "error" => "last_used_after is invalid" }
+ end
+
+ with_them do
+ it_behaves_like 'response as expected', last_used_after: params[:last_used_at]
+ end
+ end
+ end
+
+ context 'filter with search parameter' do
+ let_it_be(:token1) { create(:personal_access_token, name: 'test_1') }
+ let_it_be(:token2) { create(:personal_access_token, name: 'test_2') }
+ let_it_be(:token3) { create(:personal_access_token, name: '') }
+
+ where(:pattern, :status, :result_count, :result) do
+ 'test' | :ok | 2 | lazy { [token1.id, token2.id] }
+ '' | :ok | 4 | lazy { [token1.id, token2.id, token3.id, current_users_token.id] }
+ 'test_1' | :ok | 1 | lazy { [token1.id] }
+ 'asdf' | :ok | 0 | lazy { [] }
+ end
+
+ with_them do
+ it_behaves_like 'response as expected', search: params[:pattern]
+ end
+ end
+
+ context 'filter created_before/created_after combined with last_used_before/last_used_after' do
+ let_it_be(:date) { DateTime.new(2022, 01, 02) }
+ let_it_be(:token1) { create(:personal_access_token, created_at: date, last_used_at: date) }
+
+ where(:date_before, :date_after, :status, :result_count, :result) do
+ '2022-01-03' | '2022-01-01' | :ok | 1 | lazy { [token1.id] }
+ '2022-01-01' | '2022-01-03' | :ok | 0 | lazy { [] }
+ '2022-01-03' | nil | :ok | 1 | lazy { [token1.id] }
+ nil | '2022-01-01' | :ok | 2 | lazy { [token1.id, current_users_token.id] }
+ end
+
+ with_them do
+ it_behaves_like 'response as expected', { created_before: params[:date_before],
+ created_after: params[:date_after] }
+ it_behaves_like 'response as expected', { last_used_before: params[:date_before],
+ last_used_after: params[:date_after] }
+ end
+ end
+
+ context 'filter created_before and created_after combined is valid' do
+ let_it_be(:token1) { create(:personal_access_token, created_at: DateTime.new(2022, 01, 02)) }
+
+ where(:created_before, :created_after, :status, :result) do
+ '2022-01-02' | '2022-01-02' | :ok | lazy { [token1.id] }
+ '2022-01-03' | '2022-01-01' | :ok | lazy { [token1.id] }
+ '2022-01-01' | '2022-01-03' | :ok | lazy { [] }
+ '2022-01-03' | nil | :ok | lazy { [token1.id] }
+ nil | '2022-01-01' | :ok | lazy { [token1.id] }
+ end
+
+ with_them do
+ it "returns all valid tokens" do
+ get api(path, personal_access_token: current_users_token),
+ params: { created_before: created_before, created_after: created_after }
+
+ expect(response).to have_gitlab_http_status(status)
+
+ expect(json_response.map { |pat| pat['id'] } ).to include(*result) if status == :ok
+ end
+ end
+ end
+
+ context 'filter last_used_before and last_used_after combined is valid' do
+ let_it_be(:token1) { create(:personal_access_token, last_used_at: DateTime.new(2022, 01, 02) ) }
+
+ where(:last_used_before, :last_used_after, :status, :result) do
+ '2022-01-02' | '2022-01-02' | :ok | lazy { [token1.id] }
+ '2022-01-03' | '2022-01-01' | :ok | lazy { [token1.id] }
+ '2022-01-01' | '2022-01-03' | :ok | lazy { [] }
+ '2022-01-03' | nil | :ok | lazy { [token1.id] }
+ nil | '2022-01-01' | :ok | lazy { [token1.id] }
+ end
+
+ with_them do
+ it "returns all valid tokens" do
+ get api(path, personal_access_token: current_users_token),
+ params: { last_used_before: last_used_before, last_used_after: last_used_after }
+
+ expect(response).to have_gitlab_http_status(status)
+
+ expect(json_response.map { |pat| pat['id'] } ).to include(*result) if status == :ok
+ end
+ end
+ end
+ end
+
+ context 'logged in as a non-Administrator' do
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:current_users_token) { create(:personal_access_token, user: current_user) }
+
+ it 'returns all PATs belonging to the signed-in user' do
+ get api(path, personal_access_token: current_users_token)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response.count).to eq(1)
+ expect(json_response.map { |r| r['id'] }.uniq).to contain_exactly(current_users_token.id)
+ expect(json_response.map { |r| r['user_id'] }.uniq).to contain_exactly(current_user.id)
+ end
+
+ context 'filtered with user_id parameter' do
let_it_be(:user) { create(:user) }
- let_it_be(:token) { create(:personal_access_token, user: current_user) }
- let_it_be(:other_token) { create(:personal_access_token, user: user) }
- let_it_be(:token_impersonated) { create(:personal_access_token, impersonation: true, user: current_user) }
- it 'returns all PATs belonging to the signed-in user' do
- get api(path, current_user, personal_access_token: token)
+ it 'returns PATs belonging to the specific user' do
+ get api(path, current_user, personal_access_token: current_users_token), params: { user_id: current_user.id }
expect(response).to have_gitlab_http_status(:ok)
expect(json_response.count).to eq(1)
+ expect(json_response.map { |r| r['id'] }.uniq).to contain_exactly(current_users_token.id)
expect(json_response.map { |r| r['user_id'] }.uniq).to contain_exactly(current_user.id)
end
- context 'filtered with user_id parameter' do
- it 'returns PATs belonging to the specific user' do
- get api(path, current_user, personal_access_token: token), params: { user_id: current_user.id }
+ it 'is unauthorized if filtered by a user other than current_user' do
+ get api(path, current_user, personal_access_token: current_users_token), params: { user_id: user.id }
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response.count).to eq(1)
- expect(json_response.map { |r| r['user_id'] }.uniq).to contain_exactly(current_user.id)
- end
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ end
+ end
- it 'is unauthorized if filtered by a user other than current_user' do
- get api(path, current_user, personal_access_token: token), params: { user_id: user.id }
+ context 'filter with revoked parameter' do
+ let_it_be(:users_revoked_token) { create(:personal_access_token, revoked: true, user: current_user) }
+ let_it_be(:not_revoked_token) { create(:personal_access_token, revoked: false) }
+ let_it_be(:oter_revoked_token) { create(:personal_access_token, revoked: true) }
- expect(response).to have_gitlab_http_status(:unauthorized)
- end
+ where(:revoked, :status, :result_count, :result) do
+ true | :ok | 1 | lazy { [users_revoked_token.id] }
+ false | :ok | 1 | lazy { [current_users_token.id] }
+ end
+
+ with_them do
+ it_behaves_like 'response as expected', revoked: params[:revoked]
end
end
- context 'not authenticated' do
- it 'is forbidden' do
- get api(path)
+ context 'filter with active parameter' do
+ let_it_be(:users_inactive_token) { create(:personal_access_token, revoked: true, user: current_user) }
+ let_it_be(:inactive_token) { create(:personal_access_token, expires_at: Time.new(2022, 01, 01, 00, 00, 00)) }
+ let_it_be(:other_active_token) { create(:personal_access_token) }
- expect(response).to have_gitlab_http_status(:unauthorized)
+ where(:state, :status, :result_count, :result) do
+ 'inactive' | :ok | 1 | lazy { [users_inactive_token.id] }
+ 'active' | :ok | 1 | lazy { [current_users_token.id] }
+ end
+
+ with_them do
+ it_behaves_like 'response as expected', state: params[:state]
+ end
+ end
+
+ # The created_before filter has been extensively tested in the 'logged in as administrator' section.
+ # Here it is only tested whether PATs to which the user has no access right are excluded from the filter function.
+ context 'filter with created parameter' do
+ let_it_be(:token1) do
+ create(:personal_access_token, created_at: DateTime.new(2022, 01, 02, 12, 30, 25), user: current_user )
+ end
+
+ let_it_be(:token2) { create(:personal_access_token, created_at: DateTime.new(2022, 01, 02, 12, 30, 25)) }
+ let_it_be(:status) { :ok }
+
+ context 'created_before' do
+ let_it_be(:result_count) { 1 }
+ let_it_be(:result) { [token1.id] }
+
+ it_behaves_like 'response as expected', created_before: '2022-01-03'
+ end
+
+ context 'created_after' do
+ let_it_be(:result_count) { 2 }
+ let_it_be(:result) { [token1.id, current_users_token.id] }
+
+ it_behaves_like 'response as expected', created_after: '2022-01-01'
+ end
+ end
+
+ # The last_used_before filter has been extensively tested in the 'logged in as administrator' section.
+ # Here it is only tested whether PATs to which the user has no access right are excluded from the filter function.
+ context 'filter with last_used' do
+ let_it_be(:token1) do
+ create(:personal_access_token, last_used_at: DateTime.new(2022, 01, 01, 12, 30, 25), user: current_user)
+ end
+
+ let_it_be(:token2) { create(:personal_access_token, last_used_at: DateTime.new(2022, 01, 01, 12, 30, 25) ) }
+ let_it_be(:never_used_token) { create(:personal_access_token) }
+ let_it_be(:status) { :ok }
+
+ context 'last_used_before' do
+ let_it_be(:result_count) { 1 }
+ let_it_be(:result) { [token1.id] }
+
+ it_behaves_like 'response as expected', last_used_before: '2022-01-02'
+ end
+
+ context 'last_used_after' do
+ let_it_be(:result_count) { 2 }
+ let_it_be(:result) { [token1.id, current_users_token.id] }
+
+ it_behaves_like 'response as expected', last_used_after: '2022-01-01'
+ end
+ end
+
+ # The search filter has been extensively tested in the 'logged in as administrator' section.
+ # Here it is only tested whether PATs to which the user has no access right are excluded from the filter function.
+ context 'filter with search parameter' do
+ let_it_be(:token1) { create(:personal_access_token, name: 'test_1', user: current_user) }
+ let_it_be(:token2) { create(:personal_access_token, name: 'test_1') }
+ let_it_be(:token3) { create(:personal_access_token, name: '') }
+
+ where(:pattern, :status, :result_count, :result) do
+ 'test' | :ok | 1 | lazy { [token1.id] }
+ '' | :ok | 2 | lazy { [token1.id, current_users_token.id] }
+ 'test_1' | :ok | 1 | lazy { [token1.id] }
+ end
+
+ with_them do
+ it_behaves_like 'response as expected', search: params[:pattern]
end
end
end
+
+ context 'not authenticated' do
+ it 'is forbidden' do
+ get api(path)
+
+ expect(response).to have_gitlab_http_status(:unauthorized)
+ end
+ end
end
describe 'GET /personal_access_tokens/:id' do
+ let_it_be(:current_user) { create(:user) }
let_it_be(:user_token) { create(:personal_access_token, user: current_user) }
+ let_it_be(:token1) { create(:personal_access_token) }
let_it_be(:user_read_only_token) { create(:personal_access_token, scopes: ['read_repository'], user: current_user) }
let_it_be(:user_token_path) { "/personal_access_tokens/#{user_token.id}" }
let_it_be(:invalid_path) { "/personal_access_tokens/#{non_existing_record_id}" }
@@ -136,6 +444,9 @@ RSpec.describe API::PersonalAccessTokens do
end
describe 'DELETE /personal_access_tokens/:id' do
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:token1) { create(:personal_access_token) }
+
let(:path) { "/personal_access_tokens/#{token1.id}" }
context 'when current_user is an administrator', :enable_admin_mode do
diff --git a/yarn.lock b/yarn.lock
index 8c8eadc8e49..30e8a148a7f 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2047,10 +2047,10 @@
jest-matcher-utils "^27.0.0"
pretty-format "^27.0.0"
-"@types/json-schema@^7.0.3", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
- version "7.0.9"
- resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d"
- integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==
+"@types/json-schema@^7.0.0", "@types/json-schema@^7.0.3", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9":
+ version "7.0.11"
+ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3"
+ integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==
"@types/json5@^0.0.29":
version "0.0.29"
@@ -7492,7 +7492,7 @@ js-sdsl@^4.1.4:
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
-js-yaml@^3.13.1, js-yaml@^3.14.1:
+js-yaml@^3.13.1:
version "3.14.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537"
integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==
@@ -7587,7 +7587,7 @@ json5@^2.1.2, json5@^2.2.1:
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c"
integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==
-jsonc-parser@~3.1.0:
+jsonc-parser@^3.0.0, jsonc-parser@~3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.1.0.tgz#73b8f0e5c940b83d03476bc2e51a20ef0932615d"
integrity sha512-DRf0QjnNeCUds3xTjKlQQ3DpJD51GvDjJfnxUVWg6PZTo2otSm+slzNAxU/35hF8/oJIKoG9slq30JYOsF2azg==
@@ -8840,14 +8840,31 @@ monaco-editor@^0.30.1:
resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.30.1.tgz#47f8d18a0aa2264fc5654581741ab8d7bec01689"
integrity sha512-B/y4+b2O5G2gjuxIFtCE2EkM17R2NM7/3F8x0qcPsqy4V83bitJTIO4TIeZpYlzu/xy6INiY/+84BEm6+7Cmzg==
-monaco-yaml@3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/monaco-yaml/-/monaco-yaml-3.0.0.tgz#b3d59c3485bd5a161438072a8e5a8aaf74041dfd"
- integrity sha512-WkgdfjCj0L2VPPwPoiwc4l8+B78FyVpSsMoufEWqe3ukm8+WygKUtmtCFOFnehmMih6tSqhy4DUtoAhfnicyZA==
- dependencies:
- "@types/json-schema" "^7.0.8"
- js-yaml "^3.14.1"
- yaml-ast-parser-custom-tags "^0.0.43"
+monaco-marker-data-provider@^1.0.0:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/monaco-marker-data-provider/-/monaco-marker-data-provider-1.1.1.tgz#0ca69f367152f5aa12cec2bda95f32b7403e876f"
+ integrity sha512-PGB7TJSZE5tmHzkxv/OEwK2RGNC2A7dcq4JRJnnj31CUAsfmw0Gl+1QTrH0W0deKhcQmQM0YVPaqgQ+0wCt8Mg==
+
+monaco-worker-manager@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/monaco-worker-manager/-/monaco-worker-manager-2.0.1.tgz#f67c54dfca34ed4b225d5de84e77b24b4e36de8a"
+ integrity sha512-kdPL0yvg5qjhKPNVjJoym331PY/5JC11aPJXtCZNwWRvBr6jhkIamvYAyiY5P1AWFmNOy0aRDRoMdZfa71h8kg==
+
+monaco-yaml@4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/monaco-yaml/-/monaco-yaml-4.0.0.tgz#3bf8624f984665aba7e5f10c4987cecf2890e89b"
+ integrity sha512-7/CbvZIHE1iOQF6ny+uPclcsrBnkK54lcZugIB9SzqADljhb3TliJyYs7vouaGNDF73RWvrtZrMsWCC5N/GW+g==
+ dependencies:
+ "@types/json-schema" "^7.0.0"
+ jsonc-parser "^3.0.0"
+ monaco-marker-data-provider "^1.0.0"
+ monaco-worker-manager "^2.0.0"
+ path-browserify "^1.0.0"
+ prettier "^2.0.0"
+ vscode-languageserver-textdocument "^1.0.0"
+ vscode-languageserver-types "^3.0.0"
+ vscode-uri "^3.0.0"
+ yaml "^2.0.0"
mousetrap@1.6.5:
version "1.6.5"
@@ -9437,6 +9454,11 @@ path-browserify@0.0.1:
resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a"
integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==
+path-browserify@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd"
+ integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==
+
path-exists@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515"
@@ -9670,7 +9692,7 @@ pretender@^3.4.3:
fake-xml-http-request "^2.1.1"
route-recognizer "^0.3.3"
-prettier@2.2.1, "prettier@^1.18.2 || ^2.0.0":
+prettier@2.2.1, "prettier@^1.18.2 || ^2.0.0", prettier@^2.0.0:
version "2.2.1"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5"
integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==
@@ -11881,6 +11903,21 @@ vm-browserify@^1.0.1:
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.0.tgz#bd76d6a23323e2ca8ffa12028dc04559c75f9019"
integrity sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==
+vscode-languageserver-textdocument@^1.0.0:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.5.tgz#838769940ece626176ec5d5a2aa2d0aa69f5095c"
+ integrity sha512-1ah7zyQjKBudnMiHbZmxz5bYNM9KKZYz+5VQLj+yr8l+9w3g+WAhCkUkWbhMEdC5u0ub4Ndiye/fDyS8ghIKQg==
+
+vscode-languageserver-types@^3.0.0:
+ version "3.17.2"
+ resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2.tgz#b2c2e7de405ad3d73a883e91989b850170ffc4f2"
+ integrity sha512-zHhCWatviizPIq9B7Vh9uvrH6x3sK8itC84HkamnBWoDFJtzBf7SWlpLCZUit72b3os45h6RWQNC9xHRDF8dRA==
+
+vscode-uri@^3.0.0:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.3.tgz#a95c1ce2e6f41b7549f86279d19f47951e4f4d84"
+ integrity sha512-EcswR2S8bpR7fD0YPeS7r2xXExrScVMxg4MedACaWHEtx9ftCF/qHG1xGkolzTPcEmjTavCQgbVzHUIdTMzFGA==
+
vue-apollo@^3.0.7:
version "3.0.7"
resolved "https://registry.yarnpkg.com/vue-apollo/-/vue-apollo-3.0.7.tgz#97a031d45641faa4888a6d5a7f71c40834359704"
@@ -12402,20 +12439,15 @@ yallist@^4.0.0:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
-yaml-ast-parser-custom-tags@^0.0.43:
- version "0.0.43"
- resolved "https://registry.yarnpkg.com/yaml-ast-parser-custom-tags/-/yaml-ast-parser-custom-tags-0.0.43.tgz#46968145ce4e24cb03c3312057f0f141b93a7d02"
- integrity sha512-R5063FF/JSAN6qXCmylwjt9PcDH6M0ExEme/nJBzLspc6FJDmHHIqM7xh2WfEmsTJqClF79A9VkXjkAqmZw9SQ==
-
yaml@^1.10.0:
version "1.10.2"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
-yaml@^2.0.0-10:
- version "2.0.0-10"
- resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.0.0-10.tgz#d5b59e2d14b8683313a534f2bbc648e211a2753e"
- integrity sha512-FHV8s5ODFFQXX/enJEU2EkanNl1UDBUz8oa4k5Qo/sR+Iq7VmhCDkRMb0/mjJCNeAWQ31W8WV6PYStDE4d9EIw==
+yaml@^2.0.0, yaml@^2.0.0-10:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.1.1.tgz#1e06fb4ca46e60d9da07e4f786ea370ed3c3cfec"
+ integrity sha512-o96x3OPo8GjWeSLF+wOAbrPfhFOGY0W00GNaxCDv+9hkcDJEnev1yh8S7pgHF0ik6zc8sQLuL8hjHjJULZp8bw==
yargs-parser@^20.2.2, yargs-parser@^20.2.3:
version "20.2.9"