Add latest changes from gitlab-org/security/gitlab@14-10-stable-ee

This commit is contained in:
GitLab Bot 2022-04-29 08:18:14 +00:00
parent 88da5554d9
commit deb2f3a608
21 changed files with 200 additions and 34 deletions

View File

@ -32,6 +32,21 @@ class Projects::ApplicationController < ApplicationController
->(project) { !project.pending_delete? }
end
def authorize_read_build_trace!
return if can?(current_user, :read_build_trace, build)
if build.debug_mode?
access_denied!(
_('You must have developer or higher permissions in the associated project to view job logs when debug trace ' \
"is enabled. To disable debug trace, set the 'CI_DEBUG_TRACE' variable to 'false' in your pipeline " \
'configuration or CI/CD settings. If you need to view this job log, a project maintainer must add you to ' \
'the project with developer permissions or higher.')
)
else
access_denied!(_('The current user is not authorized to access the job log.'))
end
end
def build_canonical_path(project)
params[:namespace_id] = project.namespace.to_param
params[:project_id] = project.to_param

View File

@ -9,6 +9,7 @@ class Projects::ArtifactsController < Projects::ApplicationController
layout 'project'
before_action :authorize_read_build!
before_action :authorize_read_build_trace!, only: [:download]
before_action :authorize_update_build!, only: [:keep]
before_action :authorize_destroy_artifacts!, only: [:destroy]
before_action :extract_ref_name_and_path
@ -164,4 +165,10 @@ class Projects::ArtifactsController < Projects::ApplicationController
render_404 unless @entry.exists?
end
def authorize_read_build_trace!
return unless params[:file_type] == 'trace'
super
end
end

View File

@ -177,17 +177,7 @@ class Projects::JobsController < Projects::ApplicationController
private
def authorize_read_build_trace!
return if can?(current_user, :read_build_trace, @build)
msg = _(
"You must have developer or higher permissions in the associated project to view job logs when debug trace is enabled. To disable debug trace, set the 'CI_DEBUG_TRACE' variable to 'false' in your pipeline configuration or CI/CD settings. " \
"If you need to view this job log, a project maintainer must add you to the project with developer permissions or higher."
)
return access_denied!(msg) if @build.debug_mode?
access_denied!(_('The current user is not authorized to access the job log.'))
end
attr_reader :build
def authorize_update_build!
return access_denied! unless can?(current_user, :update_build, @build)

View File

@ -229,7 +229,13 @@ class CommitStatus < Ci::ApplicationRecord
end
def group_name
name.to_s.sub(%r{([\b\s:]+((\[.*\])|(\d+[\s:\/\\]+\d+)))+\s*\z}, '').strip
# [\b\s:] -> whitespace or column
# (\[.*\])|(\d+[\s:\/\\]+\d+) -> variables/matrix or parallel-jobs numbers
# {1,3} -> number of times that matches the variables/matrix or parallel-jobs numbers
# we limit this to 3 because of possible abuse
regex = %r{([\b\s:]+((\[.*\])|(\d+[\s:\/\\]+\d+))){1,3}\s*\z}
name.to_s.sub(regex, '').strip
end
def failed_but_allowed?

View File

@ -27,10 +27,12 @@ module Integrations
def fields
[
{
type: 'text',
type: 'password',
name: 'api_key',
title: 'API key',
help: s_('AsanaService|User Personal Access Token. User must have access to the task. All comments are attributed to this user.'),
non_empty_password_title: s_('ProjectService|Enter new API key'),
non_empty_password_help: s_('ProjectService|Leave blank to use your current API key.'),
# Example Personal Access Token from Asana docs
placeholder: '0/68a9e79b868c6789e79a124c30b0',
required: true

View File

@ -19,8 +19,19 @@ module Integrations
def fields
[
{ type: 'text', name: 'token', placeholder: '', required: true },
{ type: 'text', name: 'subdomain', placeholder: '' }
{
type: 'password',
name: 'token',
non_empty_password_title: s_('ProjectService|Enter new token'),
non_empty_password_help: s_('ProjectService|Leave blank to use your current token.'),
placeholder: '',
required: true
},
{
type: 'text',
name: 'subdomain',
placeholder: ''
}
]
end

View File

@ -54,10 +54,12 @@ module Integrations
required: true
},
{
type: 'text',
type: 'password',
name: 'build_key',
placeholder: s_('KEY'),
help: s_('BambooService|Bamboo build plan key.'),
non_empty_password_title: s_('BambooService|Enter new build key'),
non_empty_password_help: s_('BambooService|Leave blank to use your current build key.'),
placeholder: s_('KEY'),
required: true
},
{

View File

@ -26,7 +26,13 @@ module Integrations
def fields
[
{ type: 'text', name: 'token', placeholder: 'XXxxXXxxXXxxXXxxXXxxXXxx' }
{
type: 'password',
name: 'token',
non_empty_password_title: s_('ProjectService|Enter new token'),
non_empty_password_help: s_('ProjectService|Leave blank to use your current token.'),
placeholder: 'XXxxXXxxXXxxXXxxXXxxXXxx'
}
]
end

View File

@ -76,10 +76,12 @@ module Integrations
def fields
[
{ type: 'text',
{ type: 'password',
name: 'token',
title: _('Token'),
help: s_('ProjectService|The token you get after you create a Buildkite pipeline with a GitLab repository.'),
non_empty_password_title: s_('ProjectService|Enter new token'),
non_empty_password_help: s_('ProjectService|Leave blank to use your current token.'),
required: true },
{ type: 'text',

View File

@ -25,11 +25,13 @@ module Integrations
def fields
[
{
type: 'text',
type: 'password',
name: 'token',
title: _('Campfire token'),
placeholder: '',
help: s_('CampfireService|API authentication token from Campfire.'),
non_empty_password_title: s_('ProjectService|Enter new token'),
non_empty_password_help: s_('ProjectService|Leave blank to use your current token.'),
placeholder: '',
required: true
},
{

View File

@ -96,8 +96,21 @@ module Integrations
def fields
[
{ type: 'text', name: 'token', help: s_('ProjectService|Token for the Drone project.'), required: true },
{ type: 'text', name: 'drone_url', title: s_('ProjectService|Drone server URL'), placeholder: 'http://drone.example.com', required: true }
{
type: 'password',
name: 'token',
help: s_('ProjectService|Token for the Drone project.'),
non_empty_password_title: s_('ProjectService|Enter new token'),
non_empty_password_help: s_('ProjectService|Leave blank to use your current token.'),
required: true
},
{
type: 'text',
name: 'drone_url',
title: s_('ProjectService|Drone server URL'),
placeholder: 'http://drone.example.com',
required: true
}
]
end

View File

@ -24,7 +24,15 @@ module Integrations
def fields
[
{ type: 'text', name: 'token', placeholder: s_('FlowdockService|1b609b52537...'), required: true, help: 'Enter your Flowdock token.' }
{
type: 'password',
name: 'token',
help: s_('FlowdockService|Enter your Flowdock token.'),
non_empty_password_title: s_('ProjectService|Enter new token'),
non_empty_password_help: s_('ProjectService|Leave blank to use your current token.'),
placeholder: '1b609b52537...',
required: true
}
]
end

View File

@ -64,11 +64,12 @@ module Integrations
required: true
},
{
type: 'text',
type: 'password',
name: 'password',
title: s_('HarborIntegration|Harbor password'),
non_empty_password_title: s_('HarborIntegration|Enter Harbor password'),
non_empty_password_help: s_('HarborIntegration|Password for your Harbor username.'),
help: s_('HarborIntegration|Password for your Harbor username.'),
non_empty_password_title: s_('HarborIntegration|Enter new Harbor password'),
non_empty_password_help: s_('HarborIntegration|Leave blank to use your current password.'),
required: true
}
]

View File

@ -36,10 +36,12 @@ module Integrations
required: true
},
{
type: 'text',
type: 'password',
name: 'token',
title: _('Token'),
help: s_('Enter your Packagist token.'),
non_empty_password_title: s_('ProjectService|Enter new token'),
non_empty_password_help: s_('ProjectService|Leave blank to use your current token.'),
placeholder: '',
required: true
},

View File

@ -27,9 +27,11 @@ module Integrations
def fields
[
{
type: 'text',
type: 'password',
name: 'token',
help: s_('PivotalTrackerService|Pivotal Tracker API token. User must have access to the story. All comments are attributed to this user.'),
non_empty_password_title: s_('ProjectService|Enter new token'),
non_empty_password_help: s_('ProjectService|Leave blank to use your current token.'),
required: true
},
{

View File

@ -22,18 +22,22 @@ module Integrations
def fields
[
{
type: 'text',
type: 'password',
name: 'api_key',
title: _('API key'),
help: s_('PushoverService|Enter your application key.'),
non_empty_password_title: s_('ProjectService|Enter new API key'),
non_empty_password_help: s_('ProjectService|Leave blank to use your current API key.'),
placeholder: '',
required: true
},
{
type: 'text',
type: 'password',
name: 'user_key',
title: _('User key'),
help: s_('PushoverService|Enter your user key.'),
non_empty_password_title: s_('PushoverService|Enter new user key'),
non_empty_password_help: s_('PushoverService|Leave blank to use your current user key.'),
placeholder: '',
required: true
},

View File

@ -167,7 +167,7 @@ The jobs are ordered by comparing the numbers from left to right. You
usually want the first number to be the index and the second number to be the total.
[This regular expression](https://gitlab.com/gitlab-org/gitlab/-/blob/2f3dc314f42dbd79813e6251792853bc231e69dd/app/models/commit_status.rb#L99)
evaluates the job names: `([\b\s:]+((\[.*\])|(\d+[\s:\/\\]+\d+)))+\s*\z`.
evaluates the job names: `([\b\s:]+((\[.*\])|(\d+[\s:\/\\]+\d+))){1,3}\s*\z`.
One or more `: [...]`, `X Y`, `X/Y`, or `X\Y` sequences are removed from the **end**
of job names only. Matching substrings found at the beginning or in the middle of
job names are not removed.

View File

@ -5614,6 +5614,12 @@ msgstr ""
msgid "BambooService|Bamboo service root URL."
msgstr ""
msgid "BambooService|Enter new build key"
msgstr ""
msgid "BambooService|Leave blank to use your current build key."
msgstr ""
msgid "BambooService|Run CI/CD pipelines with Atlassian Bamboo."
msgstr ""
@ -16101,7 +16107,7 @@ msgstr ""
msgid "FloC|Federated Learning of Cohorts"
msgstr ""
msgid "FlowdockService|1b609b52537..."
msgid "FlowdockService|Enter your Flowdock token."
msgstr ""
msgid "FlowdockService|Send event notifications from GitLab to Flowdock flows."
@ -18357,7 +18363,7 @@ msgstr ""
msgid "HarborIntegration|Base URL of the Harbor instance."
msgstr ""
msgid "HarborIntegration|Enter Harbor password"
msgid "HarborIntegration|Enter new Harbor password"
msgstr ""
msgid "HarborIntegration|Harbor URL"
@ -18372,6 +18378,9 @@ msgstr ""
msgid "HarborIntegration|Harbor username"
msgstr ""
msgid "HarborIntegration|Leave blank to use your current password."
msgstr ""
msgid "HarborIntegration|Password for your Harbor username."
msgstr ""
@ -29398,6 +29407,9 @@ msgstr ""
msgid "ProjectService|Leave blank to use your current API key"
msgstr ""
msgid "ProjectService|Leave blank to use your current API key."
msgstr ""
msgid "ProjectService|Leave blank to use your current password"
msgstr ""
@ -30751,6 +30763,9 @@ msgstr ""
msgid "PushoverService|%{user_name} pushed new branch \"%{ref}\"."
msgstr ""
msgid "PushoverService|Enter new user key"
msgstr ""
msgid "PushoverService|Enter your application key."
msgstr ""
@ -30766,6 +30781,9 @@ msgstr ""
msgid "PushoverService|Leave blank for all active devices."
msgstr ""
msgid "PushoverService|Leave blank to use your current user key."
msgstr ""
msgid "PushoverService|Low priority"
msgstr ""

View File

@ -204,6 +204,44 @@ RSpec.describe Projects::ArtifactsController do
end
end
end
context 'when downloading a debug trace' do
let(:file_type) { 'trace' }
let(:job) { create(:ci_build, :success, :trace_artifact, pipeline: pipeline) }
before do
create(:ci_job_variable, key: 'CI_DEBUG_TRACE', value: 'true', job: job)
end
context 'when the user does not have update_build permissions' do
let(:user) { create(:user) }
before do
project.add_guest(user)
end
render_views
it 'denies the user access' do
download_artifact(file_type: file_type)
expect(response).to have_gitlab_http_status(:forbidden)
expect(response.body).to include(
'You must have developer or higher permissions in the associated project to view job logs when debug trace is enabled. ' \
'To disable debug trace, set the &#39;CI_DEBUG_TRACE&#39; variable to &#39;false&#39; in your pipeline configuration or CI/CD settings. ' \
'If you need to view this job log, a project maintainer must add you to the project with developer permissions or higher.'
)
end
end
context 'when the user has update_build permissions' do
it 'sends the trace' do
download_artifact(file_type: file_type)
expect(response).to have_gitlab_http_status(:ok)
end
end
end
end
describe 'GET browse' do

View File

@ -618,6 +618,7 @@ RSpec.describe CommitStatus do
'rspec:windows 10000 20000' | 'rspec:windows'
'rspec:windows 0 : / 1' | 'rspec:windows'
'rspec:windows 0 : / 1 name' | 'rspec:windows 0 : / 1 name'
'rspec [inception: [something, other thing], value]' | 'rspec'
'0 1 name ruby' | '0 1 name ruby'
'0 :/ 1 name ruby' | '0 :/ 1 name ruby'
'rspec: [aws]' | 'rspec'

View File

@ -0,0 +1,36 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'Every integration' do
all_integration_names = Integration.available_integration_names
all_integration_names.each do |integration_name|
describe integration_name do
let(:integration_class) { Integration.integration_name_to_model(integration_name) }
let(:integration) { integration_class.new }
context 'secret fields', :aggregate_failures do
it "uses type: 'password' for all secret fields" do
integration.fields.each do |field|
next unless Integrations::Field::SECRET_NAME.match?(field[:name])
expect(field[:type]).to eq('password'),
"Field '#{field[:name]}' should use type 'password'"
end
end
it 'defines non-empty titles and help texts for all secret fields' do
integration.fields.each do |field|
next unless field[:type] == 'password'
expect(field[:non_empty_password_title]).to be_present,
"Field '#{field[:name]}' should define :non_empty_password_title"
expect(field[:non_empty_password_help]).to be_present,
"Field '#{field[:name]}' should define :non_empty_password_help"
end
end
end
end
end
end