Commit a5b06ddc authored by Mehmet Emin INAC's avatar Mehmet Emin INAC

Add issueLinks field to Vulnerability type

issueLinks field returns all the related issue links along with issues
for vulnerabilities.
parent 9a2d788d
...@@ -12210,6 +12210,31 @@ type Vulnerability { ...@@ -12210,6 +12210,31 @@ type Vulnerability {
""" """
id: ID! id: ID!
"""
List of issue links related to the vulnerability
"""
issueLinks(
"""
Returns the elements in the list that come after the specified cursor.
"""
after: String
"""
Returns the elements in the list that come before the specified cursor.
"""
before: String
"""
Returns the first _n_ elements from the list.
"""
first: Int
"""
Returns the last _n_ elements from the list.
"""
last: Int
): VulnerabilityIssueLinkConnection!
""" """
Location metadata for the vulnerability. Its fields depend on the type of security scan that found the vulnerability Location metadata for the vulnerability. Its fields depend on the type of security scan that found the vulnerability
""" """
...@@ -12291,6 +12316,69 @@ type VulnerabilityEdge { ...@@ -12291,6 +12316,69 @@ type VulnerabilityEdge {
node: Vulnerability node: Vulnerability
} }
"""
Represents an issue link of a vulnerability.
"""
type VulnerabilityIssueLink {
"""
GraphQL ID of the vulnerability
"""
id: ID!
"""
The issue attached to issue link
"""
issue: Issue!
"""
Type of the issue link
"""
linkType: VulnerabilityIssueLinkType!
}
"""
The connection type for VulnerabilityIssueLink.
"""
type VulnerabilityIssueLinkConnection {
"""
A list of edges.
"""
edges: [VulnerabilityIssueLinkEdge]
"""
A list of nodes.
"""
nodes: [VulnerabilityIssueLink]
"""
Information to aid in pagination.
"""
pageInfo: PageInfo!
}
"""
An edge in a connection.
"""
type VulnerabilityIssueLinkEdge {
"""
A cursor for use in pagination.
"""
cursor: String!
"""
The item at the end of the edge.
"""
node: VulnerabilityIssueLink
}
"""
The type of the issue link related to a vulnerability.
"""
enum VulnerabilityIssueLinkType {
CREATED
RELATED
}
""" """
Represents a vulnerability location. The fields with data will depend on the vulnerability report type Represents a vulnerability location. The fields with data will depend on the vulnerability report type
""" """
......
...@@ -36072,6 +36072,63 @@ ...@@ -36072,6 +36072,63 @@
"isDeprecated": false, "isDeprecated": false,
"deprecationReason": null "deprecationReason": null
}, },
{
"name": "issueLinks",
"description": "List of issue links related to the vulnerability",
"args": [
{
"name": "after",
"description": "Returns the elements in the list that come after the specified cursor.",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "before",
"description": "Returns the elements in the list that come before the specified cursor.",
"type": {
"kind": "SCALAR",
"name": "String",
"ofType": null
},
"defaultValue": null
},
{
"name": "first",
"description": "Returns the first _n_ elements from the list.",
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
},
{
"name": "last",
"description": "Returns the last _n_ elements from the list.",
"type": {
"kind": "SCALAR",
"name": "Int",
"ofType": null
},
"defaultValue": null
}
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "VulnerabilityIssueLinkConnection",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{ {
"name": "location", "name": "location",
"description": "Location metadata for the vulnerability. Its fields depend on the type of security scan that found the vulnerability", "description": "Location metadata for the vulnerability. Its fields depend on the type of security scan that found the vulnerability",
...@@ -36326,6 +36383,208 @@ ...@@ -36326,6 +36383,208 @@
"enumValues": null, "enumValues": null,
"possibleTypes": null "possibleTypes": null
}, },
{
"kind": "OBJECT",
"name": "VulnerabilityIssueLink",
"description": "Represents an issue link of a vulnerability.",
"fields": [
{
"name": "id",
"description": "GraphQL ID of the vulnerability",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "issue",
"description": "The issue attached to issue link",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "Issue",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "linkType",
"description": "Type of the issue link",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "ENUM",
"name": "VulnerabilityIssueLinkType",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "VulnerabilityIssueLinkConnection",
"description": "The connection type for VulnerabilityIssueLink.",
"fields": [
{
"name": "edges",
"description": "A list of edges.",
"args": [
],
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "VulnerabilityIssueLinkEdge",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "nodes",
"description": "A list of nodes.",
"args": [
],
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "VulnerabilityIssueLink",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "pageInfo",
"description": "Information to aid in pagination.",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "OBJECT",
"name": "PageInfo",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "VulnerabilityIssueLinkEdge",
"description": "An edge in a connection.",
"fields": [
{
"name": "cursor",
"description": "A cursor for use in pagination.",
"args": [
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "String",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "node",
"description": "The item at the end of the edge.",
"args": [
],
"type": {
"kind": "OBJECT",
"name": "VulnerabilityIssueLink",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
"interfaces": [
],
"enumValues": null,
"possibleTypes": null
},
{
"kind": "ENUM",
"name": "VulnerabilityIssueLinkType",
"description": "The type of the issue link related to a vulnerability.",
"fields": null,
"inputFields": null,
"interfaces": null,
"enumValues": [
{
"name": "RELATED",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "CREATED",
"description": null,
"isDeprecated": false,
"deprecationReason": null
}
],
"possibleTypes": null
},
{ {
"kind": "UNION", "kind": "UNION",
"name": "VulnerabilityLocation", "name": "VulnerabilityLocation",
...@@ -1842,6 +1842,16 @@ Represents a vulnerability. ...@@ -1842,6 +1842,16 @@ Represents a vulnerability.
| `userPermissions` | VulnerabilityPermissions! | Permissions for the current user on the resource | | `userPermissions` | VulnerabilityPermissions! | Permissions for the current user on the resource |
| `vulnerabilityPath` | String | URL to the vulnerability's details page | | `vulnerabilityPath` | String | URL to the vulnerability's details page |
## VulnerabilityIssueLink
Represents an issue link of a vulnerability.
| Name | Type | Description |
| --- | ---- | ---------- |
| `id` | ID! | GraphQL ID of the vulnerability |
| `issue` | Issue! | The issue attached to issue link |
| `linkType` | VulnerabilityIssueLinkType! | Type of the issue link |
## VulnerabilityLocationContainerScanning ## VulnerabilityLocationContainerScanning
Represents the location of a vulnerability found by a container security scan Represents the location of a vulnerability found by a container security scan
......
# frozen_string_literal: true
module Types
module Vulnerability
# rubocop: disable Graphql/AuthorizeTypes
class IssueLinkType < BaseObject
graphql_name 'VulnerabilityIssueLink'
description 'Represents an issue link of a vulnerability.'
field :id, GraphQL::ID_TYPE, null: false,
description: 'GraphQL ID of the vulnerability'
field :link_type, ::Types::Vulnerability::IssueLinkTypeEnum, null: false,
description: "Type of the issue link"
field :issue, ::Types::IssueType, null: false,
description: 'The issue attached to issue link'
end
# rubocop: enable Graphql/AuthorizeTypes
end
end
# frozen_string_literal: true
module Types
module Vulnerability
class IssueLinkTypeEnum < BaseEnum
graphql_name 'VulnerabilityIssueLinkType'
description 'The type of the issue link related to a vulnerability.'
::Vulnerabilities::IssueLink.link_types.keys.each do |link_type|
value link_type.to_s.upcase, value: link_type.to_s
end
end
end
end
...@@ -34,6 +34,9 @@ module Types ...@@ -34,6 +34,9 @@ module Types
description: "URL to the vulnerability's details page", description: "URL to the vulnerability's details page",
resolve: -> (obj, _args, _ctx) { ::Gitlab::Routing.url_helpers.project_security_vulnerability_path(obj.project, obj) } resolve: -> (obj, _args, _ctx) { ::Gitlab::Routing.url_helpers.project_security_vulnerability_path(obj.project, obj) }
field :issue_links, ::Types::Vulnerability::IssueLinkType.connection_type, null: false,
description: "List of issue links related to the vulnerability"
field :location, VulnerabilityLocationType, null: true, field :location, VulnerabilityLocationType, null: true,
description: 'Location metadata for the vulnerability. Its fields depend on the type of security scan that found the vulnerability', description: 'Location metadata for the vulnerability. Its fields depend on the type of security scan that found the vulnerability',
resolve: -> (obj, _args, _ctx) { obj.finding&.location&.merge(report_type: obj.report_type) } resolve: -> (obj, _args, _ctx) { obj.finding&.location&.merge(report_type: obj.report_type) }
......
# frozen_string_literal: true
require 'spec_helper'
describe GitlabSchema.types['VulnerabilityIssueLinkType'] do
let(:expected_values) { %w[RELATED CREATED] }
subject { described_class.values.keys }
it { is_expected.to contain_exactly(*expected_values) }
end
# frozen_string_literal: true
require 'spec_helper'
describe GitlabSchema.types['VulnerabilityIssueLink'] do
let(:expected_fields) { %i[id link_type issue] }
subject { described_class }
it { is_expected.to have_graphql_fields(expected_fields) }
end
...@@ -8,7 +8,7 @@ describe GitlabSchema.types['Vulnerability'] do ...@@ -8,7 +8,7 @@ describe GitlabSchema.types['Vulnerability'] do
let_it_be(:vulnerability) { create(:vulnerability, project: project) } let_it_be(:vulnerability) { create(:vulnerability, project: project) }
let(:fields) do let(:fields) do
%i[userPermissions id title description user_notes_count state severity report_type vulnerability_path location project] %i[userPermissions id title description user_notes_count state severity report_type vulnerability_path location project issueLinks]
end end
before do before do
......
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