Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2020-10-26 21:08:22 +00:00
parent a683d38a36
commit caafd2e499
49 changed files with 425 additions and 159 deletions

View file

@ -37,6 +37,10 @@ export default {
required: false,
default: '',
},
mounts: {
type: Array,
required: true,
},
imageRoot: {
type: String,
required: false,

View file

@ -25,11 +25,15 @@ const createApolloProvider = appData => {
},
);
// eslint-disable-next-line @gitlab/require-i18n-strings
const mounts = appData.mounts.map(mount => ({ __typename: 'Mount', ...mount }));
defaultClient.cache.writeData({
data: {
appData: {
__typename: 'AppData',
...appData,
mounts,
},
},
});

View file

@ -6,5 +6,9 @@ query appData {
sourcePath
username
returnUrl
mounts {
source
target
}
}
}

View file

@ -14,6 +14,11 @@ type SavedContentMeta {
branch: SavedContentField!
}
type Mount {
source: String!
target: String
}
type AppData {
isSupportedContent: Boolean!
hasSubmittedChanges: Boolean!
@ -21,6 +26,7 @@ type AppData {
returnUrl: String
sourcePath: String!
username: String!
mounts: [Mount]!
}
input HasSubmittedChangesInput {

View file

@ -20,9 +20,6 @@ const initStaticSiteEditor = el => {
imageUploadPath,
mounts,
} = el.dataset;
// NOTE that the object in 'mounts' is a JSON string from the data attribute, so it must be parsed into an object.
// eslint-disable-next-line no-unused-vars
const mountsObject = JSON.parse(mounts);
const { current_username: username } = window.gon;
const returnUrl = el.dataset.returnUrl || null;
const router = createRouter(baseUrl);
@ -30,6 +27,7 @@ const initStaticSiteEditor = el => {
isSupportedContent: parseBoolean(isSupportedContent),
hasSubmittedChanges: false,
project: `${namespace}/${project}`,
mounts: JSON.parse(mounts), // NOTE that the object in 'mounts' is a JSON string from the data attribute, so it must be parsed into an object.
returnUrl,
sourcePath,
username,

View file

@ -138,6 +138,7 @@ export default {
:content="sourceContent.content"
:saving-changes="isSavingChanges"
:return-url="appData.returnUrl"
:mounts="appData.mounts"
@submit="onPrepareSubmit"
/>
<edit-meta-modal

View file

@ -0,0 +1,5 @@
---
title: Handle malformed strings in URL
merge_request: 45701
author:
type: fixed

View file

@ -28,7 +28,7 @@ module Gitlab
require_dependency Rails.root.join('lib/gitlab/middleware/basic_health_check')
require_dependency Rails.root.join('lib/gitlab/middleware/same_site_cookies')
require_dependency Rails.root.join('lib/gitlab/middleware/handle_ip_spoof_attack_error')
require_dependency Rails.root.join('lib/gitlab/middleware/handle_null_bytes')
require_dependency Rails.root.join('lib/gitlab/middleware/handle_malformed_strings')
require_dependency Rails.root.join('lib/gitlab/runtime')
# Settings in config/environments/* take precedence over those specified here.
@ -257,7 +257,7 @@ module Gitlab
config.middleware.insert_before ActionDispatch::RemoteIp, ::Gitlab::Middleware::HandleIpSpoofAttackError
config.middleware.use ::Gitlab::Middleware::HandleNullBytes
config.middleware.insert_after ActionDispatch::ActionableExceptions, ::Gitlab::Middleware::HandleMalformedStrings
# Allow access to GitLab API from other domains
config.middleware.insert_before Warden::Manager, Rack::Cors do

View file

@ -1,3 +1,9 @@
---
stage: none
group: unassigned
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/#designated-technical-writers
---
# Integrity check Rake task **(CORE ONLY)**
GitLab provides Rake tasks to check the integrity of various components.

View file

@ -1,3 +1,9 @@
---
stage: none
group: unassigned
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/#designated-technical-writers
---
# Changing your time zone
The global time zone configuration parameter can be changed in `config/gitlab.yml`:

View file

@ -1,3 +1,9 @@
---
stage: none
group: unassigned
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/#designated-technical-writers
---
# Uploads administration **(CORE ONLY)**
Uploads represent all user data that may be sent to GitLab as a single file. As an example, avatars and notes' attachments are uploads. Uploads are integral to GitLab functionality, and therefore cannot be disabled.

View file

@ -1,3 +1,9 @@
---
stage: none
group: unassigned
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/#designated-technical-writers
---
# Modifying global user settings
GitLab administrators can modify user settings for the entire GitLab instance.

View file

@ -1,3 +1,9 @@
---
stage: none
group: unassigned
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/#designated-technical-writers
---
# Sidekiq queues administration API **(CORE ONLY)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25998) in GitLab 12.9

View file

@ -1,3 +1,9 @@
---
stage: none
group: unassigned
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/#designated-technical-writers
---
# API resources
Available resources for the [GitLab API](README.md) can be grouped in the following contexts:

View file

@ -1,3 +1,9 @@
---
stage: none
group: unassigned
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/#designated-technical-writers
---
# Appearance API **(CORE ONLY)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/16647) in GitLab 12.7.

View file

@ -1,3 +1,9 @@
---
stage: none
group: unassigned
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/#designated-technical-writers
---
# Applications API
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/8160) in GitLab 10.5.

View file

@ -1,3 +1,9 @@
---
stage: none
group: unassigned
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/#designated-technical-writers
---
# Audit Events API
## Instance Audit Events **(PREMIUM ONLY)**

View file

@ -1,3 +1,9 @@
---
stage: none
group: unassigned
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/#designated-technical-writers
---
# Avatar API
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/19121) in GitLab 11.0.

View file

@ -1,3 +1,9 @@
---
stage: none
group: unassigned
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/#designated-technical-writers
---
# Broadcast Messages API
> Introduced in GitLab 8.12.

View file

@ -1,3 +1,9 @@
---
stage: none
group: unassigned
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/#designated-technical-writers
---
# Custom Attributes API
Every API call to custom attributes must be authenticated as administrator.

View file

@ -1,3 +1,9 @@
---
stage: none
group: unassigned
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/#designated-technical-writers
---
# Dependencies API **(ULTIMATE)**
CAUTION: **Caution:**

View file

@ -1,3 +1,9 @@
---
stage: none
group: unassigned
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/#designated-technical-writers
---
# Dependency Proxy API **(PREMIUM)**
## Purge the dependency proxy for a group

View file

@ -1,3 +1,9 @@
---
stage: none
group: unassigned
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/#designated-technical-writers
---
# Epic Links API **(ULTIMATE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/9188) in GitLab 11.8.

View file

@ -1,3 +1,9 @@
---
stage: none
group: unassigned
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/#designated-technical-writers
---
# Events
## Filter parameters

View file

@ -1,3 +1,9 @@
---
stage: none
group: unassigned
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/#designated-technical-writers
---
# Geo Nodes API **(PREMIUM ONLY)**
To interact with Geo node endpoints, you need to authenticate yourself as an

View file

@ -1,3 +1,9 @@
---
stage: none
group: unassigned
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/#designated-technical-writers
---
# Set up an Audit Report with GraphQL
This page describes how you can use the GraphiQL explorer to set up an audit report

View file

@ -1,3 +1,9 @@
---
stage: none
group: unassigned
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/#designated-technical-writers
---
# Getting started with GitLab GraphQL API
This guide demonstrates basic usage of GitLab's GraphQL API.

View file

@ -1,3 +1,9 @@
---
stage: none
group: unassigned
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/#designated-technical-writers
---
# GraphQL API
> - [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/19008) in GitLab 11.0 (enabled by feature flag `graphql`).

View file

@ -1,3 +1,9 @@
---
stage: none
group: unassigned
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/#designated-technical-writers
---
# Identify issue boards with GraphQL
This page describes how you can use the GraphiQL explorer to identify

View file

@ -1,3 +1,9 @@
---
stage: none
group: unassigned
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/#designated-technical-writers
---
# Group Activity Analytics API
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26460) in GitLab 12.9.

View file

@ -1,3 +1,9 @@
---
stage: none
group: unassigned
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/#designated-technical-writers
---
# Group badges API
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/17082) in GitLab 10.6.

View file

@ -1,3 +1,9 @@
---
stage: none
group: unassigned
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/#designated-technical-writers
---
# Group Import/Export API
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20353) in GitLab 12.8.

View file

@ -23,9 +23,9 @@ selected group. From your group page:
To create an epic from the epic list, in a group:
1. Go to **{epic}** **Epics**.
1. Click **New epic**.
1. Select **New epic**.
1. Enter a descriptive title.
1. Click **Create epic**.
1. Select **Create epic**.
### Access the New Epic form
@ -33,8 +33,8 @@ To create an epic from the epic list, in a group:
There are two ways to get to the New Epic form and create an epic in the group you're in:
- From an epic in your group, click **New Epic**.
- From anywhere, in the top menu, click **plus** (**{plus-square}**) **> New epic**.
- From an epic in your group, select **New Epic**.
- From anywhere, in the top menu, select **plus** (**{plus-square}**) **> New epic**.
![New epic from an open epic](img/new_epic_from_groups_v13.2.png)
@ -63,13 +63,13 @@ After you create an epic, you can edit change the following details:
To edit an epic's title or description:
1. Click the **Edit title and description** **{pencil}** button.
1. Select the **Edit title and description** **{pencil}** button.
1. Make your changes.
1. Click **Save changes**.
1. Select **Save changes**.
To edit an epics' start date, due date, or labels:
1. Click **Edit** next to each section in the epic sidebar.
1. Select **Edit** next to each section in the epic sidebar.
1. Select the dates or labels for your epic.
## Bulk-edit epics
@ -82,7 +82,7 @@ You can edit multiple epics at once. To learn how to do it, visit
NOTE: **Note:**
To delete an epic, you need to be an [Owner](../../permissions.md#group-members-permissions) of a group/subgroup.
When editing the description of an epic, click the **Delete** button to delete the epic.
When editing the description of an epic, select the **Delete** button to delete the epic.
A modal appears to confirm your action.
Deleting an epic releases all existing issues from their associated epic in the system.
@ -92,7 +92,7 @@ Deleting an epic releases all existing issues from their associated epic in the
Whenever you decide that there is no longer need for that epic,
close the epic by:
- Clicking the **Close epic** button.
- Selecting the **Close epic** button.
![close epic - button](img/button_close_epic.png)
@ -129,7 +129,7 @@ that of Issues and Merge Requests) based on following parameters:
![epics search](img/epics_search.png)
To search, go to the list of epics and click the field **Search or filter results**.
To search, go to the list of epics and select the field **Search or filter results**.
It will display a dropdown menu, from which you can add an author. You can also enter plain
text to search by epic title or description. When done, press <kbd>Enter</kbd> on your
keyboard to filter the list.
@ -168,7 +168,7 @@ To make an epic confidential:
### Add a new issue to an epic
You can add an existing issue to an epic, or, create a new issue that's
You can add an existing issue to an epic, or create a new issue that's
automatically added to the epic.
#### Add an existing issue to an epic
@ -183,15 +183,15 @@ current parent.
To add a new issue to an epic:
1. Click the **Add** dropdown button.
1. Click **Add a new issue**.
1. On the epic's page, under **Epics and Issues**, select the **Add** dropdown button.
1. Select **Add an existing issue**.
1. Identify the issue to be added, using either of the following methods:
- Paste the link of the issue.
- Search for the desired issue by entering part of the issue's title, then selecting the desired
match (introduced in [GitLab 12.5](https://gitlab.com/gitlab-org/gitlab/-/issues/9126)).
If there are multiple issues to be added, press <kbd>Spacebar</kbd> and repeat this step.
1. Click **Add**.
1. Select **Add**.
#### Create an issue from an epic
@ -202,11 +202,11 @@ while dividing work into smaller parts.
To create an issue from an epic:
1. On the epic's page, under **Epics and Issues**, click the **Add** dropdown button and select
**Create new issue**.
1. On the epic's page, under **Epics and Issues**, select the **Add** dropdown button.
1. Select **Add a new issue**.
1. Under **Title**, enter the title for the new issue.
1. From the **Project** dropdown, select the project in which the issue should be created.
1. Click **Create issue**.
1. Select **Create issue**.
### Remove an issue from an epic
@ -215,9 +215,9 @@ After you remove an issue from an epic, the issue will no longer be associated w
To remove an issue from an epic:
1. Click the **Remove** (**{close}**) button next to the issue you want to remove.
1. Select the **Remove** (**{close}**) button next to the issue you want to remove.
The **Remove issue** warning appears.
1. Click **Remove**.
1. Select **Remove**.
![List of issues assigned to an epic](img/issue_list_v13_1.png)
@ -285,15 +285,15 @@ For more on epic templates, see [Epic Templates - Repeatable sets of issues](htt
To add a child epic to an epic:
1. Click the **Add** dropdown button.
1. Click **Add a new epic**.
1. Select the **Add** dropdown button.
1. Select **Add a new epic**.
1. Identify the epic to be added, using either of the following methods:
- Paste the link of the epic.
- Search for the desired issue by entering part of the epic's title, then selecting the desired
match (introduced in [GitLab 12.5](https://gitlab.com/gitlab-org/gitlab/-/issues/9126)).
If there are multiple epics to be added, press <kbd>Spacebar</kbd> and repeat this step.
1. Click **Add**.
1. Select **Add**.
### Move child epics between epics
@ -325,5 +325,5 @@ To reorder child epics assigned to an epic:
To remove a child epic from a parent epic:
1. Click on the <kbd>x</kbd> button in the parent epic's list of epics.
1. Click **Remove** in the **Remove epic** warning message.
1. Select the <kbd>x</kbd> button in the parent epic's list of epics.
1. Select **Remove** in the **Remove epic** warning message.

View file

@ -25,7 +25,8 @@ module API
Gitlab::GrapeLogging::Loggers::QueueDurationLogger.new,
Gitlab::GrapeLogging::Loggers::PerfLogger.new,
Gitlab::GrapeLogging::Loggers::CorrelationIdLogger.new,
Gitlab::GrapeLogging::Loggers::ContextLogger.new
Gitlab::GrapeLogging::Loggers::ContextLogger.new,
Gitlab::GrapeLogging::Loggers::ContentLogger.new
]
allow_access_with_scope :api

View file

@ -134,6 +134,7 @@ mobsf-android-sast:
name: "$SAST_ANALYZER_IMAGE"
variables:
SAST_ANALYZER_IMAGE: "$SECURE_ANALYZERS_PREFIX/mobsf:$SAST_ANALYZER_IMAGE_TAG"
MOBSF_API_KEY: key
rules:
- if: $SAST_DISABLED
when: never
@ -152,6 +153,7 @@ mobsf-ios-sast:
name: "$SAST_ANALYZER_IMAGE"
variables:
SAST_ANALYZER_IMAGE: "$SECURE_ANALYZERS_PREFIX/mobsf:$SAST_ANALYZER_IMAGE_TAG"
MOBSF_API_KEY: key
rules:
- if: $SAST_DISABLED
when: never

View file

@ -54,7 +54,13 @@ module Gitlab
add_instrument_for_cache_hit(status_code, route, request)
[status_code, { 'ETag' => etag, 'X-Gitlab-From-Cache' => 'true' }, []]
new_headers = {
'ETag' => etag,
'X-Gitlab-From-Cache' => 'true',
::Gitlab::Metrics::RequestsRackMiddleware::FEATURE_CATEGORY_HEADER => route.feature_category
}
[status_code, new_headers, []]
end
def track_cache_miss(if_none_match, cached_value_present, route)

View file

@ -3,7 +3,7 @@
module Gitlab
module EtagCaching
class Router
Route = Struct.new(:regexp, :name)
Route = Struct.new(:regexp, :name, :feature_category)
# We enable an ETag for every request matching the regex.
# To match a regex the path needs to match the following:
# - Don't contain a reserved word (expect for the words used in the
@ -20,59 +20,73 @@ module Gitlab
ROUTES = [
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/noteable/issue/\d+/notes\z),
'issue_notes'
'issue_notes',
'issue_tracking'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/noteable/merge_request/\d+/notes\z),
'merge_request_notes'
'merge_request_notes',
'code_review'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/issues/\d+/realtime_changes\z),
'issue_title'
'issue_title',
'issue_tracking'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/commit/\S+/pipelines\.json\z),
'commit_pipelines'
'commit_pipelines',
'continuous_integration'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/merge_requests/new\.json\z),
'new_merge_request_pipelines'
'new_merge_request_pipelines',
'continuous_integration'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/merge_requests/\d+/pipelines\.json\z),
'merge_request_pipelines'
'merge_request_pipelines',
'continuous_integration'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/pipelines\.json\z),
'project_pipelines'
'project_pipelines',
'continuous_integration'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/pipelines/\d+\.json\z),
'project_pipeline'
'project_pipeline',
'continuous_integration'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/builds/\d+\.json\z),
'project_build'
'project_build',
'continuous_integration'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/clusters/\d+/environments\z),
'cluster_environments'
'cluster_environments',
'continuous_delivery'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/environments\.json\z),
'environments'
'environments',
'continuous_delivery'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/import/github/realtime_changes\.json\z),
'realtime_changes_import_github'
'realtime_changes_import_github',
'importers'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/import/gitea/realtime_changes\.json\z),
'realtime_changes_import_gitea'
'realtime_changes_import_gitea',
'importers'
),
Gitlab::EtagCaching::Router::Route.new(
%r(#{RESERVED_WORDS_PREFIX}/merge_requests/\d+/cached_widget\.json\z),
'merge_request_widget'
'merge_request_widget',
'code_review'
)
].freeze

View file

@ -0,0 +1,16 @@
# frozen_string_literal: true
module Gitlab
module GrapeLogging
module Loggers
class ContentLogger < ::GrapeLogging::Loggers::Base
def parameters(request, _)
{
content_length: request.env['CONTENT_LENGTH'],
content_range: request.env['HTTP_CONTENT_RANGE']
}.compact
end
end
end
end
end

View file

@ -2,9 +2,9 @@
module Gitlab
module Middleware
# There is no valid reason for a request to contain a null byte (U+0000)
# There is no valid reason for a request to contain a malformed string
# so just return HTTP 400 (Bad Request) if we receive one
class HandleNullBytes
class HandleMalformedStrings
NULL_BYTE_REGEX = Regexp.new(Regexp.escape("\u0000")).freeze
attr_reader :app
@ -14,18 +14,20 @@ module Gitlab
end
def call(env)
return [400, {}, ["Bad Request"]] if request_has_null_byte?(env)
return [400, { 'Content-Type' => 'text/plain' }, ['Bad Request']] if request_contains_malformed_string?(env)
app.call(env)
end
private
def request_has_null_byte?(request)
return false if ENV['REJECT_NULL_BYTES'] == "1"
def request_contains_malformed_string?(request)
return false if ENV['DISABLE_REQUEST_VALIDATION'] == '1'
request = Rack::Request.new(request)
return true if string_malformed?(request.path)
request.params.values.any? do |value|
param_has_null_byte?(value)
end
@ -39,7 +41,7 @@ module Gitlab
depth += 1
if value.respond_to?(:match)
string_contains_null_byte?(value)
string_malformed?(value)
elsif value.respond_to?(:values)
value.values.any? do |hash_value|
param_has_null_byte?(hash_value, depth)
@ -53,8 +55,11 @@ module Gitlab
end
end
def string_contains_null_byte?(string)
def string_malformed?(string)
string.match?(NULL_BYTE_REGEX)
rescue ArgumentError
# If we're here, we caught a malformed string. Return true
true
end
end
end

View file

@ -304,7 +304,7 @@ RSpec.describe 'User comments on a diff', :js do
wait_for_requests
end
it 'suggestion is presented' do
it 'suggestion is presented', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/268240' do
page.within('.diff-discussions') do
expect(page).to have_button('Apply suggestion')
expect(page).to have_content('Suggested change')

View file

@ -15,6 +15,7 @@ import {
sourceContentHeaderObjYAML as headerSettings,
sourceContentBody as body,
returnUrl,
mounts,
} from '../mock_data';
jest.mock('~/static_site_editor/services/formatter', () => jest.fn(str => `${str} format-pass`));
@ -31,6 +32,7 @@ describe('~/static_site_editor/components/edit_area.vue', () => {
title,
content,
returnUrl,
mounts,
savingChanges,
...propsData,
},

View file

@ -67,3 +67,10 @@ export const images = new Map([
['path/to/image1.png', 'image1-content'],
['path/to/image2.png', 'image2-content'],
]);
export const mounts = [
{
source: 'some/source/',
target: '',
},
];

View file

@ -23,6 +23,7 @@ import {
submitChangesError,
trackingCategory,
images,
mounts,
} from '../mock_data';
const localVue = createLocalVue();
@ -41,6 +42,7 @@ describe('static_site_editor/pages/home', () => {
project,
username,
sourcePath,
mounts,
};
const hasSubmittedChangesMutationPayload = {
data: {
@ -119,6 +121,7 @@ describe('static_site_editor/pages/home', () => {
it('provides source content, returnUrl, and isSavingChanges to the edit area', () => {
expect(findEditArea().props()).toMatchObject({
title,
mounts,
content,
returnUrl,
savingChanges: false,

View file

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe Gitlab::EtagCaching::Middleware do
RSpec.describe Gitlab::EtagCaching::Middleware, :clean_gitlab_redis_shared_state do
let(:app) { double(:app) }
let(:middleware) { described_class.new(app) }
let(:app_status_code) { 200 }
@ -17,10 +17,12 @@ RSpec.describe Gitlab::EtagCaching::Middleware do
mock_app_response
end
it 'does not add ETag header' do
it 'does not add ETag headers' do
_, headers, _ = middleware.call(build_request(path, if_none_match))
expect(headers['ETag']).to be_nil
expect(headers['X-Gitlab-From-Cache']).to be_nil
expect(headers[::Gitlab::Metrics::RequestsRackMiddleware::FEATURE_CATEGORY_HEADER]).to be_nil
end
it 'passes status code from app' do
@ -68,7 +70,7 @@ RSpec.describe Gitlab::EtagCaching::Middleware do
mock_value_in_store('123')
end
it 'returns this value as header' do
it 'returns the correct headers' do
_, headers, _ = middleware.call(build_request(path, if_none_match))
expect(headers['ETag']).to eq 'W/"123"'
@ -126,6 +128,13 @@ RSpec.describe Gitlab::EtagCaching::Middleware do
expect(status).to eq 304
end
it 'sets correct headers' do
_, headers, _ = middleware.call(build_request(path, if_none_match))
expect(headers).to include('X-Gitlab-From-Cache' => 'true',
::Gitlab::Metrics::RequestsRackMiddleware::FEATURE_CATEGORY_HEADER => 'issue_tracking')
end
it_behaves_like 'sends a process_action.action_controller notification', 304
it 'returns empty body' do

View file

@ -127,4 +127,12 @@ RSpec.describe Gitlab::EtagCaching::Router do
expect(result).to be_present
expect(result.name).to eq 'project_pipeline'
end
it 'has a valid feature category for every route', :aggregate_failures do
feature_categories = YAML.load_file(Rails.root.join('config', 'feature_categories.yml')).to_set
described_class::ROUTES.each do |route|
expect(feature_categories).to include(route.feature_category), "#{route.name} has a category of #{route.feature_category}, which is not valid"
end
end
end

View file

@ -0,0 +1,109 @@
# frozen_string_literal: true
require 'spec_helper'
require "rack/test"
RSpec.describe Gitlab::Middleware::HandleMalformedStrings do
let(:null_byte) { "\u0000" }
let(:invalid_string) { "mal\xC0formed" }
let(:error_400) { [400, { 'Content-Type' => 'text/plain' }, ['Bad Request']] }
let(:app) { double(:app) }
subject { described_class.new(app) }
before do
allow(app).to receive(:call) do |args|
args
end
end
def env_for(params = {})
Rack::MockRequest.env_for('/', { params: params })
end
context 'in the URL' do
it 'rejects null bytes' do
# We have to create the env separately or Rack::MockRequest complains about invalid URI
env = env_for
env['PATH_INFO'] = "/someplace/witha#{null_byte}nullbyte"
expect(subject.call(env)).to eq error_400
end
it 'rejects malformed strings' do
# We have to create the env separately or Rack::MockRequest complains about invalid URI
env = env_for
env['PATH_INFO'] = "/someplace/with_an/#{invalid_string}"
expect(subject.call(env)).to eq error_400
end
end
context 'in params' do
shared_examples_for 'checks params' do
it 'rejects bad params in a top level param' do
env = env_for(name: "null#{problematic_input}byte")
expect(subject.call(env)).to eq error_400
end
it "rejects bad params for hashes with strings" do
env = env_for(name: { inner_key: "I am #{problematic_input} bad" })
expect(subject.call(env)).to eq error_400
end
it "rejects bad params for arrays with strings" do
env = env_for(name: ["I am #{problematic_input} bad"])
expect(subject.call(env)).to eq error_400
end
it "rejects bad params for arrays containing hashes with string values" do
env = env_for(name: [
{
inner_key: "I am #{problematic_input} bad"
}
])
expect(subject.call(env)).to eq error_400
end
it "gives up and does not reject too deeply nested params" do
env = env_for(name: [
{
inner_key: { deeper_key: [{ hash_inside_array_key: "I am #{problematic_input} bad" }] }
}
])
expect(subject.call(env)).not_to eq error_400
end
end
context 'with null byte' do
it_behaves_like 'checks params' do
let(:problematic_input) { null_byte }
end
end
context 'with malformed strings' do
it_behaves_like 'checks params' do
let(:problematic_input) { invalid_string }
end
end
end
context 'without problematic input' do
it "does not error for strings" do
env = env_for(name: "safe name")
expect(subject.call(env)).not_to eq error_400
end
it "does not error with no params" do
env = env_for
expect(subject.call(env)).not_to eq error_400
end
end
end

View file

@ -1,88 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
require "rack/test"
RSpec.describe Gitlab::Middleware::HandleNullBytes do
let(:null_byte) { "\u0000" }
let(:error_400) { [400, {}, ["Bad Request"]] }
let(:app) { double(:app) }
subject { described_class.new(app) }
before do
allow(app).to receive(:call) do |args|
args
end
end
def env_for(params = {})
Rack::MockRequest.env_for('/', { params: params })
end
context 'with null bytes in params' do
it 'rejects null bytes in a top level param' do
env = env_for(name: "null#{null_byte}byte")
expect(subject.call(env)).to eq error_400
end
it "responds with 400 BadRequest for hashes with strings" do
env = env_for(name: { inner_key: "I am #{null_byte} bad" })
expect(subject.call(env)).to eq error_400
end
it "responds with 400 BadRequest for arrays with strings" do
env = env_for(name: ["I am #{null_byte} bad"])
expect(subject.call(env)).to eq error_400
end
it "responds with 400 BadRequest for arrays containing hashes with string values" do
env = env_for(name: [
{
inner_key: "I am #{null_byte} bad"
}
])
expect(subject.call(env)).to eq error_400
end
it "gives up and does not 400 with too deeply nested params" do
env = env_for(name: [
{
inner_key: { deeper_key: [{ hash_inside_array_key: "I am #{null_byte} bad" }] }
}
])
expect(subject.call(env)).not_to eq error_400
end
end
context 'without null bytes in params' do
it "does not respond with a 400 for strings" do
env = env_for(name: "safe name")
expect(subject.call(env)).not_to eq error_400
end
it "does not respond with a 400 with no params" do
env = env_for
expect(subject.call(env)).not_to eq error_400
end
end
context 'when disabled via env flag' do
before do
stub_env('REJECT_NULL_BYTES', '1')
end
it 'does not respond with a 400 no matter what' do
env = env_for(name: "null#{null_byte}byte")
expect(subject.call(env)).not_to eq error_400
end
end
end

View file

@ -0,0 +1,20 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'User sends malformed strings as params' do
let(:null_byte) { "\u0000" }
let(:invalid_string) { "mal\xC0formed" }
it 'raises a 400 error with a null byte' do
post '/nonexistent', params: { a: "A #{null_byte} nasty string" }
expect(response).to have_gitlab_http_status(:bad_request)
end
it 'raises a 400 error with an invalid string' do
post '/nonexistent', params: { a: "A #{invalid_string} nasty string" }
expect(response).to have_gitlab_http_status(:bad_request)
end
end

View file

@ -1,14 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'User sends null bytes as params' do
let(:null_byte) { "\u0000" }
it 'raises a 400 error' do
post '/nonexistent', params: { a: "A #{null_byte} nasty string" }
expect(response).to have_gitlab_http_status(:bad_request)
expect(response.body).to eq('Bad Request')
end
end