Skip to content
Snippets Groups Projects
Unverified Commit 0bd9277d authored by Francisco Javier López's avatar Francisco Javier López
Browse files

Port from EE

This commit is a port from https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/7386.
Here we refactor some code needed to clean and add some access policies to the
JobsController.
parent 6c30d9b4
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -3,18 +3,22 @@
class Projects::JobsController < Projects::ApplicationController
include SendFileUpload
 
before_action :build, except: [:index, :cancel_all]
before_action :authorize_read_build!
before_action :build,
only: [:show, :cancel, :retry, :play, :erase, :trace, :raw, :status, :terminal, :terminal_websocket_authorize]
before_action :authorize_read_build!,
only: [:show, :cancel, :retry, :play, :erase, :trace, :raw, :status, :terminal, :terminal_websocket_authorize]
before_action :authorize_update_build!,
except: [:index, :show, :status, :raw, :trace, :cancel_all, :erase]
only: [:cancel, :retry, :play, :terminal, :terminal_websocket_authorize]
before_action :authorize_erase_build!, only: [:erase]
before_action :authorize_use_build_terminal!, only: [:terminal, :terminal_workhorse_authorize]
before_action :authorize_use_build_terminal!, only: [:terminal, :terminal_websocket_authorize]
before_action :verify_api_request!, only: :terminal_websocket_authorize
 
layout 'project'
 
# rubocop: disable CodeReuse/ActiveRecord
def index
return access_denied! unless can?(current_user, :read_build, project)
@scope = params[:scope]
@all_builds = project.builds.relevant
@builds = @all_builds.order('ci_builds.id DESC')
Loading
Loading
@@ -41,7 +45,7 @@ class Projects::JobsController < Projects::ApplicationController
def cancel_all
return access_denied! unless can?(current_user, :update_build, project)
 
@project.builds.running_or_pending.each do |build|
project.builds.running_or_pending.each do |build|
build.cancel if can?(current_user, :update_build, build)
end
 
Loading
Loading
@@ -93,7 +97,11 @@ class Projects::JobsController < Projects::ApplicationController
return respond_422 unless @build.retryable?
 
build = Ci::Build.retry(@build, current_user)
redirect_to build_path(build)
respond_to do |format|
format.html { redirect_to build_path(build) }
format.json { render_build(build) }
end
end
 
def play
Loading
Loading
@@ -107,13 +115,15 @@ class Projects::JobsController < Projects::ApplicationController
return respond_422 unless @build.cancelable?
 
@build.cancel
redirect_to build_path(@build)
respond_to do |format|
format.html { redirect_to build_path(@build) }
format.json { head :ok }
end
end
 
def status
render json: BuildSerializer
.new(project: @project, current_user: @current_user)
.represent_status(@build)
render_build(@build)
end
 
def erase
Loading
Loading
@@ -152,6 +162,10 @@ class Projects::JobsController < Projects::ApplicationController
 
private
 
def authorize_read_build!
return access_denied! unless can?(current_user, :read_build, build)
end
def authorize_update_build!
return access_denied! unless can?(current_user, :update_build, build)
end
Loading
Loading
@@ -188,4 +202,10 @@ class Projects::JobsController < Projects::ApplicationController
def build_path(build)
project_job_path(build.project, build)
end
def render_build(current_build)
render json: BuildSerializer
.new(project: @project, current_user: @current_user)
.represent_status(current_build)
end
end
Loading
Loading
@@ -44,6 +44,7 @@ module Ci
 
delegate :id, to: :project, prefix: true
delegate :full_path, to: :project, prefix: true
delegate :ci_yaml_file_path, to: :project
 
validates :sha, presence: { unless: :importing? }
validates :ref, presence: { unless: :importing? }
Loading
Loading
@@ -57,6 +58,10 @@ module Ci
 
after_create :keep_around_commits, unless: :importing?
 
def self.source_enum_values
{}
end
enum_with_nil source: {
unknown: nil,
push: 1,
Loading
Loading
@@ -65,7 +70,7 @@ module Ci
schedule: 4,
api: 5,
external: 6
}
}.merge(source_enum_values)
 
enum_with_nil config_source: {
unknown_source: nil,
Loading
Loading
@@ -242,7 +247,7 @@ module Ci
end
 
def self.internal_sources
sources.reject { |source| source == "external" }.values
sources.except(:external).values
end
 
def stages_count
Loading
Loading
@@ -476,14 +481,6 @@ module Ci
end
end
 
def ci_yaml_file_path
if project.ci_config_path.blank?
'.gitlab-ci.yml'
else
project.ci_config_path
end
end
def ci_yaml_file
return @ci_yaml_file if defined?(@ci_yaml_file)
 
Loading
Loading
Loading
Loading
@@ -2090,6 +2090,10 @@ class Project < ActiveRecord::Base
auto_cancel_pending_pipelines == 'enabled'
end
 
def ci_yaml_file_path
ci_config_path.presence || '.gitlab-ci.yml'
end
private
 
# rubocop: disable CodeReuse/ServiceClass
Loading
Loading
Loading
Loading
@@ -350,11 +350,14 @@ class ProjectPolicy < BasePolicy
enable :read_issue
end
 
rule { public_builds }.policy do
rule { public_builds & can?(:public_access) }.policy do
enable :read_build
enable :read_commit_status
end
 
rule { public_builds & can?(:guest_access) }.policy do
enable :read_build
enable :read_commit_status
enable :read_pipeline
enable :read_pipeline_schedule
end
Loading
Loading
Loading
Loading
@@ -5,6 +5,6 @@ class BuildSerializer < BaseSerializer
 
def represent_status(resource)
data = represent(resource, { only: [:status] })
data.fetch(:status, {})
data&.fetch(:status, {})
end
end
Loading
Loading
@@ -356,6 +356,7 @@ GET /projects/:id/runners?status=active
| `scope` | string | no | Deprecated: Use `type` or `status` instead. The scope of specific runners to show, one of: `active`, `paused`, `online`, `offline`; showing all runners if none provided |
| `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` |
| `status` | string | no | The status of runners to show, one of: `active`, `paused`, `online`, `offline` |
| `tag_list` | array | no | The list of tags of the runners to show |
 
```
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v4/projects/9/runners"
Loading
Loading
Loading
Loading
@@ -139,6 +139,8 @@ module API
desc: 'The type of the runners to show'
optional :status, type: String, values: Ci::Runner::AVAILABLE_STATUSES,
desc: 'The status of the runners to show'
optional :tag_list, type: Array[String],
desc: 'The list of tags of the runners to show'
use :pagination
end
get ':id/runners' do
Loading
Loading
@@ -147,6 +149,10 @@ module API
runners = filter_runners(runners, params[:type], allowed_scopes: Ci::Runner::AVAILABLE_TYPES)
runners = filter_runners(runners, params[:status], allowed_scopes: Ci::Runner::AVAILABLE_STATUSES)
 
if params[:tag_list]&.any?
runners = runners.tagged_with(params[:tag_list])
end
present paginate(runners), with: Entities::Runner
end
 
Loading
Loading
Loading
Loading
@@ -84,6 +84,10 @@ module Gitlab
end
end
 
def builds_with_tag(tag_name)
builds.select { |data| data[:tag_list].include?(tag_name) }
end
private
 
def initial_parsing
Loading
Loading
Loading
Loading
@@ -1404,6 +1404,65 @@ module Gitlab
it { is_expected.to be_nil }
end
end
describe '#builds_with_tag' do
let(:config) do
<<~EOT
job1:
script:
- whatever
tags:
- custom_tag
job2:
script:
- whatever
tags:
- custom_tag
job3:
script:
- whatever
EOT
end
subject { described_class.new(config).builds_with_tag('custom_tag') }
it 'returns builds with the selected tag' do
result = subject
expect(result.count).to eq 2
expect(result[0][:name]).to eq 'job1'
expect(result[1][:name]).to eq 'job2'
end
context 'with job templates' do
let(:config) do
<<~EOT
.template: &JOBTMPL
stage: build
script: execute-script-for-job
tags: [custom_tag]
job1: *JOBTMPL
job2: *JOBTMPL
job3:
script:
- whatever
EOT
end
it 'returns builds with the selected tag' do
result = subject
expect(result.count).to eq 2
expect(result[0][:name]).to eq 'job1'
expect(result[1][:name]).to eq 'job2'
end
end
end
end
end
end
Loading
Loading
@@ -1128,28 +1128,6 @@ describe Ci::Pipeline, :mailer do
end
end
 
describe '#ci_yaml_file_path' do
subject { pipeline.ci_yaml_file_path }
it 'returns the path from project' do
allow(pipeline.project).to receive(:ci_config_path) { 'custom/path' }
is_expected.to eq('custom/path')
end
it 'returns default when custom path is nil' do
allow(pipeline.project).to receive(:ci_config_path) { nil }
is_expected.to eq('.gitlab-ci.yml')
end
it 'returns default when custom path is empty' do
allow(pipeline.project).to receive(:ci_config_path) { '' }
is_expected.to eq('.gitlab-ci.yml')
end
end
describe '#set_config_source' do
context 'when pipelines does not contain needed data and auto devops is disabled' do
before do
Loading
Loading
Loading
Loading
@@ -4038,6 +4038,30 @@ describe Project do
end
end
 
context '#ci_yaml_file_path' do
let(:project) { create(:project, :repository) }
subject { project.ci_yaml_file_path }
it 'returns the path from project' do
allow(project).to receive(:ci_config_path) { 'custom/path' }
is_expected.to eq('custom/path')
end
it 'returns default when custom path is nil' do
allow(project).to receive(:ci_config_path) { nil }
is_expected.to eq('.gitlab-ci.yml')
end
it 'returns default when custom path is empty' do
allow(project).to receive(:ci_config_path) { '' }
is_expected.to eq('.gitlab-ci.yml')
end
end
def rugged_config
Gitlab::GitalyClient::StorageSettings.allow_disk_access do
project.repository.rugged.config
Loading
Loading
Loading
Loading
@@ -269,7 +269,7 @@ describe ProjectPolicy do
context 'abilities for non-public projects' do
let(:project) { create(:project, namespace: owner.namespace) }
let(:reporter_public_build_permissions) do
reporter_permissions - [:read_build, :read_pipeline]
reporter_permissions - [:read_build, :read_pipeline, :read_commit_status]
end
 
it do
Loading
Loading
@@ -288,7 +288,7 @@ describe ProjectPolicy do
context 'public builds enabled' do
it do
expect_allowed(*guest_permissions)
expect_allowed(:read_build, :read_pipeline)
expect_allowed(:read_build, :read_pipeline, :read_commit_status)
end
end
 
Loading
Loading
@@ -299,7 +299,7 @@ describe ProjectPolicy do
 
it do
expect_allowed(*guest_permissions)
expect_disallowed(:read_build, :read_pipeline)
expect_disallowed(:read_build, :read_pipeline, :read_commit_status)
end
end
 
Loading
Loading
Loading
Loading
@@ -104,13 +104,25 @@ describe API::CommitStatuses do
end
end
 
context "guest user" do
context 'guest user' do
before do
get api(get_url, guest)
end
 
it "does not return project commits" do
expect(response).to have_gitlab_http_status(403)
context 'when project has public builds enabled' do
let(:project) { create(:project, :repository, public_builds: true) }
it 'does not return project commits' do
expect(response).to have_gitlab_http_status(200)
end
end
context 'when project has public builds disabled' do
let(:project) { create(:project, :repository, public_builds: false) }
it 'does not return project commits' do
expect(response).to have_gitlab_http_status(403)
end
end
end
 
Loading
Loading
Loading
Loading
@@ -716,6 +716,15 @@ describe API::Runners do
 
expect(response).to have_gitlab_http_status(400)
end
it 'filters runners by tag' do
runner = create(:ci_runner, :project, projects: [project], tag_list: %w(tag1 tag2))
get api("/projects/#{project.id}/runners", user), tag_list: ['tag1']
expect(json_response.count).to eq 1
expect(json_response[0]['id']).to eq runner.id
end
end
 
context 'authorized user without maintainer privileges' do
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment