summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancisco Javier López <fjlopez@gitlab.com>2018-10-02 17:56:59 +0200
committerFrancisco Javier López <fjlopez@gitlab.com>2018-10-02 21:09:44 +0200
commit0bd9277dfe285ef3c2c1b059cd747b2f88b2a4a6 (patch)
treed925027c89f94031a798211b9b2a933d5b36c073
parent6c30d9b4ede4152518fd3655e1862d54dfef6973 (diff)
downloadgitlab-ce-ce-fj-5426-web-ide-terminal.tar.gz
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.
-rw-r--r--app/controllers/projects/jobs_controller.rb40
-rw-r--r--app/models/ci/pipeline.rb17
-rw-r--r--app/models/project.rb4
-rw-r--r--app/policies/project_policy.rb5
-rw-r--r--app/serializers/build_serializer.rb2
-rw-r--r--doc/api/runners.md1
-rw-r--r--lib/api/runners.rb6
-rw-r--r--lib/gitlab/ci/yaml_processor.rb4
-rw-r--r--spec/lib/gitlab/ci/yaml_processor_spec.rb59
-rw-r--r--spec/models/ci/pipeline_spec.rb22
-rw-r--r--spec/models/project_spec.rb24
-rw-r--r--spec/policies/project_policy_spec.rb6
-rw-r--r--spec/requests/api/commit_statuses_spec.rb18
-rw-r--r--spec/requests/api/runners_spec.rb9
14 files changed, 167 insertions, 50 deletions
diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb
index 3f85e442be9..7ead8b402b3 100644
--- a/app/controllers/projects/jobs_controller.rb
+++ b/app/controllers/projects/jobs_controller.rb
@@ -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')
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index 6dac577c514..a1356bf0281 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -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? }
@@ -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,
@@ -65,7 +70,7 @@ module Ci
schedule: 4,
api: 5,
external: 6
- }
+ }.merge(source_enum_values)
enum_with_nil config_source: {
unknown_source: nil,
@@ -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
@@ -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)
diff --git a/app/models/project.rb b/app/models/project.rb
index 59f088156c7..27219d744eb 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -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
diff --git a/app/policies/project_policy.rb b/app/policies/project_policy.rb
index d0e84b1aa38..a2aba5aee2d 100644
--- a/app/policies/project_policy.rb
+++ b/app/policies/project_policy.rb
@@ -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
diff --git a/app/serializers/build_serializer.rb b/app/serializers/build_serializer.rb
index 0649fdad6a8..03eaf4eff9d 100644
--- a/app/serializers/build_serializer.rb
+++ b/app/serializers/build_serializer.rb
@@ -5,6 +5,6 @@ class BuildSerializer < BaseSerializer
def represent_status(resource)
data = represent(resource, { only: [:status] })
- data.fetch(:status, {})
+ data&.fetch(:status, {})
end
end
diff --git a/doc/api/runners.md b/doc/api/runners.md
index 0bcbd0aebf0..a1589481cbe 100644
--- a/doc/api/runners.md
+++ b/doc/api/runners.md
@@ -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"
diff --git a/lib/api/runners.rb b/lib/api/runners.rb
index 60868821810..f9d0592c942 100644
--- a/lib/api/runners.rb
+++ b/lib/api/runners.rb
@@ -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
@@ -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
diff --git a/lib/gitlab/ci/yaml_processor.rb b/lib/gitlab/ci/yaml_processor.rb
index 5d1864ae9e2..b3209dba970 100644
--- a/lib/gitlab/ci/yaml_processor.rb
+++ b/lib/gitlab/ci/yaml_processor.rb
@@ -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
diff --git a/spec/lib/gitlab/ci/yaml_processor_spec.rb b/spec/lib/gitlab/ci/yaml_processor_spec.rb
index a2d429fa859..502af4ebc23 100644
--- a/spec/lib/gitlab/ci/yaml_processor_spec.rb
+++ b/spec/lib/gitlab/ci/yaml_processor_spec.rb
@@ -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
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 4755702c0e9..06c53d4b78f 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -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
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index d15ba89efb5..8e1e02f4cb6 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -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
diff --git a/spec/policies/project_policy_spec.rb b/spec/policies/project_policy_spec.rb
index b7ec35d6ec5..8f10dd7704d 100644
--- a/spec/policies/project_policy_spec.rb
+++ b/spec/policies/project_policy_spec.rb
@@ -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
@@ -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
@@ -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
diff --git a/spec/requests/api/commit_statuses_spec.rb b/spec/requests/api/commit_statuses_spec.rb
index cd43bec35df..9d432851354 100644
--- a/spec/requests/api/commit_statuses_spec.rb
+++ b/spec/requests/api/commit_statuses_spec.rb
@@ -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
diff --git a/spec/requests/api/runners_spec.rb b/spec/requests/api/runners_spec.rb
index 49a79d2ccf9..37d08bfb301 100644
--- a/spec/requests/api/runners_spec.rb
+++ b/spec/requests/api/runners_spec.rb
@@ -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