/ee/app/graphql/types/vulnerability_type.rb

https://gitlab.com/18dit020/gitlab · Ruby · 178 lines · 132 code · 45 blank · 1 comment · 2 complexity · f53a70cb65edd91b23ab2da9860b32af MD5 · raw file

  1. # frozen_string_literal: true
  2. module Types
  3. class VulnerabilityType < BaseObject
  4. graphql_name 'Vulnerability'
  5. description 'Represents a vulnerability'
  6. implements(Types::Notes::NoteableInterface)
  7. authorize :read_security_resource
  8. expose_permissions Types::PermissionTypes::Vulnerability
  9. field :id, GraphQL::Types::ID, null: false,
  10. description: 'GraphQL ID of the vulnerability.'
  11. field :title, GraphQL::Types::String, null: true,
  12. description: 'Title of the vulnerability.'
  13. field :description, GraphQL::Types::String, null: true,
  14. description: 'Description of the vulnerability.'
  15. markdown_field :description_html, null: true
  16. field :message, GraphQL::Types::String, null: true,
  17. description: "Short text description of the vulnerability. This may include the finding's specific information.",
  18. method: :finding_message
  19. field :state, VulnerabilityStateEnum, null: true,
  20. description: "State of the vulnerability (#{::Vulnerability.states.keys.join(', ').upcase})"
  21. field :severity, VulnerabilitySeverityEnum, null: true,
  22. description: "Severity of the vulnerability (#{::Enums::Vulnerability.severity_levels.keys.join(', ').upcase})"
  23. field :report_type, VulnerabilityReportTypeEnum, null: true,
  24. description: "Type of the security report that found the vulnerability (#{::Enums::Vulnerability.report_types.keys.join(', ').upcase}). `Scan Type` in the UI."
  25. field :resolved_on_default_branch, GraphQL::Types::Boolean, null: false,
  26. description: "Indicates whether the vulnerability is fixed on the default branch or not."
  27. field :user_notes_count, GraphQL::Types::Int, null: false,
  28. description: 'Number of user notes attached to the vulnerability.'
  29. field :vulnerability_path, GraphQL::Types::String, null: true,
  30. description: "URL to the vulnerability's details page."
  31. field :issue_links, ::Types::Vulnerability::IssueLinkType.connection_type, null: false,
  32. description: "List of issue links related to the vulnerability.",
  33. resolver: Resolvers::Vulnerabilities::IssueLinksResolver
  34. field :external_issue_links, ::Types::Vulnerability::ExternalIssueLinkType.connection_type, null: false,
  35. description: 'List of external issue links related to the vulnerability.'
  36. field :links, [::Types::Vulnerabilities::LinkType], null: false,
  37. description: 'List of links associated with the vulnerability.'
  38. field :location, VulnerabilityLocationType, null: true,
  39. description: 'Location metadata for the vulnerability. Its fields depend on the type of security scan that found the vulnerability.'
  40. field :scanner, VulnerabilityScannerType, null: true,
  41. description: 'Scanner metadata for the vulnerability.'
  42. field :primary_identifier, VulnerabilityIdentifierType, null: true,
  43. description: 'Primary identifier of the vulnerability.'
  44. field :identifiers, [VulnerabilityIdentifierType], null: false,
  45. description: 'Identifiers of the vulnerability.'
  46. field :project, ::Types::ProjectType, null: true,
  47. description: 'Project on which the vulnerability was found.',
  48. authorize: :read_project
  49. field :detected_at, Types::TimeType, null: false,
  50. description: 'Timestamp of when the vulnerability was first detected.',
  51. method: :created_at
  52. field :confirmed_at, Types::TimeType, null: true,
  53. description: 'Timestamp of when the vulnerability state was changed to confirmed.'
  54. field :resolved_at, Types::TimeType, null: true,
  55. description: 'Timestamp of when the vulnerability state was changed to resolved.'
  56. field :dismissed_at, Types::TimeType, null: true,
  57. description: 'Timestamp of when the vulnerability state was changed to dismissed.'
  58. field :has_solutions, GraphQL::Types::Boolean, null: true,
  59. description: 'Indicates whether there is a solution available for this vulnerability.',
  60. resolver_method: :has_solutions?
  61. field :merge_request, ::Types::MergeRequestType, null: true,
  62. description: 'Merge request that fixes the vulnerability.'
  63. field :confirmed_by, ::Types::UserType, null: true,
  64. description: 'User that confirmed the vulnerability.'
  65. field :resolved_by, ::Types::UserType, null: true,
  66. description: 'User that resolved the vulnerability.'
  67. field :dismissed_by, ::Types::UserType, null: true,
  68. description: 'User that dismissed the vulnerability.'
  69. field :details, [VulnerabilityDetailType], null: false,
  70. description: 'Details of the vulnerability.',
  71. resolver: Resolvers::Vulnerabilities::DetailsResolver
  72. field :false_positive, GraphQL::Types::Boolean, null: true,
  73. description: 'Indicates whether the vulnerability is a false positive.',
  74. resolver_method: :false_positive?
  75. def confirmed_by
  76. ::Gitlab::Graphql::Loaders::BatchModelLoader.new(::User, object.confirmed_by_id).find
  77. end
  78. def resolved_by
  79. ::Gitlab::Graphql::Loaders::BatchModelLoader.new(::User, object.resolved_by_id).find
  80. end
  81. def dismissed_by
  82. ::Gitlab::Graphql::Loaders::BatchModelLoader.new(::User, object.dismissed_by_id).find
  83. end
  84. def user_notes_count
  85. ::Gitlab::Graphql::Aggregations::Vulnerabilities::LazyUserNotesCountAggregate.new(context, object)
  86. end
  87. def vulnerability_path
  88. ::Gitlab::Routing.url_helpers.project_security_vulnerability_path(object.project, object)
  89. end
  90. def location
  91. object_location = object.finding&.location
  92. object_location&.merge(blob_path: object.blob_path, report_type: object.report_type)&.compact
  93. end
  94. def scanner
  95. Representation::VulnerabilityScannerEntry.new(object.finding&.scanner, object.report_type)
  96. end
  97. def primary_identifier
  98. object.finding&.primary_identifier
  99. end
  100. def identifiers
  101. object.finding&.identifiers
  102. end
  103. def description
  104. object.description || object.finding_description
  105. end
  106. def description_html_resolver
  107. ::MarkupHelper.markdown(description, context.to_h.dup)
  108. end
  109. def project
  110. Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, object.project_id).find
  111. end
  112. def merge_request
  113. object.finding&.merge_request_feedback&.merge_request
  114. end
  115. def has_solutions?
  116. object.finding&.remediations&.any?
  117. end
  118. def false_positive?
  119. return unless expose_false_positive?
  120. object.finding&.false_positive? || false
  121. end
  122. private
  123. def expose_false_positive?
  124. object.project.licensed_feature_available?(:sast_fp_reduction)
  125. end
  126. end
  127. end