From dd364518278e796e4e34e83a9d91fbdfbe10accc Mon Sep 17 00:00:00 2001 From: samdbeckham Date: Mon, 25 Nov 2019 19:44:42 +0000 Subject: [PATCH 1/6] Creates a standalone vulnerability page - Adds in the standalone vulnerabilty page - Moves the project security dashboard page to the index - Renders a 404 on the vulnerability page if the `first_class_vulnerabilities` feature flag is not present. - Updates all the path helpers and related tests - Adds tests for the new route --- .../36739-standalone-vulnerability-page.yml | 5 ++ .../security/dashboard/{show => }/index.js | 0 .../projects/security/dashboard_controller.rb | 13 ++++- ee/app/presenters/ee/project_presenter.rb | 2 +- .../sidebar/_project_security_link.html.haml | 4 +- .../security/dashboard/index.html.haml | 4 ++ .../security/dashboard/list.html.haml | 9 ++++ .../security/dashboard/show.html.haml | 53 +++++++++++++++++-- ee/config/routes/project.rb | 2 +- .../security/dashboard_controller_spec.rb | 49 ++++++++++++++--- ee/spec/presenters/project_presenter_spec.rb | 6 +-- .../nav/sidebar/_project.html.haml_spec.rb | 14 ++--- 12 files changed, 136 insertions(+), 25 deletions(-) create mode 100644 changelogs/unreleased/36739-standalone-vulnerability-page.yml rename ee/app/assets/javascripts/pages/projects/security/dashboard/{show => }/index.js (100%) create mode 100644 ee/app/views/projects/security/dashboard/index.html.haml create mode 100644 ee/app/views/projects/security/dashboard/list.html.haml diff --git a/changelogs/unreleased/36739-standalone-vulnerability-page.yml b/changelogs/unreleased/36739-standalone-vulnerability-page.yml new file mode 100644 index 00000000000000..d64fe1197fa041 --- /dev/null +++ b/changelogs/unreleased/36739-standalone-vulnerability-page.yml @@ -0,0 +1,5 @@ +--- +title: Creates a dummy standalone vulnerability page +merge_request: 20734 +author: +type: other diff --git a/ee/app/assets/javascripts/pages/projects/security/dashboard/show/index.js b/ee/app/assets/javascripts/pages/projects/security/dashboard/index.js similarity index 100% rename from ee/app/assets/javascripts/pages/projects/security/dashboard/show/index.js rename to ee/app/assets/javascripts/pages/projects/security/dashboard/index.js diff --git a/ee/app/controllers/projects/security/dashboard_controller.rb b/ee/app/controllers/projects/security/dashboard_controller.rb index 65ec2f11776a55..38aac78c47aa65 100644 --- a/ee/app/controllers/projects/security/dashboard_controller.rb +++ b/ee/app/controllers/projects/security/dashboard_controller.rb @@ -7,10 +7,21 @@ class DashboardController < Projects::ApplicationController alias_method :vulnerable, :project - def show + before_action only: [:index] do + push_frontend_feature_flag(:hide_dismissed_vulnerabilities) + end + + def index @pipeline = @project.latest_pipeline_with_security_reports &.present(current_user: current_user) end + + def show + return render_404 unless Feature.enabled?(:first_class_vulnerabilities, project) + + @vulnerability = Vulnerability.find(params[:id]) + @pipeline = @vulnerability.finding.pipelines.first + end end end end diff --git a/ee/app/presenters/ee/project_presenter.rb b/ee/app/presenters/ee/project_presenter.rb index 98bd9397eeb44f..2cc3f2efc57a2f 100644 --- a/ee/app/presenters/ee/project_presenter.rb +++ b/ee/app/presenters/ee/project_presenter.rb @@ -28,7 +28,7 @@ def approver_groups def security_dashboard_data OpenStruct.new(is_link: false, label: statistic_icon('lock') + _('Security Dashboard'), - link: project_security_dashboard_path(project), + link: project_security_dashboard_index_path(project), class_modifier: 'default') end end diff --git a/ee/app/views/layouts/nav/sidebar/_project_security_link.html.haml b/ee/app/views/layouts/nav/sidebar/_project_security_link.html.haml index 9c3833100b1db8..4749d1a9025809 100644 --- a/ee/app/views/layouts/nav/sidebar/_project_security_link.html.haml +++ b/ee/app/views/layouts/nav/sidebar/_project_security_link.html.haml @@ -1,6 +1,6 @@ - return unless any_project_nav_tab?([:security, :dependencies, :licenses]) -- top_level_link = project_nav_tab?(:security) ? project_security_dashboard_path(@project) : project_dependencies_path(@project) +- top_level_link = project_nav_tab?(:security) ? project_security_dashboard_index_path(@project) : project_dependencies_path(@project) - top_level_qa_selector = project_nav_tab?(:security) ? 'security_dashboard_link' : 'dependency_list_link' = nav_link(path: sidebar_security_paths) do @@ -20,7 +20,7 @@ - if project_nav_tab?(:security) = nav_link(path: 'projects/security/dashboard#show') do - = link_to project_security_dashboard_path(@project), title: _('Security Dashboard') do + = link_to project_security_dashboard_index_path(@project), title: _('Security Dashboard') do %span= _('Security Dashboard') - if project_nav_tab?(:dependencies) diff --git a/ee/app/views/projects/security/dashboard/index.html.haml b/ee/app/views/projects/security/dashboard/index.html.haml new file mode 100644 index 00000000000000..3154cbfb060e04 --- /dev/null +++ b/ee/app/views/projects/security/dashboard/index.html.haml @@ -0,0 +1,4 @@ +- breadcrumb_title _("Security Dashboard") +- page_title _("Security Dashboard") + +#js-security-report-app{ data: project_security_dashboard_config(@project, @pipeline) } diff --git a/ee/app/views/projects/security/dashboard/list.html.haml b/ee/app/views/projects/security/dashboard/list.html.haml new file mode 100644 index 00000000000000..5c82dde253e03f --- /dev/null +++ b/ee/app/views/projects/security/dashboard/list.html.haml @@ -0,0 +1,9 @@ +- @content_class = "limit-container-width" unless fluid_layout +-# - add_to_breadcrumbs _("Security Dashboard"), project_security_dashboard_index_path(@project) +- breadcrumb_title "Vulnerability list" +- page_title "Vulnerability list" + +.issue-details.issuable-details + .detail-page-description.content-block + %h2.title= Vulnerability List + diff --git a/ee/app/views/projects/security/dashboard/show.html.haml b/ee/app/views/projects/security/dashboard/show.html.haml index 3154cbfb060e04..c1ff24e217f05d 100644 --- a/ee/app/views/projects/security/dashboard/show.html.haml +++ b/ee/app/views/projects/security/dashboard/show.html.haml @@ -1,4 +1,51 @@ -- breadcrumb_title _("Security Dashboard") -- page_title _("Security Dashboard") +- @content_class = "limit-container-width" unless fluid_layout +- add_to_breadcrumbs _("Security Dashboard"), project_security_dashboard_index_path(@project) +- breadcrumb_title @vulnerability.id +- page_title @vulnerability.title +- page_description @vulnerability.description -#js-security-report-app{ data: project_security_dashboard_config(@project, @pipeline) } +.detail-page-header + .detail-page-header-body + .issuable-status-box.status-box.status-box-open{ class: 'closed' } + %span= @vulnerability.state + -if @pipeline + %span + ="Detected" + = time_ago_with_tooltip(@pipeline.created_at) + ="in pipeline" + %a{:href=>pipeline_url(@pipeline)}= @pipeline.id + - else + %span + = time_ago_with_tooltip(@vulnerability.created_at) + +.issue-details.issuable-details + .detail-page-description.content-block + %h2.title= @vulnerability.title + .description + .md + %h3= "Description" + %p= @vulnerability.finding.description + %ul + %li= "Severity: #{@vulnerability.severity}" + %li= "Confidence: #{@vulnerability.confidence}" + %li= "Report Type: #{@vulnerability.report_type}" + + - if @vulnerability.finding.location["image"] + %li= "Image: #{@vulnerability.finding.location['image']}" + + - if @vulnerability.finding.location["operating_system"] + %li= "Namespace: #{@vulnerability.finding.location['operating_system']}" + + - if @vulnerability.finding.links.any? + %h3= "Links" + %ul + - @vulnerability.finding.links.each do |link| + %li + %a{:href=>link["url"], target: "_blank", rel: 'noopener noreferrer'}= link["url"] + + - if @vulnerability.finding.identifiers.any? + %h3= "Identifiers" + %ul + - @vulnerability.finding.identifiers.each do |identifier| + %li + %a{:href=>identifier.url, target: "_blank", rel: 'noopener noreferrer'}= identifier.name diff --git a/ee/config/routes/project.rb b/ee/config/routes/project.rb index 720432cbb38d4d..210c85f3218498 100644 --- a/ee/config/routes/project.rb +++ b/ee/config/routes/project.rb @@ -167,7 +167,7 @@ end namespace :security do - resource :dashboard, only: [:show], controller: :dashboard + resources :dashboard, only: [:show, :index, :list], controller: :dashboard resource :configuration, only: [:show], controller: :configuration resources :vulnerability_findings, only: [:index] do diff --git a/ee/spec/controllers/projects/security/dashboard_controller_spec.rb b/ee/spec/controllers/projects/security/dashboard_controller_spec.rb index a173e502c00c5d..7e057f1def7e2f 100644 --- a/ee/spec/controllers/projects/security/dashboard_controller_spec.rb +++ b/ee/spec/controllers/projects/security/dashboard_controller_spec.rb @@ -11,23 +11,24 @@ let(:vulnerable) { project } let(:security_dashboard_action) do - get :show, params: { namespace_id: project.namespace, project_id: project } + get :index, params: { namespace_id: project.namespace, project_id: project } end end before do group.add_developer(user) + project.add_developer(user) + stub_licensed_features(security_dashboard: true) end - describe 'GET #show' do + describe 'GET #index' do let(:pipeline) { create(:ci_pipeline, sha: project.commit.id, project: project, user: user) } render_views def show_security_dashboard(current_user = user) - stub_licensed_features(security_dashboard: true) sign_in(current_user) - get :show, params: { namespace_id: project.namespace, project_id: project } + get :index, params: { namespace_id: project.namespace, project_id: project } end context 'when uses legacy reports syntax' do @@ -39,7 +40,7 @@ def show_security_dashboard(current_user = user) show_security_dashboard expect(response).to have_gitlab_http_status(200) - expect(response).to render_template(:show) + expect(response).to render_template(:index) expect(response.body).to have_css("div#js-security-report-app[data-has-pipeline-data=true]") end end @@ -53,7 +54,7 @@ def show_security_dashboard(current_user = user) show_security_dashboard expect(response).to have_gitlab_http_status(200) - expect(response).to render_template(:show) + expect(response).to render_template(:index) expect(response.body).to have_css("div#js-security-report-app[data-has-pipeline-data=true]") end end @@ -63,9 +64,43 @@ def show_security_dashboard(current_user = user) show_security_dashboard expect(response).to have_gitlab_http_status(200) - expect(response).to render_template(:show) + expect(response).to render_template(:index) expect(response.body).to have_css("div#js-security-report-app[data-has-pipeline-data=false]") end end end + + describe 'GET #show' do + let_it_be(:vulnerability) { create(:vulnerability, project: project) } + let_it_be(:finding) { create(:vulnerabilities_occurrence, vulnerability: vulnerability) } + + render_views + + def show_vulnerability(current_user = user) + sign_in(current_user) + get :show, params: { namespace_id: project.namespace, project_id: project, id: vulnerability.id } + end + + context 'when the feature flag is enabled' do + it 'renders the vulnerability page' do + show_vulnerability + + expect(response).to have_gitlab_http_status(200) + expect(response).to render_template(:show) + expect(response.body).to have_text(vulnerability.title) + end + end + + context 'when the feature flag is disabled' do + before do + stub_feature_flags(first_class_vulnerabilities: false) + end + + it 'renders the 404 page' do + show_vulnerability + + expect(response).to have_gitlab_http_status(404) + end + end + end end diff --git a/ee/spec/presenters/project_presenter_spec.rb b/ee/spec/presenters/project_presenter_spec.rb index 77cdc3fbaa8e96..8faaa929ccda3b 100644 --- a/ee/spec/presenters/project_presenter_spec.rb +++ b/ee/spec/presenters/project_presenter_spec.rb @@ -15,7 +15,7 @@ let(:security_dashboard_data) do OpenStruct.new(is_link: false, label: a_string_including('Security Dashboard'), - link: project_security_dashboard_path(project), + link: project_security_dashboard_index_path(project), class_modifier: 'default') end @@ -25,7 +25,7 @@ end it 'has security dashboard link' do - expect(presenter.extra_statistics_buttons.find { |button| button[:link] == project_security_dashboard_path(project) }).not_to be_nil + expect(presenter.extra_statistics_buttons.find { |button| button[:link] == project_security_dashboard_index_path(project) }).not_to be_nil end end @@ -35,7 +35,7 @@ end it 'has no security dashboard link' do - expect(presenter.extra_statistics_buttons.find { |button| button[:link] == project_security_dashboard_path(project) }).to be_nil + expect(presenter.extra_statistics_buttons.find { |button| button[:link] == project_security_dashboard_index_path(project) }).to be_nil end end end diff --git a/ee/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb b/ee/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb index 9910c74ca4a441..4e7c893f4e0a02 100644 --- a/ee/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb +++ b/ee/spec/views/layouts/nav/sidebar/_project.html.haml_spec.rb @@ -141,11 +141,11 @@ let(:can_read_dependencies) { true } it 'top level navigation link is visible' do - expect(rendered).to have_link('Security & Compliance', href: project_security_dashboard_path(project)) + expect(rendered).to have_link('Security & Compliance', href: project_security_dashboard_index_path(project)) end it 'security dashboard link is visible' do - expect(rendered).to have_link('Security Dashboard', href: project_security_dashboard_path(project)) + expect(rendered).to have_link('Security Dashboard', href: project_security_dashboard_index_path(project)) end it 'security configuration link is visible' do @@ -162,11 +162,11 @@ let(:can_read_dependencies) { false } it 'top level navigation link is visible' do - expect(rendered).to have_link('Security & Compliance', href: project_security_dashboard_path(project)) + expect(rendered).to have_link('Security & Compliance', href: project_security_dashboard_index_path(project)) end it 'security dashboard link is visible' do - expect(rendered).to have_link('Security Dashboard', href: project_security_dashboard_path(project)) + expect(rendered).to have_link('Security Dashboard', href: project_security_dashboard_index_path(project)) end it 'security configuration link is visible' do @@ -187,7 +187,7 @@ end it 'security dashboard link is not visible' do - expect(rendered).not_to have_link('Security Dashboard', href: project_security_dashboard_path(project)) + expect(rendered).not_to have_link('Security Dashboard', href: project_security_dashboard_index_path(project)) end it 'security configuration link is not visible' do @@ -204,11 +204,11 @@ let(:can_read_dashboard) { false } it 'top level navigation link is visible' do - expect(rendered).not_to have_link('Security & Compliance', href: project_security_dashboard_path(project)) + expect(rendered).not_to have_link('Security & Compliance', href: project_security_dashboard_index_path(project)) end it 'security dashboard link is not visible' do - expect(rendered).not_to have_link('Security Dashboard', href: project_security_dashboard_path(project)) + expect(rendered).not_to have_link('Security Dashboard', href: project_security_dashboard_index_path(project)) end it 'security configuration link is not visible' do -- GitLab From d54f89da5e26591084b1e45b9ca5f9c5790c0e93 Mon Sep 17 00:00:00 2001 From: samdbeckham Date: Thu, 9 Jan 2020 10:49:56 +0000 Subject: [PATCH 2/6] Makes the vulnerability strings translateable --- .../security/dashboard/show.html.haml | 29 +++++++++---------- .../security/dashboard_controller_spec.rb | 1 - locale/gitlab.pot | 24 +++++++++++++++ 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/ee/app/views/projects/security/dashboard/show.html.haml b/ee/app/views/projects/security/dashboard/show.html.haml index c1ff24e217f05d..2e22e96cd9e414 100644 --- a/ee/app/views/projects/security/dashboard/show.html.haml +++ b/ee/app/views/projects/security/dashboard/show.html.haml @@ -6,14 +6,13 @@ .detail-page-header .detail-page-header-body - .issuable-status-box.status-box.status-box-open{ class: 'closed' } + .issuable-status-box.status-box.status-box-open.closed %span= @vulnerability.state - -if @pipeline + - if @pipeline %span - ="Detected" - = time_ago_with_tooltip(@pipeline.created_at) - ="in pipeline" - %a{:href=>pipeline_url(@pipeline)}= @pipeline.id + - timeago = time_ago_with_tooltip(@pipeline.created_at) + - pipeline_link = '%{id}'.html_safe % { url: pipeline_url(@pipeline), id: @pipeline.id } + = _('Detected %{timeago} in pipeline %{pipeline_link}').html_safe % { pipeline_link: pipeline_link, timeago: timeago } - else %span = time_ago_with_tooltip(@vulnerability.created_at) @@ -26,26 +25,26 @@ %h3= "Description" %p= @vulnerability.finding.description %ul - %li= "Severity: #{@vulnerability.severity}" - %li= "Confidence: #{@vulnerability.confidence}" - %li= "Report Type: #{@vulnerability.report_type}" + %li= _("Severity: %{severity}") % { severity: @vulnerability.severity } + %li= _("Confidence: %{confidence}") % { confidence: @vulnerability.confidence } + %li= _("Report Type: %{report_type}") % { report_type: @vulnerability.report_type } - if @vulnerability.finding.location["image"] - %li= "Image: #{@vulnerability.finding.location['image']}" + %li= _("Image: %{image}") % { image: @vulnerability.finding.location['image'] } - if @vulnerability.finding.location["operating_system"] - %li= "Namespace: #{@vulnerability.finding.location['operating_system']}" + %li= _("Namespace: %{namespace}") % { namespace: @vulnerability.finding.location['operating_system'] } - if @vulnerability.finding.links.any? - %h3= "Links" + %h3= _("Links") %ul - @vulnerability.finding.links.each do |link| %li - %a{:href=>link["url"], target: "_blank", rel: 'noopener noreferrer'}= link["url"] + %a{ :href=>link["url"], target: "_blank", rel: 'noopener noreferrer' }= link["url"] - if @vulnerability.finding.identifiers.any? - %h3= "Identifiers" + %h3= _("Identifiers") %ul - @vulnerability.finding.identifiers.each do |identifier| %li - %a{:href=>identifier.url, target: "_blank", rel: 'noopener noreferrer'}= identifier.name + %a{ :href=>identifier.url, target: "_blank", rel: 'noopener noreferrer' }= identifier.name diff --git a/ee/spec/controllers/projects/security/dashboard_controller_spec.rb b/ee/spec/controllers/projects/security/dashboard_controller_spec.rb index 7e057f1def7e2f..48a59d903126a2 100644 --- a/ee/spec/controllers/projects/security/dashboard_controller_spec.rb +++ b/ee/spec/controllers/projects/security/dashboard_controller_spec.rb @@ -17,7 +17,6 @@ before do group.add_developer(user) - project.add_developer(user) stub_licensed_features(security_dashboard: true) end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index c584defb2e4240..eebd657c76b925 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -4702,6 +4702,9 @@ msgstr "" msgid "Complete" msgstr "" +msgid "Confidence: %{confidence}" +msgstr "" + msgid "Confidential" msgstr "" @@ -6201,6 +6204,9 @@ msgstr "" msgid "Detect host keys" msgstr "" +msgid "Detected %{timeago} in pipeline %{pipeline_link}" +msgstr "" + msgid "DevOps Score" msgstr "" @@ -9604,6 +9610,9 @@ msgstr "" msgid "Identifier" msgstr "" +msgid "Identifiers" +msgstr "" + msgid "Identities" msgstr "" @@ -9655,6 +9664,9 @@ msgstr "" msgid "Iglu registry URL (optional)" msgstr "" +msgid "Image: %{image}" +msgstr "" + msgid "ImageDiffViewer|2-up" msgstr "" @@ -10827,6 +10839,9 @@ msgstr "" msgid "LinkedPipelines|%{counterLabel} more downstream pipelines" msgstr "" +msgid "Links" +msgstr "" + msgid "List" msgstr "" @@ -11783,6 +11798,9 @@ msgstr "" msgid "Name:" msgstr "" +msgid "Namespace: %{namespace}" +msgstr "" + msgid "Namespaces to index" msgstr "" @@ -15238,6 +15256,9 @@ msgstr "" msgid "Repo by URL" msgstr "" +msgid "Report Type: %{report_type}" +msgstr "" + msgid "Report abuse to admin" msgstr "" @@ -16556,6 +16577,9 @@ msgstr "" msgid "Settings" msgstr "" +msgid "Severity: %{severity}" +msgstr "" + msgid "Share" msgstr "" -- GitLab From 992891a19252103932c925eea63accb683e4194d Mon Sep 17 00:00:00 2001 From: samdbeckham Date: Thu, 9 Jan 2020 14:19:18 +0000 Subject: [PATCH 3/6] Updates the changelog entry --- changelogs/unreleased/36739-standalone-vulnerability-page.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelogs/unreleased/36739-standalone-vulnerability-page.yml b/changelogs/unreleased/36739-standalone-vulnerability-page.yml index d64fe1197fa041..8cb32673d3bfcc 100644 --- a/changelogs/unreleased/36739-standalone-vulnerability-page.yml +++ b/changelogs/unreleased/36739-standalone-vulnerability-page.yml @@ -1,5 +1,5 @@ --- -title: Creates a dummy standalone vulnerability page +title: Creates a standalone vulnerability page merge_request: 20734 author: type: other -- GitLab From bcbef97a9f9f23397fb9c91ae4277085d95e2cc6 Mon Sep 17 00:00:00 2001 From: samdbeckham Date: Fri, 10 Jan 2020 16:48:08 +0000 Subject: [PATCH 4/6] Adds changes from @nick.thomas review - Removes the redundant list route - Prevents vulnerabiltiies from being accessed outside their intended project --- ee/app/controllers/projects/security/dashboard_controller.rb | 2 +- ee/config/routes/project.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ee/app/controllers/projects/security/dashboard_controller.rb b/ee/app/controllers/projects/security/dashboard_controller.rb index 38aac78c47aa65..403f54cd7b5318 100644 --- a/ee/app/controllers/projects/security/dashboard_controller.rb +++ b/ee/app/controllers/projects/security/dashboard_controller.rb @@ -19,7 +19,7 @@ def index def show return render_404 unless Feature.enabled?(:first_class_vulnerabilities, project) - @vulnerability = Vulnerability.find(params[:id]) + @vulnerability = project.vulnerabilities.find(params[:id]) @pipeline = @vulnerability.finding.pipelines.first end end diff --git a/ee/config/routes/project.rb b/ee/config/routes/project.rb index 210c85f3218498..4dda9fd7dc9eef 100644 --- a/ee/config/routes/project.rb +++ b/ee/config/routes/project.rb @@ -167,7 +167,7 @@ end namespace :security do - resources :dashboard, only: [:show, :index, :list], controller: :dashboard + resources :dashboard, only: [:show, :index], controller: :dashboard resource :configuration, only: [:show], controller: :configuration resources :vulnerability_findings, only: [:index] do -- GitLab From 7aacd45a67ad3258d71090902f25a1df61edcfb1 Mon Sep 17 00:00:00 2001 From: samdbeckham Date: Thu, 16 Jan 2020 14:46:48 +0000 Subject: [PATCH 5/6] Adds an rspec test for missing pipelines --- .../security/dashboard/show.html.haml | 4 +-- .../security/dashboard_controller_spec.rb | 26 ++++++++++++++++--- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/ee/app/views/projects/security/dashboard/show.html.haml b/ee/app/views/projects/security/dashboard/show.html.haml index 2e22e96cd9e414..9108123724893f 100644 --- a/ee/app/views/projects/security/dashboard/show.html.haml +++ b/ee/app/views/projects/security/dashboard/show.html.haml @@ -9,12 +9,12 @@ .issuable-status-box.status-box.status-box-open.closed %span= @vulnerability.state - if @pipeline - %span + %span#js-pipeline-created - timeago = time_ago_with_tooltip(@pipeline.created_at) - pipeline_link = '%{id}'.html_safe % { url: pipeline_url(@pipeline), id: @pipeline.id } = _('Detected %{timeago} in pipeline %{pipeline_link}').html_safe % { pipeline_link: pipeline_link, timeago: timeago } - else - %span + %spa#js-vulnerability-created = time_ago_with_tooltip(@vulnerability.created_at) .issue-details.issuable-details diff --git a/ee/spec/controllers/projects/security/dashboard_controller_spec.rb b/ee/spec/controllers/projects/security/dashboard_controller_spec.rb index 48a59d903126a2..7573784517af5d 100644 --- a/ee/spec/controllers/projects/security/dashboard_controller_spec.rb +++ b/ee/spec/controllers/projects/security/dashboard_controller_spec.rb @@ -70,17 +70,19 @@ def show_security_dashboard(current_user = user) end describe 'GET #show' do + let_it_be(:pipeline) { create(:ci_pipeline, sha: project.commit.id, project: project, user: user) } let_it_be(:vulnerability) { create(:vulnerability, project: project) } - let_it_be(:finding) { create(:vulnerabilities_occurrence, vulnerability: vulnerability) } render_views - def show_vulnerability(current_user = user) - sign_in(current_user) + def show_vulnerability + sign_in(user) get :show, params: { namespace_id: project.namespace, project_id: project, id: vulnerability.id } end - context 'when the feature flag is enabled' do + context "when there's an attached pipeline" do + let_it_be(:finding) { create(:vulnerabilities_occurrence, vulnerability: vulnerability, pipelines: [pipeline]) } + it 'renders the vulnerability page' do show_vulnerability @@ -88,6 +90,22 @@ def show_vulnerability(current_user = user) expect(response).to render_template(:show) expect(response.body).to have_text(vulnerability.title) end + + it 'renders the time pipeline ran' do + show_vulnerability + + expect(response.body).to have_css("#js-pipeline-created") + end + end + + context "when there's no attached pipeline" do + let_it_be(:finding) { create(:vulnerabilities_occurrence, vulnerability: vulnerability) } + + it 'renders the time the vulnerability was created' do + show_vulnerability + + expect(response.body).to have_css("#js-vulnerability-created") + end end context 'when the feature flag is disabled' do -- GitLab From 6703577bddef6c52e33a1ad2fc7e7b25c0023592 Mon Sep 17 00:00:00 2001 From: samdbeckham Date: Mon, 20 Jan 2020 12:13:09 +0000 Subject: [PATCH 6/6] Hides inaccessible pipeles on vulnerabilities --- ee/app/controllers/projects/security/dashboard_controller.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ee/app/controllers/projects/security/dashboard_controller.rb b/ee/app/controllers/projects/security/dashboard_controller.rb index 403f54cd7b5318..5a2feb0f5e9a62 100644 --- a/ee/app/controllers/projects/security/dashboard_controller.rb +++ b/ee/app/controllers/projects/security/dashboard_controller.rb @@ -20,7 +20,8 @@ def show return render_404 unless Feature.enabled?(:first_class_vulnerabilities, project) @vulnerability = project.vulnerabilities.find(params[:id]) - @pipeline = @vulnerability.finding.pipelines.first + pipeline = @vulnerability.finding.pipelines.first + @pipeline = pipeline if Ability.allowed?(current_user, :read_pipeline, pipeline) end end end -- GitLab