Commit 72dd03d1 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents 7e9cac46 fdcf6a41
...@@ -277,7 +277,8 @@ ...@@ -277,7 +277,8 @@
"type": "string", "type": "string",
"format": "uri-reference", "format": "uri-reference",
"pattern": "\\.ya?ml$" "pattern": "\\.ya?ml$"
} },
"rules": { "$ref": "#/definitions/rules" }
}, },
"required": ["local"] "required": ["local"]
}, },
...@@ -491,7 +492,7 @@ ...@@ -491,7 +492,7 @@
}, },
"rules": { "rules": {
"type": "array", "type": "array",
"description": "rules allows for an array of individual rule objects to be evaluated in order, until one matches and dynamically provides attributes to the job.", "description": "Rules allows for an array of individual rule objects to be evaluated in order, until one matches and dynamically provides attributes to the job.",
"items": { "items": {
"type": "object", "type": "object",
"additionalProperties": false, "additionalProperties": false,
...@@ -625,17 +626,26 @@ ...@@ -625,17 +626,26 @@
] ]
}, },
"cache": { "cache": {
"oneOf": [ "properties": {
{ "when": {
"$ref": "#/definitions/cache_entry" "description": "Defines when to save the cache, based on the status of the job.",
}, "default": "on_success",
{ "oneOf": [
"type": "array", {
"items": { "enum": ["on_success"],
"$ref": "#/definitions/cache_entry" "description": "Save the cache only when the job succeeds."
} },
{
"enum": ["on_failure"],
"description": "Save the cache only when the job fails. "
},
{
"enum": ["always"],
"description": "Always save the cache. "
}
]
} }
] }
}, },
"cache_entry": { "cache_entry": {
"type": "object", "type": "object",
...@@ -1320,6 +1330,29 @@ ...@@ -1320,6 +1330,29 @@
} }
}, },
"required": ["artifact", "job"] "required": ["artifact", "job"]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"project": {
"description": "Path to another private project under the same GitLab instance, like `group/project` or `group/sub-group/project`.",
"type": "string",
"pattern": "\\S/\\S"
},
"ref": {
"description": "Branch/Tag/Commit hash for the target project.",
"minLength": 1,
"type": "string"
},
"file": {
"description": "Relative path from repository root (`/`) to the pipeline configuration YAML file.",
"type": "string",
"format": "uri-reference",
"pattern": "\\.ya?ml$"
}
},
"required": ["project", "file"]
} }
] ]
} }
......
...@@ -28,7 +28,7 @@ module Routing ...@@ -28,7 +28,7 @@ module Routing
when 'groups' when 'groups'
"/namespace:#{group.id}" "/namespace:#{group.id}"
when 'projects' when 'projects'
"/namespace:#{project.namespace.id}/project:#{project.id}" "/namespace:#{project.namespace_id}/project:#{project.id}"
when 'root' when 'root'
'' ''
else else
...@@ -44,7 +44,7 @@ module Routing ...@@ -44,7 +44,7 @@ module Routing
masked_url = "#{request.protocol}#{request.host_with_port}" masked_url = "#{request.protocol}#{request.host_with_port}"
if request_params.has_key?(:project_id) if request_params.has_key?(:project_id)
masked_url += "/namespace:#{project.namespace.id}/project:#{project.id}/-/#{namespace_type}" masked_url += "/namespace:#{project.namespace_id}/project:#{project.id}/-/#{namespace_type}"
end end
if request_params.has_key?(:id) if request_params.has_key?(:id)
......
...@@ -73,7 +73,6 @@ module TabHelper ...@@ -73,7 +73,6 @@ module TabHelper
# :action - One or more action names to check (optional). # :action - One or more action names to check (optional).
# :path - A shorthand path, such as 'dashboard#index', to check (optional). # :path - A shorthand path, such as 'dashboard#index', to check (optional).
# :html_options - Extra options to be passed to the list element (optional). # :html_options - Extra options to be passed to the list element (optional).
# :unless - Callable object to skip rendering the 'active' class on `li` element (optional).
# block - An optional block that will become the contents of the returned # block - An optional block that will become the contents of the returned
# `li` element. # `li` element.
# #
...@@ -118,11 +117,6 @@ module TabHelper ...@@ -118,11 +117,6 @@ module TabHelper
# nav_link(path: 'admin/appearances#show') { "Hello"} # nav_link(path: 'admin/appearances#show') { "Hello"}
# # => '<li class="active">Hello</li>' # # => '<li class="active">Hello</li>'
# #
# # Shorthand path + unless
# # Add `active` class when TreeController is requested, except the `index` action.
# nav_link(controller: 'tree', unless: -> { action_name?('index') }) { "Hello" }
# # => '<li class="active">Hello</li>'
#
# # When `TreeController#index` is requested # # When `TreeController#index` is requested
# # => '<li>Hello</li>' # # => '<li>Hello</li>'
# #
...@@ -151,8 +145,6 @@ module TabHelper ...@@ -151,8 +145,6 @@ module TabHelper
end end
def active_nav_link?(options) def active_nav_link?(options)
return false if options[:unless]&.call
controller = options.delete(:controller) controller = options.delete(:controller)
action = options.delete(:action) action = options.delete(:action)
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
module Projects module Projects
class OverwriteProjectService < BaseService class OverwriteProjectService < BaseService
def execute(source_project) def execute(source_project)
return unless source_project && source_project.namespace == @project.namespace return unless source_project && source_project.namespace_id == @project.namespace_id
start_time = ::Gitlab::Metrics::System.monotonic_time start_time = ::Gitlab::Metrics::System.monotonic_time
...@@ -40,7 +40,7 @@ module Projects ...@@ -40,7 +40,7 @@ module Projects
duration = ::Gitlab::Metrics::System.monotonic_time - start_time duration = ::Gitlab::Metrics::System.monotonic_time - start_time
Gitlab::AppJsonLogger.info(class: self.class.name, Gitlab::AppJsonLogger.info(class: self.class.name,
namespace_id: source_project.namespace.id, namespace_id: source_project.namespace_id,
project_id: source_project.id, project_id: source_project.id,
duration_s: duration.to_f, duration_s: duration.to_f,
error: exception.class.name) error: exception.class.name)
......
...@@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w ...@@ -5,7 +5,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
type: reference, howto type: reference, howto
--- ---
# Vault Authentication with GitLab OpenID Connect # Vault Authentication with GitLab OpenID Connect **(FREE)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/22323) in GitLab 9.0 > [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/22323) in GitLab 9.0
......
...@@ -20,7 +20,7 @@ A DAST job has two executing processes: ...@@ -20,7 +20,7 @@ A DAST job has two executing processes:
Enable the `DAST_DEBUG` CI/CD variable to debug scripts. This can help when troubleshooting the job, Enable the `DAST_DEBUG` CI/CD variable to debug scripts. This can help when troubleshooting the job,
and outputs statements indicating what percentage of the scan is complete. and outputs statements indicating what percentage of the scan is complete.
For details on using variables, see [Overriding the DAST template](index.md#customizing-the-dast-settings). For details on using variables, see [Overriding the DAST template](index.md#customize-dast-settings).
Debug mode of the ZAP server can be enabled using the `DAST_ZAP_LOG_CONFIGURATION` variable. Debug mode of the ZAP server can be enabled using the `DAST_ZAP_LOG_CONFIGURATION` variable.
The following table outlines examples of values that can be set and the effect that they have on the output that is logged. The following table outlines examples of values that can be set and the effect that they have on the output that is logged.
......
This diff is collapsed.
...@@ -51,6 +51,10 @@ class Dast::ProfileSchedule < ApplicationRecord ...@@ -51,6 +51,10 @@ class Dast::ProfileSchedule < ApplicationRecord
self.class.active_for_project(project_id) self.class.active_for_project(project_id)
end end
def owner_valid?
Ability.allowed?(owner, :create_on_demand_dast_scan, project)
end
private private
def deactivate! def deactivate!
......
...@@ -52,7 +52,9 @@ module AppSec ...@@ -52,7 +52,9 @@ module AppSec
def update_or_create_schedule! def update_or_create_schedule!
if schedule if schedule
schedule.update!(schedule_input_params) attributes = schedule_input_params
attributes = attributes.merge(user_id: current_user.id) unless schedule.owner_valid?
schedule.update!(attributes)
else else
::Dast::ProfileSchedule.new( ::Dast::ProfileSchedule.new(
dast_profile: dast_profile, dast_profile: dast_profile,
......
...@@ -35,7 +35,7 @@ module Security ...@@ -35,7 +35,7 @@ module Security
security_policy_target_project_id: project.id, security_policy_target_project_id: project.id,
name: "#{project.name} - Security policy project", name: "#{project.name} - Security policy project",
description: "This project is automatically generated to manage security policies for the project.", description: "This project is automatically generated to manage security policies for the project.",
namespace_id: project.namespace.id, namespace_id: project.namespace_id,
initialize_with_readme: true, initialize_with_readme: true,
container_registry_enabled: false, container_registry_enabled: false,
packages_enabled: false, packages_enabled: false,
......
...@@ -9,6 +9,7 @@ RSpec.describe AppSec::Dast::Profiles::UpdateService do ...@@ -9,6 +9,7 @@ RSpec.describe AppSec::Dast::Profiles::UpdateService do
let_it_be(:dast_site_profile) { create(:dast_site_profile, project: project) } let_it_be(:dast_site_profile) { create(:dast_site_profile, project: project) }
let_it_be(:dast_scanner_profile) { create(:dast_scanner_profile, project: project) } let_it_be(:dast_scanner_profile) { create(:dast_scanner_profile, project: project) }
let_it_be(:plan_limits) { create(:plan_limits, :default_plan) } let_it_be(:plan_limits) { create(:plan_limits, :default_plan) }
let_it_be(:scheduler_owner) { create(:user, name: 'Scheduler Owner') }
let(:default_params) do let(:default_params) do
{ {
...@@ -59,7 +60,7 @@ RSpec.describe AppSec::Dast::Profiles::UpdateService do ...@@ -59,7 +60,7 @@ RSpec.describe AppSec::Dast::Profiles::UpdateService do
context 'when the user can run a DAST scan' do context 'when the user can run a DAST scan' do
before do before do
project.add_developer(user) project.add_users([user, scheduler_owner], :developer)
end end
it 'communicates success' do it 'communicates success' do
...@@ -127,24 +128,69 @@ RSpec.describe AppSec::Dast::Profiles::UpdateService do ...@@ -127,24 +128,69 @@ RSpec.describe AppSec::Dast::Profiles::UpdateService do
end end
context 'when associated schedule is present' do context 'when associated schedule is present' do
before do let_it_be_with_reload(:dast_profile_schedule) { create(:dast_profile_schedule, project: project, dast_profile: dast_profile, owner: scheduler_owner) }
create(:dast_profile_schedule, dast_profile: dast_profile)
end
it 'updates the dast profile schedule' do it 'updates the dast profile schedule' do
updated_schedule = subject.payload[:dast_profile_schedule].reload subject
aggregate_failures do aggregate_failures do
expect(updated_schedule.active).to eq(params[:dast_profile_schedule][:active]) expect(dast_profile_schedule.active).to eq(params[:dast_profile_schedule][:active])
expect(updated_schedule.starts_at.to_i).to eq(params[:dast_profile_schedule][:starts_at].to_i) expect(dast_profile_schedule.starts_at.to_i).to eq(params[:dast_profile_schedule][:starts_at].to_i)
expect(updated_schedule.timezone).to eq(params[:dast_profile_schedule][:timezone]) expect(dast_profile_schedule.timezone).to eq(params[:dast_profile_schedule][:timezone])
expect(updated_schedule.cadence).to eq(params[:dast_profile_schedule][:cadence].stringify_keys) expect(dast_profile_schedule.cadence).to eq(params[:dast_profile_schedule][:cadence].stringify_keys)
end end
end end
it 'creates the audit event' do it 'creates the audit event' do
expect { subject }.to change { AuditEvent.where(target_id: dast_profile.dast_profile_schedule.id).count } expect { subject }.to change { AuditEvent.where(target_id: dast_profile.dast_profile_schedule.id).count }
end end
context 'when the owner is valid' do
it 'does not updates the schedule owner' do
subject
expect(dast_profile_schedule.user_id).to eq(scheduler_owner.id)
end
end
context 'when the owner was deleted' do
before do
scheduler_owner.destroy!
subject.payload[:dast_profile_schedule].reload
end
it 'updates the schedule owner' do
subject
expect(dast_profile_schedule.user_id).to eq(user.id)
end
end
context 'when the owner permission was downgraded' do
before do
project.add_guest(scheduler_owner)
end
it 'updates the schedule owner' do
subject
expect(dast_profile_schedule.user_id).to eq(user.id)
end
end
context 'when the owner was removed from the project' do
before do
stub_feature_flags(member_destroy_async_auth_refresh: false)
project.team.truncate
project.add_developer(user)
end
it 'updates the schedule owner' do
subject
expect(dast_profile_schedule.user_id).to eq(user.id)
end
end
end end
end end
......
...@@ -7,7 +7,7 @@ module Gitlab ...@@ -7,7 +7,7 @@ module Gitlab
grouped_items = issuables.group_by do |issuable| grouped_items = issuables.group_by do |issuable|
if issuable.project.id == project.id if issuable.project.id == project.id
:project_ref :project_ref
elsif issuable.project.namespace.id == project.namespace.id elsif issuable.project.namespace_id == project.namespace_id
:namespace_ref :namespace_ref
else else
:full_ref :full_ref
......
...@@ -6,6 +6,7 @@ RSpec.describe ::Routing::PseudonymizationHelper do ...@@ -6,6 +6,7 @@ RSpec.describe ::Routing::PseudonymizationHelper do
let_it_be(:group) { create(:group) } let_it_be(:group) { create(:group) }
let_it_be(:subgroup) { create(:group, parent: group) } let_it_be(:subgroup) { create(:group, parent: group) }
let_it_be(:project) { create(:project, group: group) } let_it_be(:project) { create(:project, group: group) }
let_it_be(:subproject) { create(:project, group: subgroup) }
let_it_be(:issue) { create(:issue, project: project) } let_it_be(:issue) { create(:issue, project: project) }
let(:merge_request) { create(:merge_request, source_project: project) } let(:merge_request) { create(:merge_request, source_project: project) }
...@@ -56,16 +57,16 @@ RSpec.describe ::Routing::PseudonymizationHelper do ...@@ -56,16 +57,16 @@ RSpec.describe ::Routing::PseudonymizationHelper do
end end
context 'with controller for groups with subgroups and project' do context 'with controller for groups with subgroups and project' do
let(:masked_url) { "http://test.host/namespace:#{subgroup.id}/project:#{project.id}"} let(:masked_url) { "http://test.host/namespace:#{subgroup.id}/project:#{subproject.id}"}
before do before do
allow(helper).to receive(:group).and_return(subgroup) allow(helper).to receive(:group).and_return(subgroup)
allow(helper.project).to receive(:namespace).and_return(subgroup) allow(helper).to receive(:project).and_return(subproject)
allow(Rails.application.routes).to receive(:recognize_path).and_return({ allow(Rails.application.routes).to receive(:recognize_path).and_return({
controller: 'projects', controller: 'projects',
action: 'show', action: 'show',
namespace_id: subgroup.name, namespace_id: subgroup.name,
id: project.name id: subproject.name
}) })
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment