Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-07-07 03:08:47 +00:00
parent 3462d7613f
commit 0dce207848
32 changed files with 431 additions and 124 deletions

View File

@ -1,16 +1,16 @@
#
# This list of browsers is a conservative first definition, based on
# This list of browsers is a conservative definition, based on
# https://docs.gitlab.com/ee/install/requirements.html#supported-web-browsers
# with the following reasoning:
#
# - Edge: Pick the last two major version before the Chrome switch
# - Rest: We should support the latest ESR of Firefox: 68, because it used quite a lot.
# For the rest, pick browser versions that have a similar age to Firefox 68.
# - We should support the latest ESR of Firefox: 78, because it used quite a lot.
# - We use Edge/Chrome >= 84 because 83 had an annoying bug which would mean we
# need to polyfill Array.reduce: https://bugs.chromium.org/p/chromium/issues/detail?id=1049982
# - Safari 13 because it is the second latest major version of Safari
#
# See also this follow-up epic:
# https://gitlab.com/groups/gitlab-org/-/epics/3957
# See also this epic: https://gitlab.com/groups/gitlab-org/-/epics/3957
#
chrome >= 73
edge >= 17
firefox >= 68
safari >= 12
chrome >= 84
edge >= 84
firefox >= 78
safari >= 13.0.4

View File

@ -75,7 +75,7 @@
policy: push # We want to rebuild the cache from scratch to ensure stale dependencies are cleaned up.
.assets-cache: &assets-cache
key: "assets-${NODE_ENV}-v1"
key: "assets-${NODE_ENV}-v2"
paths:
- assets-hash.txt
- public/assets/webpack/

View File

@ -162,6 +162,7 @@
.frontend-build-patterns: &frontend-build-patterns
- "{package.json,yarn.lock}"
- ".browserslistrc"
- "babel.config.js"
- "config/webpack.config.js"
- "config/**/*.js"
@ -170,6 +171,7 @@
.frontend-patterns: &frontend-patterns
- "{package.json,yarn.lock}"
- ".browserslistrc"
- "babel.config.js"
- "jest.config.{base,integration,unit}.js"
- ".csscomb.json"

View File

@ -149,10 +149,6 @@ h1 {
color: transparent;
text-shadow: 0 0 0 #fafafa;
}
.form-control::-ms-input-placeholder {
color: #bfbfbf;
opacity: 1;
}
.form-control::placeholder {
color: #bfbfbf;
opacity: 1;
@ -179,7 +175,6 @@ h1 {
color: #fafafa;
text-align: center;
vertical-align: middle;
-moz-user-select: none;
user-select: none;
background-color: transparent;
border: 1px solid transparent;
@ -630,9 +625,6 @@ input {
border-radius: 4px;
padding: 6px 10px;
}
.form-control::-ms-input-placeholder {
color: #868686;
}
.form-control::placeholder {
color: #868686;
}
@ -1474,7 +1466,6 @@ svg.s16 {
top: 4px;
}
.search .search-input-wrap .search-icon {
-moz-user-select: none;
user-select: none;
}
.search .search-input-wrap .clear-icon {
@ -1688,9 +1679,6 @@ body.gl-dark
body.gl-dark .search form {
background-color: rgba(250, 250, 250, 0.2);
}
body.gl-dark .search .search-input::-ms-input-placeholder {
color: rgba(250, 250, 250, 0.8);
}
body.gl-dark .search .search-input::placeholder {
color: rgba(250, 250, 250, 0.8);
}

View File

@ -130,10 +130,6 @@ h1 {
color: transparent;
text-shadow: 0 0 0 #303030;
}
.form-control::-ms-input-placeholder {
color: #5e5e5e;
opacity: 1;
}
.form-control::placeholder {
color: #5e5e5e;
opacity: 1;
@ -160,7 +156,6 @@ h1 {
color: #303030;
text-align: center;
vertical-align: middle;
-moz-user-select: none;
user-select: none;
background-color: transparent;
border: 1px solid transparent;
@ -611,9 +606,6 @@ input {
border-radius: 4px;
padding: 6px 10px;
}
.form-control::-ms-input-placeholder {
color: #868686;
}
.form-control::placeholder {
color: #868686;
}
@ -1455,7 +1447,6 @@ svg.s16 {
top: 4px;
}
.search .search-input-wrap .search-icon {
-moz-user-select: none;
user-select: none;
}
.search .search-input-wrap .clear-icon {

View File

@ -198,10 +198,6 @@ hr {
color: transparent;
text-shadow: 0 0 0 #303030;
}
.form-control::-ms-input-placeholder {
color: #5e5e5e;
opacity: 1;
}
.form-control::placeholder {
color: #5e5e5e;
opacity: 1;
@ -229,7 +225,6 @@ hr {
color: #303030;
text-align: center;
vertical-align: middle;
-moz-user-select: none;
user-select: none;
background-color: transparent;
border: 1px solid transparent;
@ -319,13 +314,6 @@ fieldset:disabled a.btn {
appearance: none;
-moz-appearance: none;
}
.gl-form-input:not(.form-control-plaintext):-moz-read-only,
.gl-form-input.form-control:not(.form-control-plaintext):-moz-read-only {
background-color: #fafafa;
color: #868686;
box-shadow: inset 0 0 0 1px #dbdbdb;
cursor: not-allowed;
}
.gl-form-input:disabled,
.gl-form-input:not(.form-control-plaintext):read-only,
.gl-form-input.form-control:disabled,
@ -335,10 +323,6 @@ fieldset:disabled a.btn {
box-shadow: inset 0 0 0 1px #dbdbdb;
cursor: not-allowed;
}
.gl-form-input::-ms-input-placeholder,
.gl-form-input.form-control::-ms-input-placeholder {
color: #868686;
}
.gl-form-input::placeholder,
.gl-form-input.form-control::placeholder {
color: #868686;
@ -495,7 +479,6 @@ hr {
z-index: 1;
}
.flash-container.sticky {
position: -webkit-sticky;
position: sticky;
top: 48px;
z-index: 251;
@ -521,9 +504,6 @@ label.label-bold {
border-radius: 4px;
padding: 6px 10px;
}
.form-control::-ms-input-placeholder {
color: #868686;
}
.form-control::placeholder {
color: #868686;
}

View File

@ -33,6 +33,10 @@ module Mutations
return { link: nil, errors: [message] }
end
unless Ability.allowed?(current_user, :update_release, release)
raise_resource_not_available_error!
end
new_link = release.links.create(link_attrs)
unless new_link.persisted?

View File

@ -158,6 +158,10 @@ class ProjectPolicy < BasePolicy
::Feature.enabled?(:build_service_proxy, @subject)
end
condition(:respect_protected_tag_for_release_permissions) do
::Feature.enabled?(:evalute_protected_tag_for_release_permissions, @subject, default_enabled: :yaml)
end
condition(:user_defined_variables_allowed) do
!@subject.restrict_user_defined_variables?
end
@ -649,6 +653,10 @@ class ProjectPolicy < BasePolicy
rule { build_service_proxy_enabled }.enable :build_service_proxy_enabled
rule { respect_protected_tag_for_release_permissions & can?(:developer_access) }.policy do
enable :destroy_release
end
rule { can?(:download_code) }.policy do
enable :read_repository_graphs
end

View File

@ -13,21 +13,9 @@ class ReleasePolicy < BasePolicy
::Feature.enabled?(:evalute_protected_tag_for_release_permissions, @subject.project, default_enabled: :yaml)
end
condition(:project_developer) do
can?(:developer_access, @subject.project)
end
rule { respect_protected_tag & protected_tag }.policy do
prevent :create_release
prevent :update_release
prevent :destroy_release
end
# NOTE: Developer role (or above) can create, update and destroy release entries.
# When we remove the `evalute_protected_tag_for_release_permissions` feature flag,
# we should move `enable :destroy_release` to ProjectPolicy alongside with .
# See https://gitlab.com/gitlab-org/gitlab/-/issues/327505 for more information.
rule { respect_protected_tag & project_developer }.policy do
enable :destroy_release
end
end

View File

@ -2,6 +2,6 @@
module Releases
class LinkPolicy < BasePolicy
delegate { @subject.release.project }
delegate { @subject.release }
end
end

View File

@ -44,7 +44,13 @@ module Releases
end
def allowed?
Ability.allowed?(current_user, :create_release, project)
Ability.allowed?(current_user, :create_release, project) && can_create_tag?
end
def can_create_tag?
return true unless ::Feature.enabled?(:evalute_protected_tag_for_release_permissions, project, default_enabled: :yaml)
::Gitlab::UserAccess.new(current_user, container: project).can_create_tag?(tag_name)
end
def create_release(tag, evidence_pipeline)

View File

@ -1,14 +1,18 @@
const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const BABEL_VERSION = require('@babel/core/package.json').version;
const SOURCEGRAPH_VERSION = require('@sourcegraph/code-host-integration/package.json').version;
const BABEL_LOADER_VERSION = require('babel-loader/package.json').version;
const CompressionPlugin = require('compression-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const glob = require('glob');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const VUE_LOADER_VERSION = require('vue-loader/package.json').version;
const VUE_VERSION = require('vue/package.json').version;
const webpack = require('webpack');
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer');
const { StatsWriterPlugin } = require('webpack-stats-plugin');
@ -21,6 +25,12 @@ const vendorDllHash = require('./helpers/vendor_dll_hash');
const MonacoWebpackPlugin = require('./plugins/monaco_webpack');
const ROOT_PATH = path.resolve(__dirname, '..');
const SUPPORTED_BROWSERS = fs.readFileSync(path.join(ROOT_PATH, '.browserslistrc'), 'utf-8');
const SUPPORTED_BROWSERS_HASH = crypto
.createHash('sha256')
.update(SUPPORTED_BROWSERS)
.digest('hex');
const VENDOR_DLL = process.env.WEBPACK_VENDOR_DLL && process.env.WEBPACK_VENDOR_DLL !== 'false';
const CACHE_PATH = process.env.WEBPACK_CACHE_PATH || path.join(ROOT_PATH, 'tmp/cache');
const IS_PRODUCTION = process.env.NODE_ENV === 'production';
@ -217,6 +227,16 @@ module.exports = {
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,
},
},
{

View File

@ -41,7 +41,8 @@ Example response:
"maven_max_file_size": 3221225472,
"npm_max_file_size": 524288000,
"nuget_max_file_size": 524288000,
"pypi_max_file_size": 3221225472
"pypi_max_file_size": 3221225472,
"terraform_module_max_file_size": 1073741824
}
```
@ -62,6 +63,7 @@ PUT /application/plan_limits
| `npm_max_file_size` | integer | no | Maximum NPM package file size in bytes. |
| `nuget_max_file_size` | integer | no | Maximum NuGet package file size in bytes. |
| `pypi_max_file_size` | integer | no | Maximum PyPI package file size in bytes. |
| `terraform_module_max_file_size` | integer | no | Maximum Terraform Module package file size in bytes. |
```shell
curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/application/plan_limits?plan_name=default&conan_max_file_size=3221225472"
@ -76,6 +78,7 @@ Example response:
"maven_max_file_size": 3221225472,
"npm_max_file_size": 524288000,
"nuget_max_file_size": 524288000,
"pypi_max_file_size": 3221225472
"pypi_max_file_size": 3221225472,
"terraform_module_max_file_size": 1073741824
}
```

View File

@ -12,6 +12,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w
> - Release Evidences were [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/26019) in GitLab 12.5.
> - `description_html` became an opt-in field [with GitLab 13.12 for performance reasons](https://gitlab.com/gitlab-org/gitlab/-/issues/299447).
Please pass the `include_html_description` query string parameter if you need it.
> - [The permission model for create, update and delete actions was fixed](https://gitlab.com/gitlab-org/gitlab/-/issues/327505) in GitLab 14.1.
See [Release permissions](../../user/project/releases/index.md#release-permissions) for more information.
## List Releases

View File

@ -105,8 +105,7 @@ The following table lists project permissions available for each role:
| Publish [packages](packages/index.md) | | | ✓ | ✓ | ✓ |
| Create/edit/delete a Cleanup policy | | | ✓ | ✓ | ✓ |
| Upload [Design Management](project/issues/design_management.md) files | | | ✓ | ✓ | ✓ |
| Create/edit [releases](project/releases/index.md)| | | ✓ | ✓ | ✓ |
| Delete [releases](project/releases/index.md)| | | | ✓ | ✓ |
| Create/edit/delete [releases](project/releases/index.md)| | | ✓ (*13*) | ✓ (*13*) | ✓ (*13*) |
| Manage merge approval rules (project settings) | | | | ✓ | ✓ |
| Create new merge request | | | ✓ | ✓ | ✓ |
| Create new branches | | | ✓ | ✓ | ✓ |
@ -205,6 +204,7 @@ The following table lists project permissions available for each role:
1. Users can only view events based on their individual actions.
1. Project access tokens are supported for self-managed instances on Free and above. They are also
supported on GitLab SaaS Premium and above (excluding [trial licenses](https://about.gitlab.com/free-trial/)).
1. If the [tag is protected](#release-permissions-with-protected-tags), this depends on the access Developers and Maintainers are given.
## Project features permissions
@ -521,6 +521,14 @@ run CI/CD pipelines and execute actions on jobs that are related to those branch
See [Security on protected branches](../ci/pipelines/index.md#pipeline-security-on-protected-branches)
for details about the pipelines security model.
## Release permissions with protected tags
[The permission to create tags](project/protected_tags.md) is used to define if a user can
create, edit, and delete [Releases](project/releases/index.md).
See [Release permissions](project/releases/index.md#release-permissions)
for more information.
## LDAP users permissions
In GitLab 8.15 and later, LDAP user permissions can now be manually overridden by an admin user.

View File

@ -63,7 +63,7 @@ We recommend using the API to create releases as one of the last steps in your
CI/CD pipeline.
Only users with Developer permissions or higher can create releases.
Read more about [Release permissions](../../../user/permissions.md#project-members-permissions).
Read more about [Release permissions](#release-permissions).
To create a new release through the GitLab UI:
@ -103,7 +103,7 @@ release tag. When the `released_at` date and time has passed, the badge is autom
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/26016) in GitLab 12.6. Asset link editing was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/9427) in GitLab 12.10.
Only users with Developer permissions or higher can edit releases.
Read more about [Release permissions](../../../user/permissions.md#project-members-permissions).
Read more about [Release permissions](#release-permissions).
To edit the details of a release:
@ -245,7 +245,7 @@ but are _not_ allowed to view details about the Git repository (in particular,
tag names). Because of this, release titles are replaced with a generic
title like "Release-1234" for Guest users to avoid leaking tag name information.
See the [Permissions](../../permissions.md#project-members-permissions) page for
See the [Release permissions](#release-permissions) section for
more information about permissions.
### Tag name
@ -565,6 +565,49 @@ In the API:
- If you do not specify a `released_at` date, release evidence is collected on the
date the release is created.
## Release permissions
> [The permission model for create, update and delete actions was fixed](https://gitlab.com/gitlab-org/gitlab/-/issues/327505) in GitLab 14.1.
### View a release and download assets
- Users with [Reporter role or above](../../../user/permissions.md#project-members-permissions)
have read and download access to the project releases.
- Users with [Guest role](../../../user/permissions.md#project-members-permissions)
have read and download access to the project releases, however,
repository-related information are redacted (for example the Git tag name).
### Create, update, and delete a release and its assets
- Users with [Developer role or above](../../../user/permissions.md#project-members-permissions)
have write access to the project releases and assets.
- If a release is associated with a [protected tag](../protected_tags.md),
the user must be [allowed to create the protected tag](../protected_tags.md#configuring-protected-tags) too.
As an example of release permission control, you can allow only
[Maintainer role or above](../../../user/permissions.md#project-members-permissions)
to create, update, and delete releases by protecting the tag with a wildcard (`*`),
and set **Maintainer** in the **Allowed to create** column.
#### Enable or disable protected tag evaluation on releases **(FREE SELF)**
Protected tag evaluation on release permissions is under development and not ready for production use.
It is deployed behind a feature flag that is **disabled by default**.
[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)
can enable it.
To enable it:
```ruby
Feature.enable(:evalute_protected_tag_for_release_permissions)
```
To disable it:
```ruby
Feature.disable(:evalute_protected_tag_for_release_permissions)
```
## Release Command Line
> [Introduced](https://gitlab.com/gitlab-org/release-cli/-/merge_requests/6) in GitLab 12.10.
@ -588,14 +631,13 @@ These metrics include:
- Total number of releases in the group
- Percentage of projects in the group that have at least one release
<!-- ## Troubleshooting
## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
one might have when setting this up, or when something is changed, or on upgrading, it's
important to describe those, too. Think of things that may go wrong and include them here.
This is important to minimize requests for support, and to avoid doc comments with
questions that you know someone might ask.
### Getting `403 Forbidden` or `Something went wrong while creating a new release` errors when creating, updating or deleting releases and their assets
Each scenario can be a third-level heading, e.g. `### Getting error message X`.
If you have none to add when creating a doc, leave this section in place
but commented out to help encourage others to add to it in the future. -->
If the release is associted with a [protected tag](../protected_tags.md),
the UI/API request might result in an authorization failure.
Make sure that the user or a service/bot account is allowed to
[create the protected tag](../protected_tags.md#configuring-protected-tags) too.
See [the release permissions](#release-permissions) for more information.

View File

@ -41,6 +41,7 @@ module API
optional :npm_max_file_size, type: Integer, desc: 'Maximum NPM package file size in bytes'
optional :nuget_max_file_size, type: Integer, desc: 'Maximum NuGet package file size in bytes'
optional :pypi_max_file_size, type: Integer, desc: 'Maximum PyPI package file size in bytes'
optional :terraform_module_max_file_size, type: Integer, desc: 'Maximum Terraform Module package file size in bytes'
end
put "application/plan_limits" do
params = declared_params(include_missing: false)

View File

@ -9,6 +9,7 @@ module API
expose :npm_max_file_size
expose :nuget_max_file_size
expose :pypi_max_file_size
expose :terraform_module_max_file_size
end
end
end

View File

@ -50,6 +50,24 @@ RSpec.describe Mutations::ReleaseAssetLinks::Create do
end
end
context 'with protected tag' do
context 'when user has access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :developers_can_create, name: '*', project: project) }
it 'does not have errors' do
expect(subject).to include(errors: [])
end
end
context 'when user does not have access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :maintainers_can_create, name: '*', project: project) }
it 'has an access error' do
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
end
context "when the user doesn't have access to the project" do
let(:current_user) { reporter }

View File

@ -7,6 +7,7 @@ RSpec.describe Mutations::ReleaseAssetLinks::Delete do
let_it_be(:project) { create(:project, :private, :repository) }
let_it_be_with_reload(:release) { create(:release, project: project) }
let_it_be(:reporter) { create(:user).tap { |u| project.add_reporter(u) } }
let_it_be(:developer) { create(:user).tap { |u| project.add_developer(u) } }
let_it_be(:maintainer) { create(:user).tap { |u| project.add_maintainer(u) } }
let_it_be_with_reload(:release_link) { create(:release_link, release: release) }
@ -22,7 +23,7 @@ RSpec.describe Mutations::ReleaseAssetLinks::Delete do
let(:deleted_link) { subject[:link] }
context 'when the current user has access to delete the link' do
let(:current_user) { maintainer }
let(:current_user) { developer }
it 'deletes the link and returns it', :aggregate_failures do
expect(deleted_link).to eq(release_link)
@ -30,6 +31,26 @@ RSpec.describe Mutations::ReleaseAssetLinks::Delete do
expect(release.links).to be_empty
end
context 'with protected tag' do
context 'when user has access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :developers_can_create, name: '*', project: project) }
it 'does not have errors' do
subject
expect(resolve).to include(errors: [])
end
end
context 'when user does not have access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :maintainers_can_create, name: '*', project: project) }
it 'raises a resource access error' do
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
end
context "when the link doesn't exist" do
let(:mutation_arguments) { super().merge(id: "gid://gitlab/Releases::Link/#{non_existing_record_id}") }
@ -48,7 +69,7 @@ RSpec.describe Mutations::ReleaseAssetLinks::Delete do
end
context 'when the current user does not have access to delete the link' do
let(:current_user) { developer }
let(:current_user) { reporter }
it 'raises an error' do
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)

View File

@ -87,6 +87,26 @@ RSpec.describe Mutations::ReleaseAssetLinks::Update do
end
it_behaves_like 'no changes to the link except for the', :name
context 'with protected tag' do
context 'when user has access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :developers_can_create, name: '*', project: project) }
it 'does not have errors' do
subject
expect(resolve).to include(errors: [])
end
end
context 'when user does not have access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :maintainers_can_create, name: '*', project: project) }
it 'raises a resource access error' do
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
end
end
end
end
context 'when nil is provided' do

View File

@ -117,6 +117,28 @@ RSpec.describe Mutations::Releases::Create do
expect(new_link.filepath).to eq(expected_link[:filepath])
end
end
context 'with protected tag' do
context 'when user has access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :developers_can_create, name: '*', project: project) }
it 'does not have errors' do
subject
expect(resolve).to include(errors: [])
end
end
context 'when user does not have access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :maintainers_can_create, name: '*', project: project) }
it 'has an access error' do
subject
expect(resolve).to include(errors: ['Access Denied'])
end
end
end
end
context "when the current user doesn't have access to create releases" do

View File

@ -5,6 +5,7 @@ require 'spec_helper'
RSpec.describe Mutations::Releases::Delete do
let_it_be(:project) { create(:project, :public, :repository) }
let_it_be(:non_project_member) { create(:user) }
let_it_be(:reporter) { create(:user) }
let_it_be(:developer) { create(:user) }
let_it_be(:maintainer) { create(:user) }
let_it_be(:tag) { 'v1.1.0'}
@ -20,6 +21,7 @@ RSpec.describe Mutations::Releases::Delete do
end
before do
project.add_reporter(reporter)
project.add_developer(developer)
project.add_maintainer(maintainer)
end
@ -36,7 +38,7 @@ RSpec.describe Mutations::Releases::Delete do
end
context 'when the current user has access to create releases' do
let(:current_user) { maintainer }
let(:current_user) { developer }
it 'deletes the release' do
expect { subject }.to change { Release.count }.by(-1)
@ -54,6 +56,28 @@ RSpec.describe Mutations::Releases::Delete do
expect(subject[:errors]).to eq([])
end
context 'with protected tag' do
context 'when user has access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :developers_can_create, name: '*', project: project) }
it 'does not have errors' do
subject
expect(resolve).to include(errors: [])
end
end
context 'when user does not have access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :maintainers_can_create, name: '*', project: project) }
it 'has an access error' do
subject
expect(resolve).to include(errors: ['Access Denied'])
end
end
end
context 'validation' do
context 'when the release does not exist' do
let(:mutation_arguments) { super().merge(tag: 'not-a-real-release') }
@ -76,8 +100,8 @@ RSpec.describe Mutations::Releases::Delete do
end
context "when the current user doesn't have access to update releases" do
context 'when the user is a developer' do
let(:current_user) { developer }
context 'when the user is a reporter' do
let(:current_user) { reporter }
it_behaves_like 'unauthorized or not found error'
end

View File

@ -107,6 +107,28 @@ RSpec.describe Mutations::Releases::Update do
end
it_behaves_like 'no changes to the release except for the', :name
context 'with protected tag' do
context 'when user has access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :developers_can_create, name: '*', project: project) }
it 'does not have errors' do
subject
expect(resolve).to include(errors: [])
end
end
context 'when user does not have access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :maintainers_can_create, name: '*', project: project) }
it 'has an access error' do
subject
expect(resolve).to include(errors: ['Access Denied'])
end
end
end
end
context 'when nil is provided' do

View File

@ -14,7 +14,8 @@ RSpec.describe API::Entities::PlanLimit do
:maven_max_file_size,
:npm_max_file_size,
:nuget_max_file_size,
:pypi_max_file_size
:pypi_max_file_size,
:terraform_module_max_file_size
)
end

View File

@ -29,6 +29,7 @@ RSpec.describe API::Admin::PlanLimits, 'PlanLimits' do
expect(json_response['npm_max_file_size']).to eq(Plan.default.actual_limits.npm_max_file_size)
expect(json_response['nuget_max_file_size']).to eq(Plan.default.actual_limits.nuget_max_file_size)
expect(json_response['pypi_max_file_size']).to eq(Plan.default.actual_limits.pypi_max_file_size)
expect(json_response['terraform_module_max_file_size']).to eq(Plan.default.actual_limits.terraform_module_max_file_size)
end
end
@ -48,6 +49,7 @@ RSpec.describe API::Admin::PlanLimits, 'PlanLimits' do
expect(json_response['npm_max_file_size']).to eq(Plan.default.actual_limits.npm_max_file_size)
expect(json_response['nuget_max_file_size']).to eq(Plan.default.actual_limits.nuget_max_file_size)
expect(json_response['pypi_max_file_size']).to eq(Plan.default.actual_limits.pypi_max_file_size)
expect(json_response['terraform_module_max_file_size']).to eq(Plan.default.actual_limits.terraform_module_max_file_size)
end
end
@ -85,7 +87,8 @@ RSpec.describe API::Admin::PlanLimits, 'PlanLimits' do
'maven_max_file_size': 30,
'npm_max_file_size': 40,
'nuget_max_file_size': 50,
'pypi_max_file_size': 60
'pypi_max_file_size': 60,
'terraform_module_max_file_size': 70
}
expect(response).to have_gitlab_http_status(:ok)
@ -96,6 +99,7 @@ RSpec.describe API::Admin::PlanLimits, 'PlanLimits' do
expect(json_response['npm_max_file_size']).to eq(40)
expect(json_response['nuget_max_file_size']).to eq(50)
expect(json_response['pypi_max_file_size']).to eq(60)
expect(json_response['terraform_module_max_file_size']).to eq(70)
end
it 'updates single plan limits' do
@ -128,7 +132,8 @@ RSpec.describe API::Admin::PlanLimits, 'PlanLimits' do
'maven_max_file_size': 'c',
'npm_max_file_size': 'd',
'nuget_max_file_size': 'e',
'pypi_max_file_size': 'f'
'pypi_max_file_size': 'f',
'terraform_module_max_file_size': 'g'
}
expect(response).to have_gitlab_http_status(:bad_request)
@ -139,7 +144,8 @@ RSpec.describe API::Admin::PlanLimits, 'PlanLimits' do
'generic_packages_max_file_size is invalid',
'npm_max_file_size is invalid',
'nuget_max_file_size is invalid',
'pypi_max_file_size is invalid'
'pypi_max_file_size is invalid',
'terraform_module_max_file_size is invalid'
)
end
end

View File

@ -55,7 +55,7 @@ RSpec.describe 'Deleting a release' do
end
context 'when the current user has access to update releases' do
let(:current_user) { maintainer }
let(:current_user) { developer }
it 'deletes the release' do
expect { delete_release }.to change { Release.count }.by(-1)
@ -105,12 +105,6 @@ RSpec.describe 'Deleting a release' do
end
context "when the current user doesn't have access to update releases" do
context 'when the current user is a Developer' do
let(:current_user) { developer }
it_behaves_like 'unauthorized or not found error'
end
context 'when the current user is a Reporter' do
let(:current_user) { reporter }

View File

@ -5,6 +5,7 @@ require 'spec_helper'
RSpec.describe API::Release::Links do
let(:project) { create(:project, :repository, :private) }
let(:maintainer) { create(:user) }
let(:developer) { create(:user) }
let(:reporter) { create(:user) }
let(:non_project_member) { create(:user) }
let(:commit) { create(:commit, project: project) }
@ -18,6 +19,7 @@ RSpec.describe API::Release::Links do
before do
project.add_maintainer(maintainer)
project.add_developer(developer)
project.add_reporter(reporter)
project.repository.add_tag(maintainer, 'v0.1', commit.id)
@ -196,6 +198,28 @@ RSpec.describe API::Release::Links do
expect(response).to match_response_schema('release/link')
end
context 'with protected tag' do
context 'when user has access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :developers_can_create, name: '*', project: project) }
it 'accepts the request' do
post api("/projects/#{project.id}/releases/v0.1/assets/links", developer), params: params
expect(response).to have_gitlab_http_status(:created)
end
end
context 'when user does not have access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :maintainers_can_create, name: '*', project: project) }
it 'forbids the request' do
post api("/projects/#{project.id}/releases/v0.1/assets/links", developer), params: params
expect(response).to have_gitlab_http_status(:forbidden)
end
end
end
context 'when name is empty' do
let(:params) do
{
@ -290,6 +314,28 @@ RSpec.describe API::Release::Links do
expect(response).to match_response_schema('release/link')
end
context 'with protected tag' do
context 'when user has access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :developers_can_create, name: '*', project: project) }
it 'accepts the request' do
put api("/projects/#{project.id}/releases/v0.1/assets/links/#{release_link.id}", developer), params: params
expect(response).to have_gitlab_http_status(:ok)
end
end
context 'when user does not have access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :maintainers_can_create, name: '*', project: project) }
it 'forbids the request' do
put api("/projects/#{project.id}/releases/v0.1/assets/links/#{release_link.id}", developer), params: params
expect(response).to have_gitlab_http_status(:forbidden)
end
end
end
context 'when params is empty' do
let(:params) { {} }
@ -365,6 +411,28 @@ RSpec.describe API::Release::Links do
expect(response).to match_response_schema('release/link')
end
context 'with protected tag' do
context 'when user has access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :developers_can_create, name: '*', project: project) }
it 'accepts the request' do
delete api("/projects/#{project.id}/releases/v0.1/assets/links/#{release_link.id}", developer)
expect(response).to have_gitlab_http_status(:ok)
end
end
context 'when user does not have access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :maintainers_can_create, name: '*', project: project) }
it 'forbids the request' do
delete api("/projects/#{project.id}/releases/v0.1/assets/links/#{release_link.id}", developer)
expect(response).to have_gitlab_http_status(:forbidden)
end
end
end
context 'when there are no corresponding release link' do
let!(:release_link) { }

View File

@ -676,6 +676,28 @@ RSpec.describe API::Releases do
end.not_to change { Project.find_by_id(project.id).repository.tag_count }
end
context 'with protected tag' do
context 'when user has access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :developers_can_create, name: '*', project: project) }
it 'accepts the request' do
post api("/projects/#{project.id}/releases", developer), params: params
expect(response).to have_gitlab_http_status(:created)
end
end
context 'when user does not have access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :maintainers_can_create, name: '*', project: project) }
it 'forbids the request' do
post api("/projects/#{project.id}/releases", developer), params: params
expect(response).to have_gitlab_http_status(:forbidden)
end
end
end
context 'when user is a reporter' do
it 'forbids the request' do
post api("/projects/#{project.id}/releases", reporter), params: params
@ -1014,6 +1036,28 @@ RSpec.describe API::Releases do
expect(project.releases.last.released_at).to eq('2015-10-10T05:00:00Z')
end
context 'with protected tag' do
context 'when user has access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :developers_can_create, name: '*', project: project) }
it 'accepts the request' do
put api("/projects/#{project.id}/releases/v0.1", developer), params: params
expect(response).to have_gitlab_http_status(:ok)
end
end
context 'when user does not have access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :maintainers_can_create, name: '*', project: project) }
it 'forbids the request' do
put api("/projects/#{project.id}/releases/v0.1", developer), params: params
expect(response).to have_gitlab_http_status(:forbidden)
end
end
end
context 'when user tries to update sha' do
let(:params) { { sha: 'xxx' } }
@ -1194,6 +1238,28 @@ RSpec.describe API::Releases do
expect(response).to match_response_schema('public_api/v4/release')
end
context 'with protected tag' do
context 'when user has access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :developers_can_create, name: '*', project: project) }
it 'accepts the request' do
delete api("/projects/#{project.id}/releases/v0.1", developer)
expect(response).to have_gitlab_http_status(:ok)
end
end
context 'when user does not have access to the protected tag' do
let!(:protected_tag) { create(:protected_tag, :maintainers_can_create, name: '*', project: project) }
it 'forbids the request' do
delete api("/projects/#{project.id}/releases/v0.1", developer)
expect(response).to have_gitlab_http_status(:forbidden)
end
end
end
context 'when there are no corresponding releases' do
let!(:release) { }

View File

@ -48,7 +48,7 @@ RSpec.shared_context 'ProjectPolicy context' do
destroy_container_image push_code read_pod_logs read_terraform_state
resolve_note update_build update_commit_status update_container_image
update_deployment update_environment update_merge_request
update_metrics_dashboard_annotation update_pipeline update_release
update_metrics_dashboard_annotation update_pipeline update_release destroy_release
]
end
@ -57,7 +57,7 @@ RSpec.shared_context 'ProjectPolicy context' do
add_cluster admin_build admin_commit_status admin_container_image
admin_deployment admin_environment admin_note admin_pipeline
admin_project admin_project_member admin_snippet admin_terraform_state
admin_wiki create_deploy_token destroy_deploy_token destroy_release
admin_wiki create_deploy_token destroy_deploy_token
push_to_delete_protected_branch read_deploy_token update_snippet
]
end

View File

@ -54,6 +54,7 @@ module Tooling
%r{\A(ee/)?scripts/frontend/} => :frontend,
%r{(\A|/)(
\.babelrc |
\.browserslistrc |
\.eslintignore |
\.eslintrc(\.yml)? |
\.nvmrc |

View File

@ -2883,16 +2883,16 @@ browserify-zlib@^0.2.0:
dependencies:
pako "~1.0.5"
browserslist@^4.12.0, browserslist@^4.8.3:
version "4.16.1"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.1.tgz#bf757a2da376b3447b800a16f0f1c96358138766"
integrity sha512-UXhDrwqsNcpTYJBTZsbGATDxZbiVDsx6UjpmRUmtnP10pr8wAYr5LgFoEFw9ixriQH2mv/NX2SfGzE/o8GndLA==
browserslist@^4.12.0, browserslist@^4.16.6:
version "4.16.6"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2"
integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==
dependencies:
caniuse-lite "^1.0.30001173"
colorette "^1.2.1"
electron-to-chromium "^1.3.634"
caniuse-lite "^1.0.30001219"
colorette "^1.2.2"
electron-to-chromium "^1.3.723"
escalade "^3.1.1"
node-releases "^1.1.69"
node-releases "^1.1.71"
bser@2.1.1:
version "2.1.1"
@ -3079,10 +3079,10 @@ camelcase@^6.0.0:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.0.0.tgz#5259f7c30e35e278f1bdc2a4d91230b37cad981e"
integrity sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==
caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001173:
version "1.0.30001185"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001185.tgz#3482a407d261da04393e2f0d61eefbc53be43b95"
integrity sha512-Fpi4kVNtNvJ15H0F6vwmXtb3tukv3Zg3qhKkOGUq7KJ1J6b9kf4dnNgtEAFXhRsJo0gNj9W60+wBvn0JcTvdTg==
caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001219:
version "1.0.30001241"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001241.tgz#cd3fae47eb3d7691692b406568d7a3e5b23c7598"
integrity sha512-1uoSZ1Pq1VpH0WerIMqwptXHNNGfdl7d1cJUFs80CwQ/lVzdhTvsFZCeNFslze7AjsQnb4C85tzclPa1VShbeQ==
capture-exit@^2.0.0:
version "2.0.0"
@ -3631,11 +3631,11 @@ copy-webpack-plugin@^6.4.1:
webpack-sources "^1.4.3"
core-js-compat@^3.6.2:
version "3.6.4"
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.4.tgz#938476569ebb6cda80d339bcf199fae4f16fff17"
integrity sha512-zAa3IZPvsJ0slViBQ2z+vgyyTuhd3MFn1rBQjZSKVEgB0UMYhUkCj9jJUVPgGTGqWvsBVmfnruXgTcNyTlEiSA==
version "3.15.2"
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.15.2.tgz#47272fbb479880de14b4e6081f71f3492f5bd3cb"
integrity sha512-Wp+BJVvwopjI+A1EFqm2dwUmWYXrvucmtIB2LgXn/Rb+gWPKYxtmb4GKHGKG/KGF1eK9jfjzT38DITbTOCX/SQ==
dependencies:
browserslist "^4.8.3"
browserslist "^4.16.6"
semver "7.0.0"
core-js-pure@^3.0.0:
@ -4613,10 +4613,10 @@ ee-first@1.1.1:
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
electron-to-chromium@^1.3.634:
version "1.3.642"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.642.tgz#8b884f50296c2ae2a9997f024d0e3e57facc2b94"
integrity sha512-cev+jOrz/Zm1i+Yh334Hed6lQVOkkemk2wRozfMF4MtTR7pxf3r3L5Rbd7uX1zMcEqVJ7alJBnJL7+JffkC6FQ==
electron-to-chromium@^1.3.723:
version "1.3.762"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.762.tgz#3fa4e3bcbda539b50e3aa23041627063a5cffe61"
integrity sha512-LehWjRpfPcK8F1Lf/NZoAwWLWnjJVo0SZeQ9j/tvnBWYcT99qDqgo4raAfS2oTKZjPrR/jxruh85DGgDUmywEA==
elliptic@^6.0.0:
version "6.5.4"
@ -8744,10 +8744,10 @@ node-notifier@^8.0.0:
uuid "^8.3.0"
which "^2.0.2"
node-releases@^1.1.69:
version "1.1.70"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.70.tgz#66e0ed0273aa65666d7fe78febe7634875426a08"
integrity sha512-Slf2s69+2/uAD79pVVQo8uSiC34+g8GWY8UH2Qtqv34ZfhYrxpYpfzs9Js9d6O0mbDmALuxaTlplnBTnSELcrw==
node-releases@^1.1.71:
version "1.1.73"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.73.tgz#dd4e81ddd5277ff846b80b52bb40c49edf7a7b20"
integrity sha512-uW7fodD6pyW2FZNZnp/Z3hvWKeEW1Y8R1+1CnErE8cXFXzl5blBOoVB41CvMer6P6Q0S5FXDwcHgFd1Wj0U9zg==
nodemon@^2.0.4:
version "2.0.4"