Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
b2362c5f21
commit
a7b422860c
53 changed files with 921 additions and 378 deletions
|
@ -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'
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.'),
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}"
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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' }),
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 |
|
||||
|
||||
|
|
|
@ -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
|
||||
```
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]] = Gitlab::Utils::UsageData::FALLBACK
|
||||
end
|
||||
data[aggregation[:name]] = calculate_count_for_aggregation(aggregation: aggregation, time_frame: time_frame)
|
||||
end
|
||||
end
|
||||
|
||||
def calculate_count_for_aggregation(aggregation:, start_date:, end_date:)
|
||||
source = SOURCES[aggregation[:source]]
|
||||
def calculate_count_for_aggregation(aggregation:, time_frame:)
|
||||
with_validate_configuration(aggregation, time_frame) do
|
||||
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
|
||||
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 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
|
||||
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) { {} }
|
||||
|
|
|
@ -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';
|
||||
|
|
4
spec/frontend/__mocks__/monaco-yaml/index.js
Normal file
4
spec/frontend/__mocks__/monaco-yaml/index.js
Normal file
|
@ -0,0 +1,4 @@
|
|||
const setDiagnosticsOptions = jest.fn();
|
||||
const yamlDefaults = {};
|
||||
|
||||
export { setDiagnosticsOptions, yamlDefaults };
|
|
@ -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),
|
||||
);
|
||||
});
|
||||
|
|
|
@ -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] }),
|
||||
);
|
||||
});
|
||||
|
|
|
@ -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';
|
|
@ -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'),
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
@ -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) }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) }
|
||||
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) }
|
||||
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) }
|
||||
|
||||
it 'returns all PATs belonging to the signed-in user' do
|
||||
get api(path, current_user, personal_access_token: token)
|
||||
|
||||
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)
|
||||
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
|
||||
|
||||
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 }
|
||||
with_them do
|
||||
it_behaves_like 'response as expected', revoked: params[:revoked]
|
||||
end
|
||||
end
|
||||
|
||||
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)
|
||||
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
|
||||
|
||||
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 }
|
||||
with_them do
|
||||
it_behaves_like 'response as expected', created_before: params[:created_at]
|
||||
end
|
||||
end
|
||||
|
||||
expect(response).to have_gitlab_http_status(:unauthorized)
|
||||
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 'not authenticated' do
|
||||
it 'is forbidden' do
|
||||
get api(path)
|
||||
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) }
|
||||
|
||||
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
|
||||
|
||||
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(:unauthorized)
|
||||
end
|
||||
end
|
||||
|
||||
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) }
|
||||
|
||||
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 '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) }
|
||||
|
||||
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
|
||||
|
|
78
yarn.lock
78
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==
|
||||
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.8"
|
||||
js-yaml "^3.14.1"
|
||||
yaml-ast-parser-custom-tags "^0.0.43"
|
||||
"@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"
|
||||
|
|
Loading…
Reference in a new issue