Class: Sbom::Data::Package

Inherits:
Object
  • Object
show all
Defined in:
lib/sbom/data/package.rb

Constant Summary collapse

VALID_TYPES =
%w[
  APPLICATION FRAMEWORK LIBRARY CONTAINER OPERATING-SYSTEM
  DEVICE FIRMWARE FILE MACHINE-LEARNING-MODEL DATA
  DEVICE-DRIVER PLATFORM CRYPTOGRAPHIC-ASSET
].freeze
VALID_SUPPLIER_TYPES =
%w[Person Organization].freeze
VALID_ALGORITHMS =
%w[
  MD5 SHA1 SHA256 SHA384 SHA512
  SHA3-256 SHA3-384 SHA3-512
  BLAKE2b-256 BLAKE2b-384 BLAKE2b-512 BLAKE3
].freeze
VALID_EXTERNAL_REF_CATEGORIES =
%w[
  vcs issue-tracker website advisories bom mailing-list
  social chat documentation support source-distribution
  distribution distribution-intake license build-meta
  build-system release-notes security-contact model-card
  log configuration evidence formulation attestation
  threat-model adversary-model risk-assessment
  vulnerability-assertion exploitability-statement
  pentest-report static-analysis-report dynamic-analysis-report
  runtime-analysis-report component-analysis-report
  maturity-report certification-report codified-infrastructure
  quality-metrics poam electronic-signature digital-signature
  rfc-9116 other
].freeze
URL_PATTERN =
%r{
  \A(https?|ssh|git|svn|sftp|ftp)://
  [a-z0-9]+([\-\.]{1}[a-z0-9]+){0,100}\.[a-z]{2,5}
  (:[0-9]{1,5})?(/.*)?
\z}xi

Instance Method Summary collapse

Constructor Details

#initializePackage

Returns a new instance of Package.



41
42
43
# File 'lib/sbom/data/package.rb', line 41

def initialize
  @data = {}
end

Instance Method Details

#[](key) ⇒ Object



356
357
358
# File 'lib/sbom/data/package.rb', line 356

def [](key)
  @data[key.to_sym]
end

#[]=(key, value) ⇒ Object



360
361
362
# File 'lib/sbom/data/package.rb', line 360

def []=(key, value)
  @data[key.to_sym] = value
end

#add_attribution(value) ⇒ Object



264
265
266
267
# File 'lib/sbom/data/package.rb', line 264

def add_attribution(value)
  @data[:attributions] ||= []
  @data[:attributions] << value
end

#add_checksum(algorithm, value) ⇒ Object



153
154
155
156
157
158
# File 'lib/sbom/data/package.rb', line 153

def add_checksum(algorithm, value)
  return unless valid_checksum?(value) && valid_algorithm?(algorithm)

  @data[:checksums] ||= []
  @data[:checksums] << [algorithm.strip, value.downcase]
end

#add_evidence(evidence) ⇒ Object



347
348
349
350
# File 'lib/sbom/data/package.rb', line 347

def add_evidence(evidence)
  @data[:evidence] ||= []
  @data[:evidence] << evidence
end

#add_external_reference(category, ref_type, locator) ⇒ Object



273
274
275
276
277
278
279
280
281
282
283
284
# File 'lib/sbom/data/package.rb', line 273

def add_external_reference(category, ref_type, locator)
  if %w[SECURITY PACKAGE-MANAGER PACKAGE_MANAGER].include?(category) &&
     %w[cpe22Type cpe23Type purl].include?(ref_type)
    entry = [category, ref_type.strip, locator]
  else
    normalized_type = VALID_EXTERNAL_REF_CATEGORIES.include?(ref_type.downcase) ? ref_type.downcase : "other"
    entry = [category, normalized_type.strip, locator]
  end

  @data[:external_references] ||= []
  @data[:external_references] << entry
end

#add_license_info_in_files(license_info) ⇒ Object



223
224
225
226
# File 'lib/sbom/data/package.rb', line 223

def add_license_info_in_files(license_info)
  @data[:license_info_in_files] ||= []
  @data[:license_info_in_files] << license_info
end

#add_property(name, value) ⇒ Object



164
165
166
167
168
169
# File 'lib/sbom/data/package.rb', line 164

def add_property(name, value)
  return if value.nil?

  @data[:properties] ||= []
  @data[:properties] << [name.strip, value]
end

#add_tag(name) ⇒ Object



175
176
177
178
179
180
# File 'lib/sbom/data/package.rb', line 175

def add_tag(name)
  return if name.nil?

  @data[:tags] ||= []
  @data[:tags] << name.strip
end

#attributionsObject



269
270
271
# File 'lib/sbom/data/package.rb', line 269

def attributions
  @data[:attributions] || []
end

#checksumsObject



160
161
162
# File 'lib/sbom/data/package.rb', line 160

def checksums
  @data[:checksums] || []
end

#commentObject



240
241
242
# File 'lib/sbom/data/package.rb', line 240

def comment
  @data[:comment]
end

#comment=(value) ⇒ Object



244
245
246
# File 'lib/sbom/data/package.rb', line 244

def comment=(value)
  @data[:comment] = clean_text(value) unless value.nil? || value.empty?
end

#copy_from(package_hash) ⇒ Object



368
369
370
371
372
# File 'lib/sbom/data/package.rb', line 368

def copy_from(package_hash)
  package_hash.each do |key, value|
    @data[key.to_sym] = value
  end
end


232
233
234
# File 'lib/sbom/data/package.rb', line 232

def copyright_text
  @data[:copyright_text]
end


236
237
238
# File 'lib/sbom/data/package.rb', line 236

def copyright_text=(value)
  @data[:copyright_text] = clean_text(value) unless value.nil? || value.empty?
end

#cpeObject



337
338
339
# File 'lib/sbom/data/package.rb', line 337

def cpe
  external_references.find { |_, type, _| type.start_with?("cpe") }&.last
end

#descriptionObject



256
257
258
# File 'lib/sbom/data/package.rb', line 256

def description
  @data[:description]
end

#description=(value) ⇒ Object



260
261
262
# File 'lib/sbom/data/package.rb', line 260

def description=(value)
  @data[:description] = clean_text(value) unless value.nil? || value.empty?
end

#download_locationObject



113
114
115
# File 'lib/sbom/data/package.rb', line 113

def download_location
  @data[:download_location]
end

#download_location=(value) ⇒ Object



117
118
119
# File 'lib/sbom/data/package.rb', line 117

def download_location=(value)
  @data[:download_location] = value if valid_url?(value)
end

#evidenceObject



352
353
354
# File 'lib/sbom/data/package.rb', line 352

def evidence
  @data[:evidence] || []
end

#external_referencesObject



286
287
288
# File 'lib/sbom/data/package.rb', line 286

def external_references
  @data[:external_references] || []
end

#filenameObject



121
122
123
# File 'lib/sbom/data/package.rb', line 121

def filename
  @data[:filename]
end

#filename=(value) ⇒ Object



125
126
127
# File 'lib/sbom/data/package.rb', line 125

def filename=(value)
  @data[:filename] = value
end

#files_analyzedObject



145
146
147
# File 'lib/sbom/data/package.rb', line 145

def files_analyzed
  @data[:files_analyzed]
end

#files_analyzed=(value) ⇒ Object



149
150
151
# File 'lib/sbom/data/package.rb', line 149

def files_analyzed=(value)
  @data[:files_analyzed] = value
end

#generate_purl(type:, namespace: nil, qualifiers: nil, subpath: nil) ⇒ Object



324
325
326
327
328
329
330
331
332
333
334
335
# File 'lib/sbom/data/package.rb', line 324

def generate_purl(type:, namespace: nil, qualifiers: nil, subpath: nil)
  purl_obj = Purl::PackageURL.new(
    type: type,
    namespace: namespace,
    name: name,
    version: version,
    qualifiers: qualifiers,
    subpath: subpath
  )
  self.purl = purl_obj.to_s
  purl_obj.to_s
end

#homepageObject



129
130
131
# File 'lib/sbom/data/package.rb', line 129

def homepage
  @data[:homepage]
end

#homepage=(value) ⇒ Object



133
134
135
# File 'lib/sbom/data/package.rb', line 133

def homepage=(value)
  @data[:homepage] = value if valid_url?(value)
end

#idObject



57
58
59
# File 'lib/sbom/data/package.rb', line 57

def id
  @data[:id]
end

#id=(value) ⇒ Object



61
62
63
# File 'lib/sbom/data/package.rb', line 61

def id=(value)
  @data[:id] = value
end

#license_commentsObject



215
216
217
# File 'lib/sbom/data/package.rb', line 215

def license_comments
  @data[:license_comments]
end

#license_comments=(value) ⇒ Object



219
220
221
# File 'lib/sbom/data/package.rb', line 219

def license_comments=(value)
  @data[:license_comments] = clean_text(value) unless value.nil? || value.empty?
end

#license_concludedObject



186
187
188
# File 'lib/sbom/data/package.rb', line 186

def license_concluded
  @data[:license_concluded]
end

#license_concluded=(value) ⇒ Object



190
191
192
# File 'lib/sbom/data/package.rb', line 190

def license_concluded=(value)
  @data[:license_concluded] = value
end

#license_declaredObject



194
195
196
# File 'lib/sbom/data/package.rb', line 194

def license_declared
  @data[:license_declared]
end

#license_info_in_filesObject



228
229
230
# File 'lib/sbom/data/package.rb', line 228

def license_info_in_files
  @data[:license_info_in_files] || []
end

#license_listObject



207
208
209
# File 'lib/sbom/data/package.rb', line 207

def license_list
  @data[:license_list]
end

#license_list=(value) ⇒ Object



211
212
213
# File 'lib/sbom/data/package.rb', line 211

def license_list=(value)
  @data[:license_list] = value
end

#license_nameObject



203
204
205
# File 'lib/sbom/data/package.rb', line 203

def license_name
  @data[:license_name]
end

#nameObject



49
50
51
# File 'lib/sbom/data/package.rb', line 49

def name
  @data[:name]
end

#name=(value) ⇒ Object



53
54
55
# File 'lib/sbom/data/package.rb', line 53

def name=(value)
  @data[:name] = value
end

#originatorObject



98
99
100
# File 'lib/sbom/data/package.rb', line 98

def originator
  @data[:originator]
end

#originator_typeObject



102
103
104
# File 'lib/sbom/data/package.rb', line 102

def originator_type
  @data[:originator_type]
end

#package_typeObject



74
75
76
# File 'lib/sbom/data/package.rb', line 74

def package_type
  @data[:type]
end

#package_type=(value) ⇒ Object



78
79
80
81
# File 'lib/sbom/data/package.rb', line 78

def package_type=(value)
  normalized = value.to_s.upcase.tr("_", "-").strip
  @data[:type] = VALID_TYPES.include?(normalized) ? normalized : "FILE"
end

#parsed_purlObject



300
301
302
303
304
305
306
# File 'lib/sbom/data/package.rb', line 300

def parsed_purl
  return nil unless purl

  Purl.parse(purl)
rescue Purl::InvalidPackageURL
  nil
end

#propertiesObject



171
172
173
# File 'lib/sbom/data/package.rb', line 171

def properties
  @data[:properties] || []
end

#purlObject



290
291
292
# File 'lib/sbom/data/package.rb', line 290

def purl
  external_references.find { |_, type, _| type == "purl" }&.last
end

#purl=(value) ⇒ Object



294
295
296
297
298
# File 'lib/sbom/data/package.rb', line 294

def purl=(value)
  return if value.nil? || value.to_s.empty?

  add_external_reference("PACKAGE_MANAGER", "purl", value.to_s)
end

#purl_nameObject



316
317
318
# File 'lib/sbom/data/package.rb', line 316

def purl_name
  parsed_purl&.name
end

#purl_namespaceObject



312
313
314
# File 'lib/sbom/data/package.rb', line 312

def purl_namespace
  parsed_purl&.namespace
end

#purl_typeObject



308
309
310
# File 'lib/sbom/data/package.rb', line 308

def purl_type
  parsed_purl&.type
end

#purl_versionObject



320
321
322
# File 'lib/sbom/data/package.rb', line 320

def purl_version
  parsed_purl&.version
end

#reset!Object



45
46
47
# File 'lib/sbom/data/package.rb', line 45

def reset!
  @data = {}
end

#set_cpe(vector, cpe_type = "cpe23Type") ⇒ Object



341
342
343
344
345
# File 'lib/sbom/data/package.rb', line 341

def set_cpe(vector, cpe_type = "cpe23Type")
  return unless %w[cpe22Type cpe23Type].include?(cpe_type)

  add_external_reference("SECURITY", cpe_type, vector)
end

#set_license_declared(license, name = nil) ⇒ Object



198
199
200
201
# File 'lib/sbom/data/package.rb', line 198

def set_license_declared(license, name = nil)
  @data[:license_declared] = license
  @data[:license_name] = name if name
end

#set_originator(type, name) ⇒ Object



106
107
108
109
110
111
# File 'lib/sbom/data/package.rb', line 106

def set_originator(type, name)
  return if name.nil? || name.empty?

  @data[:originator_type] = normalize_supplier_type(type)
  @data[:originator] = name
end

#set_supplier(type, name) ⇒ Object



91
92
93
94
95
96
# File 'lib/sbom/data/package.rb', line 91

def set_supplier(type, name)
  return if name.nil? || name.empty?

  @data[:supplier_type] = normalize_supplier_type(type)
  @data[:supplier] = name
end

#source_infoObject



137
138
139
# File 'lib/sbom/data/package.rb', line 137

def source_info
  @data[:source_info]
end

#source_info=(value) ⇒ Object



141
142
143
# File 'lib/sbom/data/package.rb', line 141

def source_info=(value)
  @data[:source_info] = clean_text(value) unless value.nil? || value.empty?
end

#summaryObject



248
249
250
# File 'lib/sbom/data/package.rb', line 248

def summary
  @data[:summary]
end

#summary=(value) ⇒ Object



252
253
254
# File 'lib/sbom/data/package.rb', line 252

def summary=(value)
  @data[:summary] = clean_text(value) unless value.nil? || value.empty?
end

#supplierObject



83
84
85
# File 'lib/sbom/data/package.rb', line 83

def supplier
  @data[:supplier]
end

#supplier_typeObject



87
88
89
# File 'lib/sbom/data/package.rb', line 87

def supplier_type
  @data[:supplier_type]
end

#tagsObject



182
183
184
# File 'lib/sbom/data/package.rb', line 182

def tags
  @data[:tags] || []
end

#to_hObject



364
365
366
# File 'lib/sbom/data/package.rb', line 364

def to_h
  @data.dup
end

#versionObject



65
66
67
# File 'lib/sbom/data/package.rb', line 65

def version
  @data[:version]
end

#version=(value) ⇒ Object



69
70
71
72
# File 'lib/sbom/data/package.rb', line 69

def version=(value)
  @data[:version] = value
  @data[:id] ||= "#{name}_#{value}" if name
end