Skip to content

Commit

Permalink
Add latest changes from gitlab-org/gitlab@master
Browse files Browse the repository at this point in the history
  • Loading branch information
GitLab Bot committed Jul 21, 2022
1 parent 265a7ce commit f44215b
Show file tree
Hide file tree
Showing 55 changed files with 603 additions and 634 deletions.
12 changes: 12 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,18 @@ RSpec/HaveGitlabHttpStatus:
- 'spec/**/*'
- 'ee/spec/**/*'

RSpec/ContextWording:
Prefixes:
- when
- with
- without
- for
- and
- on
- in
- as
- if

Style/MultilineWhenThen:
Enabled: false

Expand Down
559 changes: 142 additions & 417 deletions .rubocop_todo/rspec/context_wording.yml

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion app/assets/javascripts/repository/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ export const LFS_STORAGE = 'lfs';
*/
export const LEGACY_FILE_TYPES = [
'gemfile',
'gemspec',
'composer_json',
'podfile',
'podspec',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,4 @@ export const HLJS_COMMENT_SELECTOR = 'hljs-comment';
export const HLJS_ON_AFTER_HIGHLIGHT = 'after:highlight';

export const NPM_URL = 'https://npmjs.com/package';
export const GEM_URL = 'https://rubygems.org/gems';
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import packageJsonLinker from './utils/package_json_linker';
import gemspecLinker from './utils/gemspec_linker';

const DEPENDENCY_LINKERS = {
package_json: packageJsonLinker,
gemspec: gemspecLinker,
};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@ export const createLink = (href, innerText) => {
return link.outerHTML;
};

export const generateHLJSOpenTag = (type) => `<span class="hljs-${escape(type)}">&quot;`;
export const generateHLJSOpenTag = (type, delimiter = '&quot;') =>
`<span class="hljs-${escape(type)}">${delimiter}`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { joinPaths } from '~/lib/utils/url_utility';
import { GEM_URL } from '../../constants';
import { createLink, generateHLJSOpenTag } from './dependency_linker_util';

const methodRegex = '.*add_dependency.*|.*add_runtime_dependency.*|.*add_development_dependency.*';
const openTagRegex = generateHLJSOpenTag('string', '(&.*;)');
const closeTagRegex = '&.*</span>';

const DEPENDENCY_REGEX = new RegExp(
/*
* Detects gemspec dependencies inside of content that is highlighted by Highlight.js
* Example: s.add_dependency(<span class="hljs-string">&#x27;rugged&#x27;</span>, <span class="hljs-string">&#x27;~&gt; 0.24.0&#x27;</span>)
*
* Group 1 (method) : s.add_dependency(
* Group 2 (delimiter) : &#x27;
* Group 3 (packageName): rugged
* Group 4 (closeTag) : &#x27;</span>
* Group 5 (rest) : , <span class="hljs-string">&#x27;~&gt; 0.24.0&#x27;</span>)
*/
`(${methodRegex})${openTagRegex}(.*)(${closeTagRegex})(.*${closeTagRegex})`,
'gm',
);

const handleReplace = (method, delimiter, packageName, closeTag, rest) => {
// eslint-disable-next-line @gitlab/require-i18n-strings
const openTag = generateHLJSOpenTag('string linked', delimiter);
const href = joinPaths(GEM_URL, packageName);
const packageLink = createLink(href, packageName);

return `${method}${openTag}${packageLink}${closeTag}${rest}`;
};

export default (result) => {
return result.value.replace(
DEPENDENCY_REGEX,
(_, method, delimiter, packageName, closeTag, rest) =>
handleReplace(method, delimiter, packageName, closeTag, rest),
);
};
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#import "./work_item.fragment.graphql"
#import "ee_else_ce/work_items/graphql/work_item.fragment.graphql"

mutation createWorkItem($input: WorkItemCreateInput!) {
workItemCreate(input: $input) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#import "./work_item.fragment.graphql"
#import "ee_else_ce/work_items/graphql/work_item.fragment.graphql"

mutation workItemCreateFromTask($input: WorkItemCreateFromTaskInput!) {
workItemCreateFromTask(input: $input) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#import "./work_item.fragment.graphql"
#import "ee_else_ce/work_items/graphql/work_item.fragment.graphql"

mutation localUpdateWorkItem($input: LocalUpdateWorkItemInput) {
localUpdateWorkItem(input: $input) @client {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#import "./work_item.fragment.graphql"
#import "ee_else_ce/work_items/graphql/work_item.fragment.graphql"

mutation workItemUpdate($input: WorkItemUpdateInput!) {
workItemUpdate(input: $input) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#import "./work_item.fragment.graphql"
#import "ee_else_ce/work_items/graphql/work_item.fragment.graphql"

mutation workItemUpdateTask($input: WorkItemUpdateTaskInput!) {
workItemUpdate: workItemUpdateTask(input: $input) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#import "./work_item.fragment.graphql"
#import "ee_else_ce/work_items/graphql/work_item.fragment.graphql"

mutation workItemUpdateWidgets($input: WorkItemUpdateWidgetsInput!) {
workItemUpdateWidgets(input: $input) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,6 @@ fragment WorkItem on WorkItem {
}
}
}
... on WorkItemWidgetWeight {
type
weight
}
... on WorkItemWidgetHierarchy {
type
parent {
Expand All @@ -40,10 +36,8 @@ fragment WorkItem on WorkItem {
title
}
children {
edges {
node {
id
}
nodes {
id
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#import "~/graphql_shared/fragments/label.fragment.graphql"
#import "./work_item.fragment.graphql"
#import "ee_else_ce/work_items/graphql/work_item.fragment.graphql"

query workItem($id: WorkItemID!) {
workItem(id: $id) {
Expand Down
10 changes: 9 additions & 1 deletion app/controllers/import/bulk_imports_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,14 @@ def status
end

def create
responses = create_params.map { |entry| ::BulkImports::CreateService.new(current_user, entry, credentials).execute }
responses = create_params.map do |entry|
if entry[:destination_name]
entry[:destination_slug] ||= entry[:destination_name]
entry.delete(:destination_name)
end

::BulkImports::CreateService.new(current_user, entry, credentials).execute
end

render json: responses.map { |response| { success: response.success?, id: response.payload[:id], message: response.message } }
end
Expand Down Expand Up @@ -100,6 +107,7 @@ def bulk_import_params
source_type
source_full_path
destination_name
destination_slug
destination_namespace
]
end
Expand Down
2 changes: 1 addition & 1 deletion app/graphql/types/ci/pipeline_type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ def job(id: nil, name: nil)
if id
pipeline.statuses.id_in(id.model_id)
else
pipeline.statuses.by_name(name)
pipeline.latest_statuses.by_name(name)
end.take # rubocop: disable CodeReuse/ActiveRecord
end

Expand Down
2 changes: 2 additions & 0 deletions app/models/bulk_imports/entity.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ class BulkImports::Entity < ApplicationRecord
scope :by_bulk_import_id, ->(bulk_import_id) { where(bulk_import_id: bulk_import_id)}
scope :order_by_created_at, -> (direction) { order(created_at: direction) }

alias_attribute :destination_slug, :destination_name

state_machine :status, initial: :created do
state :created, value: 0
state :started, value: 1
Expand Down
26 changes: 24 additions & 2 deletions app/models/environment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,10 @@ class Environment < ApplicationRecord

validates :external_url,
length: { maximum: 255 },
allow_nil: true,
addressable_url: true
allow_nil: true

validates :external_url, addressable_url: true, allow_nil: true, unless: :soft_validation_on_external_url_enabled?
validate :safe_external_url, if: :soft_validation_on_external_url_enabled?

delegate :manual_actions, :other_manual_actions, to: :last_deployment, allow_nil: true
delegate :auto_rollback_enabled?, to: :project
Expand Down Expand Up @@ -493,6 +495,26 @@ def unfoldered?

private

def soft_validation_on_external_url_enabled?
::Feature.enabled?(:soft_validation_on_external_url, project)
end

# We deliberately avoid using AddressableUrlValidator to allow users to update their environments even if they have
# misconfigured `environment:url` keyword. The external URL is presented as a clickable link on UI and not consumed
# in GitLab internally, thus we sanitize the URL before the persistence to make sure the rendered link is XSS safe.
# See https://gitlab.com/gitlab-org/gitlab/-/issues/337417
def safe_external_url
return unless self.external_url.present?

new_external_url = Addressable::URI.parse(self.external_url)

if Gitlab::Utils::SanitizeNodeLink::UNSAFE_PROTOCOLS.include?(new_external_url.normalized_scheme)
errors.add(:external_url, "#{new_external_url.normalized_scheme} scheme is not allowed")
end
rescue Addressable::URI::InvalidURIError
errors.add(:external_url, 'URI is invalid')
end

def rollout_status_available?
has_terminals?
end
Expand Down
23 changes: 1 addition & 22 deletions app/models/members/group_member.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ class GroupMember < Member

SOURCE_TYPE = 'Namespace'
SOURCE_TYPE_FORMAT = /\ANamespace\z/.freeze
THRESHOLD_FOR_REFRESHING_AUTHORIZATIONS_VIA_PROJECTS = 1000

belongs_to :group, foreign_key: 'source_id'
alias_attribute :namespace_id, :source_id
Expand Down Expand Up @@ -67,28 +66,8 @@ def refresh_member_authorized_projects(blocking:)
# its projects are also destroyed, so the removal of project_authorizations
# will happen behind the scenes via DB foreign keys anyway.
return if destroyed_by_association.present?
return unless user_id
return super if Feature.disabled?(:refresh_authorizations_via_affected_projects_on_group_membership, group)

# rubocop:disable CodeReuse/ServiceClass
projects_to_refresh = Groups::ProjectsRequiringAuthorizationsRefresh::OnDirectMembershipFinder.new(group).execute
threshold_exceeded = (projects_to_refresh.size > THRESHOLD_FOR_REFRESHING_AUTHORIZATIONS_VIA_PROJECTS)

# We want to try the new approach only if the number of affected projects are greater than the set threshold.
return super unless threshold_exceeded

AuthorizedProjectUpdate::ProjectAccessChangedService
.new(projects_to_refresh)
.execute(blocking: false)

# Until we compare the inconsistency rates of the new approach
# the old approach, we still run AuthorizedProjectsWorker
# but with some delay and lower urgency as a safety net.
UserProjectAccessChangedService
.new(user_id)
.execute(blocking: false, priority: UserProjectAccessChangedService::LOW_PRIORITY)

# rubocop:enable CodeReuse/ServiceClass
super
end

def send_invite
Expand Down
4 changes: 0 additions & 4 deletions app/services/boards/destroy_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,6 @@
module Boards
class DestroyService < Boards::BaseService
def execute(board)
if boards.size == 1
return ServiceResponse.error(message: "The board could not be deleted, because the parent doesn't have any other boards.")
end

board.destroy!

ServiceResponse.success
Expand Down
2 changes: 1 addition & 1 deletion app/services/bulk_imports/create_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def create_bulk_import
bulk_import: bulk_import,
source_type: entity[:source_type],
source_full_path: entity[:source_full_path],
destination_name: entity[:destination_name],
destination_slug: entity[:destination_slug],
destination_namespace: entity[:destination_namespace]
)
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
name: refresh_authorizations_via_affected_projects_on_group_membership
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/87071
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/362204
milestone: '15.0'
name: soft_validation_on_external_url
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91970
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/367206
milestone: '15.2'
type: development
group: group::workspace
group: group::release
default_enabled: false
3 changes: 2 additions & 1 deletion doc/administration/incoming_email.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,12 @@ Email is processed correctly when a configured email address is present in one o
(sorted in the order they are checked):

- `To`
- `References`
- `Delivered-To`
- `Envelope-To` or `X-Envelope-To`
- `Received`

The `References` header is also accepted, however it is used specifically to relate email responses to existing discussion threads. It is not used for creating issues by email.

In GitLab 14.6 and later, [Service Desk](../user/project/service_desk.md)
also checks accepted headers.

Expand Down
9 changes: 5 additions & 4 deletions doc/api/bulk_imports.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ POST /bulk_imports
| `entities` | Array | yes | List of entities to import. |
| `entities[source_type]` | String | yes | Source entity type (only `group_entity` is supported). |
| `entities[source_full_path]` | String | yes | Source full path of the entity to import. |
| `entities[destination_name]` | String | yes | Destination slug for the entity. |
| `entities[destination_name]` | String | yes | Deprecated: Use :destination_slug instead. Destination slug for the entity. |
| `entities[destination_slug]` | String | yes | Destination slug for the entity. |
| `entities[destination_namespace]` | String | no | Destination namespace for the entity. |

```shell
Expand All @@ -41,7 +42,7 @@ curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitla
{
"source_full_path": "source/full/path",
"source_type": "group_entity",
"destination_name": "destination_slug",
"destination_slug": "destination_slug",
"destination_namespace": "destination/namespace/path"
}
]
Expand Down Expand Up @@ -126,7 +127,7 @@ curl --request GET --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab
"bulk_import_id": 1,
"status": "finished",
"source_full_path": "source_group",
"destination_name": "destination_slug",
"destination_slug": "destination_slug",
"destination_namespace": "destination_path",
"parent_id": null,
"namespace_id": 1,
Expand All @@ -140,7 +141,7 @@ curl --request GET --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab
"bulk_import_id": 2,
"status": "failed",
"source_full_path": "another_group",
"destination_name": "another_slug",
"destination_slug": "another_slug",
"destination_namespace": "another_namespace",
"parent_id": null,
"namespace_id": null,
Expand Down
Loading

0 comments on commit f44215b

Please sign in to comment.