diff --git a/ontology/uco/observable/observable.ttl b/ontology/uco/observable/observable.ttl
index 37dc84be..0c9feee3 100644
--- a/ontology/uco/observable/observable.ttl
+++ b/ontology/uco/observable/observable.ttl
@@ -2242,6 +2242,12 @@ observable:DeviceFacet
sh:nodeKind sh:IRI ;
sh:path observable:manufacturer ;
] ,
+ [
+ sh:datatype xsd:string ;
+ sh:maxCount "1"^^xsd:integer ;
+ sh:nodeKind sh:Literal ;
+ sh:path observable:cpeid ;
+ ] ,
[
sh:datatype xsd:string ;
sh:maxCount "1"^^xsd:integer ;
@@ -2259,6 +2265,12 @@ observable:DeviceFacet
sh:maxCount "1"^^xsd:integer ;
sh:nodeKind sh:Literal ;
sh:path observable:serialNumber ;
+ ] ,
+ [
+ sh:message "In UCO 2.0.0, cpeid in DeviceFacet will be constrained to be a CPE version 2.3 hardware name."@en ;
+ sh:path observable:cpeid ;
+ sh:pattern "^cpe:2.3:h:.+" ;
+ sh:severity sh:Warning ;
]
;
sh:targetClass observable:DeviceFacet ;
@@ -5150,6 +5162,15 @@ observable:OperatingSystem
rdfs:subClassOf observable:ObservableObject ;
rdfs:label "OperatingSystem"@en ;
rdfs:comment "An operating system is the software that manages computer hardware, software resources, and provides common services for computer programs. [based on https://en.wikipedia.org/wiki/Operating_system]"@en ;
+ sh:property [
+ sh:message "In UCO 2.0.0, cpeid in any Facet attached to an OperatingSystem will be constrained to be a CPE version 2.3 operating system name."@en ;
+ sh:path (
+ core:hasFacet
+ observable:cpeid
+ ) ;
+ sh:pattern "^cpe:2.3:o:.+" ;
+ sh:severity sh:Warning ;
+ ] ;
sh:targetClass observable:OperatingSystem ;
.
@@ -5202,6 +5223,12 @@ observable:OperatingSystemFacet
sh:datatype xsd:string ;
sh:nodeKind sh:Literal ;
sh:path observable:advertisingID ;
+ ] ,
+ [
+ sh:maxCount "0"^^xsd:integer ;
+ sh:message "observable:cpeid should appear on a SoftwareFacet instead of an OperatingSystemFacet."@en ;
+ sh:path observable:cpeid ;
+ sh:severity sh:Warning ;
]
;
sh:targetClass observable:OperatingSystemFacet ;
@@ -6207,6 +6234,12 @@ observable:SoftwareFacet
sh:maxCount "1"^^xsd:integer ;
sh:nodeKind sh:Literal ;
sh:path observable:version ;
+ ] ,
+ [
+ sh:message "In UCO 2.0.0, cpeid in SoftwareFacet will be constrained to be a CPE version 2.3 application or operating system name."@en ;
+ sh:path observable:cpeid ;
+ sh:pattern "^cpe:2.3:[a,o]:.+" ;
+ sh:severity sh:Warning ;
]
;
sh:targetClass observable:SoftwareFacet ;
diff --git a/tests/examples/Makefile b/tests/examples/Makefile
index 66b33e05..2ccd0c04 100644
--- a/tests/examples/Makefile
+++ b/tests/examples/Makefile
@@ -26,6 +26,7 @@ all: \
co_XFAIL_validation.ttl \
configuration_setting_PASS_validation.ttl \
configuration_setting_XFAIL_validation.ttl \
+ cpe_PASS_validation.ttl \
database_records_PASS_validation.ttl \
database_records_XFAIL_validation.ttl \
dictionary_PASS_validation.ttl \
@@ -101,6 +102,7 @@ check: \
co_XFAIL_validation.ttl \
configuration_setting_PASS_validation.ttl \
configuration_setting_XFAIL_validation.ttl \
+ cpe_PASS_validation.ttl \
database_records_PASS_validation.ttl \
database_records_XFAIL_validation.ttl \
dictionary_PASS_validation.ttl \
diff --git a/tests/examples/cpe_PASS.json b/tests/examples/cpe_PASS.json
new file mode 100644
index 00000000..56555ab5
--- /dev/null
+++ b/tests/examples/cpe_PASS.json
@@ -0,0 +1,84 @@
+{
+ "@context": {
+ "core": "https://ontology.unifiedcyberontology.org/uco/core/",
+ "ex": "http://example.org/ontology/",
+ "kb": "http://example.org/kb/",
+ "observable": "https://ontology.unifiedcyberontology.org/uco/observable/",
+ "rdfs": "http://www.w3.org/2000/01/rdf-schema#"
+ },
+ "@graph": [
+ {
+ "@id": "kb:Device-3b8fde6f-0f0b-4472-b9c8-31380eb80dc3",
+ "@type": "observable:Tablet",
+ "core:hasFacet": {
+ "@id": "kb:DeviceFacet-4a1cdff8-be81-46e3-8502-0f488d353ca0",
+ "@type": "observable:DeviceFacet",
+ "rdfs:comment": "This node will trigger a warning for assigning an operating system CPE to a device. This will be an error in UCO 2.0.0.",
+ "observable:cpeid": "cpe:2.3:o:exampleco:exampletabletos:-:*:*:*:*:*:*:*"
+ }
+ },
+ {
+ "@id": "ex:hadInventoryNumber",
+ "@type": "owl:DatatypeProperty",
+ "rdfs:domain": "observable:Tablet",
+ "rdfs:range": "xsd:string"
+ },
+ {
+ "@id": "kb:Device-b1432774-082d-4eda-ad2e-fcdbe159d37c",
+ "@type": "observable:Tablet",
+ "core:hasFacet": {
+ "@id": "kb:DeviceFacet-57721427-8a91-4b2a-a685-8de72cabdebc",
+ "@type": "observable:DeviceFacet",
+ "observable:cpeid": "cpe:2.3:h:exampleco:exampletablet:-:*:*:*:*:*:*:*",
+ "observable:serialNumber": "XYZ56780000000002"
+ },
+ "ex:hadInventoryNumber": "TAB-1234"
+ },
+ {
+ "@id": "kb:OperatingSystem-628d531f-254c-4efb-aaa0-0874306afa01",
+ "@type": "observable:OperatingSystem",
+ "core:name": "ExampleTabletOS",
+ "core:hasFacet": {
+ "@id": "kb:SoftwareFacet-ff426a44-65eb-4940-b61a-d70357273a8c",
+ "@type": "observable:SoftwareFacet",
+ "rdfs:comment": "This node will trigger a warning for assigning an Application CPE for an OperatingSystem. This will be an error in UCO 2.0.0.",
+ "observable:cpeid": "cpe:2.3:a:exampleco:exampletabletos:2024.06:*:*:*:*:*:*:*",
+ "observable:version": "2024.06"
+ }
+ },
+ {
+ "@id": "kb:OperatingSystem-7f06e899-2dbb-4847-9956-5c4a68723c49",
+ "@type": "observable:OperatingSystem",
+ "core:name": "ExampleTabletOS",
+ "core:hasFacet": {
+ "@id": "kb:OperatingSystemFacet-872c1ba2-e1b4-4bc6-8267-6dbed687d0be",
+ "@type": "observable:OperatingSystemFacet",
+ "rdfs:comment": "This node will trigger a warning for assigning a CPE with an OperatingSystemFacet. This will be an error in UCO 2.0.0.",
+ "observable:cpeid": "cpe:2.3:o:exampleco:exampletabletos:2024.07:*:*:*:*:*:*:*",
+ "observable:version": "2024.07"
+ }
+ },
+ {
+ "@id": "kb:OperatingSystem-cbbaf178-ccc0-495e-a068-65085d499d7f",
+ "@type": "observable:OperatingSystem",
+ "core:name": "ExampleTabletOS",
+ "core:hasFacet": {
+ "@id": "kb:SoftwareFacet-b2b8ed66-f681-4eda-b013-b8861843420c",
+ "@type": "observable:SoftwareFacet",
+ "observable:cpeid": "cpe:2.3:o:exampleco:exampletabletos:2024.08:*:*:*:*:*:*:*",
+ "observable:version": "2024.08"
+ }
+ },
+ {
+ "@id": "kb:Software-687a7648-6902-4233-a37d-f31bb2245a15",
+ "@type": "observable:Software",
+ "core:name": "ExampleCalculator",
+ "core:hasFacet": {
+ "@id": "kb:SoftwareFacet-cd6d68ae-9248-4657-86d4-a4fe398f1004",
+ "@type": "observable:SoftwareFacet",
+ "observable:cpeid": "cpe:2.3:a:exampleco:examplecalculator:5.5:*:*:*:*:*:*:*",
+ "observable:version": "5.5"
+ }
+ }
+ ]
+}
diff --git a/tests/examples/cpe_PASS_validation.ttl b/tests/examples/cpe_PASS_validation.ttl
new file mode 100644
index 00000000..617122ba
--- /dev/null
+++ b/tests/examples/cpe_PASS_validation.ttl
@@ -0,0 +1,65 @@
+@prefix core: .
+@prefix observable: .
+@prefix owl: .
+@prefix rdf: .
+@prefix rdfs: .
+@prefix sh: .
+@prefix xsd: .
+
+[]
+ a sh:ValidationReport ;
+ sh:conforms "true"^^xsd:boolean ;
+ sh:result
+ [
+ a sh:ValidationResult ;
+ sh:focusNode ;
+ sh:resultMessage "In UCO 2.0.0, cpeid in DeviceFacet will be constrained to be a CPE version 2.3 hardware name."@en ;
+ sh:resultPath observable:cpeid ;
+ sh:resultSeverity sh:Warning ;
+ sh:sourceConstraintComponent sh:PatternConstraintComponent ;
+ sh:sourceShape [
+ sh:message "In UCO 2.0.0, cpeid in DeviceFacet will be constrained to be a CPE version 2.3 hardware name."@en ;
+ sh:path observable:cpeid ;
+ sh:pattern "^cpe:2.3:h:.+" ;
+ sh:severity sh:Warning ;
+ ] ;
+ sh:value "cpe:2.3:o:exampleco:exampletabletos:-:*:*:*:*:*:*:*" ;
+ ] ,
+ [
+ a sh:ValidationResult ;
+ sh:focusNode ;
+ sh:resultMessage "In UCO 2.0.0, cpeid in any Facet attached to an OperatingSystem will be constrained to be a CPE version 2.3 operating system name."@en ;
+ sh:resultPath (
+ core:hasFacet
+ observable:cpeid
+ ) ;
+ sh:resultSeverity sh:Warning ;
+ sh:sourceConstraintComponent sh:PatternConstraintComponent ;
+ sh:sourceShape [
+ sh:message "In UCO 2.0.0, cpeid in any Facet attached to an OperatingSystem will be constrained to be a CPE version 2.3 operating system name."@en ;
+ sh:path (
+ core:hasFacet
+ observable:cpeid
+ ) ;
+ sh:pattern "^cpe:2.3:o:.+" ;
+ sh:severity sh:Warning ;
+ ] ;
+ sh:value "cpe:2.3:a:exampleco:exampletabletos:2024.06:*:*:*:*:*:*:*" ;
+ ] ,
+ [
+ a sh:ValidationResult ;
+ sh:focusNode ;
+ sh:resultMessage "observable:cpeid should appear on a SoftwareFacet instead of an OperatingSystemFacet."@en ;
+ sh:resultPath observable:cpeid ;
+ sh:resultSeverity sh:Warning ;
+ sh:sourceConstraintComponent sh:MaxCountConstraintComponent ;
+ sh:sourceShape [
+ sh:maxCount "0"^^xsd:integer ;
+ sh:message "observable:cpeid should appear on a SoftwareFacet instead of an OperatingSystemFacet."@en ;
+ sh:path observable:cpeid ;
+ sh:severity sh:Warning ;
+ ] ;
+ ]
+ ;
+ .
+
diff --git a/tests/examples/test_validation.py b/tests/examples/test_validation.py
index 6c4fc658..95d80d8d 100644
--- a/tests/examples/test_validation.py
+++ b/tests/examples/test_validation.py
@@ -200,6 +200,17 @@ def test_configuration_setting_XFAIL_validation() -> None:
}
)
+def test_cpe_PASS_validation() -> None:
+ confirm_validation_results(
+ "cpe_PASS_validation.ttl",
+ True,
+ expected_focus_node_severities={
+ ("http://example.org/kb/DeviceFacet-4a1cdff8-be81-46e3-8502-0f488d353ca0", str(NS_SH.Warning)),
+ ("http://example.org/kb/OperatingSystem-628d531f-254c-4efb-aaa0-0874306afa01", str(NS_SH.Warning)),
+ ("http://example.org/kb/OperatingSystemFacet-872c1ba2-e1b4-4bc6-8267-6dbed687d0be", str(NS_SH.Warning)),
+ }
+ )
+
def test_database_records_PASS() -> None:
confirm_validation_results(
"database_records_PASS_validation.ttl",