diff options
author | Francisco Javier López <fjlopez@gitlab.com> | 2018-10-02 17:56:59 +0200 |
---|---|---|
committer | Francisco Javier López <fjlopez@gitlab.com> | 2018-10-02 21:09:44 +0200 |
commit | 0bd9277dfe285ef3c2c1b059cd747b2f88b2a4a6 (patch) | |
tree | d925027c89f94031a798211b9b2a933d5b36c073 | |
parent | 6c30d9b4ede4152518fd3655e1862d54dfef6973 (diff) | |
download | gitlab-ce-ce-fj-5426-web-ide-terminal.tar.gz |
Port from EEce-fj-5426-web-ide-terminal
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.rb | 40 | ||||
-rw-r--r-- | app/models/ci/pipeline.rb | 17 | ||||
-rw-r--r-- | app/models/project.rb | 4 | ||||
-rw-r--r-- | app/policies/project_policy.rb | 5 | ||||
-rw-r--r-- | app/serializers/build_serializer.rb | 2 | ||||
-rw-r--r-- | doc/api/runners.md | 1 | ||||
-rw-r--r-- | lib/api/runners.rb | 6 | ||||
-rw-r--r-- | lib/gitlab/ci/yaml_processor.rb | 4 | ||||
-rw-r--r-- | spec/lib/gitlab/ci/yaml_processor_spec.rb | 59 | ||||
-rw-r--r-- | spec/models/ci/pipeline_spec.rb | 22 | ||||
-rw-r--r-- | spec/models/project_spec.rb | 24 | ||||
-rw-r--r-- | spec/policies/project_policy_spec.rb | 6 | ||||
-rw-r--r-- | spec/requests/api/commit_statuses_spec.rb | 18 | ||||
-rw-r--r-- | spec/requests/api/runners_spec.rb | 9 |
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 |