/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
- # frozen_string_literal: true
- module Types
- class VulnerabilityType < BaseObject
- graphql_name 'Vulnerability'
- description 'Represents a vulnerability'
- implements(Types::Notes::NoteableInterface)
- authorize :read_security_resource
- expose_permissions Types::PermissionTypes::Vulnerability
- field :id, GraphQL::Types::ID, null: false,
- description: 'GraphQL ID of the vulnerability.'
- field :title, GraphQL::Types::String, null: true,
- description: 'Title of the vulnerability.'
- field :description, GraphQL::Types::String, null: true,
- description: 'Description of the vulnerability.'
- markdown_field :description_html, null: true
- field :message, GraphQL::Types::String, null: true,
- description: "Short text description of the vulnerability. This may include the finding's specific information.",
- method: :finding_message
- field :state, VulnerabilityStateEnum, null: true,
- description: "State of the vulnerability (#{::Vulnerability.states.keys.join(', ').upcase})"
- field :severity, VulnerabilitySeverityEnum, null: true,
- description: "Severity of the vulnerability (#{::Enums::Vulnerability.severity_levels.keys.join(', ').upcase})"
- field :report_type, VulnerabilityReportTypeEnum, null: true,
- description: "Type of the security report that found the vulnerability (#{::Enums::Vulnerability.report_types.keys.join(', ').upcase}). `Scan Type` in the UI."
- field :resolved_on_default_branch, GraphQL::Types::Boolean, null: false,
- description: "Indicates whether the vulnerability is fixed on the default branch or not."
- field :user_notes_count, GraphQL::Types::Int, null: false,
- description: 'Number of user notes attached to the vulnerability.'
- field :vulnerability_path, GraphQL::Types::String, null: true,
- description: "URL to the vulnerability's details page."
- field :issue_links, ::Types::Vulnerability::IssueLinkType.connection_type, null: false,
- description: "List of issue links related to the vulnerability.",
- resolver: Resolvers::Vulnerabilities::IssueLinksResolver
- field :external_issue_links, ::Types::Vulnerability::ExternalIssueLinkType.connection_type, null: false,
- description: 'List of external issue links related to the vulnerability.'
- field :links, [::Types::Vulnerabilities::LinkType], null: false,
- description: 'List of links associated with the vulnerability.'
- field :location, VulnerabilityLocationType, null: true,
- description: 'Location metadata for the vulnerability. Its fields depend on the type of security scan that found the vulnerability.'
- field :scanner, VulnerabilityScannerType, null: true,
- description: 'Scanner metadata for the vulnerability.'
- field :primary_identifier, VulnerabilityIdentifierType, null: true,
- description: 'Primary identifier of the vulnerability.'
- field :identifiers, [VulnerabilityIdentifierType], null: false,
- description: 'Identifiers of the vulnerability.'
- field :project, ::Types::ProjectType, null: true,
- description: 'Project on which the vulnerability was found.',
- authorize: :read_project
- field :detected_at, Types::TimeType, null: false,
- description: 'Timestamp of when the vulnerability was first detected.',
- method: :created_at
- field :confirmed_at, Types::TimeType, null: true,
- description: 'Timestamp of when the vulnerability state was changed to confirmed.'
- field :resolved_at, Types::TimeType, null: true,
- description: 'Timestamp of when the vulnerability state was changed to resolved.'
- field :dismissed_at, Types::TimeType, null: true,
- description: 'Timestamp of when the vulnerability state was changed to dismissed.'
- field :has_solutions, GraphQL::Types::Boolean, null: true,
- description: 'Indicates whether there is a solution available for this vulnerability.',
- resolver_method: :has_solutions?
- field :merge_request, ::Types::MergeRequestType, null: true,
- description: 'Merge request that fixes the vulnerability.'
- field :confirmed_by, ::Types::UserType, null: true,
- description: 'User that confirmed the vulnerability.'
- field :resolved_by, ::Types::UserType, null: true,
- description: 'User that resolved the vulnerability.'
- field :dismissed_by, ::Types::UserType, null: true,
- description: 'User that dismissed the vulnerability.'
- field :details, [VulnerabilityDetailType], null: false,
- description: 'Details of the vulnerability.',
- resolver: Resolvers::Vulnerabilities::DetailsResolver
- field :false_positive, GraphQL::Types::Boolean, null: true,
- description: 'Indicates whether the vulnerability is a false positive.',
- resolver_method: :false_positive?
- def confirmed_by
- ::Gitlab::Graphql::Loaders::BatchModelLoader.new(::User, object.confirmed_by_id).find
- end
- def resolved_by
- ::Gitlab::Graphql::Loaders::BatchModelLoader.new(::User, object.resolved_by_id).find
- end
- def dismissed_by
- ::Gitlab::Graphql::Loaders::BatchModelLoader.new(::User, object.dismissed_by_id).find
- end
- def user_notes_count
- ::Gitlab::Graphql::Aggregations::Vulnerabilities::LazyUserNotesCountAggregate.new(context, object)
- end
- def vulnerability_path
- ::Gitlab::Routing.url_helpers.project_security_vulnerability_path(object.project, object)
- end
- def location
- object_location = object.finding&.location
- object_location&.merge(blob_path: object.blob_path, report_type: object.report_type)&.compact
- end
- def scanner
- Representation::VulnerabilityScannerEntry.new(object.finding&.scanner, object.report_type)
- end
- def primary_identifier
- object.finding&.primary_identifier
- end
- def identifiers
- object.finding&.identifiers
- end
- def description
- object.description || object.finding_description
- end
- def description_html_resolver
- ::MarkupHelper.markdown(description, context.to_h.dup)
- end
- def project
- Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, object.project_id).find
- end
- def merge_request
- object.finding&.merge_request_feedback&.merge_request
- end
- def has_solutions?
- object.finding&.remediations&.any?
- end
- def false_positive?
- return unless expose_false_positive?
- object.finding&.false_positive? || false
- end
- private
- def expose_false_positive?
- object.project.licensed_feature_available?(:sast_fp_reduction)
- end
- end
- end