Commit 81628d41 authored by James Fargher's avatar James Fargher

Merge branch '267521-add-blobPath-to-vulnerabilitylocation' into 'master'

Add `blobPath` field to `VulnerabilityLocation` types where `file` field is present in GraphQL

See merge request gitlab-org/gitlab!52599
parents 158e768a 461622a2
......@@ -28014,6 +28014,11 @@ type VulnerabilityLocationContainerScanning {
Represents the location of a vulnerability found by a Coverage Fuzzing scan
"""
type VulnerabilityLocationCoverageFuzzing {
"""
Blob path to the vulnerable file
"""
blobPath: String
"""
Number of the last relevant line in the vulnerable file
"""
......@@ -28069,6 +28074,11 @@ type VulnerabilityLocationDast {
Represents the location of a vulnerability found by a dependency security scan
"""
type VulnerabilityLocationDependencyScanning {
"""
Blob path to the vulnerable file
"""
blobPath: String
"""
Dependency containing the vulnerability
"""
......@@ -28084,6 +28094,11 @@ type VulnerabilityLocationDependencyScanning {
Represents the location of a vulnerability found by a SAST scan
"""
type VulnerabilityLocationSast {
"""
Blob path to the vulnerable file
"""
blobPath: String
"""
Number of the last relevant line in the vulnerable file
"""
......@@ -28114,6 +28129,11 @@ type VulnerabilityLocationSast {
Represents the location of a vulnerability found by a secret detection scan
"""
type VulnerabilityLocationSecretDetection {
"""
Blob path to the vulnerable file
"""
blobPath: String
"""
Number of the last relevant line in the vulnerable file
"""
......
......@@ -81316,6 +81316,20 @@
"name": "VulnerabilityLocationCoverageFuzzing",
"description": "Represents the location of a vulnerability found by a Coverage Fuzzing scan",
"fields": [
{
"name": "blobPath",
"description": "Blob path to the vulnerable file",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "endLine",
"description": "Number of the last relevant line in the vulnerable file",
......@@ -81468,6 +81482,20 @@
"name": "VulnerabilityLocationDependencyScanning",
"description": "Represents the location of a vulnerability found by a dependency security scan",
"fields": [
{
"name": "blobPath",
"description": "Blob path to the vulnerable file",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "dependency",
"description": "Dependency containing the vulnerability",
......@@ -81509,6 +81537,20 @@
"name": "VulnerabilityLocationSast",
"description": "Represents the location of a vulnerability found by a SAST scan",
"fields": [
{
"name": "blobPath",
"description": "Blob path to the vulnerable file",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "endLine",
"description": "Number of the last relevant line in the vulnerable file",
......@@ -81592,6 +81634,20 @@
"name": "VulnerabilityLocationSecretDetection",
"description": "Represents the location of a vulnerability found by a secret detection scan",
"fields": [
{
"name": "blobPath",
"description": "Blob path to the vulnerable file",
"args": [
],
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "endLine",
"description": "Number of the last relevant line in the vulnerable file",
......@@ -4266,6 +4266,7 @@ Represents the location of a vulnerability found by a Coverage Fuzzing scan.
| Field | Type | Description |
| ----- | ---- | ----------- |
| `blobPath` | String | Blob path to the vulnerable file |
| `endLine` | String | Number of the last relevant line in the vulnerable file |
| `file` | String | Path to the vulnerable file |
| `startLine` | String | Number of the first relevant line in the vulnerable file |
......@@ -4289,6 +4290,7 @@ Represents the location of a vulnerability found by a dependency security scan.
| Field | Type | Description |
| ----- | ---- | ----------- |
| `blobPath` | String | Blob path to the vulnerable file |
| `dependency` | VulnerableDependency | Dependency containing the vulnerability |
| `file` | String | Path to the vulnerable file |
......@@ -4298,6 +4300,7 @@ Represents the location of a vulnerability found by a SAST scan.
| Field | Type | Description |
| ----- | ---- | ----------- |
| `blobPath` | String | Blob path to the vulnerable file |
| `endLine` | String | Number of the last relevant line in the vulnerable file |
| `file` | String | Path to the vulnerable file |
| `startLine` | String | Number of the first relevant line in the vulnerable file |
......@@ -4310,6 +4313,7 @@ Represents the location of a vulnerability found by a secret detection scan.
| Field | Type | Description |
| ----- | ---- | ----------- |
| `blobPath` | String | Blob path to the vulnerable file |
| `endLine` | String | Number of the last relevant line in the vulnerable file |
| `file` | String | Path to the vulnerable file |
| `startLine` | String | Number of the first relevant line in the vulnerable file |
......
......@@ -23,6 +23,9 @@ module Types
field :start_line, GraphQL::STRING_TYPE, null: true,
description: 'Number of the first relevant line in the vulnerable file'
field :blob_path, GraphQL::STRING_TYPE, null: true,
description: 'Blob path to the vulnerable file'
end
end
end
......@@ -12,6 +12,9 @@ module Types
field :file, GraphQL::STRING_TYPE, null: true,
description: 'Path to the vulnerable file'
field :blob_path, GraphQL::STRING_TYPE, null: true,
description: 'Blob path to the vulnerable file'
end
end
end
......@@ -23,6 +23,9 @@ module Types
field :start_line, GraphQL::STRING_TYPE, null: true,
description: 'Number of the first relevant line in the vulnerable file'
field :blob_path, GraphQL::STRING_TYPE, null: true,
description: 'Blob path to the vulnerable file'
end
end
end
......@@ -23,6 +23,9 @@ module Types
field :start_line, GraphQL::STRING_TYPE, null: true,
description: 'Number of the first relevant line in the vulnerable file'
field :blob_path, GraphQL::STRING_TYPE, null: true,
description: 'Blob path to the vulnerable file'
end
end
end
......@@ -115,7 +115,8 @@ module Types
end
def location
object.finding&.location&.merge(report_type: object.report_type)
object_location = object.finding&.location
object_location&.merge(blob_path: object.blob_path, report_type: object.report_type)&.compact
end
def scanner
......
......@@ -64,14 +64,7 @@ module VulnerabilitiesHelper
def vulnerability_finding_data(vulnerability)
data = Vulnerabilities::FindingSerializer.new(current_user: current_user).represent(vulnerability.finding, only: FINDING_FIELDS)
if data[:location]['file']
branch = vulnerability.finding.pipelines&.last&.sha || vulnerability.project.default_branch
path = project_blob_path(vulnerability.project, tree_join(branch, data[:location]['file']))
data[:location]['blob_path'] = path
end
data[:location].merge!('blob_path' => vulnerability.blob_path).compact!
data
end
end
......@@ -127,6 +127,8 @@ module EE
:cve_value, :cwe_value, :other_identifier_values,
to: :finding, allow_nil: true
delegate :file, to: :finding, prefix: true, private: true
def to_reference(from = nil, full: false)
project
.to_reference_base(from, full: full)
......@@ -161,6 +163,12 @@ module EE
::Vulnerabilities::StatDiff.new(self)
end
def blob_path
return unless finding_file
::Gitlab::Routing.url_helpers.project_blob_path(project, File.join(finding.pipeline_branch, finding_file))
end
private
def user_notes_count_service
......
......@@ -372,6 +372,10 @@ module Vulnerabilities
Gitlab::UUID.v5?(uuid) ? uuid : Gitlab::UUID.v5(uuid_v5_name)
end
def pipeline_branch
pipelines&.last&.sha || project.default_branch
end
protected
def first_fingerprint
......
......@@ -34,7 +34,7 @@ class VulnerabilityPresenter < Gitlab::View::Presenter::Delegated
def blob_path
return unless file
path_with_line_number(project_blob_path(vulnerability.project, File.join(pipeline_branch, file)))
path_with_line_number(vulnerability.blob_path)
end
def scanner
......
---
title: Add blobPath field to VulnerabilityLocation types in GraphQL
merge_request: 52599
author:
type: added
......@@ -42,7 +42,7 @@ RSpec.describe Projects::Security::VulnerabilitiesController do
end
context "when there's no attached pipeline" do
let_it_be(:finding) { create(:vulnerabilities_finding, vulnerability: vulnerability) }
let_it_be(:finding) { create(:vulnerabilities_finding, vulnerability: vulnerability, project: vulnerability.project ) }
it 'renders the vulnerability page' do
show_vulnerability
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe GitlabSchema.types['VulnerabilityLocationCoverageFuzzing'] do
it do
expect(described_class).to have_graphql_fields(
:vulnerable_class,
:end_line,
:file,
:vulnerable_method,
:start_line,
:blob_path
)
end
end
......@@ -3,5 +3,5 @@
require 'spec_helper'
RSpec.describe GitlabSchema.types['VulnerabilityLocationDependencyScanning'] do
it { expect(described_class).to have_graphql_fields(:dependency, :file) }
it { expect(described_class).to have_graphql_fields(:dependency, :file, :blob_path) }
end
......@@ -9,7 +9,8 @@ RSpec.describe GitlabSchema.types['VulnerabilityLocationSast'] do
:file,
:start_line,
:vulnerable_class,
:vulnerable_method
:vulnerable_method,
:blob_path
)
end
end
......@@ -9,7 +9,8 @@ RSpec.describe GitlabSchema.types['VulnerabilityLocationSecretDetection'] do
:file,
:start_line,
:vulnerable_class,
:vulnerable_method
:vulnerable_method,
:blob_path
)
end
end
......@@ -763,4 +763,18 @@ RSpec.describe Vulnerability do
it { is_expected.to be_an_instance_of(Vulnerabilities::StatDiff) }
end
describe '#blob_path' do
let_it_be(:vulnerability) { create(:vulnerability) }
let_it_be(:pipeline) { create(:ci_pipeline) }
let_it_be(:finding) { create(:vulnerabilities_finding, pipelines: [pipeline], vulnerability: vulnerability) }
subject { vulnerability.blob_path }
it 'returns project blob path' do
expect(subject).to eq(
"/#{vulnerability.project.namespace.path}/#{vulnerability.project.name}/-/blob/#{pipeline.sha}/#{vulnerability.finding.file}"
)
end
end
end
......@@ -32,6 +32,7 @@ RSpec.describe 'Query.vulnerabilities.location' do
name
}
}
blobPath
}
... on VulnerabilityLocationDast {
hostname
......@@ -45,6 +46,7 @@ RSpec.describe 'Query.vulnerabilities.location' do
startLine
vulnerableClass
vulnerableMethod
blobPath
}
... on VulnerabilityLocationSecretDetection {
endLine
......@@ -52,6 +54,7 @@ RSpec.describe 'Query.vulnerabilities.location' do
startLine
vulnerableClass
vulnerableMethod
blobPath
}
}
QUERY
......@@ -112,6 +115,8 @@ RSpec.describe 'Query.vulnerabilities.location' do
create(:vulnerability, project: project, report_type: :dependency_scanning)
end
let_it_be(:pipeline) { create(:ci_pipeline, :success, project: project) }
let_it_be(:metadata) do
{
location: {
......@@ -130,7 +135,8 @@ RSpec.describe 'Query.vulnerabilities.location' do
create(
:vulnerabilities_finding,
vulnerability: vulnerability,
raw_metadata: metadata.to_json
raw_metadata: metadata.to_json,
pipelines: [pipeline]
)
end
......@@ -149,6 +155,8 @@ RSpec.describe 'Query.vulnerabilities.location' do
create(:vulnerability, project: project, report_type: :sast)
end
let_it_be(:pipeline) { create(:ci_pipeline, :success, project: project) }
let_it_be(:metadata) do
{
location: {
......@@ -156,7 +164,8 @@ RSpec.describe 'Query.vulnerabilities.location' do
method: 'vulnerable_method',
file: 'vulnerable_file',
start_line: '420',
end_line: '666'
end_line: '666',
blob_path: 'blob/vulnerable_file'
}
}
end
......@@ -165,7 +174,8 @@ RSpec.describe 'Query.vulnerabilities.location' do
create(
:vulnerabilities_finding,
vulnerability: vulnerability,
raw_metadata: metadata.to_json
raw_metadata: metadata.to_json,
pipelines: [pipeline]
)
end
......@@ -186,6 +196,8 @@ RSpec.describe 'Query.vulnerabilities.location' do
create(:vulnerability, project: project, report_type: :secret_detection)
end
let_it_be(:pipeline) { create(:ci_pipeline, :success, project: project) }
let_it_be(:metadata) do
{
location: {
......@@ -202,7 +214,8 @@ RSpec.describe 'Query.vulnerabilities.location' do
create(
:vulnerabilities_finding,
vulnerability: vulnerability,
raw_metadata: metadata.to_json
raw_metadata: metadata.to_json,
pipelines: [pipeline]
)
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment