Extend GraphQL's vulnerabilities query

What we have today

The groupthreat insights owns 4 Dashboards. The Project Level Security Dashboard, the Group Level Security Dashboard, the Security Center and the Pipeline Security Dashboard. Each of these dashboards display a list of vulnerabilities which can be fetched using GraphQL. Below is a table that demonstrates which query is used to fetch the vulnerabilities for the related dashboard:

Dashboard Query Name
Security Center vulnerabilities
Group Level Security Dashboard group.vulnerabilities
Project Level Security Dashboard project.vulnerabilities
Pipeline Security Dashboard project.pipeline.securityReportFindings

Problem

This creates an additional complexity in the frontend while fetching the vulnerabilities / findings. Technically speaking, we re-use the ee/app/assets/javascripts/security_dashboard/components/shared/vulnerability_list.vue component in order to display the vulnerabilities/findings for each dashboard and we have a wrapper component which creates the query for the related dashboard.

Proposal

I'm going to suggest to deprecate all these queries except the vulnerabilities query and extend it by allowing it to receive the following arguments:

argument type default value description
projectId [ID!] [] An array of project ids.
groupId or groupFullPath [ID!] [] An array of group ids or full paths depending on which one we want use. Our UI is not designed to display multiple groups at the same time, but API-wise it could be beneficial for the user.
isSecurityCenter Boolean false Whether we're fetching the vulnerabilities for the security center (user level security dashboard)
pipelineId [ID!] [] Similar to groupId, we do not display vulnerabilities for multiple pipelines at the same time, but this could still be beneficial for the user.

So this is what the query would look like to fetch the vulnerabilities:

#import "~/graphql_shared/fragments/pageInfoCursorsOnly.fragment.graphql"
#import "../fragments/vulnerability.fragment.graphql"

query vulnerabilities(
  $after: String
  $first: Int
  $projectId: [ID!]
  $severity: [VulnerabilitySeverity!]
  $reportType: [VulnerabilityReportType!]
  $scanner: [String!]
  $scannerId: [VulnerabilitiesScannerID!]
  $state: [VulnerabilityState!]
  $sort: VulnerabilitySort
  $hasIssues: Boolean
  $hasResolution: Boolean
  $groupId: [!ID]
  $projectId: [!ID]
  $pipelineId: [!ID]
  $isSecurityCenter: Boolean
) {
  vulnerabilities(
    after: $after
    first: $first
    severity: $severity
    reportType: $reportType
    state: $state
    projectId: $projectId
    scanner: $scanner
    scannerId: $scannerId
    sort: $sort
    hasIssues: $hasIssues
    hasResolution: $hasResolution
    groupId: $groupId                     # part of the proposal
    projectId: $projectId                 # part of the proposal
    pipelineId: $pipelineId               # part of the proposal
    isSecurityCenter: $isSecurityCenter   # part of the proposal
  ) {
    nodes {
      ...Vulnerability
    }
    pageInfo {
      ...PageInfo
    }
  }
}

So for instance providing the $projectId: ["/root/security-reports"] argument would return the vulnerabilities for this project, but omitting the $projectId and providing isSecurityCenter: true would return the security center vulnerabilities.

The only unknown in this proposal is whether we can provide the findings in the same query or not. A Finding and a Vulnerability are different entities in the backend even though for the end-user and the frontend they are very similar. If we can provide the findings in the same query, it would then remove many complexities in the frontend as we would be able to treat them alike. If this is technically not possible, or hard to implement, we can always reiterate on this proposal and start from providing a single query for the 3 dashboards.

Edited by Savas Vedova