Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-07-18 06:08:47 +00:00
parent 3b406199b5
commit 6a20140614
19 changed files with 86 additions and 135 deletions

View File

@ -60,6 +60,13 @@
@include icon-styles($gray-500, $gray-100);
}
.password-status-icon-success {
svg {
vertical-align: middle;
fill: $green-500;
}
}
.icon-link {
&:hover {
text-decoration: none;

View File

@ -56,10 +56,8 @@ class Environment < ApplicationRecord
validates :external_url,
length: { maximum: 255 },
allow_nil: true
validates :external_url, addressable_url: true, unless: :soft_validation_on_external_url_enabled?
validate :safe_external_url, if: :soft_validation_on_external_url_enabled?
allow_nil: true,
addressable_url: true
delegate :manual_actions, :other_manual_actions, to: :last_deployment, allow_nil: true
delegate :auto_rollback_enabled?, to: :project
@ -495,26 +493,6 @@ class Environment < ApplicationRecord
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

View File

@ -33,7 +33,8 @@
- else
.form-group.gl-form-group{ role: 'group' }
= f.label :password, _('Password'), class: 'gl-display-block col-form-label'
= f.password_field :password, disabled: f.object.force_random_password, autocomplete: 'new-password', class: 'form-control gl-form-input'
= f.password_field :password, disabled: f.object.force_random_password, autocomplete: 'new-password', class: 'form-control gl-form-input js-password-complexity-validation'
= render_if_exists 'shared/password_requirements_list'
.form-group.gl-form-group{ role: 'group' }
= f.label :password_confirmation, _('Password confirmation'), class: 'gl-display-block col-form-label'
= f.password_field :password_confirmation, disabled: f.object.force_random_password, autocomplete: 'new-password', class: 'form-control gl-form-input'

View File

@ -7,7 +7,8 @@
= f.hidden_field :reset_password_token
.form-group.gl-px-5
= f.label _('New password'), for: "user_password"
= f.password_field :password, autocomplete: 'new-password', class: "form-control gl-form-input top", required: true, title: _('This field is required.'), data: { qa_selector: 'password_field'}
= f.password_field :password, autocomplete: 'new-password', class: "form-control gl-form-input top js-password-complexity-validation", required: true, title: _('This field is required.'), data: { qa_selector: 'password_field'}
= render_if_exists 'shared/password_requirements_list'
.form-group.gl-px-5
= f.label _('Confirm new password'), for: "user_password_confirmation"
= f.password_field :password_confirmation, autocomplete: 'new-password', class: "form-control gl-form-input bottom", title: _('This field is required.'), data: { qa_selector: 'password_confirmation_field' }, required: true

View File

@ -55,13 +55,14 @@
.form-group.gl-mb-5#password-strength
= f.label :password, class: 'label-bold'
= f.password_field :password,
class: 'form-control gl-form-input bottom',
class: 'form-control gl-form-input bottom js-password-complexity-validation',
data: { qa_selector: 'new_user_password_field' },
autocomplete: 'new-password',
required: true,
pattern: ".{#{@minimum_password_length},}",
title: s_('SignUp|Minimum length is %{minimum_password_length} characters.') % { minimum_password_length: @minimum_password_length }
%p.gl-field-hint.text-secondary= s_('SignUp|Minimum length is %{minimum_password_length} characters.') % { minimum_password_length: @minimum_password_length }
= render_if_exists 'shared/password_requirements_list'
= render_if_exists 'devise/shared/phone_verification', form: f
%div
- if show_recaptcha_sign_up?

View File

@ -25,7 +25,8 @@
= _('You must provide your current password in order to change it.')
.form-group
= f.label :new_password, _('New password'), class: 'label-bold'
= f.password_field :new_password, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input', data: { qa_selector: 'new_password_field' }
= f.password_field :new_password, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input js-password-complexity-validation', data: { qa_selector: 'new_password_field' }
= render_if_exists 'shared/password_requirements_list'
.form-group
= f.label :password_confirmation, _('Password confirmation'), class: 'label-bold'
= f.password_field :password_confirmation, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input', data: { qa_selector: 'confirm_password_field' }

View File

@ -21,7 +21,8 @@
.col-sm-2.col-form-label
= f.label :new_password, _('New password')
.col-sm-10
= f.password_field :new_password, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input', data: { qa_selector: 'new_password_field' }
= f.password_field :new_password, required: true, autocomplete: 'new-password', class: 'form-control gl-form-input js-password-complexity-validation', data: { qa_selector: 'new_password_field' }
= render_if_exists 'shared/password_requirements_list'
.form-group.row
.col-sm-2.col-form-label
= f.label :password_confirmation, _('Password confirmation')

View File

@ -1,8 +0,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::release
default_enabled: false

View File

@ -0,0 +1,19 @@
# frozen_string_literal: true
class RemoveNotNullConstraintsFromRequirements < Gitlab::Database::Migration[2.0]
disable_ddl_transaction!
def up
change_column_null :requirements, :created_at, true
change_column_null :requirements, :updated_at, true
change_column_null :requirements, :title, true
change_column_null :requirements, :state, true
end
def down
# No OP
# The columns could have nil values again at this point. Rolling back
# would cause an exception, also we cannot insert data and modify the schema within the same migration.
# More details at https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91611#note_1017066470
end
end

View File

@ -0,0 +1 @@
7c9b8b433553e83bb05208e62541e3d51bcc1083ff33d1146e93b92d954f9cb0

View File

@ -20270,14 +20270,14 @@ ALTER SEQUENCE required_code_owners_sections_id_seq OWNED BY required_code_owner
CREATE TABLE requirements (
id bigint NOT NULL,
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
created_at timestamp with time zone,
updated_at timestamp with time zone,
project_id integer NOT NULL,
author_id integer,
iid integer NOT NULL,
cached_markdown_version integer,
state smallint DEFAULT 1 NOT NULL,
title character varying(255) NOT NULL,
state smallint DEFAULT 1,
title character varying(255),
title_html text,
description text,
description_html text,

View File

@ -220,6 +220,12 @@ on the Gitaly server matches the one on Gitaly client. If it doesn't match,
update the secrets file on the Gitaly server to match the Gitaly client, then
[reconfigure](../restart_gitlab.md#omnibus-gitlab-reconfigure).
If you've confirmed that your `gitlab-secrets.json` file is the same on all Gitaly servers and clients,
the application might be fetching this secret from a different file. Your Gitaly server's
`config.toml file` indicates the secrets file in use.
If that setting is missing, GitLab defaults to using `.gitlab_shell_secret` under
`/opt/gitlab/embedded/service/gitlab-rails/.gitlab_shell_secret`.
### Repository pushes fail with a `deny updating a hidden ref` error
Due to [a change](https://gitlab.com/gitlab-org/gitaly/-/merge_requests/3426)

View File

@ -107,6 +107,9 @@ grep -2 search_term <filename>
# Search on all files in directory (recursively)
grep -r search_term <directory>
# Grep namespace/project/name of a GitLab repository
grep 'fullpath' /var/opt/gitlab/git-data/repositories/@hashed/<repo hash>/.git/config
# search through *.gz files is the same except with zgrep
zgrep search_term <filename>
@ -126,6 +129,7 @@ history
# Search through command history
<ctrl>-R
# Execute last command with sudo
sudo !!
```

View File

@ -374,8 +374,6 @@ To retry or rollback a deployment:
### Environment URL
> [Fixed](https://gitlab.com/gitlab-org/gitlab/-/issues/337417) to persist arbitrary URLs in GitLab 15.2 [with a flag](../../administration/feature_flags.md) named `soft_validation_on_external_url`. Disabled by default.
The [environment URL](../yaml/index.md#environmenturl) is displayed in a few
places in GitLab:

View File

@ -387,3 +387,28 @@ When you are using GDK, you can set it up with:
1. Start the database: `gdk start db`
1. Load the environment from GDK: `eval $(cd ../gitaly && gdk env)`
1. Create the database: `createdb --encoding=UTF8 --locale=C --echo praefect_test`
## Git references used by Gitaly
Gitaly uses many Git references ([refs](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefrefaref)) to provide Git services to GitLab.
### Standard Git references
These standard Git references are used by GitLab (through Gitaly) in any Git repository:
- `refs/heads/`. Used for branches. See the [`git branch`](https://git-scm.com/docs/git-branch) documentation.
- `refs/tags/`. Used for tags. See the [`git tag`](https://git-scm.com/docs/git-tag) documentation.
### GitLab-specific references
These GitLab-specific references are used exclusively by GitLab (through Gitaly):
- `refs/keep-around/<object-id>`. References to commits that have pipeline jobs or merge requests. The `object-id` points to the commit the pipeline was run on.
- `refs/merge-requests/<merge-request-iid>/`. [Merges](https://git-scm.com/docs/git-merge) merge two histories together. This ref namespace tracks information about a
merge using the following refs under it:
- `head`. Current `HEAD` of the merge request.
- `merge`. Commit for the merge request. Every merge request creates a commit object under `refs/keep-around`.
- If [merge trains are enabled](../ci/pipelines/merge_trains.md): `train`. Commit for the merge train.
- `refs/pipelines/<pipeline-iid>`. References to pipelines. Temporarily used to store the pipeline commit object ID.
- `refs/environments/<environment-slug>`. References to commits where deployments to environments were performed.
- `refs/heads/revert-<source-commit-short-object-id>`. References to the commit's object ID created when [reverting changes](../user/project/merge_requests/revert_changes.md).

View File

@ -35,6 +35,11 @@ other internal references (refs) that are automatically created by GitLab. These
These refs are not automatically downloaded and hidden refs are not advertised, but we can remove these refs using a project export.
WARNING:
This process is not suitable for removing sensitive data like password or keys from your repository.
Information about commits, including file content, is cached in the database, and remain
visible even after they have been removed from the repository.
To purge files from a GitLab repository:
1. Install either [`git filter-repo`](https://github.com/newren/git-filter-repo/blob/main/INSTALL.md) or
@ -247,11 +252,6 @@ increased, your only option is to:
1. Prune all the unneeded stuff locally.
1. Create a new project on GitLab and start using that instead.
WARNING:
This process is not suitable for removing sensitive data like password or keys from your repository.
Information about commits, including file content, is cached in the database, and remain
visible even after they have been removed from the repository.
## Troubleshooting
### Incorrect repository statistics shown in the GUI

View File

@ -233,7 +233,7 @@ RSpec.describe Projects::EnvironmentsController do
end
context "when environment params are invalid" do
let(:params) { environment_params.merge(environment: { external_url: 'javascript:alert("hello")' }) }
let(:params) { environment_params.merge(environment: { name: '/foo/', external_url: '/git.gitlab.com' }) }
it 'returns bad request' do
subject

View File

@ -34,90 +34,6 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do
it { is_expected.to validate_length_of(:external_url).is_at_most(255) }
describe 'validate and sanitize external url' do
let_it_be_with_refind(:environment) { create(:environment) }
where(:source_external_url, :expected_error_message) do
'http://example.com' | nil
'example.com' | nil
'www.example.io' | nil
'http://$URL' | nil
'http://$(URL)' | nil
'custom://example.com' | nil
'1.1.1.1' | nil
'$BASE_URL/${CI_COMMIT_REF_NAME}' | nil
'$ENVIRONMENT_URL' | nil
'https://$SUB.$MAIN' | nil
'https://$SUB-$REGION.$MAIN' | nil
'https://example.com?param={()}' | nil
'http://XSS?x=<script>alert(1)</script>' | nil
'https://user:${VARIABLE}@example.io' | nil
'https://example.com/test?param={data}' | nil
'http://${URL}' | 'URI is invalid'
'https://${URL}.example/test' | 'URI is invalid'
'http://test${CI_MERGE_REQUEST_IID}.example.com' | 'URI is invalid'
'javascript:alert("hello")' | 'javascript scheme is not allowed'
end
with_them do
it 'sets an external URL or an error' do
environment.external_url = source_external_url
environment.valid?
if expected_error_message
expect(environment.errors[:external_url].first).to eq(expected_error_message)
else
expect(environment.errors[:external_url]).to be_empty,
"There were unexpected errors: #{environment.errors.full_messages}"
expect(environment.external_url).to eq(source_external_url)
end
end
end
context 'when soft_validation_on_external_url feature flag is disabled' do
before do
stub_feature_flags(soft_validation_on_external_url: false)
end
where(:source_external_url, :expected_error_message) do
'http://example.com' | nil
'example.com' | 'is blocked: Only allowed schemes are http, https'
'www.example.io' | 'is blocked: Only allowed schemes are http, https'
'http://$URL' | 'is blocked: Hostname or IP address invalid'
'http://$(URL)' | 'is blocked: Hostname or IP address invalid'
'custom://example.com' | 'is blocked: Only allowed schemes are http, https'
'1.1.1.1' | 'is blocked: Only allowed schemes are http, https'
'$BASE_URL/${CI_COMMIT_REF_NAME}' | 'is blocked: Only allowed schemes are http, https'
'$ENVIRONMENT_URL' | 'is blocked: Only allowed schemes are http, https'
'https://$SUB.$MAIN' | 'is blocked: Hostname or IP address invalid'
'https://$SUB-$REGION.$MAIN' | 'is blocked: Hostname or IP address invalid'
'https://example.com?param={()}' | nil
'http://XSS?x=<script>alert(1)</script>' | nil
'https://user:${VARIABLE}@example.io' | nil
'https://example.com/test?param={data}' | nil
'http://${URL}' | 'is blocked: URI is invalid'
'https://${URL}.example/test' | 'is blocked: URI is invalid'
'http://test${CI_MERGE_REQUEST_IID}.example.com' | 'is blocked: URI is invalid'
'javascript:alert("hello")' | 'is blocked: Only allowed schemes are http, https'
end
with_them do
it 'sets an external URL or an error' do
environment.external_url = source_external_url
environment.valid?
if expected_error_message
expect(environment.errors[:external_url].first).to eq(expected_error_message)
else
expect(environment.errors[:external_url]).to be_empty,
"There were unexpected errors: #{environment.errors.full_messages}"
expect(environment.external_url).to eq(source_external_url)
end
end
end
end
end
describe '.before_save' do
it 'ensures environment tier when a new object is created' do
environment = build(:environment, name: 'gprd', tier: nil)

View File

@ -112,7 +112,7 @@ RSpec.describe Deployments::UpdateEnvironmentService do
end
context 'when external URL is invalid' do
let(:external_url) { 'javascript:alert("hello")' }
let(:external_url) { 'google.com' }
it 'fails to update the tier due to validation error' do
expect { subject.execute }.not_to change { environment.tier }
@ -123,7 +123,7 @@ RSpec.describe Deployments::UpdateEnvironmentService do
.with(an_instance_of(described_class::EnvironmentUpdateFailure),
project_id: project.id,
environment_id: environment.id,
reason: %q{External url javascript scheme is not allowed})
reason: %q{External url is blocked: Only allowed schemes are http, https})
.once
subject.execute