Commit 6776fac6 authored by Kamil Trzciński's avatar Kamil Trzciński
Browse files

Respect permissions when showing Failed Jobs

parent 927a9b13
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -87,7 +87,7 @@ def builds
  end

  def failures
    if @pipeline.statuses.latest.failed.present?
    if @pipeline.failed_builds.present?
      render_show
    else
      redirect_to pipeline_path(@pipeline)
+10 −0
Original line number Diff line number Diff line
module Ci
  class PipelinePresenter < Gitlab::View::Presenter::Delegated
    include Gitlab::Utils::StrongMemoize

    FAILURE_REASONS = {
      config_error: 'CI/CD YAML configuration error!'
    }.freeze

    presents :pipeline

    def failed_builds
      return [] unless can?(current_user, :read_build, pipeline)

      strong_memoize(:failed_builds) do
        pipeline.builds.latest.failed
      end
    end

    def failure_reason
      return unless pipeline.failure_reason?

+5 −6
Original line number Diff line number Diff line
- failed_builds = @pipeline.statuses.latest.failed

.tabs-holder
  %ul.pipelines-tabs.nav-links.no-top.no-bottom.mobile-separator
    %li.js-pipeline-tab-link
@@ -9,11 +7,11 @@
      = link_to builds_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-builds', action: 'builds', toggle: 'tab' }, class: 'builds-tab' do
        = _("Jobs")
        %span.badge.js-builds-counter= pipeline.total_size
    - if failed_builds.present?
    - if @pipeline.failed_builds.present?
      %li.js-failures-tab-link
        = link_to failures_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-failures', action: 'failures', toggle: 'tab' }, class: 'failures-tab' do
          = _("Failed Jobs")
          %span.badge.js-failures-counter= failed_builds.count
          %span.badge.js-failures-counter= @pipeline.failed_builds.count

.tab-content
  #js-tab-pipeline.tab-pane
@@ -43,9 +41,10 @@
            %th Coverage
            %th
        = render partial: "projects/stage/stage", collection: pipeline.legacy_stages, as: :stage
  - if failed_builds.present?

  - if @pipeline.failed_builds.present?
    #js-tab-failures.build-failures.tab-pane
      - failed_builds.each_with_index do |build, index|
      - @pipeline.failed_builds.each_with_index do |build, index|
        .build-state
          %span.ci-status-icon-failed= custom_icon('icon_status_failed')
          %span.stage
+44 −5
Original line number Diff line number Diff line
@@ -3,10 +3,11 @@
describe 'Pipeline', :js do
  let(:project) { create(:project) }
  let(:user) { create(:user) }
  let(:role) { :developer }

  before do
    sign_in(user)
    project.add_developer(user)
    project.add_role(user, role)
  end

  shared_context 'pipeline builds' do
@@ -153,9 +154,10 @@
    end

    context 'page tabs' do
      it 'shows Pipeline and Jobs tabs with link' do
      it 'shows Pipeline, Jobs and Failed Jobs tabs with link' do
        expect(page).to have_link('Pipeline')
        expect(page).to have_link('Jobs')
        expect(page).to have_link('Failed Jobs')
      end

      it 'shows counter in Jobs tab' do
@@ -165,6 +167,16 @@
      it 'shows Pipeline tab as active' do
        expect(page).to have_css('.js-pipeline-tab-link.active')
      end

      context 'without permission to access builds' do
        let(:project) { create(:project, :public, :repository, public_builds: false) }
        let(:role) { :guest }

        it 'does not show failed jobs tab pane' do
          expect(page).to have_link('Pipeline')
          expect(page).not_to have_content('Failed Jobs')
        end
      end
    end

    context 'retrying jobs' do
@@ -308,8 +320,7 @@
  end

  describe 'GET /:project/pipelines/:id/failures' do
    let(:project) { create(:project, :repository) }
    let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: project.commit.id) }
    let(:pipeline) { create(:ci_pipeline, project: project, ref: 'master', sha: '1234') }
    let(:pipeline_failures_page) { failures_project_pipeline_path(project, pipeline) }
    let!(:failed_build) { create(:ci_build, :failed, pipeline: pipeline) }

@@ -340,11 +351,39 @@
        visit pipeline_failures_page
      end

      it 'includes failed jobs' do
      it 'shows jobs tab pane as active' do
        expect(page).to have_content('Failed Jobs')
        expect(page).to have_css('#js-tab-failures.active')
      end

      it 'lists failed builds' do
        expect(page).to have_content(failed_build.name)
        expect(page).to have_content(failed_build.stage)
      end

      it 'does not show trace' do
        expect(page).to have_content('No job trace')
      end
    end

    context 'without permission to access builds' do
      let(:role) { :guest }

      before do
        project.update(public_builds: false)
      end

      context 'when accessing failed jobs page' do
        before do
          visit pipeline_failures_page
        end

        it 'fails to access the page' do
          expect(page).to have_content('Access Denied')
        end
      end
    end

    context 'without failures' do
      before do
        failed_build.update!(status: :success)