Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-10-09 21:14:51 +00:00
parent 5b4e0ca32c
commit 20625a2433
36 changed files with 734 additions and 87 deletions

View File

@ -1804,7 +1804,6 @@ Layout/LineLength:
- 'ee/spec/requests/api/related_epic_links_spec.rb'
- 'ee/spec/requests/api/releases_spec.rb'
- 'ee/spec/requests/api/resource_iteration_events_spec.rb'
- 'ee/spec/requests/api/search_spec.rb'
- 'ee/spec/requests/api/settings_spec.rb'
- 'ee/spec/requests/api/status_checks_spec.rb'
- 'ee/spec/requests/api/users_spec.rb'

View File

@ -69,7 +69,6 @@ Performance/MapCompact:
- 'ee/lib/gitlab/ci/reports/metrics/reports_comparer.rb'
- 'ee/lib/gitlab/search/aggregation_parser.rb'
- 'ee/spec/models/ee/member_spec.rb'
- 'ee/spec/requests/api/search_spec.rb'
- 'haml_lint/linter/no_plain_nodes.rb'
- 'lib/api/entities/feature.rb'
- 'lib/api/helpers/common_helpers.rb'

View File

@ -71,7 +71,6 @@ Rails/Pluck:
- 'ee/spec/requests/api/protected_environments_spec.rb'
- 'ee/spec/requests/api/protected_tags_spec.rb'
- 'ee/spec/requests/api/releases_spec.rb'
- 'ee/spec/requests/api/search_spec.rb'
- 'ee/spec/requests/api/status_checks_spec.rb'
- 'ee/spec/requests/api/users_spec.rb'
- 'ee/spec/requests/api/vulnerabilities_spec.rb'

View File

@ -470,7 +470,6 @@ RSpec/BeforeAllRoleAssignment:
- 'ee/spec/requests/api/related_epic_links_spec.rb'
- 'ee/spec/requests/api/repositories_spec.rb'
- 'ee/spec/requests/api/saml_group_links_spec.rb'
- 'ee/spec/requests/api/search_spec.rb'
- 'ee/spec/requests/api/todos_spec.rb'
- 'ee/spec/requests/api/vulnerabilities_spec.rb'
- 'ee/spec/requests/api/vulnerability_exports_spec.rb'

View File

@ -2,6 +2,23 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
## 17.4.2 (2024-10-09)
### Fixed (1 change)
- [Drop project_id not null constraint ci_deleted_objects](https://gitlab.com/gitlab-org/security/gitlab/-/commit/e02a0c065456a51ad57a93d56150271cc4dd442e)
### Security (8 changes)
- [Do not create a pipeline on MR refresh if source branch was deleted](https://gitlab.com/gitlab-org/security/gitlab/-/commit/66c4e57a3494686a9dc6058d2348074b465f5dd3) ([merge request](https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/4522))
- [Escape OAuth application name on authorize page](https://gitlab.com/gitlab-org/security/gitlab/-/commit/293bb1f70c681b75672e0b41af84ab5ae47d1e1e) ([merge request](https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/4517))
- [Prevent guest access to project templates](https://gitlab.com/gitlab-org/security/gitlab/-/commit/544398bdf7ea2b81100f8b95496f14d9b4698db8) ([merge request](https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/4477))
- [Remove access to local requests via cube query service](https://gitlab.com/gitlab-org/security/gitlab/-/commit/86894edacdaf1cad4b0e85f71918109d48013ccb) ([merge request](https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/4492))
- [External webhook token should be set](https://gitlab.com/gitlab-org/security/gitlab/-/commit/70fb8bebe2e8f1b85d625a8e496515c3f7e0e6d8) ([merge request](https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/4510))
- [Skip content when listing conflict files with types](https://gitlab.com/gitlab-org/security/gitlab/-/commit/c19d8a96d103680ec874327c1631e179e17da06a) ([merge request](https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/4513))
- [Hide version info from unauthorized users](https://gitlab.com/gitlab-org/security/gitlab/-/commit/0dd81e22f819f916c50cf531fa769000e9b5941b) ([merge request](https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/4500))
- [Prevent deploy keys from pushing code to an archived project](https://gitlab.com/gitlab-org/security/gitlab/-/commit/ed7a5173cae50f610d2c0263197f7996653cfc10) ([merge request](https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/4486))
## 17.4.1 (2024-09-24)
### Fixed (2 changes)
@ -872,6 +889,23 @@ entry.
- [Update learn more link and docs formatting](https://gitlab.com/gitlab-org/gitlab/-/commit/6f536fdb20c2d2b96124afe693042c91483a32b2) ([merge request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/164889))
## 17.3.5 (2024-10-09)
### Fixed (1 change)
- [Ensure levels is an array](https://gitlab.com/gitlab-org/security/gitlab/-/commit/74594891f31984feaaae6a069f057d6f48a489a6)
### Security (8 changes)
- [Do not create a pipeline on MR refresh if source branch was deleted](https://gitlab.com/gitlab-org/security/gitlab/-/commit/c36869b2e5cb0f88793bec7e20ded3e4d005f942) ([merge request](https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/4523))
- [Escape OAuth application name on authorize page](https://gitlab.com/gitlab-org/security/gitlab/-/commit/b5a704563f746e5c61301d3a7db0eab68d434e24) ([merge request](https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/4518))
- [Prevent guest access to project templates](https://gitlab.com/gitlab-org/security/gitlab/-/commit/92d177e2c5aaafb4f74bc2ceafe39b9a068e803d) ([merge request](https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/4449))
- [Remove access to local requests via cube query service](https://gitlab.com/gitlab-org/security/gitlab/-/commit/7043d0116cbf2051907dfd88d56ed3f847ab95b2) ([merge request](https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/4493))
- [External webhook token should be set](https://gitlab.com/gitlab-org/security/gitlab/-/commit/77c2a678acfc6fded56c6e10147701b6ef7aaeb5) ([merge request](https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/4511))
- [Skip content when listing conflict files with types](https://gitlab.com/gitlab-org/security/gitlab/-/commit/2b559425cb195a78007db930cbbf8450b5254c89) ([merge request](https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/4514))
- [Hide version info from unauthorized users](https://gitlab.com/gitlab-org/security/gitlab/-/commit/94e70d423789a50fc8e172b002bf1428593bbc51) ([merge request](https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/4501))
- [Prevent deploy keys from pushing code to an archived project](https://gitlab.com/gitlab-org/security/gitlab/-/commit/3cd52356b4b1194e7108af832d5da4087e4be05c) ([merge request](https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/4487))
## 17.3.4 (2024-09-24)
### Security (3 changes)
@ -1662,6 +1696,23 @@ No changes.
- [Dynamically gets the column type for assertion](https://gitlab.com/gitlab-org/gitlab/-/commit/1389a3daffd104925cce71776903cbf527723222) ([merge request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/159099))
- [Quarantine a flaky test](https://gitlab.com/gitlab-org/gitlab/-/commit/c94fca35b909440ec66ea35c97ab11aa847dde58) ([merge request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/158180))
## 17.2.9 (2024-10-09)
### Fixed (1 change)
- [Ensure levels is an array](https://gitlab.com/gitlab-org/security/gitlab/-/commit/d5450d020895b9fab3c7c6ad4191001308590899)
### Security (8 changes)
- [Do not create a pipeline on MR refresh if source branch was deleted](https://gitlab.com/gitlab-org/security/gitlab/-/commit/3dd89a71b436e8218a5d159a1dd75cb2de078129) ([merge request](https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/4524))
- [Escape OAuth application name on authorize page](https://gitlab.com/gitlab-org/security/gitlab/-/commit/b5cf4d286ae83033912e342177a501ffc2ad6a53) ([merge request](https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/4519))
- [Prevent guest access to project templates](https://gitlab.com/gitlab-org/security/gitlab/-/commit/9666414231dbfc03eb0711ec501b7d02665120df) ([merge request](https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/4450))
- [Remove access to local requests via cube query service](https://gitlab.com/gitlab-org/security/gitlab/-/commit/1a46c8c1753f08ba55e8a0d2fbcbc710feecf898) ([merge request](https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/4494))
- [External webhook token should be set](https://gitlab.com/gitlab-org/security/gitlab/-/commit/c795ea96a4dac381cf434aa7e3f379907ec6366d) ([merge request](https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/4512))
- [Skip content when listing conflict files with types](https://gitlab.com/gitlab-org/security/gitlab/-/commit/c7f598b42b0c6cd68cdcdb8b79293e7e2b22b457) ([merge request](https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/4515))
- [Hide version info from unauthorized users](https://gitlab.com/gitlab-org/security/gitlab/-/commit/0184d4e9c665c209e1c67eff2da9059e17304f1d) ([merge request](https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/4502))
- [Prevent deploy keys from pushing code to an archived project](https://gitlab.com/gitlab-org/security/gitlab/-/commit/0a5dc2f0b302123a941a4676eedd52c3423ef73b) ([merge request](https://gitlab.com/gitlab-org/security/gitlab/-/merge_requests/4488))
## 17.2.8 (2024-09-24)
### Security (3 changes)

View File

@ -48,19 +48,7 @@ export default {
},
computed: {
itemGroups() {
return {
versionCheck: {
items: [
{
text: this.$options.i18n.version,
href: helpPagePath('update/index'),
version: `${this.sidebarData.gitlab_version.major}.${this.sidebarData.gitlab_version.minor}`,
extraAttrs: {
...this.trackingAttrs('version_help_dropdown'),
},
},
],
},
const groups = {
helpLinks: {
items: [
{
@ -157,6 +145,23 @@ export default {
].filter(Boolean),
},
};
if (this.sidebarData.show_version_check) {
groups.versionCheck = {
items: [
{
text: this.$options.i18n.version,
href: helpPagePath('update/index'),
version: `${this.sidebarData.gitlab_version.major}.${this.sidebarData.gitlab_version.minor}`,
extraAttrs: {
...this.trackingAttrs('version_help_dropdown'),
},
},
],
};
}
return groups;
},
updateSeverity() {
return this.sidebarData.gitlab_version_check?.severity;

View File

@ -266,7 +266,12 @@ module DiffHelper
return unless merge_request.cannot_be_merged? && merge_request.source_branch_exists? && merge_request.target_branch_exists?
cached_conflicts_with_types do
conflicts_service = MergeRequests::Conflicts::ListService.new(merge_request, allow_tree_conflicts: true) # rubocop:disable CodeReuse/ServiceClass
# We set skip_content to true since we don't really need the content to list the conflicts and their types
conflicts_service = MergeRequests::Conflicts::ListService.new( # rubocop:disable CodeReuse/ServiceClass
merge_request,
allow_tree_conflicts: true,
skip_content: true
)
{}.tap do |h|
conflicts_service.conflicts.files.each do |file|

View File

@ -43,7 +43,7 @@ module SidebarsHelper
end
def super_sidebar_logged_out_context(panel:, panel_type:) # rubocop:disable Metrics/AbcSize
{
super_sidebar_instance_version_data.merge(super_sidebar_whats_new_data).merge({
is_logged_in: false,
context_switcher_links: context_switcher_links,
current_menu_items: panel.super_sidebar_menu_items,
@ -51,16 +51,12 @@ module SidebarsHelper
support_path: support_url,
docs_path: help_docs_path,
display_whats_new: display_whats_new?,
whats_new_most_recent_release_items_count: whats_new_most_recent_release_items_count,
whats_new_version_digest: whats_new_version_digest,
show_version_check: show_version_check?,
gitlab_version: Gitlab.version_info,
gitlab_version_check: gitlab_version_check,
search: search_data,
panel_type: panel_type,
shortcut_links: shortcut_links,
terms: terms_link
}
})
end
def super_sidebar_logged_in_context(user, group:, project:, panel:, panel_type:) # rubocop:disable Metrics/AbcSize
@ -126,6 +122,24 @@ module SidebarsHelper
})
end
def super_sidebar_instance_version_data
return {} unless show_version_check?
{
gitlab_version: Gitlab.version_info,
gitlab_version_check: gitlab_version_check
}
end
def super_sidebar_whats_new_data
return {} unless display_whats_new?
{
whats_new_most_recent_release_items_count: whats_new_most_recent_release_items_count,
whats_new_version_digest: whats_new_version_digest
}
end
def work_items_modal_data(group)
return unless group && group.id

View File

@ -226,6 +226,11 @@ module Auth
return if path.has_repository?
return unless actions.include?('push')
find_or_create_repository_from_path(path)
end
# Overridden in EE
def find_or_create_repository_from_path(path)
ContainerRepository.find_or_create_from_path!(path)
end

View File

@ -239,7 +239,7 @@ class IssuableBaseService < ::BaseContainerService
elsif author_id
issuable.author_id = author_id
else
issuable.author = current_user
issuable.author ||= current_user
end
end

View File

@ -30,7 +30,8 @@ module MergeRequests
@conflicts ||=
Gitlab::Conflict::FileCollection.new(
merge_request,
allow_tree_conflicts: params[:allow_tree_conflicts]
allow_tree_conflicts: params[:allow_tree_conflicts],
skip_content: params[:skip_content]
)
end
end

View File

@ -44,7 +44,7 @@ module MergeRequests
mark_mr_as_draft_from_commits(mr)
execute_mr_web_hooks(mr)
# Run at the end of the loop to avoid any potential contention on the MR object
refresh_pipelines_on_merge_requests(mr)
refresh_pipelines_on_merge_requests(mr) unless @push.branch_removed?
merge_request_activity_counter.track_mr_including_ci_config(user: mr.author, merge_request: mr)
end

View File

@ -1,7 +1,9 @@
.gl-ml-auto.gl-mr-auto{ class: 'sm:gl-w-1/2' }
.gl-items-center
.gl-text-size-h1
= html_escape(_('%{client_name} is requesting access to your account on %{title}.')) % { title: brand_title.html_safe, client_name: "<strong>#{html_escape(@pre_auth.client.name)}</strong>".html_safe }
= safe_format(_('%{strong_start}%{client_name}%{strong_end} is requesting access to your account on %{title}.'),
{ client_name: @pre_auth.client.name, title: brand_title },
tag_pair(tag.strong, :strong_start, :strong_end))
.gl-flex.gl-items-center.gl-gap-2.gl-py-5
= render Pajamas::AvatarComponent.new(current_user, size: 24, avatar_options: { data: { testid: 'user_avatar_content' }, title: current_user.username })
.gl-pl-1
@ -12,7 +14,9 @@
- if current_user.admin?
= render Pajamas::AlertComponent.new(variant: :warning, dismissible: false, alert_options: { class: 'gl-mb-5'}) do |c|
- c.with_body do
= html_escape(_('You are an administrator, which means authorizing access to %{client_name} will allow it to interact with GitLab as an administrator as well.')) % { client_name: "<strong>#{html_escape(@pre_auth.client.name)}</strong>".html_safe }
= safe_format(_('You are an administrator, which means authorizing access to %{strong_start}%{client_name}%{strong_end} will allow it to interact with GitLab as an administrator as well.'),
{ client_name: @pre_auth.client.name },
tag_pair(tag.strong, :strong_start, :strong_end))
- if @pre_auth.scopes
- @pre_auth.scopes.each do |scope|
%strong= t scope, scope: [:doorkeeper, :scopes]
@ -26,12 +30,17 @@
- else
%p.gl-text-orange-500
= sprite_icon('warning-solid')
= html_escape(_('Make sure you trust %{client_name} before authorizing.')) % { client_name: "<strong>#{html_escape(@pre_auth.client.name)}</strong>".html_safe }
= safe_format(_('Make sure you trust %{strong_start}%{client_name}%{strong_end} before authorizing.'),
{ client_name: @pre_auth.client.name },
tag_pair(tag.strong, :strong_start, :strong_end))
%p
= html_escape(_('%{owner} %{created_date} ago.')) % { owner: auth_app_owner_text(@pre_auth.client.application.owner), created_date: time_ago_in_words(@pre_auth.client.application.created_at.to_date) }
= safe_format(_('%{owner} %{created_date} ago.'),
{ owner: auth_app_owner_text(@pre_auth.client.application.owner),
created_date: time_ago_in_words(@pre_auth.client.application.created_at.to_date) })
- domain = URI.parse(@pre_auth.redirect_uri).host.gsub(/^www\./, '')
- if @pre_auth.redirect_uri.start_with?('http://', 'https://') && domain != 'localhost'
= html_escape(_('You will be redirected to %{domain} after authorizing.')) % { domain: "<strong>#{domain}</strong>".html_safe }
= safe_format(_('You will be redirected to %{strong_start}%{domain}%{strong_end} after authorizing.'),
{ domain: domain }, tag_pair(tag.strong, :strong_start, :strong_end))
%div
= form_tag oauth_authorization_path, method: :post, class: 'gl-inline-block gl-pr-3' do
= hidden_field_tag :client_id, @pre_auth.client.uid
@ -44,8 +53,8 @@
= hidden_field_tag :code_challenge_method, @pre_auth.code_challenge_method
= render Pajamas::ButtonComponent.new(type: :submit,
variant: :confirm,
button_options: {testid: 'authorization-button'}) do
= html_escape(_('Authorize %{client_name}')) % { client_name: @pre_auth.client.name.html_safe }
button_options: { data: { testid: 'authorization-button' }}) do
= safe_format(_('Authorize %{client_name}'), { client_name: @pre_auth.client.name })
= form_tag oauth_authorization_path, method: :delete, class: 'gl-inline-block' do
= hidden_field_tag :client_id, @pre_auth.client.uid
= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri

View File

@ -100,6 +100,52 @@ Example response:
]
```
## Add deploy key
DETAILS:
**Tier:** Free, Premium, Ultimate
**Offering:** Self-managed, GitLab Dedicated
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/478476) in GitLab 17.5.
Create a deploy key for the GitLab instance. This endpoint requires administrator
access.
```plaintext
POST /deploy_keys
```
Supported attributes:
| Attribute | Type | Required | Description |
|:--------------|:---------|:---------|:----------------------------------------------------------------------------------------------------------------------------------|
| `key` | string | yes | New deploy key |
| `title` | string | yes | New deploy key's title |
| `expires_at` | datetime | no | Expiration date for the deploy key. Does not expire if no value is provided. Expected in ISO 8601 format (`2024-12-31T08:00:00Z`) |
Example request:
```shell
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" --header "Content-Type: application/json" \
--data '{"title": "My deploy key", "key": "ssh-rsa AAAA...", "expired_at": "2024-12-31T08:00:00Z"}' \
"https://gitlab.example.com/api/v4/deploy_keys/"
```
Example response:
```json
{
"id" : 5,
"title" : "My deploy key",
"key": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDNJAkI3Wdf0r13c8a5pEExB2YowPWCSVzfZV22pNBc1CuEbyYLHpUyaD0GwpGvFdx2aP7lMEk35k6Rz3ccBF6jRaVJyhsn5VNnW92PMpBJ/P1UebhXwsFHdQf5rTt082cSxWuk61kGWRQtk4ozt/J2DF/dIUVaLvc+z4HomT41fQ==",
"fingerprint": "4a:9d:64:15:ed:3a:e6:07:6e:89:36:b3:3b:03:05:d9",
"fingerprint_sha256": "SHA256:Jrs3LD1Ji30xNLtTVf9NDCj7kkBgPBb2pjvTZ3HfIgU",
"usage_type": "auth_and_signing",
"created_at": "2024-10-03T01:32:21.992Z",
"expires_at": "2024-12-31T08:00:00.000Z"
}
```
## List deploy keys for project
Get a list of a project's deploy keys.
@ -236,7 +282,7 @@ Example response:
}
```
## Add deploy key
## Add deploy key for a project
Creates a new deploy key for a project.

View File

@ -60,7 +60,9 @@ Go pseudo versions are not supported. A project dependency that references a Go
never considered as affected because this might result in false negatives.
RPM versions containing `^` are not supported. Work to support these versions is tracked in [issue 459969](https://gitlab.com/gitlab-org/gitlab/-/issues/459969).
APK versions containing leading zeros are not supported. Work to support these versions is tracked in [issue 471509](https://gitlab.com/gitlab-org/gitlab/-/issues/471509)
APK versions containing leading zeros are not supported. Work to support these versions is tracked in [issue 471509](https://gitlab.com/gitlab-org/gitlab/-/issues/471509).
RPM packages in Red Hat distributions are not supported. Work to support this use case is tracked in [epic 12980](https://gitlab.com/groups/gitlab-org/-/epics/12980).
## How to generate a CycloneDX SBOM report

View File

@ -50,6 +50,9 @@ GitLab Advanced SAST includes the following features:
- Cross-file analysis: Tracks data flow across different files, discovering vulnerabilities at a deeper level.
- Sanitizer detection: Avoid false positive results in case the user input is properly sanitized.
<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
For an overview of GitLab Advanced SAST and how it works, see [GitLab Advanced SAST: Accelerating Vulnerability Resolution](https://youtu.be/xDa1MHOcyn8).
For a product tour, see the [GitLab Advanced SAST product tour](https://gitlab.navattic.com/advanced-sast).
## Supported languages
@ -137,6 +140,20 @@ To enable Advanced SAST by using the pipeline editor:
Pipelines now include an Advanced SAST job.
## Vulnerability code flow
For some vulnerabilities detected by Advanced SAST, a **Code flow** tab is available in the [Vulnerability Page](../vulnerabilities/index.md).
A vulnerability's code flow is the path the data takes from the user input (source) to the vulnerable line of code (sink),
through all assignments, manipulation, and sanitization. This information helps you understand and evaluate the
vulnerability's context, impact, and risk.
The **Code flow** tab shows:
- The steps from source to sink.
- The relevant files, including code snippets.
![Vulnerability Code Flow](../vulnerabilities/img/example_code_flow_of_python_applications_v17_3.png)
## Troubleshooting
If you encounter issues while using GitLab Advanced SAST, refer to the [troubleshooting guide](troubleshooting.md).

View File

@ -193,6 +193,7 @@ Audit event types belong to the following product categories.
| Name | Description | Saved to database | Streamed | Introduced in | Scope |
|:------------|:------------|:------------------|:---------|:--------------|:--------------|
| [`container_repository_created`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/156037) | Triggered when a container repository is first pushed to the registry | **{check-circle}** Yes | **{check-circle}** Yes | GitLab [17.5](https://gitlab.com/gitlab-org/gitlab/-/issues/362290) | Project |
| [`container_repository_deleted`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152967) | Triggered when a project's container registry is deleted | **{check-circle}** Yes | **{check-circle}** Yes | GitLab [17.2](https://gitlab.com/gitlab-org/gitlab/-/issues/362290) | Project |
| [`container_repository_deletion_marked`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152967) | Triggered when a project's container repository is marked for deletion | **{check-circle}** Yes | **{check-circle}** Yes | GitLab [17.2](https://gitlab.com/gitlab-org/gitlab/-/issues/362290) | Project |
| [`container_repository_tags_deleted`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/156066) | Triggered when a project's container repository tag is deleted | **{check-circle}** Yes | **{check-circle}** Yes | GitLab [17.2](https://gitlab.com/gitlab-org/gitlab/-/issues/362290) | Project |

View File

@ -47,6 +47,33 @@ module API
with: Entities::DeployKey, include_projects_with_write_access: true, include_projects_with_readonly_access: true
end
desc 'Create a deploy key' do
detail 'Create a deploy key for the GitLab instance. This endpoint requires administrator access.'
success Entities::DeployKey
failure [
{ code: 400, message: 'Bad request' },
{ code: 401, message: 'Unauthorized' },
{ code: 403, message: 'Forbidden' }
]
tags deploy_keys_tags
end
params do
requires :key, type: String, desc: 'New deploy key'
requires :title, type: String, desc: "New deploy key's title"
optional :expires_at, type: DateTime, desc: 'The expiration date of the SSH key in ISO 8601 format (YYYY-MM-DDTHH:MM:SSZ)'
end
post "deploy_keys" do
authenticated_as_admin!
deploy_key = ::DeployKeys::CreateService.new(current_user, declared_params.merge(public: true)).execute
if deploy_key.persisted?
present deploy_key, with: Entities::DeployKey
else
render_validation_error!(deploy_key)
end
end
params do
requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project owned by the authenticated user'
end

View File

@ -14,6 +14,14 @@ module API
feature_category :source_code_management
helpers do
def authorize_template_permissions!
permission = params[:type] == 'issues' ? :read_project : :download_code
authorize! permission, user_project, "Your current role does not have the required permissions to access the #{params[:type]} template. Contact your project administrator for assistance."
end
end
params do
requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
requires :type, type: String, values: TEMPLATE_TYPES, desc: 'The type (dockerfiles|gitignores|gitlab_ci_ymls|licenses|issues|merge_requests) of the template'
@ -32,6 +40,8 @@ module API
use :pagination
end
get ':id/templates/:type' do
authorize_template_permissions!
templates = TemplateFinder.all_template_names(user_project, params[:type]).values.flatten
present paginate(::Kaminari.paginate_array(templates)), with: Entities::TemplatesList
@ -60,6 +70,8 @@ module API
end
get ':id/templates/:type/:name', requirements: TEMPLATE_NAMES_ENDPOINT_REQUIREMENTS do
authorize_template_permissions!
begin
template = TemplateFinder.build(
params[:type],

View File

@ -12,6 +12,10 @@ module Gitlab
def name
@name || _('Deploy Token')
end
def impersonated?
false
end
end
end
end

View File

@ -7,14 +7,14 @@ module Gitlab
attr_reader :merge_request, :resolver
def initialize(merge_request, allow_tree_conflicts: false)
def initialize(merge_request, allow_tree_conflicts: false, skip_content: false)
our_commit = merge_request.source_branch_head.raw
their_commit = merge_request.target_branch_head.raw
@target_repo = merge_request.target_project.repository
@source_repo = merge_request.source_project.repository.raw
@our_commit_id = our_commit.id
@their_commit_id = their_commit.id
@resolver = Gitlab::Git::Conflict::Resolver.new(@target_repo.raw, @our_commit_id, @their_commit_id, allow_tree_conflicts: allow_tree_conflicts)
@resolver = Gitlab::Git::Conflict::Resolver.new(@target_repo.raw, @our_commit_id, @their_commit_id, allow_tree_conflicts: allow_tree_conflicts, skip_content: skip_content)
@merge_request = merge_request
end

View File

@ -9,16 +9,22 @@ module Gitlab
ConflictSideMissing = Class.new(StandardError)
ResolutionError = Class.new(StandardError)
def initialize(target_repository, our_commit_oid, their_commit_oid, allow_tree_conflicts: false)
def initialize(target_repository, our_commit_oid, their_commit_oid, allow_tree_conflicts: false, skip_content: false)
@target_repository = target_repository
@our_commit_oid = our_commit_oid
@their_commit_oid = their_commit_oid
@allow_tree_conflicts = allow_tree_conflicts
@skip_content = skip_content
end
def conflicts
@conflicts ||= wrapped_gitaly_errors do
gitaly_conflicts_client(@target_repository).list_conflict_files(allow_tree_conflicts: @allow_tree_conflicts).to_a
gitaly_conflicts_client(@target_repository)
.list_conflict_files(
allow_tree_conflicts: @allow_tree_conflicts,
skip_content: @skip_content
)
.to_a
rescue GRPC::FailedPrecondition => e
raise Gitlab::Git::Conflict::Resolver::ConflictSideMissing, e.message
end

View File

@ -29,6 +29,7 @@ module Gitlab
upload_pack_disabled_over_http: 'Pulling over HTTP is not allowed.',
receive_pack_disabled_over_http: 'Pushing over HTTP is not allowed.',
read_only: 'The repository is temporarily read-only. Please try again later.',
archived: "You can't push code to an archived project.",
cannot_push_to_read_only: "You can't push code to a read-only GitLab instance.",
push_code: 'You are not allowed to push code to this project.'
}.freeze
@ -341,6 +342,10 @@ module Gitlab
raise ForbiddenError, error_message(:read_only)
end
if project&.archived?
raise ForbiddenError, error_message(:archived)
end
if deploy_key?
unless deploy_key.can_push_to?(project)
raise ForbiddenError, error_message(:deploy_key_upload)

View File

@ -636,9 +636,6 @@ msgstr[1] ""
msgid "%{chartTitle} no data series"
msgstr ""
msgid "%{client_name} is requesting access to your account on %{title}."
msgstr ""
msgid "%{codeStart}$%{codeEnd} will be treated as the start of a reference to another variable."
msgstr ""
@ -1363,6 +1360,9 @@ msgid_plural "%{strong_start}%{branch_count}%{strong_end} Branches"
msgstr[0] ""
msgstr[1] ""
msgid "%{strong_start}%{client_name}%{strong_end} is requesting access to your account on %{title}."
msgstr ""
msgid "%{strong_start}%{commit_count}%{strong_end} Commit"
msgid_plural "%{strong_start}%{commit_count}%{strong_end} Commits"
msgstr[0] ""
@ -32776,7 +32776,7 @@ msgstr ""
msgid "Make sure you save it - you won't be able to access it again."
msgstr ""
msgid "Make sure you trust %{client_name} before authorizing."
msgid "Make sure you trust %{strong_start}%{client_name}%{strong_end} before authorizing."
msgstr ""
msgid "Makes this %{type} confidential."
@ -63005,7 +63005,7 @@ msgstr ""
msgid "You are already impersonating another user"
msgstr ""
msgid "You are an administrator, which means authorizing access to %{client_name} will allow it to interact with GitLab as an administrator as well."
msgid "You are an administrator, which means authorizing access to %{strong_start}%{client_name}%{strong_end} will allow it to interact with GitLab as an administrator as well."
msgstr ""
msgid "You are attempting to delete a file that has been previously updated."
@ -63608,7 +63608,7 @@ msgstr ""
msgid "You tried to fork %{link_to_the_project} but it failed for the following reason:"
msgstr ""
msgid "You will be redirected to %{domain} after authorizing."
msgid "You will be redirected to %{strong_start}%{domain}%{strong_end} after authorizing."
msgstr ""
msgid "You will be the author of all events in the activity feed that are the result of an update, like new branches being created or new commits being pushed to existing branches."

View File

@ -3,21 +3,81 @@
require 'spec_helper'
RSpec.describe 'OAuth Provider', feature_category: :system_access do
def visit_oauth_authorization_path
visit oauth_authorization_path(
client_id: application.uid,
redirect_uri: application.redirect_uri.split.first,
response_type: 'code',
state: 'my_state',
scope: 'read_user'
)
end
before do
sign_in(user)
end
describe 'Standard OAuth Authorization' do
let(:application) { create(:oauth_application, scopes: 'read_user') }
before do
sign_in(user)
visit oauth_authorization_path(
client_id: application.uid,
redirect_uri: application.redirect_uri.split.first,
response_type: 'code',
state: 'my_state',
scope: 'read_user'
)
visit_oauth_authorization_path
end
it_behaves_like 'Secure OAuth Authorizations'
end
context 'when the OAuth application has HTML in the name' do
let(:client_name) { '<img src=x onerror=alert(1)>' }
let(:application) { create(:oauth_application, name: client_name, scopes: 'read_user') }
let(:user) { create(:admin) }
before do
visit_oauth_authorization_path
end
it 'sanitizes the HTML in the authorize button' do
within_testid('authorization-button') do
expect(page).to have_content(format(_('Authorize %{client_name}'), client_name: client_name))
end
end
# rubocop:disable Layout/LineLength -- It is a string
it 'sanitizes the HTML in the warning text' do
expect(page).to have_content(
format(
_('You are an administrator, which means authorizing access to %{client_name} will allow it to interact with GitLab as an administrator as well.'),
client_name: client_name
)
)
end
# rubocop:enable Layout/LineLength
it 'sanitizes the trust text HTML' do
expect(page).to have_content(
format(
_('Make sure you trust %{client_name} before authorizing.'),
client_name: client_name
))
end
end
context 'when brand title has HTML' do
let(:application) { create(:oauth_application, scopes: 'read_user') }
let(:user) { create(:user) }
let!(:appearance) { create(:appearance, title: '<img src=x onerror=alert(1)>') }
before do
visit_oauth_authorization_path
end
it 'sanitizes the HTML' do
expect(page).to have_content(
format(_('%{client_name} is requesting access to your account on %{title}.'),
title: '<img src=x onerror=alert(1)>',
client_name: application.name
)
)
end
end
end

View File

@ -696,7 +696,12 @@ RSpec.describe DiffHelper, feature_category: :code_review_workflow do
.with(when_renamed: true)
.and_return(:renamed_same_file)
allow_next_instance_of(MergeRequests::Conflicts::ListService, merge_request, allow_tree_conflicts: true) do |svc|
allow_next_instance_of(
MergeRequests::Conflicts::ListService,
merge_request,
allow_tree_conflicts: true,
skip_content: true
) do |svc|
if exception.present?
allow(svc).to receive_message_chain(:conflicts, :files).and_raise(exception)
else

View File

@ -231,6 +231,58 @@ RSpec.describe SidebarsHelper, feature_category: :navigation do
it { is_expected.to include({ is_admin: true }) }
end
describe "what's new information" do
context 'when display_whats_new? is true' do
before do
allow(helper).to receive(:display_whats_new?).and_return(true)
end
it do
is_expected.to include({
whats_new_most_recent_release_items_count: helper.whats_new_most_recent_release_items_count,
whats_new_version_digest: helper.whats_new_version_digest
})
end
end
context 'when display_whats_new? is false' do
before do
allow(helper).to receive(:display_whats_new?).and_return(false)
end
it do
is_expected.not_to have_key(:whats_new_most_recent_release_items_count)
is_expected.not_to have_key(:whats_new_version_digest)
end
end
end
describe 'instance version information' do
context 'when show_version_check? is true' do
before do
allow(helper).to receive(:show_version_check?).and_return(true)
end
it do
is_expected.to include({
gitlab_version: Gitlab.version_info,
gitlab_version_check: helper.gitlab_version_check
})
end
end
context 'when show_version_check? is false' do
before do
allow(helper).to receive(:show_version_check?).and_return(false)
end
it do
is_expected.not_to have_key(:gitlab_version)
is_expected.not_to have_key(:gitlab_version_check)
end
end
end
describe "shortcut links" do
describe "as the anonymous user" do
let_it_be(:user) { nil }

View File

@ -4,12 +4,78 @@ require 'spec_helper'
RSpec.describe Gitlab::Conflict::FileCollection do
let(:merge_request) { create(:merge_request, source_branch: 'conflict-resolvable', target_branch: 'conflict-start') }
let(:file_collection) { described_class.new(merge_request) }
let(:allow_tree_conflicts) { false }
let(:skip_content) { false }
let(:file_collection) do
described_class.new(
merge_request,
allow_tree_conflicts: allow_tree_conflicts,
skip_content: skip_content
)
end
describe '#files' do
let(:conflict_files) { [instance_double(Gitlab::Conflict::File, path: 'file.md')] }
let(:git_conflict_files) { [instance_double(Gitlab::Git::Conflict::File, path: 'file.md')] }
let(:resolver) { instance_double(Gitlab::Git::Conflict::Resolver, conflicts: git_conflict_files) }
it 'returns an array of Conflict::Files' do
expect(file_collection.files).to all(be_an_instance_of(Gitlab::Conflict::File))
end
it 'returns conflict files' do
expect(Gitlab::Git::Conflict::Resolver)
.to receive(:new)
.with(
merge_request.source_project.repository.raw,
merge_request.source_branch_head.raw.id,
merge_request.target_branch_head.raw.id,
allow_tree_conflicts: false,
skip_content: false
)
.and_return(resolver)
expect(file_collection.files.map(&:path)).to eq(conflict_files.map(&:path))
end
context 'when allow_tree_conflicts is set to true' do
let(:allow_tree_conflicts) { true }
it 'returns conflict files with allow_tree_conflicts as true' do
expect(Gitlab::Git::Conflict::Resolver)
.to receive(:new)
.with(
merge_request.source_project.repository.raw,
merge_request.source_branch_head.raw.id,
merge_request.target_branch_head.raw.id,
allow_tree_conflicts: true,
skip_content: false
)
.and_return(resolver)
expect(file_collection.files.map(&:path)).to eq(conflict_files.map(&:path))
end
end
context 'when skip_content is set to true' do
let(:skip_content) { true }
it 'returns conflict files with skip_content as true' do
expect(Gitlab::Git::Conflict::Resolver)
.to receive(:new)
.with(
merge_request.source_project.repository.raw,
merge_request.source_branch_head.raw.id,
merge_request.target_branch_head.raw.id,
allow_tree_conflicts: false,
skip_content: true
)
.and_return(resolver)
expect(file_collection.files.map(&:path)).to eq(conflict_files.map(&:path))
end
end
end
describe '#cache' do

View File

@ -7,21 +7,61 @@ RSpec.describe Gitlab::Git::Conflict::Resolver do
let(:our_commit_oid) { 'our-commit-oid' }
let(:their_commit_oid) { 'their-commit-oid' }
let(:gitaly_conflicts_client) { instance_double(Gitlab::GitalyClient::ConflictsService) }
let(:allow_tree_conflicts) { false }
let(:skip_content) { false }
subject(:resolver) { described_class.new(repository, our_commit_oid, their_commit_oid) }
subject(:resolver) do
described_class.new(
repository,
our_commit_oid,
their_commit_oid,
allow_tree_conflicts: allow_tree_conflicts,
skip_content: skip_content
)
end
describe '#conflicts' do
let(:conflicts) { [double] }
before do
allow(repository).to receive(:gitaly_conflicts_client).and_return(gitaly_conflicts_client)
end
it 'returns list of conflicts' do
conflicts = [double]
expect(gitaly_conflicts_client)
.to receive(:list_conflict_files)
.with(allow_tree_conflicts: false, skip_content: false)
.and_return(conflicts)
expect(gitaly_conflicts_client).to receive(:list_conflict_files).and_return(conflicts)
expect(resolver.conflicts).to eq(conflicts)
end
context 'when allow_tree_conflicts is set to true' do
let(:allow_tree_conflicts) { true }
it 'returns list of conflicts with allow_tree_conflicts as true' do
expect(gitaly_conflicts_client)
.to receive(:list_conflict_files)
.with(allow_tree_conflicts: true, skip_content: false)
.and_return(conflicts)
expect(resolver.conflicts).to eq(conflicts)
end
end
context 'when skip_content is set to true' do
let(:skip_content) { true }
it 'returns list of conflicts with skip_content as true' do
expect(gitaly_conflicts_client)
.to receive(:list_conflict_files)
.with(allow_tree_conflicts: false, skip_content: true)
.and_return(conflicts)
expect(resolver.conflicts).to eq(conflicts)
end
end
context 'when GRPC::FailedPrecondition is raised' do
it 'rescues and raises Gitlab::Git::Conflict::Resolver::ConflictSideMissing' do
expect(gitaly_conflicts_client).to receive(:list_conflict_files).and_raise(GRPC::FailedPrecondition)

View File

@ -1127,6 +1127,16 @@ RSpec.describe Gitlab::GitAccess, :aggregate_failures, feature_category: :system
end
end
context 'when the project is archived' do
let(:project) { create(:project, :repository, :archived) }
it 'denies push access' do
project.add_maintainer(user)
expect { push_access_check }.to raise_forbidden(described_class::ERROR_MESSAGES[:archived])
end
end
describe 'deploy key permissions' do
let(:key) { create(:deploy_key, user: user) }
let(:actor) { key }
@ -1138,6 +1148,14 @@ RSpec.describe Gitlab::GitAccess, :aggregate_failures, feature_category: :system
end
it { expect { push_access_check }.not_to raise_error }
context 'when project is archived' do
before do
project.update!(archived: true)
end
it { expect { push_access_check }.to raise_forbidden(described_class::ERROR_MESSAGES[:archived]) }
end
end
context 'when unauthorized' do

View File

@ -110,6 +110,64 @@ RSpec.describe API::DeployKeys, :aggregate_failures, feature_category: :continuo
end
end
describe 'POST /deploy_keys' do
let_it_be(:path) { '/deploy_keys' }
it_behaves_like 'POST request permissions for admin mode' do
let(:params) { attributes_for :another_key }
let(:failed_status_code) { :forbidden }
end
context 'when unauthenticated' do
it 'returns authentication error' do
post api(path), params: attributes_for(:another_key)
expect(response).to have_gitlab_http_status(:unauthorized)
end
end
context 'when authenticated as admin' do
let_it_be(:pat) { create(:personal_access_token, :admin_mode, user: admin) }
it 'creates a new deploy key' do
expect do
post api(path, personal_access_token: pat), params: attributes_for(:another_key)
end.to change { DeployKey.count }.by(1)
expect(response).to have_gitlab_http_status(:created)
end
it 'does not create an invalid ssh key' do
post api(path, personal_access_token: pat), params: { title: 'invalid key' }
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['error']).to eq('key is missing')
end
it 'does not create a key without title' do
post api(path, personal_access_token: pat), params: { key: 'some key' }
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['error']).to eq('title is missing')
end
it 'returns Bad Request when deploy key is duplicated' do
post api(path, personal_access_token: pat), params: { key: deploy_key.key, title: deploy_key.title }
expect(response).to have_gitlab_http_status(:bad_request)
expect(json_response['message']['fingerprint_sha256']).to eq(['has already been taken'])
end
it 'accepts optional expires_at parameter' do
attrs = attributes_for(:another_key).merge(expires_at: 2.days.since.iso8601)
post api(path, personal_access_token: pat), params: attrs
expect(response).to have_gitlab_http_status(:created)
expect(Time.parse(json_response['expires_at'])).to be_like_time(2.days.since)
end
end
end
describe 'GET /projects/:id/deploy_keys' do
let(:deploy_key) { create(:deploy_key, public: true, user: admin) }

View File

@ -5,13 +5,15 @@ require 'spec_helper'
RSpec.describe API::ProjectTemplates, feature_category: :source_code_management do
let_it_be(:public_project) { create(:project, :public, :repository, create_templates: :merge_request, path: 'path.with.dot') }
let_it_be(:private_project) { create(:project, :private, :repository, create_templates: :issue) }
let_it_be(:developer) { create(:user) }
let_it_be(:reporter) { create(:user) }
let_it_be(:guest) { create(:user) }
let(:url_encoded_path) { "#{public_project.namespace.path}%2F#{public_project.path}" }
before do
stub_feature_flags(remove_monitor_metrics: false)
private_project.add_developer(developer)
private_project.add_developer(reporter)
private_project.add_guest(guest)
end
shared_examples 'accepts project paths with dots' do
@ -64,7 +66,7 @@ RSpec.describe API::ProjectTemplates, feature_category: :source_code_management
end
it 'returns issue templates' do
get api("/projects/#{private_project.id}/templates/issues", developer)
get api("/projects/#{private_project.id}/templates/issues", reporter)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
@ -94,23 +96,58 @@ RSpec.describe API::ProjectTemplates, feature_category: :source_code_management
end
it 'permits access to a developer on a private project' do
get api("/projects/#{private_project.id}/templates/licenses", developer)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('public_api/v4/template_list')
end
end
describe 'GET /projects/:id/templates/licenses' do
it 'returns key and name for the listed licenses' do
get api("/projects/#{public_project.id}/templates/licenses")
get api("/projects/#{private_project.id}/templates/licenses", reporter)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('public_api/v4/template_list')
end
it_behaves_like 'accepts project paths with dots' do
subject { get api("/projects/#{url_encoded_path}/templates/licenses") }
context 'when a guest has no permission to a template' do
it 'denies access to the dockerfile' do
get api("/projects/#{private_project.id}/templates/dockerfiles", guest)
expect(response).to have_gitlab_http_status(:forbidden)
expect(json_response['message']).to eq("403 Forbidden - Your current role does not have the required permissions to access the dockerfiles template. Contact your project administrator for assistance.")
end
it 'denies access to the gitignore' do
get api("/projects/#{private_project.id}/templates/gitignores", guest)
expect(response).to have_gitlab_http_status(:forbidden)
expect(json_response['message']).to eq("403 Forbidden - Your current role does not have the required permissions to access the gitignores template. Contact your project administrator for assistance.")
end
it 'denies access to the gitlab_ci_yml' do
get api("/projects/#{private_project.id}/templates/gitlab_ci_ymls", guest)
expect(response).to have_gitlab_http_status(:forbidden)
expect(json_response['message']).to eq("403 Forbidden - Your current role does not have the required permissions to access the gitlab_ci_ymls template. Contact your project administrator for assistance.")
end
it 'denies access to the license' do
get api("/projects/#{private_project.id}/templates/licenses", guest)
expect(response).to have_gitlab_http_status(:forbidden)
expect(json_response['message']).to eq("403 Forbidden - Your current role does not have the required permissions to access the licenses template. Contact your project administrator for assistance.")
end
it 'denies access to the merge request' do
get api("/projects/#{private_project.id}/templates/merge_requests", guest)
expect(response).to have_gitlab_http_status(:forbidden)
expect(json_response['message']).to eq("403 Forbidden - Your current role does not have the required permissions to access the merge_requests template. Contact your project administrator for assistance.")
end
end
context 'when a guest has permission to an issues template' do
it 'returns an issue template' do
get api("/projects/#{private_project.id}/templates/issues", guest)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to include_pagination_headers
expect(response).to match_response_schema('public_api/v4/template_list')
expect(json_response.map { |t| t['key'] }).to match_array(%w[bug feature_proposal template_test (test)])
end
end
end
@ -163,7 +200,7 @@ RSpec.describe API::ProjectTemplates, feature_category: :source_code_management
end
it 'returns a specific issue template' do
get api("/projects/#{private_project.id}/templates/issues/bug", developer)
get api("/projects/#{private_project.id}/templates/issues/bug", reporter)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('public_api/v4/template')
@ -173,7 +210,7 @@ RSpec.describe API::ProjectTemplates, feature_category: :source_code_management
context 'when issue template uses parentheses' do
it 'returns a specific issue template' do
get api("/projects/#{private_project.id}/templates/issues/(test)", developer)
get api("/projects/#{private_project.id}/templates/issues/(test)", reporter)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('public_api/v4/template')
@ -216,7 +253,7 @@ RSpec.describe API::ProjectTemplates, feature_category: :source_code_management
end
it 'permits access to a developer on a private project' do
get api("/projects/#{private_project.id}/templates/licenses/mit", developer)
get api("/projects/#{private_project.id}/templates/licenses/mit", reporter)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('public_api/v4/license')
@ -243,6 +280,54 @@ RSpec.describe API::ProjectTemplates, feature_category: :source_code_management
TemplateFinder::VENDORED_TEMPLATES.each do |template_type, _|
it_behaves_like 'path traversal attempt', template_type
end
context 'when a guest has no permission to a template' do
it 'denies access to the dockerfile' do
get api("/projects/#{private_project.id}/templates/dockerfiles/Binary", guest)
expect(response).to have_gitlab_http_status(:forbidden)
expect(json_response['message']).to eq("403 Forbidden - Your current role does not have the required permissions to access the dockerfiles template. Contact your project administrator for assistance.")
end
it 'denies access to the gitignore' do
get api("/projects/#{private_project.id}/templates/gitignores/Actionscript", guest)
expect(response).to have_gitlab_http_status(:forbidden)
expect(json_response['message']).to eq("403 Forbidden - Your current role does not have the required permissions to access the gitignores template. Contact your project administrator for assistance.")
end
it 'denies access to the gitlab_ci_yml' do
get api("/projects/#{private_project.id}/templates/gitlab_ci_ymls/Android", guest)
expect(response).to have_gitlab_http_status(:forbidden)
expect(json_response['message']).to eq("403 Forbidden - Your current role does not have the required permissions to access the gitlab_ci_ymls template. Contact your project administrator for assistance.")
end
it 'denies access to the license' do
get api("/projects/#{private_project.id}/templates/licenses/mit", guest)
expect(response).to have_gitlab_http_status(:forbidden)
expect(json_response['message']).to eq("403 Forbidden - Your current role does not have the required permissions to access the licenses template. Contact your project administrator for assistance.")
end
it 'denies access to the merge request' do
get api("/projects/#{private_project.id}/templates/merge_requests/feature_proposal", guest)
expect(response).to have_gitlab_http_status(:forbidden)
expect(json_response['message']).to eq("403 Forbidden - Your current role does not have the required permissions to access the merge_requests template. Contact your project administrator for assistance.")
end
end
context 'when a guest has permission to an issues template' do
it 'returns an issue template' do
get api("/projects/#{private_project.id}/templates/issues/bug", guest)
expect(response).to have_gitlab_http_status(:ok)
expect(response).to match_response_schema('public_api/v4/template')
expect(json_response['name']).to eq('bug')
expect(json_response['content']).to eq('something valid')
end
end
end
describe 'GET /projects/:id/templates/licenses/:key' do

View File

@ -10,10 +10,6 @@ RSpec.describe MergeRequests::Conflicts::ListService, feature_category: :code_re
end
end
def conflicts_service(merge_request)
described_class.new(merge_request)
end
it 'returns a falsey value when the MR can be merged without conflicts' do
merge_request = create_merge_request('master')
merge_request.mark_as_mergeable
@ -95,4 +91,58 @@ RSpec.describe MergeRequests::Conflicts::ListService, feature_category: :code_re
expect(conflicts_service(merge_request).can_be_resolved_in_ui?).to be_falsey
end
end
describe '#conflicts' do
let(:merge_request) { build_stubbed(:merge_request) }
let(:file_collection) { [instance_double(Gitlab::Conflict::FileCollection)] }
it 'returns conflict file collection' do
expect(Gitlab::Conflict::FileCollection)
.to receive(:new)
.with(
merge_request,
allow_tree_conflicts: nil,
skip_content: nil
)
.and_return(file_collection)
expect(conflicts_service(merge_request).conflicts).to eq(file_collection)
end
context 'when allow_tree_conflicts is set to true' do
it 'returns conflict file collection with allow_tree_conflicts as true' do
expect(Gitlab::Conflict::FileCollection)
.to receive(:new)
.with(
merge_request,
allow_tree_conflicts: true,
skip_content: nil
)
.and_return(file_collection)
expect(conflicts_service(merge_request, allow_tree_conflicts: true).conflicts)
.to eq(file_collection)
end
end
context 'when skip_content is set to true' do
it 'returns conflict file collection with skip_content as true' do
expect(Gitlab::Conflict::FileCollection)
.to receive(:new)
.with(
merge_request,
allow_tree_conflicts: nil,
skip_content: true
)
.and_return(file_collection)
expect(conflicts_service(merge_request, skip_content: true).conflicts)
.to eq(file_collection)
end
end
end
def conflicts_service(merge_request, params = {})
described_class.new(merge_request, params)
end
end

View File

@ -246,6 +246,18 @@ RSpec.describe MergeRequests::RefreshService, feature_category: :code_review_wor
expect(@another_merge_request.has_commits?).to be_falsy
end
context 'when push is a branch removal' do
before do
# If @newrev is a blank SHA, it means the ref has been removed
@newrev = Gitlab::Git::SHA1_BLANK_SHA
end
it 'does not create detached merge request pipeline' do
expect { subject }
.not_to change { @merge_request.pipelines_for_merge_request.count }
end
end
context 'when "push_options: nil" is passed' do
let(:service_instance) { service.new(project: project, current_user: @user, params: { push_options: nil }) }

View File

@ -1909,7 +1909,6 @@
- './ee/spec/requests/api/resource_label_events_spec.rb'
- './ee/spec/requests/api/resource_weight_events_spec.rb'
- './ee/spec/requests/api/saml_group_links_spec.rb'
- './ee/spec/requests/api/search_spec.rb'
- './ee/spec/requests/api/settings_spec.rb'
- './ee/spec/requests/api/status_checks_spec.rb'
- './ee/spec/requests/api/submodules_spec.rb'

View File

@ -7,11 +7,7 @@ RSpec.shared_examples 'shared super sidebar context' do
current_context_header: nil,
support_path: helper.support_url,
display_whats_new: helper.display_whats_new?,
whats_new_most_recent_release_items_count: helper.whats_new_most_recent_release_items_count,
whats_new_version_digest: helper.whats_new_version_digest,
show_version_check: helper.show_version_check?,
gitlab_version: Gitlab.version_info,
gitlab_version_check: helper.gitlab_version_check,
search: {
search_path: search_path,
issues_path: issues_dashboard_path,