summaryrefslogtreecommitdiff
path: root/lib/gitlab/ci/reports
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/ci/reports')
-rw-r--r--lib/gitlab/ci/reports/security/analyzer.rb20
-rw-r--r--lib/gitlab/ci/reports/security/concerns/fingerprint_path_from_file.rb19
-rw-r--r--lib/gitlab/ci/reports/security/identifier.rb69
-rw-r--r--lib/gitlab/ci/reports/security/link.rb25
-rw-r--r--lib/gitlab/ci/reports/security/scan.rb29
-rw-r--r--lib/gitlab/ci/reports/security/scanned_resource.rb25
-rw-r--r--lib/gitlab/ci/reports/security/scanner.rb60
7 files changed, 247 insertions, 0 deletions
diff --git a/lib/gitlab/ci/reports/security/analyzer.rb b/lib/gitlab/ci/reports/security/analyzer.rb
new file mode 100644
index 00000000000..b88eaf87cef
--- /dev/null
+++ b/lib/gitlab/ci/reports/security/analyzer.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Reports
+ module Security
+ class Analyzer
+ attr_reader :id, :name, :version, :vendor
+
+ def initialize(id:, name:, version:, vendor:)
+ @id = id
+ @name = name
+ @version = version
+ @vendor = vendor
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/reports/security/concerns/fingerprint_path_from_file.rb b/lib/gitlab/ci/reports/security/concerns/fingerprint_path_from_file.rb
new file mode 100644
index 00000000000..ec1d80e11c8
--- /dev/null
+++ b/lib/gitlab/ci/reports/security/concerns/fingerprint_path_from_file.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Reports
+ module Security
+ module Concerns
+ module FingerprintPathFromFile
+ extend ActiveSupport::Concern
+
+ def fingerprint_path
+ File.basename(file_path.to_s)
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/reports/security/identifier.rb b/lib/gitlab/ci/reports/security/identifier.rb
new file mode 100644
index 00000000000..4ba943cdcbc
--- /dev/null
+++ b/lib/gitlab/ci/reports/security/identifier.rb
@@ -0,0 +1,69 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Reports
+ module Security
+ class Identifier
+ attr_reader :external_id
+ attr_reader :external_type
+ attr_reader :fingerprint
+ attr_reader :name
+ attr_reader :url
+
+ def initialize(external_id:, external_type:, name:, url: nil)
+ @external_id = external_id
+ @external_type = external_type
+ @name = name
+ @url = url
+
+ @fingerprint = generate_fingerprint
+ end
+
+ def key
+ fingerprint
+ end
+
+ def to_hash
+ %i[
+ external_id
+ external_type
+ fingerprint
+ name
+ url
+ ].each_with_object({}) do |key, hash|
+ hash[key] = public_send(key) # rubocop:disable GitlabSecurity/PublicSend
+ end
+ end
+
+ def ==(other)
+ other.external_type == external_type &&
+ other.external_id == external_id
+ end
+
+ def type_identifier?
+ cwe? || wasc?
+ end
+
+ def cve?
+ external_type.to_s.casecmp?('cve')
+ end
+
+ def cwe?
+ external_type.to_s.casecmp?('cwe')
+ end
+
+ def wasc?
+ external_type.to_s.casecmp?('wasc')
+ end
+
+ private
+
+ def generate_fingerprint
+ Digest::SHA1.hexdigest("#{external_type}:#{external_id}")
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/reports/security/link.rb b/lib/gitlab/ci/reports/security/link.rb
new file mode 100644
index 00000000000..1c4c05cd9ac
--- /dev/null
+++ b/lib/gitlab/ci/reports/security/link.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Reports
+ module Security
+ class Link
+ attr_accessor :name, :url
+
+ def initialize(name: nil, url: nil)
+ @name = name
+ @url = url
+ end
+
+ def to_hash
+ {
+ name: name,
+ url: url
+ }.compact
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/reports/security/scan.rb b/lib/gitlab/ci/reports/security/scan.rb
new file mode 100644
index 00000000000..7dd0acc868b
--- /dev/null
+++ b/lib/gitlab/ci/reports/security/scan.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Reports
+ module Security
+ class Scan
+ attr_accessor :type, :status, :start_time, :end_time
+
+ def initialize(params = {})
+ @type = params.dig('type')
+ @status = params.dig('status')
+ @start_time = params.dig('start_time')
+ @end_time = params.dig('end_time')
+ end
+
+ def to_hash
+ {
+ type: type,
+ status: status,
+ start_time: start_time,
+ end_time: end_time
+ }.compact
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/reports/security/scanned_resource.rb b/lib/gitlab/ci/reports/security/scanned_resource.rb
new file mode 100644
index 00000000000..605577eafcd
--- /dev/null
+++ b/lib/gitlab/ci/reports/security/scanned_resource.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Reports
+ module Security
+ class ScannedResource
+ include Gitlab::Utils::StrongMemoize
+
+ attr_reader :request_method
+ attr_reader :request_uri
+
+ delegate :scheme, :host, :port, :path, :query, to: :request_uri, prefix: :url
+
+ def initialize(uri, request_method)
+ raise ArgumentError unless uri.is_a?(URI)
+
+ @request_method = request_method
+ @request_uri = uri
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/ci/reports/security/scanner.rb b/lib/gitlab/ci/reports/security/scanner.rb
new file mode 100644
index 00000000000..c1de03cea44
--- /dev/null
+++ b/lib/gitlab/ci/reports/security/scanner.rb
@@ -0,0 +1,60 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module Ci
+ module Reports
+ module Security
+ class Scanner
+ ANALYZER_ORDER = {
+ "bundler_audit" => 1,
+ "retire.js" => 2,
+ "gemnasium" => 3,
+ "gemnasium-maven" => 3,
+ "gemnasium-python" => 3,
+ "bandit" => 1,
+ "semgrep" => 2
+ }.freeze
+
+ attr_accessor :external_id, :name, :vendor, :version
+
+ alias_method :key, :external_id
+
+ def initialize(external_id:, name:, vendor:, version:)
+ @external_id = external_id
+ @name = name
+ @vendor = vendor
+ @version = version
+ end
+
+ def to_hash
+ {
+ external_id: external_id.to_s,
+ name: name.to_s,
+ vendor: vendor.presence
+ }.compact
+ end
+
+ def ==(other)
+ other.external_id == external_id
+ end
+
+ def <=>(other)
+ sort_keys.compact <=> other.sort_keys.compact
+ end
+
+ protected
+
+ def sort_keys
+ @sort_keys ||= [order, external_id, name, vendor]
+ end
+
+ private
+
+ def order
+ ANALYZER_ORDER.fetch(external_id, Float::INFINITY)
+ end
+ end
+ end
+ end
+ end
+end