Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-06-30 15:09:03 +00:00
parent b0139a824f
commit e7b262a4c5
66 changed files with 1110 additions and 165 deletions

View File

@ -1501,6 +1501,12 @@
changes: ["vendor/gems/ipynbdiff/**/*"]
- <<: *if-merge-request-labels-run-all-rspec
.vendor:rules:omniauth-gitlab:
rules:
- <<: *if-merge-request
changes: ["vendor/gems/omniauth-gitlab/**/*"]
- <<: *if-merge-request-labels-run-all-rspec
##################
# Releases rules #
##################

View File

@ -5,6 +5,7 @@ vendor mail-smtp_pool:
trigger:
include: vendor/gems/mail-smtp_pool/.gitlab-ci.yml
strategy: depend
vendor ipynbdiff:
extends:
- .vendor:rules:ipynbdiff
@ -12,3 +13,11 @@ vendor ipynbdiff:
trigger:
include: vendor/gems/ipynbdiff/.gitlab-ci.yml
strategy: depend
vendor omniauth-gitlab:
extends:
- .vendor:rules:omniauth-gitlab
needs: []
trigger:
include: vendor/gems/omniauth-gitlab/.gitlab-ci.yml
strategy: depend

View File

@ -88,7 +88,6 @@ Layout/LineLength:
- 'app/controllers/projects/issues_controller.rb'
- 'app/controllers/projects/jobs_controller.rb'
- 'app/controllers/projects/labels_controller.rb'
- 'app/controllers/projects/logs_controller.rb'
- 'app/controllers/projects/merge_requests/conflicts_controller.rb'
- 'app/controllers/projects/merge_requests/creations_controller.rb'
- 'app/controllers/projects/merge_requests/diffs_controller.rb'
@ -696,8 +695,6 @@ Layout/LineLength:
- 'app/services/pages/migrate_legacy_storage_to_deployment_service.rb'
- 'app/services/personal_access_tokens/create_service.rb'
- 'app/services/personal_access_tokens/revoke_service.rb'
- 'app/services/pod_logs/elasticsearch_service.rb'
- 'app/services/pod_logs/kubernetes_service.rb'
- 'app/services/projects/branches_by_mode_service.rb'
- 'app/services/projects/container_repository/cleanup_tags_service.rb'
- 'app/services/projects/container_repository/gitlab/delete_tags_service.rb'
@ -3485,7 +3482,6 @@ Layout/LineLength:
- 'lib/gitlab/diff/highlight_cache.rb'
- 'lib/gitlab/diff/parser.rb'
- 'lib/gitlab/diff/rendered/notebook/diff_file.rb'
- 'lib/gitlab/elasticsearch/logs/lines.rb'
- 'lib/gitlab/email/failure_handler.rb'
- 'lib/gitlab/email/handler/create_issue_handler.rb'
- 'lib/gitlab/email/handler/create_merge_request_handler.rb'
@ -5007,7 +5003,6 @@ Layout/LineLength:
- 'spec/lib/gitlab/diff/position_tracer/image_strategy_spec.rb'
- 'spec/lib/gitlab/diff/position_tracer/line_strategy_spec.rb'
- 'spec/lib/gitlab/diff/suggestion_spec.rb'
- 'spec/lib/gitlab/elasticsearch/logs/lines_spec.rb'
- 'spec/lib/gitlab/email/failure_handler_spec.rb'
- 'spec/lib/gitlab/email/handler/create_issue_handler_spec.rb'
- 'spec/lib/gitlab/email/handler/create_merge_request_handler_spec.rb'
@ -6090,8 +6085,6 @@ Layout/LineLength:
- 'spec/services/pages/migrate_legacy_storage_to_deployment_service_spec.rb'
- 'spec/services/personal_access_tokens/create_service_spec.rb'
- 'spec/services/personal_access_tokens/revoke_service_spec.rb'
- 'spec/services/pod_logs/elasticsearch_service_spec.rb'
- 'spec/services/pod_logs/kubernetes_service_spec.rb'
- 'spec/services/post_receive_service_spec.rb'
- 'spec/services/projects/apple_target_platform_detector_service_spec.rb'
- 'spec/services/projects/autocomplete_service_spec.rb'

View File

@ -1471,7 +1471,6 @@ RSpec/ContextWording:
- 'spec/features/ics/project_issues_spec.rb'
- 'spec/features/ide/clientside_preview_csp_spec.rb'
- 'spec/features/ide/static_object_external_storage_csp_spec.rb'
- 'spec/features/incidents/incident_details_spec.rb'
- 'spec/features/incidents/user_creates_new_incident_spec.rb'
- 'spec/features/invites_spec.rb'
- 'spec/features/issuables/markdown_references/internal_references_spec.rb'

View File

@ -23,7 +23,6 @@ RSpec/RepeatedExampleGroupBody:
- 'spec/controllers/projects/blob_controller_spec.rb'
- 'spec/controllers/projects/graphs_controller_spec.rb'
- 'spec/controllers/projects/registry/repositories_controller_spec.rb'
- 'spec/features/incidents/incident_details_spec.rb'
- 'spec/features/issues/spam_akismet_issue_creation_spec.rb'
- 'spec/features/merge_request/user_sees_closing_issues_message_spec.rb'
- 'spec/features/projects/commit/cherry_pick_spec.rb'

View File

@ -44,7 +44,7 @@ gem 'omniauth-dingtalk-oauth2', '~> 1.0'
gem 'omniauth-alicloud', '~> 1.0.1'
gem 'omniauth-facebook', '~> 4.0.0'
gem 'omniauth-github', '~> 1.4'
gem 'omniauth-gitlab', '~> 1.0.2'
gem 'omniauth-gitlab', '~> 4.0.0', path: 'vendor/gems/omniauth-gitlab' # See vendor/gems/omniauth-gitlab/README.md
gem 'omniauth-google-oauth2', '~> 0.6.0'
gem 'omniauth-oauth2-generic', '~> 0.2.2'
gem 'omniauth-saml', '~> 1.10'
@ -407,7 +407,7 @@ group :development, :test do
end
group :development, :test, :danger do
gem 'gitlab-dangerfiles', '~> 3.4.1', require: false
gem 'gitlab-dangerfiles', '~> 3.4.2', require: false
end
group :development, :test, :coverage do

View File

@ -12,6 +12,13 @@ PATH
connection_pool (~> 2.0)
mail (~> 2.7)
PATH
remote: vendor/gems/omniauth-gitlab
specs:
omniauth-gitlab (4.0.0)
omniauth (~> 1.0)
omniauth-oauth2 (~> 1.7.1)
GEM
remote: https://rubygems.org/
specs:
@ -482,7 +489,7 @@ GEM
terminal-table (~> 1.5, >= 1.5.1)
gitlab-chronic (0.10.5)
numerizer (~> 0.2)
gitlab-dangerfiles (3.4.1)
gitlab-dangerfiles (3.4.2)
danger (>= 8.4.5)
danger-gitlab (>= 8.0.0)
rake
@ -872,9 +879,6 @@ GEM
omniauth-github (1.4.0)
omniauth (~> 1.5)
omniauth-oauth2 (>= 1.4.0, < 2.0)
omniauth-gitlab (1.0.3)
omniauth (~> 1.0)
omniauth-oauth2 (~> 1.0)
omniauth-google-oauth2 (0.6.0)
jwt (>= 2.0)
omniauth (>= 1.1.1)
@ -1538,7 +1542,7 @@ DEPENDENCIES
gitaly (~> 15.1.0.pre.rc1)
github-markup (~> 1.7.0)
gitlab-chronic (~> 0.10.5)
gitlab-dangerfiles (~> 3.4.1)
gitlab-dangerfiles (~> 3.4.2)
gitlab-experiment (~> 0.7.1)
gitlab-fog-azure-rm (~> 1.3.0)
gitlab-labkit (~> 0.23.0)
@ -1623,7 +1627,7 @@ DEPENDENCIES
omniauth-dingtalk-oauth2 (~> 1.0)
omniauth-facebook (~> 4.0.0)
omniauth-github (~> 1.4)
omniauth-gitlab (~> 1.0.2)
omniauth-gitlab (~> 4.0.0)!
omniauth-google-oauth2 (~> 0.6.0)
omniauth-oauth2-generic (~> 0.2.2)
omniauth-salesforce (~> 1.0.5)

View File

@ -98,9 +98,9 @@ export default class Renderer {
requestAnimationFrame(this.renderWrapper);
}
changeObjectMaterials(type) {
changeObjectMaterials(material) {
this.objects.forEach((obj) => {
obj.changeMaterial(type);
obj.changeMaterial(material);
});
}

View File

@ -30,7 +30,7 @@ export default class MeshObject extends Mesh {
}
}
changeMaterial(type) {
this.material = materials[type];
changeMaterial(materialKey) {
this.material = materials[materialKey];
}
}

View File

@ -5,15 +5,15 @@ export default () => {
[].slice.call(document.querySelectorAll('.js-material-changer')).forEach((el) => {
el.addEventListener('click', (e) => {
const { target } = e;
const { currentTarget } = e;
e.preventDefault();
document.querySelector('.js-material-changer.selected').classList.remove('selected');
target.classList.add('selected');
target.blur();
currentTarget.classList.add('selected');
currentTarget.blur();
viewer.changeObjectMaterials(target.dataset.type);
viewer.changeObjectMaterials(currentTarget.dataset.material);
});
});
};

View File

@ -133,6 +133,7 @@
"WorkItemWidget": [
"WorkItemWidgetAssignees",
"WorkItemWidgetDescription",
"WorkItemWidgetHierarchy"
"WorkItemWidgetHierarchy",
"WorkItemWidgetWeight"
]
}

View File

@ -30,7 +30,7 @@ export default () => {
deleteAccountModal,
},
mounted() {
deleteAccountButton.classList.remove('disabled');
deleteAccountButton.disabled = false;
deleteAccountButton.addEventListener('click', () => {
this.$root.$emit(BV_SHOW_MODAL, 'delete-account-modal', '#delete-account-button');
});

View File

@ -18,6 +18,9 @@ module Mutations
argument :description_widget, ::Types::WorkItems::Widgets::DescriptionInputType,
required: false,
description: 'Input for description widget.'
argument :weight_widget, ::Types::WorkItems::Widgets::WeightInputType,
required: false,
description: 'Input for weight widget.'
end
end
end

View File

@ -18,6 +18,8 @@ module Types
::Types::WorkItems::Widgets::HierarchyType
when ::WorkItems::Widgets::Assignees
::Types::WorkItems::Widgets::AssigneesType
when ::WorkItems::Widgets::Weight
::Types::WorkItems::Widgets::WeightType
else
raise "Unknown GraphQL type for widget #{object}"
end
@ -25,7 +27,8 @@ module Types
orphan_types ::Types::WorkItems::Widgets::DescriptionType,
::Types::WorkItems::Widgets::HierarchyType,
::Types::WorkItems::Widgets::AssigneesType
::Types::WorkItems::Widgets::AssigneesType,
::Types::WorkItems::Widgets::WeightType
end
end
end

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
module Types
module WorkItems
module Widgets
class WeightInputType < BaseInputObject
graphql_name 'WorkItemWidgetWeightInput'
argument :weight, GraphQL::Types::Int,
required: true,
description: 'Weight of the work item.'
end
end
end
end

View File

@ -0,0 +1,21 @@
# frozen_string_literal: true
module Types
module WorkItems
module Widgets
# Disabling widget level authorization as it might be too granular
# and we already authorize the parent work item
# rubocop:disable Graphql/AuthorizeTypes
class WeightType < BaseObject
graphql_name 'WorkItemWidgetWeight'
description 'Represents a weight widget'
implements Types::WorkItems::WidgetInterface
field :weight, GraphQL::Types::Int, null: true,
description: 'Weight of the work item.'
end
# rubocop:enable Graphql/AuthorizeTypes
end
end
end

View File

@ -26,6 +26,13 @@ class Ability
end
end
# A list of users that can read confidential notes in a project
def users_that_can_read_internal_notes(users, note_parent)
DeclarativePolicy.subject_scope do
users.select { |u| allowed?(u, :reporter_access, note_parent) }
end
end
# Returns an Array of Issues that can be read by the given user.
#
# issues - The issues to reduce down to those readable by the user.

View File

@ -172,7 +172,7 @@ module CacheMarkdownField
refs = all_references(self.author)
references = {}
references[:mentioned_users_ids] = refs.mentioned_user_ids.presence
references[:mentioned_users_ids] = mentioned_filtered_user_ids_for(refs)
references[:mentioned_groups_ids] = refs.mentioned_group_ids.presence
references[:mentioned_projects_ids] = refs.mentioned_project_ids.presence
@ -185,6 +185,13 @@ module CacheMarkdownField
true
end
# Overriden on objects that needs to filter
# mentioned users that cannot read them, for example,
# guest users that are referenced on a confidential note.
def mentioned_filtered_user_ids_for(refs)
refs.mentioned_user_ids.presence
end
def mentionable_attributes_changed?(changes = saved_changes)
return false unless is_a?(Mentionable)

View File

@ -92,7 +92,13 @@ module Participable
end
def raw_participants(current_user = nil, verify_access: false)
ext = Gitlab::ReferenceExtractor.new(project, current_user)
extractor = Gitlab::ReferenceExtractor.new(project, current_user)
# Used to extract references from confidential notes.
# Referenced users that cannot read confidential notes are
# later removed from participants array.
internal_notes_extractor = Gitlab::ReferenceExtractor.new(project, current_user)
participants = Set.new
process = [self]
@ -107,6 +113,8 @@ module Participable
source.class.participant_attrs.each do |attr|
if attr.respond_to?(:call)
ext = use_internal_notes_extractor_for?(source) ? internal_notes_extractor : extractor
source.instance_exec(current_user, ext, &attr)
else
process << source.__send__(attr) # rubocop:disable GitlabSecurity/PublicSend
@ -121,7 +129,18 @@ module Participable
end
end
participants.merge(ext.users)
participants.merge(users_that_can_read_internal_notes(internal_notes_extractor))
participants.merge(extractor.users)
end
def use_internal_notes_extractor_for?(source)
source.is_a?(Note) && source.confidential?
end
def users_that_can_read_internal_notes(extractor)
return [] unless self.is_a?(Noteable) && self.try(:resource_parent)
Ability.users_that_can_read_internal_notes(extractor.users, self.resource_parent)
end
def source_visible_to_user?(source, user)

View File

@ -665,6 +665,25 @@ class Note < ApplicationRecord
)
end
def mentioned_users(current_user = nil)
users = super
return users unless confidential?
Ability.users_that_can_read_internal_notes(users, resource_parent)
end
def mentioned_filtered_user_ids_for(references)
return super unless confidential?
user_ids = references.mentioned_user_ids.presence
return [] if user_ids.blank?
users = User.where(id: user_ids)
Ability.users_that_can_read_internal_notes(users, resource_parent).pluck(:id)
end
private
def system_note_viewable_by?(user)

View File

@ -21,11 +21,11 @@ module WorkItems
}.freeze
WIDGETS_FOR_TYPE = {
issue: [Widgets::Description, Widgets::Hierarchy, Widgets::Assignees],
issue: [Widgets::Assignees, Widgets::Description, Widgets::Hierarchy, Widgets::Weight],
incident: [Widgets::Description],
test_case: [Widgets::Description],
requirement: [Widgets::Description],
task: [Widgets::Description, Widgets::Hierarchy, Widgets::Assignees]
task: [Widgets::Assignees, Widgets::Description, Widgets::Hierarchy, Widgets::Weight]
}.freeze
cache_markdown_field :description, pipeline: :single_line

View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
module WorkItems
module Widgets
class Weight < Base
delegate :weight, to: :work_item
end
end
end

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
module WorkItems
module Widgets
module WeightService
class UpdateService < WorkItems::Widgets::BaseService
def update(params: {})
return unless params.present? && params[:weight]
widget.work_item.weight = params[:weight]
end
end
end
end
end

View File

@ -68,7 +68,7 @@
= render 'users/deletion_guidance', user: current_user
-# Delete button here
%button#delete-account-button.gl-button.btn.btn-danger.disabled{ data: { qa_selector: 'delete_account_button' } }
= render Pajamas::ButtonComponent.new(variant: :danger, button_options: { id: 'delete-account-button', disabled: true, data: { qa_selector: 'delete_account_button' }}) do
= s_('Profiles|Delete account')
#delete-account-modal{ data: { action_url: user_registration_path,

View File

@ -3,7 +3,7 @@
= gl_loading_icon(size: "md", css_class: "gl-my-4")
.text-center.gl-mt-3.gl-mb-3.stl-controls
.btn-group
%button.gl-button.btn.btn-default.btn-sm.js-material-changer{ data: { type: 'wireframe' } }
Wireframe
%button.gl-button.btn.btn-default.btn-sm.selected.js-material-changer{ data: { type: 'default' } }
Solid
= render Pajamas::ButtonComponent.new(size: :small, button_options: { class: 'js-material-changer', data: { material: 'wireframe' } }) do
= _('Wireframe')
= render Pajamas::ButtonComponent.new(size: :small, button_options: { class: 'js-material-changer selected', data: { material: 'default' } }) do
= _('Solid')

View File

@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/362246
milestone: '15.1'
type: development
group: group::sharding
default_enabled: false
default_enabled: true

View File

@ -238,13 +238,6 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
end
end
resources :logs, only: [:index] do
collection do
get :k8s
get :elasticsearch
end
end
resources :starrers, only: [:index]
resources :forks, only: [:index, :new, :create]
resources :group_links, only: [:update, :destroy], constraints: { id: /\d+|:id/ }

View File

@ -996,7 +996,7 @@ You can switch an exiting database cluster to use Patroni instead of repmgr with
### Upgrading PostgreSQL major version in a Patroni cluster
As of GitLab 13.3, PostgreSQL 11.7 and 12.3 are both shipped with Omnibus GitLab by default. As of GitLab 13.7, PostgreSQL 12 is the default. If you want to upgrade to PostgreSQL 12 in versions prior to GitLab 13.7, you must ask for it explicitly.
As of GitLab 14.1, PostgreSQL 12.6 and 13.3 are both shipped with Omnibus GitLab by default. As of GitLab 15.0, PostgreSQL 13 is the default. If you want to upgrade to PostgreSQL 13 in versions prior to GitLab 15.0, you must ask for it explicitly.
WARNING:
The procedure for upgrading PostgreSQL in a Patroni cluster is different than when upgrading using repmgr.
@ -1046,7 +1046,7 @@ Considering these, you should carefully plan your PostgreSQL upgrade:
1. Upgrade PostgreSQL on **the leader node** and make sure that the upgrade is completed successfully:
```shell
sudo gitlab-ctl pg-upgrade -V 12
sudo gitlab-ctl pg-upgrade -V 13
```
NOTE:
@ -1073,7 +1073,7 @@ Considering these, you should carefully plan your PostgreSQL upgrade:
1. Upgrade PostgreSQL **on replicas** (you can do this in parallel on all of them):
```shell
sudo gitlab-ctl pg-upgrade -V 12
sudo gitlab-ctl pg-upgrade -V 13
```
NOTE:

View File

@ -5655,6 +5655,7 @@ Input type: `WorkItemUpdateInput`
| <a id="mutationworkitemupdateid"></a>`id` | [`WorkItemID!`](#workitemid) | Global ID of the work item. |
| <a id="mutationworkitemupdatestateevent"></a>`stateEvent` | [`WorkItemStateEvent`](#workitemstateevent) | Close or reopen a work item. |
| <a id="mutationworkitemupdatetitle"></a>`title` | [`String`](#string) | Title of the work item. |
| <a id="mutationworkitemupdateweightwidget"></a>`weightWidget` | [`WorkItemWidgetWeightInput`](#workitemwidgetweightinput) | Input for weight widget. |
#### Fields
@ -18518,6 +18519,17 @@ Represents a hierarchy widget.
| <a id="workitemwidgethierarchyparent"></a>`parent` | [`WorkItem`](#workitem) | Parent work item. |
| <a id="workitemwidgethierarchytype"></a>`type` | [`WorkItemWidgetType`](#workitemwidgettype) | Widget type. |
### `WorkItemWidgetWeight`
Represents a weight widget.
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="workitemwidgetweighttype"></a>`type` | [`WorkItemWidgetType`](#workitemwidgettype) | Widget type. |
| <a id="workitemwidgetweightweight"></a>`weight` | [`Int`](#int) | Weight of the work item. |
## Enumeration types
Also called _Enums_, enumeration types are a special kind of scalar that
@ -20372,6 +20384,7 @@ Type of a work item widget.
| <a id="workitemwidgettypeassignees"></a>`ASSIGNEES` | Assignees widget. |
| <a id="workitemwidgettypedescription"></a>`DESCRIPTION` | Description widget. |
| <a id="workitemwidgettypehierarchy"></a>`HIERARCHY` | Hierarchy widget. |
| <a id="workitemwidgettypeweight"></a>`WEIGHT` | Weight widget. |
## Scalar types
@ -21593,6 +21606,7 @@ Implementations:
- [`WorkItemWidgetAssignees`](#workitemwidgetassignees)
- [`WorkItemWidgetDescription`](#workitemwidgetdescription)
- [`WorkItemWidgetHierarchy`](#workitemwidgethierarchy)
- [`WorkItemWidgetWeight`](#workitemwidgetweight)
##### Fields
@ -22082,6 +22096,7 @@ A time-frame defined as a closed inclusive range of two dates.
| <a id="workitemupdatedtaskinputid"></a>`id` | [`WorkItemID!`](#workitemid) | Global ID of the work item. |
| <a id="workitemupdatedtaskinputstateevent"></a>`stateEvent` | [`WorkItemStateEvent`](#workitemstateevent) | Close or reopen a work item. |
| <a id="workitemupdatedtaskinputtitle"></a>`title` | [`String`](#string) | Title of the work item. |
| <a id="workitemupdatedtaskinputweightwidget"></a>`weightWidget` | [`WorkItemWidgetWeightInput`](#workitemwidgetweightinput) | Input for weight widget. |
### `WorkItemWidgetDescriptionInput`
@ -22090,3 +22105,11 @@ A time-frame defined as a closed inclusive range of two dates.
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="workitemwidgetdescriptioninputdescription"></a>`description` | [`String!`](#string) | Description of the work item. |
### `WorkItemWidgetWeightInput`
#### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="workitemwidgetweightinputweight"></a>`weight` | [`Int!`](#int) | Weight of the work item. |

View File

@ -248,9 +248,13 @@ set `CI_AWS_ECS_WAIT_FOR_ROLLOUT_COMPLETE_DISABLED` to a non-empty value.
## Set up Review Apps
In order to use [Review Apps](../../../development/testing_guide/review_apps.md) with ECS, you should create another
[service](#create-an-ecs-service) and specify its name using the `CI_AWS_ECS_SERVICE` variable scoped to `review/*`.
Since this service is shared by all review apps, there is a limitation that only one Review App can be deployed at a time.
To use [Review Apps](../../../development/testing_guide/review_apps.md) with ECS:
1. Set up a new [service](#create-an-ecs-service).
1. Use the `CI_AWS_ECS_SERVICE` variable to set the name.
1. Set the environment scope to `review/*`.
Only one Review App at a time can be deployed because this service is shared by all review apps.
## Set up Security Testing
@ -275,6 +279,20 @@ include:
- template: Security/DAST.gitlab-ci.yml
```
To use DAST on the default branch:
1. Set up a new [service](#create-an-ecs-service). This service will be used to deploy a temporary
DAST environment.
1. Use the `CI_AWS_ECS_SERVICE` variable to set the name.
1. Set the scope to the `dast-default` environment.
1. Add the following to your `.gitlab-ci.yml` file:
```yaml
include:
- template: Security/DAST.gitlab-ci.yml
- template: Jobs/DAST-Default-Branch-Deploy.gitlab-ci.yml
```
For more details and configuration options, see the [DAST documentation](../../../user/application_security/dast/index.md).
## Further reading

View File

@ -451,7 +451,7 @@ The `identifiers` array describes the detected vulnerability. An identifier obje
`value` fields are used to tell if two identifiers are the same. The user interface uses the
object's `name` and `url` fields to display the identifier.
It is recommended to reuse the identifiers the GitLab scanners already define:
We recommend that you use the identifiers the GitLab scanners already define:
| Identifier | Type | Example value |
|------------|------|---------------|

View File

@ -0,0 +1,28 @@
---
type: reference, howto
stage: Secure
group: Threat Insights
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# Generate test vulnerabilities
You can generate test vulnerabilities when you work on the [Vulnerability Report](../vulnerability_report/index.md).
1. Go to `/-/profile/personal_access_tokens` and generate a personal access token with `api` permissions.
1. Go to your project page and find the project ID. You can find the project ID below the project title.
1. Open a terminal and go to the `gitlab/qa` directory.
1. Run the following command:
```shell
GITLAB_QA_ACCESS_TOKEN=<your_personal_access_token> GITLAB_URL="http://localhost:3000" bundle exec rake vulnerabilities:setup\[<your_project_id>,<vulnerability_count>\] --trace
```
Make sure you do the following:
- Replace `<your_personal_access_token>` with the token you generated in step one.
- Double check the `GITLAB_URL`. It should point to the running local instance.
- Replace `<your_project_id>` with the ID you obtained in step two.
- Replace `<vulnerability_count>` with the number of vulnerabilities you'd like to generate.
The script creates the specified amount of vulnerabilities in the project.

View File

@ -4,6 +4,14 @@ variables:
.dast-auto-deploy:
image: "registry.gitlab.com/gitlab-org/cluster-integration/auto-deploy-image:${DAST_AUTO_DEPLOY_IMAGE_VERSION}"
.common_rules: &common_rules
- if: $CI_DEFAULT_BRANCH != $CI_COMMIT_REF_NAME
when: never
- if: $DAST_DISABLED || $DAST_DISABLED_FOR_DEFAULT_BRANCH
when: never
- if: $DAST_WEBSITE # we don't need to create a review app if a URL is already given
when: never
dast_environment_deploy:
extends: .dast-auto-deploy
stage: review
@ -23,12 +31,7 @@ dast_environment_deploy:
artifacts:
paths: [environment_url.txt]
rules:
- if: $CI_DEFAULT_BRANCH != $CI_COMMIT_REF_NAME
when: never
- if: $DAST_DISABLED || $DAST_DISABLED_FOR_DEFAULT_BRANCH
when: never
- if: $DAST_WEBSITE # we don't need to create a review app if a URL is already given
when: never
- *common_rules
- if: $CI_COMMIT_BRANCH &&
($CI_KUBERNETES_ACTIVE || $KUBECONFIG) &&
$GITLAB_FEATURES =~ /\bdast\b/
@ -47,13 +50,53 @@ stop_dast_environment:
action: stop
needs: ["dast"]
rules:
- if: $CI_DEFAULT_BRANCH != $CI_COMMIT_REF_NAME
when: never
- if: $DAST_DISABLED || $DAST_DISABLED_FOR_DEFAULT_BRANCH
when: never
- if: $DAST_WEBSITE # we don't need to create a review app if a URL is already given
when: never
- *common_rules
- if: $CI_COMMIT_BRANCH &&
($CI_KUBERNETES_ACTIVE || $KUBECONFIG) &&
$GITLAB_FEATURES =~ /\bdast\b/
when: always
.ecs_image:
image: 'registry.gitlab.com/gitlab-org/cloud-deploy/aws-ecs:latest'
.ecs_rules: &ecs_rules
- if: $AUTO_DEVOPS_PLATFORM_TARGET != "ECS"
when: never
- if: $CI_KUBERNETES_ACTIVE || $KUBECONFIG
when: never
dast_ecs_environment_deploy:
extends: .ecs_image
stage: review
script:
- ecs update-task-definition
- echo "http://$(ecs get-task-hostname)" > environment_url.txt
environment:
name: dast-default
on_stop: stop_dast_ecs_environment
artifacts:
paths:
- environment_url.txt
rules:
- *common_rules
- *ecs_rules
- if: $CI_COMMIT_BRANCH && $GITLAB_FEATURES =~ /\bdast\b/
stop_dast_ecs_environment:
extends: .ecs_image
stage: cleanup
variables:
GIT_STRATEGY: none
script:
- ecs stop-task
allow_failure: true
environment:
name: dast-default
action: stop
needs:
- dast
rules:
- *common_rules
- *ecs_rules
- if: $CI_COMMIT_BRANCH && $GITLAB_FEATURES =~ /\bdast\b/
when: always

View File

@ -9,7 +9,6 @@ module Sidebars
return false unless context.project.feature_available?(:operations, context.current_user)
add_item(metrics_dashboard_menu_item)
add_item(logs_menu_item)
add_item(error_tracking_menu_item)
add_item(alert_management_menu_item)
add_item(incidents_menu_item)
@ -56,21 +55,6 @@ module Sidebars
)
end
def logs_menu_item
if !Feature.enabled?(:monitor_logging, context.project) ||
!can?(context.current_user, :read_environment, context.project) ||
!can?(context.current_user, :read_pod_logs, context.project)
return ::Sidebars::NilMenuItem.new(item_id: :logs)
end
::Sidebars::MenuItem.new(
title: _('Logs'),
link: project_logs_path(context.project),
active_routes: { path: 'logs#index' },
item_id: :logs
)
end
def error_tracking_menu_item
unless can?(context.current_user, :read_sentry_issue, context.project)
return ::Sidebars::NilMenuItem.new(item_id: :error_tracking)

View File

@ -6222,12 +6222,6 @@ msgstr ""
msgid "Billing|You can begin moving members in %{namespaceName} now. A member loses access to the group when you turn off %{strongStart}In a seat%{strongEnd}. If over 5 members have %{strongStart}In a seat%{strongEnd} enabled after June 22, 2022, we'll select the 5 members who maintain access. We'll first count members that have Owner and Maintainer roles, then the most recently active members until we reach 5 members. The remaining members will get a status of Over limit and lose access to the group."
msgstr ""
msgid "Billing|Your free group is now limited to %{free_user_limit} members"
msgstr ""
msgid "Billing|Your group recently changed to use the Free plan. Free groups are limited to %{free_user_limit} members and the remaining members will get a status of over-limit and lose access to the group. You can free up space for new members by removing those who no longer need access or toggling them to over-limit. To get an unlimited number of members, you can %{link_start}upgrade%{link_end} to a paid tier."
msgstr ""
msgid "Bitbucket Server Import"
msgstr ""
@ -36098,6 +36092,9 @@ msgstr ""
msgid "Snowplow"
msgstr ""
msgid "Solid"
msgstr ""
msgid "Solution"
msgstr ""
@ -43551,6 +43548,9 @@ msgstr ""
msgid "Will deploy to"
msgstr ""
msgid "Wireframe"
msgstr ""
msgid "With requirements, you can set criteria to check your products against."
msgstr ""

View File

@ -52,8 +52,8 @@
"@babel/preset-env": "^7.18.2",
"@gitlab/at.js": "1.5.7",
"@gitlab/favicon-overlay": "2.0.0",
"@gitlab/svgs": "2.21.0",
"@gitlab/ui": "42.9.0",
"@gitlab/svgs": "2.22.0",
"@gitlab/ui": "42.11.0",
"@gitlab/visual-review-tools": "1.7.3",
"@rails/actioncable": "6.1.4-7",
"@rails/ujs": "6.1.4-7",

View File

@ -6,6 +6,7 @@ RSpec.describe 'Incident details', :js do
let_it_be(:project) { create(:project) }
let_it_be(:developer) { create(:user) }
let_it_be(:incident) { create(:incident, project: project, author: developer, description: 'description') }
let_it_be(:issue) { create(:issue, project: project, author: developer, description: 'Issue description') }
let_it_be(:escalation_status) { create(:incident_management_issuable_escalation_status, issue: incident) }
before_all do
@ -14,23 +15,24 @@ RSpec.describe 'Incident details', :js do
before do
sign_in(developer)
visit project_issues_incident_path(project, incident)
wait_for_requests
end
context 'when a developer+ displays the incident' do
it 'shows the incident' do
before do
visit project_issues_incident_path(project, incident)
wait_for_requests
end
it 'shows correct elements on the page', :aggregate_failures do
# shows the incident
page.within('.issuable-details') do
expect(find('h1')).to have_content(incident.title)
end
end
it 'does not show design management' do
# does not show design management
expect(page).not_to have_selector('.js-design-management')
end
it 'shows the incident tabs' do
# shows the incident tabs
page.within('.issuable-details') do
incident_tabs = find('[data-testid="incident-tabs"]')
@ -38,9 +40,8 @@ RSpec.describe 'Incident details', :js do
expect(incident_tabs).to have_content('Summary')
expect(incident_tabs).to have_content(incident.description)
end
end
it 'shows the right sidebar mounted with type issue' do
# shows the right sidebar mounted with type issue
page.within('.layout-page') do
sidebar = find('.right-sidebar')
@ -51,12 +52,12 @@ RSpec.describe 'Incident details', :js do
end
end
context 'escalation status' do
describe 'escalation status' do
let(:sidebar) { page.find('.right-sidebar') }
let(:widget) { sidebar.find('[data-testid="escalation_status_container"]') }
let(:expected_dropdown_options) { escalation_status.class::STATUSES.keys.take(3).map { |key| key.to_s.titleize } }
it 'has an interactable escalation status widget' do
it 'has an interactable escalation status widget', :aggregate_failures do
expect(current_status).to have_text(escalation_status.status_name.to_s.titleize)
# list the available statuses
@ -87,41 +88,41 @@ RSpec.describe 'Incident details', :js do
end
end
context 'when an incident `issue_type` is edited by a signed in user' do
it 'routes the user to the incident details page when the `issue_type` is set to incident' do
wait_for_requests
project_path = "/#{project.full_path}"
click_button 'Edit title and description'
it 'routes the user to the incident details page when the `issue_type` is set to incident' do
visit project_issue_path(project, issue)
wait_for_requests
project_path = "/#{project.full_path}"
click_button 'Edit title and description'
wait_for_requests
page.within('[data-testid="issuable-form"]') do
click_button 'Issue'
click_button 'Incident'
click_button 'Save changes'
wait_for_requests
page.within('[data-testid="issuable-form"]') do
click_button 'Incident'
click_button 'Issue'
click_button 'Save changes'
wait_for_requests
expect(page).to have_current_path("#{project_path}/-/issues/#{incident.iid}")
end
expect(page).to have_current_path("#{project_path}/-/issues/incident/#{issue.iid}")
end
end
context 'when incident details are edited by a signed in user' do
it 'routes the user to the incident details page when the `issue_type` is set to incident' do
wait_for_requests
project_path = "/#{project.full_path}"
click_button 'Edit title and description'
it 'routes the user to the issue details page when the `issue_type` is set to issue' do
visit project_issues_incident_path(project, incident)
wait_for_requests
project_path = "/#{project.full_path}"
click_button 'Edit title and description'
wait_for_requests
page.within('[data-testid="issuable-form"]') do
click_button 'Incident'
click_button 'Issue'
click_button 'Save changes'
wait_for_requests
page.within('[data-testid="issuable-form"]') do
click_button 'Incident'
click_button 'Issue'
click_button 'Save changes'
wait_for_requests
expect(page).to have_current_path("#{project_path}/-/issues/#{incident.iid}")
end
expect(page).to have_current_path("#{project_path}/-/issues/#{incident.iid}")
end
end
end

View File

@ -17,6 +17,7 @@ exports[`Alert integration settings form default state should match the default
<gl-form-checkbox-stub
checked="true"
data-qa-selector="create_issue_checkbox"
id="2"
>
<span>
Create an incident. Incidents are created for each alert triggered.
@ -87,7 +88,9 @@ exports[`Alert integration settings form default state should match the default
labeldescription=""
optionaltext="(optional)"
>
<gl-form-checkbox-stub>
<gl-form-checkbox-stub
id="3"
>
<span>
Send a single email notification to Owners and Maintainers for new alerts.
</span>
@ -101,6 +104,7 @@ exports[`Alert integration settings form default state should match the default
>
<gl-form-checkbox-stub
checked="true"
id="4"
>
<span>
Automatically close associated incident when a recovery alert notification resolves an alert

View File

@ -7,6 +7,7 @@ exports[`Keep latest artifact checkbox when application keep latest artifact set
<b-form-checkbox-stub
checked="true"
class="gl-form-checkbox"
id="4"
value="true"
>
<strong

View File

@ -151,6 +151,38 @@ RSpec.describe Ability do
end
end
describe '.users_that_can_read_internal_note' do
shared_examples 'filtering users that can read internal note' do
let_it_be(:guest) { create(:user) }
let_it_be(:reporter) { create(:user) }
let(:users) { [reporter, guest] }
before do
parent.add_guest(guest)
parent.add_reporter(reporter)
end
it 'returns users that can read internal notes' do
result = described_class.users_that_can_read_internal_notes(users, parent)
expect(result).to match_array([reporter])
end
end
context 'for groups' do
it_behaves_like 'filtering users that can read internal note' do
let(:parent) { create(:group) }
end
end
context 'for projects' do
it_behaves_like 'filtering users that can read internal note' do
let(:parent) { create(:project) }
end
end
end
describe '.merge_requests_readable_by_user' do
context 'with an admin when admin mode is enabled', :enable_admin_mode do
it 'returns all merge requests' do

View File

@ -31,7 +31,7 @@ RSpec.describe Participable do
expect(instance).to receive(:foo).and_return(user2)
expect(instance).to receive(:bar).and_return(user3)
expect(instance).to receive(:project).twice.and_return(project)
expect(instance).to receive(:project).thrice.and_return(project)
participants = instance.participants(user1)
@ -66,7 +66,7 @@ RSpec.describe Participable do
expect(instance).to receive(:foo).and_return(other)
expect(other).to receive(:bar).and_return(user2)
expect(instance).to receive(:project).twice.and_return(project)
expect(instance).to receive(:project).thrice.and_return(project)
expect(instance.participants(user1)).to eq([user2])
end
@ -86,7 +86,7 @@ RSpec.describe Participable do
instance = model.new
expect(instance).to receive(:project).twice.and_return(project)
expect(instance).to receive(:project).thrice.and_return(project)
instance.participants(user1)
@ -138,7 +138,7 @@ RSpec.describe Participable do
allow(instance).to receive_message_chain(:model_name, :element) { 'class' }
expect(instance).to receive(:foo).and_return(user2)
expect(instance).to receive(:bar).and_return(user3)
expect(instance).to receive(:project).twice.and_return(project)
expect(instance).to receive(:project).thrice.and_return(project)
participants = instance.visible_participants(user1)
@ -159,7 +159,7 @@ RSpec.describe Participable do
allow(instance).to receive_message_chain(:model_name, :element) { 'class' }
allow(instance).to receive(:bar).and_return(user2)
expect(instance).to receive(:project).twice.and_return(project)
expect(instance).to receive(:project).thrice.and_return(project)
expect(instance.visible_participants(user1)).to be_empty
end

View File

@ -744,25 +744,11 @@ RSpec.describe Issue do
end
describe '#participants' do
context 'using a public project' do
let_it_be(:public_project) { create(:project, :public) }
let_it_be(:issue) { create(:issue, project: public_project) }
it_behaves_like 'issuable participants' do
let_it_be(:issuable_parent) { create(:project, :public) }
let_it_be_with_refind(:issuable) { create(:issue, project: issuable_parent) }
let!(:note1) do
create(:note_on_issue, noteable: issue, project: public_project, note: 'a')
end
let!(:note2) do
create(:note_on_issue, noteable: issue, project: public_project, note: 'b')
end
it 'includes the issue author' do
expect(issue.participants).to include(issue.author)
end
it 'includes the authors of the notes' do
expect(issue.participants).to include(note1.author, note2.author)
end
let(:params) { { noteable: issuable, project: issuable_parent } }
end
context 'using a private project' do

View File

@ -39,7 +39,8 @@ RSpec.describe WorkItem do
it 'returns instances of supported widgets' do
is_expected.to match_array([instance_of(WorkItems::Widgets::Description),
instance_of(WorkItems::Widgets::Hierarchy),
instance_of(WorkItems::Widgets::Assignees)])
instance_of(WorkItems::Widgets::Assignees),
instance_of(WorkItems::Widgets::Weight)])
end
end

View File

@ -66,7 +66,8 @@ RSpec.describe WorkItems::Type do
it 'returns list of all possible widgets' do
is_expected.to match_array([::WorkItems::Widgets::Description,
::WorkItems::Widgets::Hierarchy,
::WorkItems::Widgets::Assignees])
::WorkItems::Widgets::Assignees,
::WorkItems::Widgets::Weight])
end
end

View File

@ -113,5 +113,29 @@ RSpec.describe 'Update a work item' do
end
end
end
context 'with weight widget input' do
let(:fields) do
<<~FIELDS
workItem {
widgets {
type
... on WorkItemWidgetWeight {
weight
}
}
}
errors
FIELDS
end
it_behaves_like 'update work item weight widget' do
let(:new_weight) { 2 }
let(:input) do
{ 'weightWidget' => { 'weight' => new_weight } }
end
end
end
end
end

View File

@ -8,7 +8,7 @@ RSpec.describe 'Query.work_item(id)' do
let_it_be(:developer) { create(:user) }
let_it_be(:guest) { create(:user) }
let_it_be(:project) { create(:project, :private) }
let_it_be(:work_item) { create(:work_item, project: project, description: '- List item') }
let_it_be(:work_item) { create(:work_item, project: project, description: '- List item', weight: 1) }
let_it_be(:child_item1) { create(:work_item, :task, project: project) }
let_it_be(:child_item2) { create(:work_item, :task, confidential: true, project: project) }
let_it_be(:child_link1) { create(:parent_link, work_item_parent: work_item, work_item: child_item1) }
@ -163,6 +163,32 @@ RSpec.describe 'Query.work_item(id)' do
end
end
describe 'weight widget' do
let(:work_item_fields) do
<<~GRAPHQL
id
widgets {
type
... on WorkItemWidgetWeight {
weight
}
}
GRAPHQL
end
it 'returns widget information' do
expect(work_item_data).to include(
'id' => work_item.to_gid.to_s,
'widgets' => include(
hash_including(
'type' => 'WEIGHT',
'weight' => work_item.weight
)
)
)
end
end
describe 'assignees widget' do
let(:assignees) { create_list(:user, 2) }
let(:work_item) { create(:work_item, project: project, assignees: assignees) }

View File

@ -147,6 +147,34 @@ RSpec.describe NotificationService, :mailer do
end
end
shared_examples 'participating by confidential note notification' do
context 'when user is mentioned on confidential note' do
let_it_be(:guest_1) { create(:user) }
let_it_be(:guest_2) { create(:user) }
let_it_be(:reporter) { create(:user) }
before do
issuable.resource_parent.add_guest(guest_1)
issuable.resource_parent.add_guest(guest_2)
issuable.resource_parent.add_reporter(reporter)
end
it 'only emails authorized users' do
confidential_note_text = "#{guest_1.to_reference} and #{guest_2.to_reference} and #{reporter.to_reference}"
note_text = "Mentions #{guest_2.to_reference}"
create(:note_on_issue, noteable: issuable, project_id: project.id, note: confidential_note_text, confidential: true)
create(:note_on_issue, noteable: issuable, project_id: project.id, note: note_text)
reset_delivered_emails!
notification_trigger
should_not_email(guest_1)
should_email(guest_2)
should_email(reporter)
end
end
end
shared_examples 'participating by assignee notification' do
it 'emails the participant' do
issuable.assignees << participant
@ -736,6 +764,20 @@ RSpec.describe NotificationService, :mailer do
let(:notification_target) { note }
let(:notification_trigger) { notification.new_note(note) }
end
context 'when note is confidential' do
let(:note) { create(:note_on_issue, author: author, noteable: issue, project_id: issue.project_id, note: '@all mentioned', confidential: true) }
let(:guest) { create(:user) }
it 'does not notify users that cannot read note' do
project.add_guest(guest)
reset_delivered_emails!
notification.new_note(note)
should_not_email(guest)
end
end
end
end
@ -1376,6 +1418,11 @@ RSpec.describe NotificationService, :mailer do
let(:notification_trigger) { notification.reassigned_issue(issue, @u_disabled, [assignee]) }
end
it_behaves_like 'participating by confidential note notification' do
let(:issuable) { issue }
let(:notification_trigger) { notification.reassigned_issue(issue, @u_disabled, [assignee]) }
end
it_behaves_like 'project emails are disabled' do
let(:notification_target) { issue }
let(:notification_trigger) { notification.reassigned_issue(issue, @u_disabled, [assignee]) }
@ -1494,6 +1541,11 @@ RSpec.describe NotificationService, :mailer do
let(:notification_target) { issue }
let(:notification_trigger) { notification.removed_milestone_issue(issue, issue.author) }
end
it_behaves_like 'participating by confidential note notification' do
let(:issuable) { issue }
let(:notification_trigger) { notification.removed_milestone_issue(issue, issue.author) }
end
end
context 'confidential issues' do
@ -1616,6 +1668,11 @@ RSpec.describe NotificationService, :mailer do
let(:notification_trigger) { notification.close_issue(issue, @u_disabled) }
end
it_behaves_like 'participating by confidential note notification' do
let(:issuable) { issue }
let(:notification_trigger) { notification.close_issue(issue, @u_disabled) }
end
it 'adds "subscribed" reason to subscriber emails' do
user_1 = create(:user)
issue.subscribe(user_1)
@ -1658,6 +1715,11 @@ RSpec.describe NotificationService, :mailer do
let(:notification_trigger) { notification.reopen_issue(issue, @u_disabled) }
end
it_behaves_like 'participating by confidential note notification' do
let(:issuable) { issue }
let(:notification_trigger) { notification.reopen_issue(issue, @u_disabled) }
end
it_behaves_like 'project emails are disabled' do
let(:notification_target) { issue }
let(:notification_trigger) { notification.reopen_issue(issue, @u_disabled) }
@ -1689,6 +1751,11 @@ RSpec.describe NotificationService, :mailer do
let(:notification_trigger) { notification.issue_moved(issue, new_issue, @u_disabled) }
end
it_behaves_like 'participating by confidential note notification' do
let(:issuable) { issue }
let(:notification_trigger) { notification.issue_moved(issue, new_issue, @u_disabled) }
end
it_behaves_like 'project emails are disabled' do
let(:notification_target) { issue }
let(:notification_trigger) { notification.issue_moved(issue, new_issue, @u_disabled) }
@ -1720,6 +1787,11 @@ RSpec.describe NotificationService, :mailer do
let(:notification_trigger) { notification.issue_cloned(issue, new_issue, @u_disabled) }
end
it_behaves_like 'participating by confidential note notification' do
let(:issuable) { issue }
let(:notification_trigger) { notification.issue_cloned(issue, new_issue, @u_disabled) }
end
it_behaves_like 'project emails are disabled' do
let(:notification_target) { issue }
let(:notification_trigger) { notification.issue_cloned(issue, new_issue, @u_disabled) }
@ -1765,6 +1837,11 @@ RSpec.describe NotificationService, :mailer do
let(:notification_trigger) { notification.issue_due(issue) }
end
it_behaves_like 'participating by confidential note notification' do
let(:issuable) { issue }
let(:notification_trigger) { notification.issue_due(issue) }
end
it_behaves_like 'project emails are disabled' do
let(:notification_target) { issue }
let(:notification_trigger) { notification.issue_due(issue) }

View File

@ -0,0 +1,36 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe WorkItems::Widgets::WeightService::UpdateService do
let_it_be(:user) { create(:user) }
let_it_be(:project) { create(:project) }
let_it_be_with_reload(:work_item) { create(:work_item, project: project, weight: 1) }
let(:widget) { work_item.widgets.find {|widget| widget.is_a?(WorkItems::Widgets::Weight) } }
describe '#update' do
subject { described_class.new(widget: widget, current_user: user).update(params: params) } # rubocop:disable Rails/SaveBang
context 'when weight param is present' do
let(:params) { { weight: 2 } }
it 'correctly sets work item weight value' do
subject
expect(work_item.weight).to eq(2)
end
end
context 'when weight param is not present' do
let(:params) { {} }
it 'does not change work item weight value', :aggregate_failures do
expect { subject }
.to not_change { work_item.weight }
expect(work_item.weight).to eq(1)
end
end
end
end

View File

@ -83,7 +83,6 @@ RSpec.shared_context 'project navbar structure' do
nav_item: _('Monitor'),
nav_sub_items: [
_('Metrics'),
_('Logs'),
_('Error Tracking'),
_('Alerts'),
_('Incidents'),

View File

@ -0,0 +1,34 @@
# frozen_string_literal: true
RSpec.shared_examples 'update work item weight widget' do
it 'updates the weight widget' do
expect do
post_graphql_mutation(mutation, current_user: current_user)
work_item.reload
end.to change(work_item, :weight).from(nil).to(new_weight)
expect(response).to have_gitlab_http_status(:success)
expect(mutation_response['workItem']['widgets']).to include(
{
'weight' => new_weight,
'type' => 'WEIGHT'
}
)
end
context 'when the updated work item is not valid' do
it 'returns validation errors without the work item' do
errors = ActiveModel::Errors.new(work_item).tap { |e| e.add(:weight, 'error message') }
allow_next_found_instance_of(::WorkItem) do |instance|
allow(instance).to receive(:valid?).and_return(false)
allow(instance).to receive(:errors).and_return(errors)
end
post_graphql_mutation(mutation, current_user: current_user)
expect(mutation_response['workItem']).to be_nil
expect(mutation_response['errors']).to match_array(['Weight error message'])
end
end
end

View File

@ -0,0 +1,53 @@
# frozen_string_literal: true
RSpec.shared_examples 'issuable participants' do
context 'when resource parent is public' do
context 'and users are referenced on notes' do
let_it_be(:notes_author) { create(:user) }
let(:note_params) { params.merge(author: notes_author) }
before do
create(:note, note_params)
end
it 'includes the issue author' do
expect(issuable.participants).to include(issuable.author)
end
it 'includes the authors of the notes' do
expect(issuable.participants).to include(notes_author)
end
context 'and note is confidential' do
context 'and mentions users' do
let_it_be(:guest_1) { create(:user) }
let_it_be(:guest_2) { create(:user) }
let_it_be(:reporter) { create(:user) }
before do
issuable_parent.add_guest(guest_1)
issuable_parent.add_guest(guest_2)
issuable_parent.add_reporter(reporter)
confidential_note_params =
note_params.merge(
confidential: true,
note: "mentions #{guest_1.to_reference} and #{guest_2.to_reference} and #{reporter.to_reference}"
)
regular_note_params =
note_params.merge(note: "Mentions #{guest_2.to_reference}")
create(:note, confidential_note_params)
create(:note, regular_note_params)
end
it 'only includes users that can read the note as participants' do
expect(issuable.participants).to contain_exactly(issuable.author, notes_author, reporter, guest_2)
end
end
end
end
end
end

View File

@ -260,6 +260,25 @@ RSpec.shared_examples 'mentions in notes' do |mentionable_type|
expect(mentionable.referenced_projects(user)).to eq [mentionable.project].compact # epic.project is nil, and we want empty []
expect(mentionable.referenced_groups(user)).to eq [group]
end
if [:epic, :issue].include?(mentionable_type)
context 'and note is confidential' do
let_it_be(:guest) { create(:user) }
let(:note_desc) { "#{guest.to_reference} and #{user2.to_reference} and #{user.to_reference}" }
before do
note.resource_parent.add_reporter(user2)
note.resource_parent.add_guest(guest)
# Bypass :confidential update model validation for testing purposes
note.update_attribute(:confidential, true)
end
it 'returns only mentioned users that has permissions' do
expect(note.mentioned_users).to contain_exactly(user, user2)
end
end
end
end
end
@ -294,6 +313,26 @@ RSpec.shared_examples 'load mentions from DB' do |mentionable_type|
end
end
if [:epic, :issue].include?(mentionable_type)
context 'and note is confidential' do
let_it_be(:guest) { create(:user) }
let(:note_desc) { "#{guest.to_reference} and #{mentioned_user.to_reference}" }
before do
note.resource_parent.add_reporter(mentioned_user)
note.resource_parent.add_guest(guest)
# Bypass :confidential update model validation for testing purposes
note.update_attribute(:confidential, true)
note.store_mentions!
end
it 'stores only mentioned users that has permissions' do
expect(mentionable.referenced_users).to contain_exactly(mentioned_user)
end
end
end
context 'when private projects and groups are mentioned' do
let(:mega_user) { create(:user) }
let(:private_project) { create(:project, :private) }

17
vendor/gems/omniauth-gitlab/.gitignore vendored Normal file
View File

@ -0,0 +1,17 @@
*.gem
*.rbc
.bundle
.config
.yardoc
.rvmrc
InstalledFiles
_yardoc
coverage
doc/
lib/bundler/man
pkg
rdoc
spec/reports
test/tmp
test/version_tmp
tmp

View File

@ -0,0 +1,30 @@
workflow:
rules:
- if: $CI_MERGE_REQUEST_ID
.rspec:
cache:
key: omniauth-gitlab-ruby
paths:
- vendor/gems/omniauth-gitlab/vendor/ruby
before_script:
- cd vendor/gems/omniauth-gitlab
- ruby -v # Print out ruby version for debugging
- gem install bundler --no-document # Bundler is not installed with the image
- bundle config set --local path 'vendor' # Install dependencies into ./vendor/ruby
- bundle config set with 'development'
- bundle install -j $(nproc)
script:
- bundle exec rspec
rspec-2.6:
image: "ruby:2.6"
extends: .rspec
rspec-2.7:
image: "ruby:2.7"
extends: .rspec
rspec-3.0:
image: "ruby:3.0"
extends: .rspec

4
vendor/gems/omniauth-gitlab/Gemfile vendored Normal file
View File

@ -0,0 +1,4 @@
source 'https://rubygems.org'
# Specify your gem's dependencies in omniauth-gitlab.gemspec
gemspec

View File

@ -0,0 +1,73 @@
PATH
remote: .
specs:
omniauth-gitlab (4.0.0)
omniauth (~> 1.0)
omniauth-oauth2 (~> 1.7.1)
GEM
remote: https://rubygems.org/
specs:
diff-lcs (1.5.0)
docile (1.4.0)
faraday (2.3.0)
faraday-net_http (~> 2.0)
ruby2_keywords (>= 0.0.4)
faraday-net_http (2.0.3)
hashie (5.0.0)
jwt (2.4.1)
multi_xml (0.6.0)
oauth2 (2.0.1)
faraday (>= 0.17.3, < 3.0)
jwt (>= 1.0, < 3.0)
multi_xml (~> 0.5)
rack (>= 1.2, < 3)
rash_alt (>= 0.4, < 1)
version_gem (~> 1.0)
omniauth (1.9.1)
hashie (>= 3.4.6)
rack (>= 1.6.2, < 3)
omniauth-oauth2 (1.7.3)
oauth2 (>= 1.4, < 3)
omniauth (>= 1.9, < 3)
rack (2.2.3.1)
rake (13.0.6)
rash_alt (0.4.12)
hashie (>= 3.4)
rspec (3.11.0)
rspec-core (~> 3.11.0)
rspec-expectations (~> 3.11.0)
rspec-mocks (~> 3.11.0)
rspec-core (3.11.0)
rspec-support (~> 3.11.0)
rspec-expectations (3.11.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.11.0)
rspec-its (1.3.0)
rspec-core (>= 3.0.0)
rspec-expectations (>= 3.0.0)
rspec-mocks (3.11.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.11.0)
rspec-support (3.11.0)
ruby2_keywords (0.0.5)
simplecov (0.21.2)
docile (~> 1.1)
simplecov-html (~> 0.11)
simplecov_json_formatter (~> 0.1)
simplecov-html (0.12.3)
simplecov_json_formatter (0.1.4)
version_gem (1.0.0)
PLATFORMS
ruby
DEPENDENCIES
omniauth-gitlab!
rake (>= 12.0)
rspec (~> 3.1)
rspec-its (~> 1.0)
simplecov
BUNDLED WITH
2.3.15

22
vendor/gems/omniauth-gitlab/LICENSE.txt vendored Normal file
View File

@ -0,0 +1,22 @@
Copyright (c) 2013 ssein
MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

94
vendor/gems/omniauth-gitlab/README.md vendored Normal file
View File

@ -0,0 +1,94 @@
# Omniauth::Gitlab
This is fork of [omniauth-gitlab](https://github.com/linchus/omniauth-gitlab) to support:
1. OmniAuth v1 and v2. OmniAuth v2 disables GET requests by default
and defaults to POST. GitLab already has patched v1 to use POST,
but other dependencies need to be updated:
https://gitlab.com/gitlab-org/gitlab/-/issues/30073.
2. [`oauth2`](https://github.com/oauth-xx/oauth2) v1.4.9 and up.
[v1.4.9 fixed relative URL handling](https://github.com/oauth-xx/oauth2/pull/469).
However, this breaks the default GitLab.com configuration and
existing configurations that use the `/api/v4` suffix in the `site`
parameter.
[omniauth-gitlab v4.0.0 fixed the first issue](https://github.com/linchus/omniauth-gitlab/pull/22),
but the second issue requires an admin to update `site` to drop the suffix.
This fork restores backwards compatibility that was removed in omniauth-gitlab v2.0.0:
https://github.com/linchus/omniauth-gitlab/commit/bb4cec2c9f8f067fdfe1f9aa219973e5d8e4a0a3
[![Join the chat at https://gitter.im/linchus/omniauth-gitlab](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/linchus/omniauth-gitlab?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
This is the OAuth2 strategy for authenticating to your GitLab service.
## Requirements
Gitlab 7.7.0+
## Installation
Add this line to your application's Gemfile:
gem 'omniauth-gitlab'
And then execute:
$ bundle
Or install it yourself as:
$ gem install omniauth-gitlab
## Basic Usage
use OmniAuth::Builder do
provider :gitlab, ENV['GITLAB_KEY'], ENV['GITLAB_SECRET']
end
## Standalone Usage
use OmniAuth::Builder do
provider :gitlab, ENV['GITLAB_KEY'], ENV['GITLAB_SECRET'],
{
client_options: {
site: 'https://gitlab.YOURDOMAIN.com/api/v4'
}
}
end
## Custom scopes
By default, the `api` scope is requested and must be allowed in GitLab's application configuration. To use different scopes:
use OmniAuth::Builder do
provider :gitlab, ENV['GITLAB_KEY'], ENV['GITLAB_SECRET'], scope: 'read_user openid'
end
Requesting a scope that is not configured will result the error "The requested scope is invalid, unknown, or malformed.".
## Old API version
API V3 will be unsupported from GitLab 9.5 and will be removed in GitLab 9.5 or later.
[https://gitlab.com/help/api/v3_to_v4.md](https://gitlab.com/help/api/v3_to_v4.md)
If you use GitLab 9.0 and below you could configure V3 API:
use OmniAuth::Builder do
provider :gitlab, ENV['GITLAB_KEY'], ENV['GITLAB_SECRET'],
{
client_options: {
site: 'https://gitlab.YOURDOMAIN.com/api/v3'
}
}
end
## Contributing
1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request

7
vendor/gems/omniauth-gitlab/Rakefile vendored Normal file
View File

@ -0,0 +1,7 @@
require 'bundler/gem_tasks'
require 'rspec/core/rake_task'
RSpec::Core::RakeTask.new
desc 'Run specs'
task default: :spec

View File

@ -0,0 +1,2 @@
require 'omniauth-gitlab/version'
require 'omniauth/strategies/gitlab'

View File

@ -0,0 +1,5 @@
module Omniauth
module Gitlab
VERSION = '4.0.0'
end
end

View File

@ -0,0 +1,46 @@
# frozen_string_literal: true
require 'omniauth-oauth2'
module OmniAuth
module Strategies
class GitLab < OmniAuth::Strategies::OAuth2
API_SUFFIX_REGEX = %r{/api/v(\d+)/?$}.freeze
option :client_options, site: 'https://gitlab.com'
option :redirect_url
uid { raw_info['id'].to_s }
info do
{
name: raw_info['name'],
username: raw_info['username'],
email: raw_info['email'],
image: raw_info['avatar_url']
}
end
extra do
{ raw_info: raw_info }
end
def raw_info
@raw_info ||= access_token.get(user_endpoint_url).parsed
end
private
def user_endpoint_url
options.client_options.site.match(API_SUFFIX_REGEX) ? 'user' : 'api/v4/user'
end
def callback_url
options.redirect_url || (full_host + script_name + callback_path)
end
end
end
end
OmniAuth.config.add_camelization 'gitlab', 'GitLab'

View File

@ -0,0 +1,25 @@
# -*- encoding: utf-8 -*-
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'omniauth-gitlab/version'
Gem::Specification.new do |gem|
gem.name = 'omniauth-gitlab'
gem.version = Omniauth::Gitlab::VERSION
gem.authors = ['Sergey Sein']
gem.email = ['linchus@gmail.com']
gem.description = 'This is the strategy for authenticating to your GitLab service'
gem.summary = 'This is the strategy for authenticating to your GitLab service'
gem.homepage = 'https://github.com/linchus/omniauth-gitlab'
gem.files = Dir['lib/**/*.rb']
gem.test_files = Dir['spec/**/*.rb']
gem.require_paths = ['lib']
gem.add_dependency 'omniauth', '~> 1.0'
gem.add_dependency 'omniauth-oauth2', '~> 1.7.1'
gem.add_development_dependency 'rspec', '~> 3.1'
gem.add_development_dependency 'rspec-its', '~> 1.0'
gem.add_development_dependency 'simplecov'
gem.add_development_dependency 'rake', '>= 12.0'
end

View File

@ -0,0 +1,80 @@
require 'spec_helper'
describe OmniAuth::Strategies::GitLab do
let(:access_token) { double('AccessToken') }
let(:parsed_response) { double('ParsedResponse') }
let(:response) { double('Response', parsed: parsed_response) }
let(:enterprise_site) { 'https://some.other.site.com' }
let(:gitlab_service) { OmniAuth::Strategies::GitLab.new({}) }
let(:enterprise) do
OmniAuth::Strategies::GitLab.new(
'GITLAB_KEY',
'GITLAB_SECRET',
client_options: { site: enterprise_site },
redirect_url: 'http://localhost:9292/callback_url'
)
end
subject { gitlab_service }
before(:each) do
allow(subject).to receive(:access_token).and_return(access_token)
end
describe 'client options' do
context 'with defaults' do
subject { gitlab_service.options.client_options }
its(:site) { is_expected.to eq 'https://gitlab.com' }
end
context 'with override' do
subject { enterprise.options.client_options }
its(:site) { is_expected.to eq enterprise_site }
end
end
describe 'redirect_url' do
context 'with defaults' do
subject { gitlab_service.options }
its(:redirect_url) { is_expected.to be_nil }
end
context 'with customs' do
subject { enterprise.options }
its(:redirect_url) { is_expected.to eq 'http://localhost:9292/callback_url' }
end
end
describe '#raw_info' do
context 'with new configuration' do
it 'sent request to current user endpoint' do
expect(access_token).to receive(:get).with('api/v4/user').and_return(response)
expect(subject.raw_info).to eq(parsed_response)
end
end
context 'with old style configuration' do
let(:enterprise_site) { 'https://some.other.site.com/api/v4' }
subject { enterprise }
it 'sent request to current user endpoint' do
expect(access_token).to receive(:get).with('user').and_return(response)
expect(subject.raw_info).to eq(parsed_response)
end
context 'with a trailing slash' do
let(:enterprise_site) { 'https://some.other.site.com/api/v4/' }
it 'sent request to current user endpoint' do
expect(access_token).to receive(:get).with('user').and_return(response)
expect(subject.raw_info).to eq(parsed_response)
end
end
end
end
end

View File

@ -0,0 +1,8 @@
$LOAD_PATH.unshift File.expand_path('..', __FILE__)
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
require 'simplecov'
SimpleCov.start
require 'rspec'
require 'rspec/its'
require 'omniauth'
require 'omniauth-gitlab'

View File

@ -1048,15 +1048,15 @@
stylelint-declaration-strict-value "1.8.0"
stylelint-scss "4.2.0"
"@gitlab/svgs@2.21.0":
version "2.21.0"
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-2.21.0.tgz#bc71951dc35a61647fb2c0267cca6fb55a04d317"
integrity sha512-cVa5cgvVmY2MsRdV61id+rLTsY/tAGPq7Og9ETblUuZXl06ciw8H/g7cYPMxN39DdEfDklzbUnS98OJlMmD9TQ==
"@gitlab/svgs@2.22.0":
version "2.22.0"
resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-2.22.0.tgz#66211ba26418b8dfb3ac796d795a0e3392d22ada"
integrity sha512-9Es97o/VByIsCNNfSF28oTYW5XIJ2dZSK0YjSpyy5yBF0QPwEjzRhxapYGz2c8YBFVC9WkoGHjp5PJ9tJgmmuA==
"@gitlab/ui@42.9.0":
version "42.9.0"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-42.9.0.tgz#506a642b9bef9eb5d363684c8ef81129a9b284ef"
integrity sha512-i575fmHOXYPGWdaaSqt7cdgpfhPvnbIwhavslgbj9g9LNzffH7fea4P6BobKakb1AZuOfahJfarqfOJ2pYuRSQ==
"@gitlab/ui@42.11.0":
version "42.11.0"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-42.11.0.tgz#68b1cca7414a9f8e6d7e18ab8325daac000588f8"
integrity sha512-IxawSvXyL4ysvriOcQ+2TpdEzZxDumj9H/K3MTxmvKYtrFEygNE7wCPasQa3/jxmdfn6sYuPDHVg1tk1ziXyVQ==
dependencies:
"@popperjs/core" "^2.11.2"
bootstrap-vue "2.20.1"