sbom-cyclonedx 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (368) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +15 -0
  3. data/.gitlab-ci.yml +49 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +72 -0
  6. data/.vscode/settings.json +6 -0
  7. data/CHANGELOG.md +9 -0
  8. data/CODE_OF_CONDUCT.md +132 -0
  9. data/Gemfile +26 -0
  10. data/Gemfile.lock +179 -0
  11. data/LICENSE.txt +21 -0
  12. data/README.md +39 -0
  13. data/Rakefile +36 -0
  14. data/Steepfile +14 -0
  15. data/bin/console +11 -0
  16. data/bin/rbs_spec +9 -0
  17. data/bin/setup +8 -0
  18. data/bom-1.6.schema.json +7334 -0
  19. data/lib/email_address_extension.rb +26 -0
  20. data/lib/sbom/cyclone_dx/enum.rb +2178 -0
  21. data/lib/sbom/cyclone_dx/field.rb +404 -0
  22. data/lib/sbom/cyclone_dx/pattern.rb +43 -0
  23. data/lib/sbom/cyclone_dx/record/advisory.rb +17 -0
  24. data/lib/sbom/cyclone_dx/record/annotation.rb +46 -0
  25. data/lib/sbom/cyclone_dx/record/attachment.rb +21 -0
  26. data/lib/sbom/cyclone_dx/record/base.rb +244 -0
  27. data/lib/sbom/cyclone_dx/record/cipher_suite.rb +23 -0
  28. data/lib/sbom/cyclone_dx/record/co2_measure.rb +18 -0
  29. data/lib/sbom/cyclone_dx/record/command.rb +18 -0
  30. data/lib/sbom/cyclone_dx/record/commit.rb +25 -0
  31. data/lib/sbom/cyclone_dx/record/component.rb +126 -0
  32. data/lib/sbom/cyclone_dx/record/component_data.rb +46 -0
  33. data/lib/sbom/cyclone_dx/record/component_evidence.rb +68 -0
  34. data/lib/sbom/cyclone_dx/record/component_identity_evidence.rb +36 -0
  35. data/lib/sbom/cyclone_dx/record/composition.rb +33 -0
  36. data/lib/sbom/cyclone_dx/record/condition.rb +20 -0
  37. data/lib/sbom/cyclone_dx/record/copyright.rb +16 -0
  38. data/lib/sbom/cyclone_dx/record/crypto_properties.rb +137 -0
  39. data/lib/sbom/cyclone_dx/record/data_governance.rb +21 -0
  40. data/lib/sbom/cyclone_dx/record/data_governance_responsible_party.rb +22 -0
  41. data/lib/sbom/cyclone_dx/record/declarations.rb +193 -0
  42. data/lib/sbom/cyclone_dx/record/definitions.rb +17 -0
  43. data/lib/sbom/cyclone_dx/record/dependency.rb +21 -0
  44. data/lib/sbom/cyclone_dx/record/diff.rb +18 -0
  45. data/lib/sbom/cyclone_dx/record/energy_consumption.rb +31 -0
  46. data/lib/sbom/cyclone_dx/record/energy_measure.rb +18 -0
  47. data/lib/sbom/cyclone_dx/record/energy_provider.rb +31 -0
  48. data/lib/sbom/cyclone_dx/record/environmental_consideration.rb +20 -0
  49. data/lib/sbom/cyclone_dx/record/event.rb +31 -0
  50. data/lib/sbom/cyclone_dx/record/external_reference.rb +25 -0
  51. data/lib/sbom/cyclone_dx/record/fairness_assessment.rb +22 -0
  52. data/lib/sbom/cyclone_dx/record/formula.rb +29 -0
  53. data/lib/sbom/cyclone_dx/record/graphic.rb +19 -0
  54. data/lib/sbom/cyclone_dx/record/graphics_collection.rb +19 -0
  55. data/lib/sbom/cyclone_dx/record/hash_data.rb +18 -0
  56. data/lib/sbom/cyclone_dx/record/identifiable_action.rb +21 -0
  57. data/lib/sbom/cyclone_dx/record/input.rb +34 -0
  58. data/lib/sbom/cyclone_dx/record/input_output_ml_parameter.rb +17 -0
  59. data/lib/sbom/cyclone_dx/record/issue.rb +36 -0
  60. data/lib/sbom/cyclone_dx/record/license.rb +90 -0
  61. data/lib/sbom/cyclone_dx/record/license_choice.rb +35 -0
  62. data/lib/sbom/cyclone_dx/record/metadata.rb +55 -0
  63. data/lib/sbom/cyclone_dx/record/model_card.rb +89 -0
  64. data/lib/sbom/cyclone_dx/record/note.rb +20 -0
  65. data/lib/sbom/cyclone_dx/record/organizational_contact.rb +26 -0
  66. data/lib/sbom/cyclone_dx/record/organizational_entity.rb +28 -0
  67. data/lib/sbom/cyclone_dx/record/output.rb +34 -0
  68. data/lib/sbom/cyclone_dx/record/parameter.rb +20 -0
  69. data/lib/sbom/cyclone_dx/record/patch.rb +23 -0
  70. data/lib/sbom/cyclone_dx/record/performance_metric.rb +30 -0
  71. data/lib/sbom/cyclone_dx/record/postal_address.rb +34 -0
  72. data/lib/sbom/cyclone_dx/record/property.rb +18 -0
  73. data/lib/sbom/cyclone_dx/record/rating.rb +27 -0
  74. data/lib/sbom/cyclone_dx/record/release_notes.rb +44 -0
  75. data/lib/sbom/cyclone_dx/record/resource_reference_choice.rb +22 -0
  76. data/lib/sbom/cyclone_dx/record/risk.rb +18 -0
  77. data/lib/sbom/cyclone_dx/record/root.rb +63 -0
  78. data/lib/sbom/cyclone_dx/record/secured_by.rb +20 -0
  79. data/lib/sbom/cyclone_dx/record/service.rb +54 -0
  80. data/lib/sbom/cyclone_dx/record/service_data.rb +32 -0
  81. data/lib/sbom/cyclone_dx/record/signature.rb +85 -0
  82. data/lib/sbom/cyclone_dx/record/standard.rb +72 -0
  83. data/lib/sbom/cyclone_dx/record/step.rb +24 -0
  84. data/lib/sbom/cyclone_dx/record/swid.rb +29 -0
  85. data/lib/sbom/cyclone_dx/record/task.rb +56 -0
  86. data/lib/sbom/cyclone_dx/record/tools.rb +20 -0
  87. data/lib/sbom/cyclone_dx/record/trigger.rb +48 -0
  88. data/lib/sbom/cyclone_dx/record/version.rb +24 -0
  89. data/lib/sbom/cyclone_dx/record/volume.rb +33 -0
  90. data/lib/sbom/cyclone_dx/record/vulnerability.rb +119 -0
  91. data/lib/sbom/cyclone_dx/record/vulnerability_source.rb +20 -0
  92. data/lib/sbom/cyclone_dx/record/workflow.rb +59 -0
  93. data/lib/sbom/cyclone_dx/record/workspace.rb +45 -0
  94. data/lib/sbom/cyclone_dx/record.rb +12 -0
  95. data/lib/sbom/cyclone_dx/validator/array_validator.rb +66 -0
  96. data/lib/sbom/cyclone_dx/validator/base_validator.rb +43 -0
  97. data/lib/sbom/cyclone_dx/validator/boolean_validator.rb +16 -0
  98. data/lib/sbom/cyclone_dx/validator/date_time_validator.rb +29 -0
  99. data/lib/sbom/cyclone_dx/validator/email_address_validator.rb +31 -0
  100. data/lib/sbom/cyclone_dx/validator/float_validator.rb +30 -0
  101. data/lib/sbom/cyclone_dx/validator/integer_validator.rb +30 -0
  102. data/lib/sbom/cyclone_dx/validator/record_validator.rb +26 -0
  103. data/lib/sbom/cyclone_dx/validator/string_validator.rb +33 -0
  104. data/lib/sbom/cyclone_dx/validator/union_validator.rb +39 -0
  105. data/lib/sbom/cyclone_dx/validator/uri_validator.rb +32 -0
  106. data/lib/sbom/cyclone_dx/validator.rb +32 -0
  107. data/lib/sbom/cyclone_dx/version.rb +7 -0
  108. data/lib/sbom/cyclone_dx.rb +39 -0
  109. data/rbs_collection.lock.yaml +288 -0
  110. data/rbs_collection.yaml +31 -0
  111. data/sbom-cyclone_dx.gemspec +32 -0
  112. data/sig/email_address_extension.rbs +14 -0
  113. data/sig/sbom/cyclone_dx/enum.rbs +93 -0
  114. data/sig/sbom/cyclone_dx/field.rbs +434 -0
  115. data/sig/sbom/cyclone_dx/pattern.rbs +24 -0
  116. data/sig/sbom/cyclone_dx/record/advisory.rbs +19 -0
  117. data/sig/sbom/cyclone_dx/record/annotation.rbs +63 -0
  118. data/sig/sbom/cyclone_dx/record/attachment.rbs +24 -0
  119. data/sig/sbom/cyclone_dx/record/base.rbs +62 -0
  120. data/sig/sbom/cyclone_dx/record/cipher_suite.rbs +24 -0
  121. data/sig/sbom/cyclone_dx/record/co2_measure.rbs +14 -0
  122. data/sig/sbom/cyclone_dx/record/command.rbs +19 -0
  123. data/sig/sbom/cyclone_dx/record/commit.rbs +34 -0
  124. data/sig/sbom/cyclone_dx/record/component.rbs +203 -0
  125. data/sig/sbom/cyclone_dx/record/component_data.rbs +73 -0
  126. data/sig/sbom/cyclone_dx/record/component_evidence.rbs +115 -0
  127. data/sig/sbom/cyclone_dx/record/component_identity_evidence.rbs +53 -0
  128. data/sig/sbom/cyclone_dx/record/composition.rbs +39 -0
  129. data/sig/sbom/cyclone_dx/record/condition.rbs +24 -0
  130. data/sig/sbom/cyclone_dx/record/copyright.rbs +14 -0
  131. data/sig/sbom/cyclone_dx/record/crypto_properties.rbs +268 -0
  132. data/sig/sbom/cyclone_dx/record/data_governance.rbs +24 -0
  133. data/sig/sbom/cyclone_dx/record/data_governance_responsible_party.rbs +19 -0
  134. data/sig/sbom/cyclone_dx/record/declarations.rbs +352 -0
  135. data/sig/sbom/cyclone_dx/record/definitions.rbs +14 -0
  136. data/sig/sbom/cyclone_dx/record/dependency.rbs +24 -0
  137. data/sig/sbom/cyclone_dx/record/diff.rbs +19 -0
  138. data/sig/sbom/cyclone_dx/record/energy_consumption.rbs +39 -0
  139. data/sig/sbom/cyclone_dx/record/energy_measure.rbs +14 -0
  140. data/sig/sbom/cyclone_dx/record/energy_provider.rbs +39 -0
  141. data/sig/sbom/cyclone_dx/record/environmental_consideration.rbs +19 -0
  142. data/sig/sbom/cyclone_dx/record/event.rbs +44 -0
  143. data/sig/sbom/cyclone_dx/record/external_reference.rbs +29 -0
  144. data/sig/sbom/cyclone_dx/record/fairness_assessment.rbs +29 -0
  145. data/sig/sbom/cyclone_dx/record/formula.rbs +34 -0
  146. data/sig/sbom/cyclone_dx/record/graphic.rbs +19 -0
  147. data/sig/sbom/cyclone_dx/record/graphics_collection.rbs +19 -0
  148. data/sig/sbom/cyclone_dx/record/hash_data.rbs +19 -0
  149. data/sig/sbom/cyclone_dx/record/identifiable_action.rbs +24 -0
  150. data/sig/sbom/cyclone_dx/record/input.rbs +44 -0
  151. data/sig/sbom/cyclone_dx/record/input_output_ml_parameter.rbs +14 -0
  152. data/sig/sbom/cyclone_dx/record/issue.rbs +53 -0
  153. data/sig/sbom/cyclone_dx/record/license.rbs +134 -0
  154. data/sig/sbom/cyclone_dx/record/license_choice.rbs +39 -0
  155. data/sig/sbom/cyclone_dx/record/metadata.rbs +82 -0
  156. data/sig/sbom/cyclone_dx/record/model_card.rbs +143 -0
  157. data/sig/sbom/cyclone_dx/record/note.rbs +19 -0
  158. data/sig/sbom/cyclone_dx/record/organizational_contact.rbs +29 -0
  159. data/sig/sbom/cyclone_dx/record/organizational_entity.rbs +34 -0
  160. data/sig/sbom/cyclone_dx/record/output.rbs +44 -0
  161. data/sig/sbom/cyclone_dx/record/parameter.rbs +24 -0
  162. data/sig/sbom/cyclone_dx/record/patch.rbs +24 -0
  163. data/sig/sbom/cyclone_dx/record/performance_metric.rbs +43 -0
  164. data/sig/sbom/cyclone_dx/record/postal_address.rbs +44 -0
  165. data/sig/sbom/cyclone_dx/record/property.rbs +19 -0
  166. data/sig/sbom/cyclone_dx/record/rating.rbs +39 -0
  167. data/sig/sbom/cyclone_dx/record/release_notes.rbs +64 -0
  168. data/sig/sbom/cyclone_dx/record/resource_reference_choice.rbs +19 -0
  169. data/sig/sbom/cyclone_dx/record/risk.rbs +19 -0
  170. data/sig/sbom/cyclone_dx/record/root.rbs +84 -0
  171. data/sig/sbom/cyclone_dx/record/secured_by.rbs +19 -0
  172. data/sig/sbom/cyclone_dx/record/service.rbs +99 -0
  173. data/sig/sbom/cyclone_dx/record/service_data.rbs +44 -0
  174. data/sig/sbom/cyclone_dx/record/signature.rbs +130 -0
  175. data/sig/sbom/cyclone_dx/record/standard.rbs +132 -0
  176. data/sig/sbom/cyclone_dx/record/step.rbs +29 -0
  177. data/sig/sbom/cyclone_dx/record/swid.rbs +44 -0
  178. data/sig/sbom/cyclone_dx/record/task.rbs +84 -0
  179. data/sig/sbom/cyclone_dx/record/tools.rbs +19 -0
  180. data/sig/sbom/cyclone_dx/record/trigger.rbs +69 -0
  181. data/sig/sbom/cyclone_dx/record/version.rbs +24 -0
  182. data/sig/sbom/cyclone_dx/record/volume.rbs +49 -0
  183. data/sig/sbom/cyclone_dx/record/vulnerability.rbs +209 -0
  184. data/sig/sbom/cyclone_dx/record/vulnerability_source.rbs +19 -0
  185. data/sig/sbom/cyclone_dx/record/workflow.rbs +94 -0
  186. data/sig/sbom/cyclone_dx/record/workspace.rbs +69 -0
  187. data/sig/sbom/cyclone_dx/record.rbs +161 -0
  188. data/sig/sbom/cyclone_dx/type.rbs +16 -0
  189. data/sig/sbom/cyclone_dx/validator/array_validator.rbs +31 -0
  190. data/sig/sbom/cyclone_dx/validator/base_validator.rbs +21 -0
  191. data/sig/sbom/cyclone_dx/validator/boolean_validator.rbs +9 -0
  192. data/sig/sbom/cyclone_dx/validator/date_time_validator.rbs +10 -0
  193. data/sig/sbom/cyclone_dx/validator/email_address_validator.rbs +10 -0
  194. data/sig/sbom/cyclone_dx/validator/float_validator.rbs +12 -0
  195. data/sig/sbom/cyclone_dx/validator/integer_validator.rbs +12 -0
  196. data/sig/sbom/cyclone_dx/validator/record_validator.rbs +12 -0
  197. data/sig/sbom/cyclone_dx/validator/string_validator.rbs +14 -0
  198. data/sig/sbom/cyclone_dx/validator/union_validator.rbs +24 -0
  199. data/sig/sbom/cyclone_dx/validator/uri_validator.rbs +10 -0
  200. data/sig/sbom/cyclone_dx/validator.rbs +66 -0
  201. data/sig/sbom/cyclone_dx.rbs +13 -0
  202. data/sig/types.rbs +45 -0
  203. data/spec/email_address_extension_spec.rb +27 -0
  204. data/spec/factories/factory_helper.rb +78 -0
  205. data/spec/factories/record/advisory_factory.rb +11 -0
  206. data/spec/factories/record/annotation_factory.rb +63 -0
  207. data/spec/factories/record/attachment_factory.rb +9 -0
  208. data/spec/factories/record/cipher_suite_factory.rb +26 -0
  209. data/spec/factories/record/co2_measure_factory.rb +9 -0
  210. data/spec/factories/record/command_factory.rb +10 -0
  211. data/spec/factories/record/commit_factory.rb +13 -0
  212. data/spec/factories/record/component_data_factory.rb +28 -0
  213. data/spec/factories/record/component_evidence_factory.rb +44 -0
  214. data/spec/factories/record/component_factory.rb +102 -0
  215. data/spec/factories/record/component_identity_evidence_factory.rb +25 -0
  216. data/spec/factories/record/composition_factory.rb +20 -0
  217. data/spec/factories/record/condition_factory.rb +11 -0
  218. data/spec/factories/record/copyright_factory.rb +9 -0
  219. data/spec/factories/record/crypto_properties_factory.rb +191 -0
  220. data/spec/factories/record/data_governance_factory.rb +11 -0
  221. data/spec/factories/record/data_governance_responsible_party_factory.rb +31 -0
  222. data/spec/factories/record/declarations_factory.rb +145 -0
  223. data/spec/factories/record/definitions_factory.rb +9 -0
  224. data/spec/factories/record/dependency_factory.rb +12 -0
  225. data/spec/factories/record/diff_factory.rb +24 -0
  226. data/spec/factories/record/energy_consumption_factory.rb +15 -0
  227. data/spec/factories/record/energy_measure_factory.rb +9 -0
  228. data/spec/factories/record/energy_provider_factory.rb +15 -0
  229. data/spec/factories/record/environmental_consideration_factory.rb +10 -0
  230. data/spec/factories/record/event_factory.rb +15 -0
  231. data/spec/factories/record/external_reference_factory.rb +13 -0
  232. data/spec/factories/record/fairness_assessment_factory.rb +12 -0
  233. data/spec/factories/record/formula_factory.rb +13 -0
  234. data/spec/factories/record/graphic_factory.rb +10 -0
  235. data/spec/factories/record/graphics_collection_factory.rb +10 -0
  236. data/spec/factories/record/hash_data_factory.rb +10 -0
  237. data/spec/factories/record/identifiable_action_factory.rb +11 -0
  238. data/spec/factories/record/input_factory.rb +36 -0
  239. data/spec/factories/record/input_output_ml_parameter_factory.rb +9 -0
  240. data/spec/factories/record/issue_factory.rb +22 -0
  241. data/spec/factories/record/license_choice_factory.rb +23 -0
  242. data/spec/factories/record/license_factory.rb +99 -0
  243. data/spec/factories/record/metadata_factory.rb +38 -0
  244. data/spec/factories/record/model_card_factory.rb +59 -0
  245. data/spec/factories/record/note_factory.rb +11 -0
  246. data/spec/factories/record/organizational_contact_factory.rb +12 -0
  247. data/spec/factories/record/organizational_entity_factory.rb +13 -0
  248. data/spec/factories/record/output_factory.rb +32 -0
  249. data/spec/factories/record/parameter_factory.rb +11 -0
  250. data/spec/factories/record/patch_factory.rb +12 -0
  251. data/spec/factories/record/performance_metric_factory.rb +20 -0
  252. data/spec/factories/record/postal_address_factory.rb +14 -0
  253. data/spec/factories/record/property_factory.rb +11 -0
  254. data/spec/factories/record/rating_factory.rb +14 -0
  255. data/spec/factories/record/release_notes_factory.rb +20 -0
  256. data/spec/factories/record/resource_reference_choice_factory.rb +27 -0
  257. data/spec/factories/record/risk_factory.rb +10 -0
  258. data/spec/factories/record/root_factory.rb +23 -0
  259. data/spec/factories/record/secured_by_factory.rb +10 -0
  260. data/spec/factories/record/service_data_factory.rb +16 -0
  261. data/spec/factories/record/service_factory.rb +27 -0
  262. data/spec/factories/record/signature_factory.rb +50 -0
  263. data/spec/factories/record/standard_factory.rb +37 -0
  264. data/spec/factories/record/step_factory.rb +12 -0
  265. data/spec/factories/record/swid_factory.rb +16 -0
  266. data/spec/factories/record/task_factory.rb +24 -0
  267. data/spec/factories/record/tools_factory.rb +10 -0
  268. data/spec/factories/record/trigger_factory.rb +21 -0
  269. data/spec/factories/record/version_factory.rb +19 -0
  270. data/spec/factories/record/volume_factory.rb +16 -0
  271. data/spec/factories/record/vulnerability_factory.rb +70 -0
  272. data/spec/factories/record/vulnerability_source_factory.rb +10 -0
  273. data/spec/factories/record/workflow_factory.rb +26 -0
  274. data/spec/factories/record/workspace_factory.rb +21 -0
  275. data/spec/factories/record_factory.rb +159 -0
  276. data/spec/fixtures/cipher_info.yml +948 -0
  277. data/spec/fixtures/purl_data.yml +0 -0
  278. data/spec/sbom/cyclone_dx/enum_spec.rb +30 -0
  279. data/spec/sbom/cyclone_dx/field_spec.rb +104 -0
  280. data/spec/sbom/cyclone_dx/pattern_spec.rb +18 -0
  281. data/spec/sbom/cyclone_dx/record/advisory_spec.rb +14 -0
  282. data/spec/sbom/cyclone_dx/record/annotation_spec.rb +31 -0
  283. data/spec/sbom/cyclone_dx/record/attachment_spec.rb +14 -0
  284. data/spec/sbom/cyclone_dx/record/base_spec.rb +363 -0
  285. data/spec/sbom/cyclone_dx/record/cipher_suite_spec.rb +14 -0
  286. data/spec/sbom/cyclone_dx/record/co2_measure_spec.rb +14 -0
  287. data/spec/sbom/cyclone_dx/record/command_spec.rb +14 -0
  288. data/spec/sbom/cyclone_dx/record/commit_spec.rb +14 -0
  289. data/spec/sbom/cyclone_dx/record/component_data_spec.rb +14 -0
  290. data/spec/sbom/cyclone_dx/record/component_evidence_spec.rb +14 -0
  291. data/spec/sbom/cyclone_dx/record/component_identity_evidence_spec.rb +14 -0
  292. data/spec/sbom/cyclone_dx/record/component_spec.rb +14 -0
  293. data/spec/sbom/cyclone_dx/record/composition_spec.rb +14 -0
  294. data/spec/sbom/cyclone_dx/record/condition_spec.rb +14 -0
  295. data/spec/sbom/cyclone_dx/record/copyright_spec.rb +14 -0
  296. data/spec/sbom/cyclone_dx/record/crypto_properties_spec.rb +14 -0
  297. data/spec/sbom/cyclone_dx/record/data_governance_responsible_party_spec.rb +19 -0
  298. data/spec/sbom/cyclone_dx/record/data_governance_spec.rb +14 -0
  299. data/spec/sbom/cyclone_dx/record/declarations_spec.rb +14 -0
  300. data/spec/sbom/cyclone_dx/record/definitions_spec.rb +14 -0
  301. data/spec/sbom/cyclone_dx/record/dependency_spec.rb +14 -0
  302. data/spec/sbom/cyclone_dx/record/diff_spec.rb +14 -0
  303. data/spec/sbom/cyclone_dx/record/energy_consumption_spec.rb +14 -0
  304. data/spec/sbom/cyclone_dx/record/energy_measure_spec.rb +14 -0
  305. data/spec/sbom/cyclone_dx/record/energy_provider_spec.rb +14 -0
  306. data/spec/sbom/cyclone_dx/record/environmental_consideration_spec.rb +14 -0
  307. data/spec/sbom/cyclone_dx/record/event_spec.rb +14 -0
  308. data/spec/sbom/cyclone_dx/record/external_reference_spec.rb +14 -0
  309. data/spec/sbom/cyclone_dx/record/fairness_assessment_spec.rb +14 -0
  310. data/spec/sbom/cyclone_dx/record/formula_spec.rb +14 -0
  311. data/spec/sbom/cyclone_dx/record/graphic_spec.rb +14 -0
  312. data/spec/sbom/cyclone_dx/record/graphics_collection_spec.rb +14 -0
  313. data/spec/sbom/cyclone_dx/record/hash_data_spec.rb +14 -0
  314. data/spec/sbom/cyclone_dx/record/identifiable_action_spec.rb +14 -0
  315. data/spec/sbom/cyclone_dx/record/input_output_ml_parameter_spec.rb +14 -0
  316. data/spec/sbom/cyclone_dx/record/input_spec.rb +14 -0
  317. data/spec/sbom/cyclone_dx/record/issue_spec.rb +14 -0
  318. data/spec/sbom/cyclone_dx/record/license_choice_spec.rb +26 -0
  319. data/spec/sbom/cyclone_dx/record/license_spec.rb +14 -0
  320. data/spec/sbom/cyclone_dx/record/metadata_spec.rb +14 -0
  321. data/spec/sbom/cyclone_dx/record/model_card_spec.rb +14 -0
  322. data/spec/sbom/cyclone_dx/record/note_spec.rb +14 -0
  323. data/spec/sbom/cyclone_dx/record/organizational_contact_spec.rb +14 -0
  324. data/spec/sbom/cyclone_dx/record/organizational_entity_spec.rb +14 -0
  325. data/spec/sbom/cyclone_dx/record/output_spec.rb +14 -0
  326. data/spec/sbom/cyclone_dx/record/parameter_spec.rb +14 -0
  327. data/spec/sbom/cyclone_dx/record/patch_spec.rb +14 -0
  328. data/spec/sbom/cyclone_dx/record/performance_metric_spec.rb +14 -0
  329. data/spec/sbom/cyclone_dx/record/postal_address_spec.rb +14 -0
  330. data/spec/sbom/cyclone_dx/record/property_spec.rb +14 -0
  331. data/spec/sbom/cyclone_dx/record/rating_spec.rb +14 -0
  332. data/spec/sbom/cyclone_dx/record/release_notes_spec.rb +14 -0
  333. data/spec/sbom/cyclone_dx/record/resource_reference_choice_spec.rb +14 -0
  334. data/spec/sbom/cyclone_dx/record/risk_spec.rb +14 -0
  335. data/spec/sbom/cyclone_dx/record/root_spec.rb +14 -0
  336. data/spec/sbom/cyclone_dx/record/secured_by_spec.rb +14 -0
  337. data/spec/sbom/cyclone_dx/record/service_data_spec.rb +14 -0
  338. data/spec/sbom/cyclone_dx/record/service_spec.rb +14 -0
  339. data/spec/sbom/cyclone_dx/record/signature_spec.rb +26 -0
  340. data/spec/sbom/cyclone_dx/record/standard_spec.rb +14 -0
  341. data/spec/sbom/cyclone_dx/record/step_spec.rb +14 -0
  342. data/spec/sbom/cyclone_dx/record/swid_spec.rb +14 -0
  343. data/spec/sbom/cyclone_dx/record/task_spec.rb +14 -0
  344. data/spec/sbom/cyclone_dx/record/tools_spec.rb +14 -0
  345. data/spec/sbom/cyclone_dx/record/trigger_spec.rb +14 -0
  346. data/spec/sbom/cyclone_dx/record/version_spec.rb +14 -0
  347. data/spec/sbom/cyclone_dx/record/volume_spec.rb +14 -0
  348. data/spec/sbom/cyclone_dx/record/vulnerability_source_spec.rb +14 -0
  349. data/spec/sbom/cyclone_dx/record/vulnerability_spec.rb +14 -0
  350. data/spec/sbom/cyclone_dx/record/workflow_spec.rb +14 -0
  351. data/spec/sbom/cyclone_dx/record/workspace_spec.rb +14 -0
  352. data/spec/sbom/cyclone_dx/record_spec.rb +7 -0
  353. data/spec/sbom/cyclone_dx/validator/array_validator_spec.rb +184 -0
  354. data/spec/sbom/cyclone_dx/validator/base_validator_spec.rb +71 -0
  355. data/spec/sbom/cyclone_dx/validator/boolean_validator_spec.rb +26 -0
  356. data/spec/sbom/cyclone_dx/validator/date_time_validator_spec.rb +28 -0
  357. data/spec/sbom/cyclone_dx/validator/email_address_validator_spec.rb +23 -0
  358. data/spec/sbom/cyclone_dx/validator/float_validator_spec.rb +71 -0
  359. data/spec/sbom/cyclone_dx/validator/integer_validator_spec.rb +71 -0
  360. data/spec/sbom/cyclone_dx/validator/record_validator_spec.rb +35 -0
  361. data/spec/sbom/cyclone_dx/validator/string_validator_spec.rb +94 -0
  362. data/spec/sbom/cyclone_dx/validator/union_validator_spec.rb +65 -0
  363. data/spec/sbom/cyclone_dx/validator/uri_validator_spec.rb +21 -0
  364. data/spec/sbom/cyclone_dx/validator_spec.rb +38 -0
  365. data/spec/sbom/cyclone_dx/version_spec.rb +9 -0
  366. data/spec/sbom/cyclone_dx_spec.rb +7 -0
  367. data/spec/spec_helper.rb +39 -0
  368. metadata +377 -6
@@ -0,0 +1,404 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "validator/array_validator"
4
+ require_relative "validator/boolean_validator"
5
+ require_relative "validator/date_time_validator"
6
+ require_relative "validator/email_address_validator"
7
+ require_relative "validator/float_validator"
8
+ require_relative "validator/integer_validator"
9
+ require_relative "validator/record_validator"
10
+ require_relative "validator/string_validator"
11
+ require_relative "validator/union_validator"
12
+ require_relative "validator/uri_validator"
13
+ require_relative "pattern"
14
+
15
+ module SBOM
16
+ module CycloneDX
17
+ module Field # rubocop:disable Metrics/ModuleLength
18
+ class Base
19
+ attr_reader :errors, :value
20
+
21
+ def initialize
22
+ raise "Cannot instantiate abstract Field"
23
+ end
24
+
25
+ def value?
26
+ @value.nil?
27
+ end
28
+
29
+ def valid?
30
+ @errors = validator.validate(value)
31
+ @errors.empty?
32
+ end
33
+
34
+ %i[
35
+ field_name
36
+ validator
37
+ json_name
38
+ required?
39
+ const?
40
+ const
41
+ default?
42
+ default
43
+ ].each { |m| define_method(m) { self.class.public_send(m) } }
44
+
45
+ class << self
46
+ attr_reader :field_name, :validator, :json_name, :const
47
+
48
+ def required?
49
+ validator.required?
50
+ end
51
+
52
+ def const?
53
+ @const_present
54
+ end
55
+
56
+ def default
57
+ # Skip type-checking here because it is already checked, and Steep is cranky about these
58
+ default_value = _ = @default
59
+ return default_value unless default_value.is_a?(Proc)
60
+
61
+ default_value.call
62
+ end
63
+
64
+ def default?
65
+ @default_present
66
+ end
67
+ end
68
+ end
69
+
70
+ class ConstBase < Base
71
+ def initialize # rubocop:disable Lint/MissingSuper
72
+ raise "Cannot instantiate abstract Field" unless self.class < ConstBase
73
+
74
+ @errors = []
75
+ @value_set = true
76
+ @value = const
77
+ end
78
+ end
79
+
80
+ class PropBase < Base
81
+ def initialize(*value) # rubocop:disable Lint/MissingSuper
82
+ raise "Cannot instantiate abstract Field" unless self.class < PropBase
83
+ raise ArgumentError, "Wrong number of arguments" if value.size > 1
84
+
85
+ if value.empty?
86
+ unset_value
87
+ return
88
+ end
89
+
90
+ self.value = value.first
91
+ end
92
+
93
+ def value=(val)
94
+ if val.nil? && required?
95
+ @value_set = !default?
96
+ @value = default
97
+ return
98
+ end
99
+
100
+ @value_set = true
101
+ @value = val
102
+ end
103
+
104
+ def unset_value
105
+ @value_set = !default?
106
+ @value = default
107
+ end
108
+
109
+ def self.coerce(_value)
110
+ raise NotImplementedError
111
+ end
112
+ end
113
+
114
+ class << self # rubocop:disable Metrics/ClassLength
115
+ def array(field_name:, items:, unique: false, required: false, json_name: nil, const: :undefined, # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
116
+ default: :undefined)
117
+ validator = Validator::ArrayValidator.new(items: items, unique: unique, required: required)
118
+ Field(
119
+ field_name: field_name,
120
+ type: :array,
121
+ validator: validator,
122
+ json_name: json_name,
123
+ const: const,
124
+ default: default
125
+ ) do |value|
126
+ raise TypeError, "Expected Array, got #{value.class}" unless value.is_a?(::Array) || value.nil?
127
+ next value if value.nil?
128
+
129
+ value.map do |item|
130
+ next item if validator.raw_types.any? { |type| item.is_a?(type) } || item.nil?
131
+
132
+ if item.is_a?(Hash)
133
+ coerced_value = validator.raw_types.filter_map do |type|
134
+ next nil unless type < SBOM::CycloneDX::Record::Base
135
+
136
+ begin
137
+ type.new(**item)
138
+ rescue StandardError
139
+ nil
140
+ end
141
+ end
142
+
143
+ next coerced_value.first if coerced_value.any?
144
+ end
145
+
146
+ raise TypeError, "Expected one of #{items.to_json}, got #{value.class}"
147
+ end
148
+ end
149
+ end
150
+
151
+ def boolean(field_name:, json_name: nil, required: false, const: :undefined, default: :undefined) # rubocop:disable Metrics/MethodLength
152
+ Field(
153
+ field_name: field_name,
154
+ type: :boolean,
155
+ validator: SBOM::CycloneDX::Validator::BooleanValidator.new(required: required),
156
+ json_name: json_name,
157
+ const: const,
158
+ default: default
159
+ ) do |value|
160
+ next value if value.is_a?(TrueClass) || value.is_a?(FalseClass) || value.nil?
161
+
162
+ raise TypeError, "Expected Boolean, got #{value.class}"
163
+ end
164
+ end
165
+
166
+ def date_time(field_name:, json_name: nil, required: false, const: :undefined, default: :undefined) # rubocop:disable Metrics/MethodLength
167
+ Field(
168
+ field_name: field_name,
169
+ type: :date_time,
170
+ validator: SBOM::CycloneDX::Validator::DateTimeValidator.new(required: required),
171
+ json_name: json_name,
172
+ const: const,
173
+ default: default
174
+ ) do |value|
175
+ next value if value.is_a?(::Time) || value.is_a?(::DateTime) || value.is_a?(::String) || value.nil?
176
+
177
+ raise TypeError, "Expected Time, DateTime, or String, got #{value.class}"
178
+ end
179
+ end
180
+
181
+ def email_address(field_name:, json_name: nil, required: false, const: :undefined, default: :undefined) # rubocop:disable Metrics/MethodLength
182
+ Field(
183
+ field_name: field_name,
184
+ type: :email_address,
185
+ validator: SBOM::CycloneDX::Validator::EmailAddressValidator.new(required: required),
186
+ json_name: json_name,
187
+ const: const,
188
+ default: default
189
+ ) do |value|
190
+ next value if value.is_a?(EmailAddress::Address) || value.is_a?(String) || value.nil?
191
+
192
+ raise TypeError, "Expected EmailAddress::Address or String, got #{value.class}"
193
+ end
194
+ end
195
+
196
+ def float(field_name:, minimum: nil, maximum: nil, required: false, const: :undefined, default: :undefined, # rubocop:disable Metrics/MethodLength
197
+ json_name: nil)
198
+ Field(
199
+ field_name: field_name,
200
+ type: :float,
201
+ validator: SBOM::CycloneDX::Validator::FloatValidator.new(
202
+ minimum: minimum,
203
+ maximum: maximum,
204
+ required: required
205
+ ),
206
+ json_name: json_name,
207
+ const: const,
208
+ default: default
209
+ ) do |value|
210
+ next value if value.is_a?(::Float) || value.nil?
211
+
212
+ raise TypeError, "Expected Float, got #{value.class}"
213
+ end
214
+ end
215
+
216
+ def integer(field_name:, minimum: nil, maximum: nil, required: false, const: :undefined, default: :undefined, # rubocop:disable Metrics/MethodLength
217
+ json_name: nil)
218
+ Field(
219
+ field_name: field_name,
220
+ type: :integer,
221
+ validator: SBOM::CycloneDX::Validator::IntegerValidator.new(
222
+ minimum: minimum,
223
+ maximum: maximum,
224
+ required: required
225
+ ),
226
+ json_name: json_name,
227
+ const: const,
228
+ default: default
229
+ ) do |value|
230
+ next value if value.is_a?(::Integer) || value.nil?
231
+
232
+ raise TypeError, "Expected Integer, got #{value.class}"
233
+ end
234
+ end
235
+
236
+ def record(field_name:, klass:, json_name: nil, required: false, const: :undefined, default: :undefined) # rubocop:disable Metrics/MethodLength
237
+ Field(
238
+ field_name: field_name,
239
+ type: klass,
240
+ validator: SBOM::CycloneDX::Validator::RecordValidator.new(type: klass, required: required),
241
+ json_name: json_name,
242
+ const: const,
243
+ default: default
244
+ ) do |value|
245
+ next value if value.is_a?(klass) || value.nil?
246
+ next klass.new(**value) if value.is_a?(::Hash)
247
+
248
+ raise TypeError, "Expected #{klass.name}, got #{value.class}"
249
+ end
250
+ end
251
+
252
+ def string( # rubocop:disable Metrics/MethodLength
253
+ field_name:,
254
+ enum: nil,
255
+ max_length: nil,
256
+ min_length: nil,
257
+ pattern: Pattern::DEFAULT,
258
+ required: false,
259
+ const: :undefined,
260
+ default: :undefined,
261
+ json_name: nil
262
+ )
263
+ Field(
264
+ field_name: field_name,
265
+ type: :string,
266
+ validator: SBOM::CycloneDX::Validator::StringValidator.new(
267
+ enum: enum,
268
+ max_length: max_length,
269
+ min_length: min_length,
270
+ pattern: pattern,
271
+ required: required
272
+ ),
273
+ json_name: json_name,
274
+ const: const,
275
+ default: default
276
+ ) do |value|
277
+ next value if value.is_a?(::String) || value.nil?
278
+
279
+ raise TypeError, "Expected String, got #{value.class}"
280
+ end
281
+ end
282
+
283
+ def union(field_name:, of:, required: false, const: :undefined, default: :undefined, json_name: nil) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
284
+ validator = SBOM::CycloneDX::Validator::UnionValidator.new(required: required, of: of)
285
+ Field(
286
+ field_name: field_name,
287
+ type: :union,
288
+ validator: validator,
289
+ json_name: json_name,
290
+ const: const,
291
+ default: default
292
+ ) do |value|
293
+ next value if validator.raw_types.any? { |type| value.is_a?(type) } || value.nil?
294
+
295
+ if value.is_a?(Hash)
296
+ coerced_value = validator.raw_types.filter_map do |type|
297
+ next nil unless type < SBOM::CycloneDX::Record::Base
298
+
299
+ begin
300
+ type.new(**value)
301
+ rescue StandardError
302
+ nil
303
+ end
304
+ end
305
+
306
+ next coerced_value.first if coerced_value.any?
307
+ end
308
+
309
+ raise TypeError, "Expected one of #{of.map(&:to_s).join(", ")}, got #{value.class}"
310
+ end
311
+ end
312
+
313
+ def uri(field_name:, json_name: nil, required: false, const: :undefined, default: :undefined) # rubocop:disable Metrics/MethodLength
314
+ Field(
315
+ field_name: field_name,
316
+ type: :uri,
317
+ validator: SBOM::CycloneDX::Validator::URIValidator.new(required: required),
318
+ json_name: json_name,
319
+ const: const,
320
+ default: default
321
+ ) do |value|
322
+ next value if value.is_a?(::URI::Generic) || value.is_a?(::String) || value.nil?
323
+
324
+ raise TypeError, "Expected URI or String, got #{value.class}"
325
+ end
326
+ end
327
+
328
+ private
329
+
330
+ def make_const_default_hash(const, default)
331
+ raise ArgumentError, "Can not set both :const and :default" if const != :undefined && default != :undefined
332
+
333
+ return { const: const } if const != :undefined
334
+ return { default: default } if default != :undefined
335
+
336
+ {}
337
+ end
338
+
339
+ def Field(field_name:, type:, validator:, json_name: nil, const: :undefined, default: :undefined, &coerce_block) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity, Naming/MethodName
340
+ const_and_default_set = const != :undefined && default != :undefined
341
+ raise "Can not set both :const and :default" if const_and_default_set
342
+
343
+ const_present = const != :undefined
344
+ const_value = const_present ? const : nil #: fieldValue
345
+ default_present = default != :undefined
346
+ default_value = default_present ? default : nil #: defaultValue[fieldValue]
347
+
348
+ json_name ||= field_name.to_s.camelize(:lower)
349
+
350
+ const_and_default = {} #: { ?const: fieldValue?, ?default: defaultValue[fieldValue]? }
351
+ const_and_default[:const] = const_value if const_present
352
+ const_and_default[:default] = default_value if default_present
353
+
354
+ validate_types(type, validator, **const_and_default)
355
+
356
+ base_klass = const_present ? ConstBase : PropBase
357
+
358
+ _ = Class.new(base_klass).tap do |field_class|
359
+ field_class.instance_variable_set(:@field_name, field_name)
360
+ field_class.instance_variable_set(:@validator, validator)
361
+ field_class.instance_variable_set(:@json_name, json_name)
362
+ field_class.instance_variable_set(:@const_present, const_present)
363
+ field_class.instance_variable_set(:@const, const_value)
364
+ field_class.instance_variable_set(:@default_present, default_present)
365
+ field_class.instance_variable_set(:@default, default_value)
366
+ field_class.define_singleton_method(:coerce, &coerce_block)
367
+ end
368
+ end
369
+
370
+ def validate_types(type, validator, **const_and_default) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/MethodLength,Metrics/AbcSize,Metrics/PerceivedComplexity
371
+ const_set = const_and_default.key?(:const)
372
+ const = const_and_default[:const]
373
+ default_set = const_and_default.key?(:default)
374
+ default = const_and_default[:default].then { |dv| dv.is_a?(Proc) ? dv.call : dv }
375
+
376
+ validator_klass =
377
+ case type
378
+ when :array then Validator::ArrayValidator
379
+ when :boolean then Validator::BooleanValidator
380
+ when :date_time then Validator::DateTimeValidator
381
+ when :email_address then Validator::EmailAddressValidator
382
+ when :float then Validator::FloatValidator
383
+ when :integer then Validator::IntegerValidator
384
+ when Class then Validator::RecordValidator
385
+ when :string then Validator::StringValidator
386
+ when :union then Validator::UnionValidator
387
+ when :uri then Validator::URIValidator
388
+ else raise "Unknown type: #{type}"
389
+ end
390
+
391
+ unless validator.is_a?(validator_klass)
392
+ raise TypeError, "Incorrect validator #{validator.class.name} for #{type}"
393
+ end
394
+
395
+ const_errors = const_set ? validator.validate(const) : [] #: ::Array[String]
396
+ default_errors = default_set ? validator.validate(default) : [] #: ::Array[String]
397
+
398
+ raise "Invalid value for const:\n#{const_errors.join("\n")}" if const_errors.any?
399
+ raise "Invalid value for default:\n#{default_errors.join("\n")}" if default_errors.any?
400
+ end
401
+ end
402
+ end
403
+ end
404
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SBOM
4
+ module CycloneDX
5
+ module Pattern
6
+ # While we currently only support Regexp patterns, this may change in the future. Some of the relevant
7
+ # standards/specifications use BNF grammars, which may not be representable as Regexp patterns.
8
+
9
+ UUID = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/
10
+
11
+ CDX_URN_FRAGMENT = %r{([a-z0-9._~!$&'()*+,;=:@/?-]|%[0-9a-f][0-9a-f])+}i
12
+ CDX_BOM_VERSION = /[1-9][0-9]*/
13
+ CDX_URN_NSS = %r{#{UUID}/#{CDX_BOM_VERSION}}
14
+ CDX_URN_ASSIGNED_NAME = /urn:cdx:#{CDX_URN_NSS}/
15
+ CDX_URN = /#{CDX_URN_ASSIGNED_NAME}(##{CDX_URN_FRAGMENT})?/
16
+
17
+ BOM_SERIAL_NUMBER = /urn:uuid:#{UUID}/
18
+
19
+ CDX_URN_WITH_FRAGMENT = /#{CDX_URN_ASSIGNED_NAME}##{CDX_URN_FRAGMENT}/
20
+ REF_LINK = /(?!urn:cdx:)#{CDX_URN_FRAGMENT}+/
21
+ REF_OR_CDX_URN = /(#{REF_LINK}|#{CDX_URN_WITH_FRAGMENT})/
22
+
23
+ HASH_VALUE = /([a-fA-F0-9]{32}|[a-fA-F0-9]{40}|[a-fA-F0-9]{64}|[a-fA-F0-9]{96}|[a-fA-F0-9]{128})/
24
+ LOCALE = /([a-z]{2})(-[A-Z]{2})?/
25
+ MIME_TYPE = %r{[-+a-z0-9.]+/[-+a-z0-9.]+}
26
+ OPEN_CRE = /CRE:[0-9]+-[0-9]+/
27
+
28
+ CONTENT_TYPE = %r{
29
+ ([0-9A-Za-z!#$%&'*+.^_`|~-]+|x-(?:[0-9A-Za-z!#$%&'*+.^_`|~-]+))
30
+ /
31
+ ([0-9A-Za-z!#$%&'*+.^_`|~-]+)
32
+ ((?:[ \t]*;[ \t]*[0-9A-Za-z!#$%&'*+.^_`|~-]+=(?:[0-9A-Za-z!#$%&'*+.^_`|~-]+|"(?:[^"\\]|\\.)*"))*)
33
+ }x
34
+
35
+ # This is used when no patern is provided for validation
36
+ DEFAULT = /.*/m
37
+
38
+ def self.match_exactly?(pattern, value)
39
+ /\A#{pattern}\z/.match?(value)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "uri"
4
+ require_relative "base"
5
+
6
+ # Advisory - Title and location where advisory information can be obtained. An advisory is a notification of a threat to a component, service, or system.
7
+ module SBOM
8
+ module CycloneDX
9
+ module Record
10
+ # Schema name: Advisory
11
+ class Advisory < Base
12
+ prop :title, :string
13
+ prop :url, :uri, required: true
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../pattern"
4
+ require_relative "base"
5
+ require_relative "component"
6
+ require_relative "organizational_contact"
7
+ require_relative "organizational_entity"
8
+ require_relative "service"
9
+ require_relative "signature"
10
+
11
+ # Annotations - A comment, note, explanation, or similar textual content which provides additional context to the object(s) being annotated.
12
+ module SBOM
13
+ module CycloneDX
14
+ module Record
15
+ # Schema name: Annotation
16
+ class Annotation < Base
17
+ # Schema name: Annotator
18
+ class Annotator < Base
19
+ # Organization - The organization that created the annotation
20
+ prop :organization, OrganizationalEntity
21
+ # Individual - The person that created the annotation
22
+ prop :individual, OrganizationalContact
23
+ # Component - The tool or component that created the annotation
24
+ prop :component, Component
25
+ # Service - The service that created the annotation
26
+ prop :service, Service
27
+
28
+ validate :organization, :individual, :component, :service, presence: :any
29
+ end
30
+
31
+ # BOM Reference - An optional identifier which can be used to reference the annotation elsewhere in the BOM. Every bom-ref must be unique within the BOM. Value SHOULD not start with the BOM-Link intro 'urn:cdx:' to avoid conflicts with BOM-Links.
32
+ prop :bom_ref, :string, pattern: Pattern::REF_LINK, json_name: "bom-ref"
33
+ # Subjects - The object in the BOM identified by its bom-ref. This is often a component or service, but may be any object type supporting bom-refs.
34
+ prop :subjects, :array, items: [:string, pattern: Pattern::REF_OR_CDX_URN], unique: true, required: true
35
+ # Annotator - The organization, person, component, or service which created the textual content of the annotation.
36
+ prop :annotator, Annotator, required: true
37
+ # Timestamp - The date and time (timestamp) when the annotation was created.
38
+ prop :timestamp, :date_time, required: true
39
+ # Text - The textual content of the annotation.
40
+ prop :text, :string, required: true
41
+ # Signature - Enveloped signature in [JSON Signature Format (JSF)](https://cyberphone.github.io/doc/security/jsf.html).
42
+ prop :signature, :union, of: [Signature::JSFSignature, Signature::SignatureChain, Signature::SignerList]
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../pattern"
4
+ require_relative "base"
5
+
6
+ # Attachment - Specifies the metadata and content for an attachment.
7
+ module SBOM
8
+ module CycloneDX
9
+ module Record
10
+ # Schema name: Attachment
11
+ class Attachment < Base
12
+ # Content-Type - Specifies the format and nature of the data being attached, helping systems correctly interpret and process the content. Common content type examples include `application/json` for JSON data and `text/plain` for plan text documents. [RFC 2045 section 5.1](https://www.ietf.org/rfc/rfc2045.html#section-5.1) outlines the structure and use of content types. For a comprehensive list of registered content types, refer to the [IANA media types registry](https://www.iana.org/assignments/media-types/media-types.xhtml).
13
+ prop :content_type, :string, pattern: Pattern::CONTENT_TYPE, required: true, default: "text/plain"
14
+ # Attachment Text - The attachment data. Proactive controls such as input validation and sanitization should be employed to prevent misuse of attachment text.
15
+ prop :content, :string, required: true
16
+ # Encoding - Specifies the optional encoding the text is represented in.
17
+ const :encoding, :string, "base64"
18
+ end
19
+ end
20
+ end
21
+ end