diff --git a/ontology/uco/types/types.ttl b/ontology/uco/types/types.ttl index 2f646d9f..2b366e0e 100644 --- a/ontology/uco/types/types.ttl +++ b/ontology/uco/types/types.ttl @@ -135,6 +135,7 @@ types:Hash rdfs:subClassOf core:UcoInherentCharacterizationThing ; rdfs:label "Hash"@en ; rdfs:comment "A hash is a grouping of characteristics unique to the result of applying a mathematical algorithm that maps data of arbitrary size to a bit string (the 'hash') and is a one-way function, that is, a function which is practically infeasible to invert. This is commonly used for integrity checking of data. [based on https://en.wikipedia.org/wiki/Cryptographic_hash_function]"@en ; + rdfs:seeAlso types:hashMethod-objects-in-shape ; sh:property [ sh:datatype xsd:hexBinary ; @@ -144,49 +145,15 @@ types:Hash sh:path types:hashValue ; ] , [ - sh:datatype vocabulary:HashNameVocab ; - sh:message "Value is outside the default vocabulary HashNameVocab." ; + sh:datatype xsd:string ; + sh:message "As of UCO 1.4.0, the datatype to use for types:hashMethod should be xsd:string. Not using xsd:string will be an error in UCO 2.0.0." ; sh:path types:hashMethod ; - sh:severity sh:Info ; + sh:severity sh:Warning ; ] , [ sh:maxCount "1"^^xsd:integer ; sh:minCount "1"^^xsd:integer ; sh:nodeKind sh:Literal ; - sh:or ( - [ - sh:datatype vocabulary:HashNameVocab ; - ] - [ - sh:datatype xsd:string ; - ] - ) ; - sh:path types:hashMethod ; - ] , - [ - sh:message "Value is not member of the vocabulary HashNameVocab." ; - sh:or ( - [ - sh:datatype vocabulary:HashNameVocab ; - sh:in ( - "MD5"^^vocabulary:HashNameVocab - "MD6"^^vocabulary:HashNameVocab - "SHA1"^^vocabulary:HashNameVocab - "SHA224"^^vocabulary:HashNameVocab - "SHA256"^^vocabulary:HashNameVocab - "SHA3-224"^^vocabulary:HashNameVocab - "SHA3-256"^^vocabulary:HashNameVocab - "SHA3-384"^^vocabulary:HashNameVocab - "SHA3-512"^^vocabulary:HashNameVocab - "SHA384"^^vocabulary:HashNameVocab - "SHA512"^^vocabulary:HashNameVocab - "SSDEEP"^^vocabulary:HashNameVocab - ) ; - ] - [ - sh:datatype xsd:string ; - ] - ) ; sh:path types:hashMethod ; ] ; @@ -339,6 +306,27 @@ types:hashMethod ] ; . +types:hashMethod-objects-in-shape + a sh:NodeShape ; + sh:in ( + "MD5" + "MD6" + "SHA1" + "SHA224" + "SHA256" + "SHA3-224" + "SHA3-256" + "SHA3-384" + "SHA3-512" + "SHA384" + "SHA512" + "SSDEEP" + ) ; + sh:message "Value is not member of the vocabulary HashNameVocab." ; + sh:severity sh:Info ; + sh:targetObjectsOf types:hashMethod ; + . + types:hashValue a owl:DatatypeProperty ; rdfs:label "hashValue"@en ; diff --git a/ontology/uco/vocabulary/vocabulary.ttl b/ontology/uco/vocabulary/vocabulary.ttl index d13c89e7..8b128275 100644 --- a/ontology/uco/vocabulary/vocabulary.ttl +++ b/ontology/uco/vocabulary/vocabulary.ttl @@ -609,18 +609,18 @@ vocabulary:HashNameVocab a rdfs:Datatype ; owl:onDatatype xsd:string ; owl:oneOf ( - "MD5"^^vocabulary:HashNameVocab - "MD6"^^vocabulary:HashNameVocab - "SHA1"^^vocabulary:HashNameVocab - "SHA224"^^vocabulary:HashNameVocab - "SHA256"^^vocabulary:HashNameVocab - "SHA3-224"^^vocabulary:HashNameVocab - "SHA3-256"^^vocabulary:HashNameVocab - "SHA3-384"^^vocabulary:HashNameVocab - "SHA3-512"^^vocabulary:HashNameVocab - "SHA384"^^vocabulary:HashNameVocab - "SHA512"^^vocabulary:HashNameVocab - "SSDEEP"^^vocabulary:HashNameVocab + "MD5" + "MD6" + "SHA1" + "SHA224" + "SHA256" + "SHA3-224" + "SHA3-256" + "SHA3-384" + "SHA3-512" + "SHA384" + "SHA512" + "SSDEEP" ) ; ] ; . diff --git a/tests/examples/hash_PASS.json b/tests/examples/hash_PASS.json index c663ea5a..753470f1 100644 --- a/tests/examples/hash_PASS.json +++ b/tests/examples/hash_PASS.json @@ -1,14 +1,36 @@ { "@context": { "kb": "http://example.org/kb/", + "rdfs": "http://www.w3.org/2000/01/rdf-schema#", "types": "https://ontology.unifiedcyberontology.org/uco/types/", "vocabulary": "https://ontology.unifiedcyberontology.org/uco/vocabulary/", "xsd": "http://www.w3.org/2001/XMLSchema#" }, "@graph": [ + { + "@id": "kb:hash-04dcd1dc-6920-4977-a898-e242870249a4", + "@type": "types:Hash", + "rdfs:comment": "Should trigger sh:Info from the hashMethod literal not having its value be in the HashNameVocab vocabulary.", + "types:hashMethod": "CUSTOM_hash", + "types:hashValue": { + "@type": "xsd:hexBinary", + "@value": "a39a3ee5e6b4b0d3255bfef95601890afd80709d" + } + }, + { + "@id": "kb:hash-af4b0c85-b042-4e2d-a213-210b3d7f115c", + "@type": "types:Hash", + "rdfs:comment": "Should trigger sh:Info from the hashMethod literal not being a member of the vocabulary. ('SHA1' is in the vocabulary; 'SHA-1' isn't.)", + "types:hashMethod": "SHA-1", + "types:hashValue": { + "@type": "xsd:hexBinary", + "@value": "da39a3ee5e6b4b0d3255bfef95601890afd80709" + } + }, { "@id": "kb:hash-b7eca8de-142d-4aa9-b546-0796a268afa4", "@type": "types:Hash", + "rdfs:comment": "Should trigger an sh:Info from the hashMethod value not having its (literal-)value in the HashNameVocab vocabulary, and also not being an xsd:string.", "types:hashMethod": { "@type": "vocabulary:HashNameVocab", "@value": "SHA1" @@ -17,6 +39,16 @@ "@type": "xsd:hexBinary", "@value": "da39a3ee5e6b4b0d3255bfef95601890afd80709" } + }, + { + "@id": "kb:hash-f46c714f-559a-4325-bf8a-4ef60c92c771", + "@type": "types:Hash", + "rdfs:comment": "This should trigger an sh:Warning from the hashMethod value not being a string, and not being in the HashNameVocab vocabulary.", + "types:hashMethod": 1, + "types:hashValue": { + "@type": "xsd:hexBinary", + "@value": "da39a3ee5e6b4b0d3255bfef95601890afd80709" + } } ] } diff --git a/tests/examples/hash_XFAIL.json b/tests/examples/hash_XFAIL.json index 9b056adc..d0097408 100644 --- a/tests/examples/hash_XFAIL.json +++ b/tests/examples/hash_XFAIL.json @@ -7,47 +7,11 @@ }, "@graph": [ { - "@id": "kb:hash-04dcd1dc-6920-4977-a898-e242870249a4", + "@id": "kb:hash-66954988-aa9a-4f0d-8ad1-380700c830fc", "@type": "types:Hash", - "rdfs:comment": "Should trigger sh:Info from the literal not having its datatype be the HashNameVocab vocabulary.", - "types:hashMethod": "CUSTOM_hash", - "types:hashValue": { - "@type": "xsd:hexBinary", - "@value": "a39a3ee5e6b4b0d3255bfef95601890afd80709d" - } - }, - { - "@id": "kb:hash-af4b0c85-b042-4e2d-a213-210b3d7f115c", - "@type": "types:Hash", - "rdfs:comment": "Should trigger sh:Violation from the literal declaring itself a member of the vocabulary, but not being a member. ('SHA1' is in the vocabulary; 'SHA-1' isn't.)", - "types:hashMethod": { - "@type": "vocabulary:HashNameVocab", - "@value": "SHA-1" - }, - "types:hashValue": { - "@type": "xsd:hexBinary", - "@value": "da39a3ee5e6b4b0d3255bfef95601890afd80709" - } - }, - { - "@id": "kb:hash-e97431ea-6fb8-46d9-9c23-94be4b7cc977", - "@type": "types:Hash", - "rdfs:comment": "This should trigger sh:Info from the term not having its datatype be the vocabulary. Currently, no inspection is done on the lexical value.", + "rdfs:comment": "This should trigger sh:Violation from the hash value not being hexBinary.", "types:hashMethod": "SHA1", - "types:hashValue": { - "@type": "xsd:hexBinary", - "@value": "da39a3ee5e6b4b0d3255bfef95601890afd80709" - } - }, - { - "@id": "kb:hash-f46c714f-559a-4325-bf8a-4ef60c92c771", - "@type": "types:Hash", - "rdfs:comment": "This should trigger sh:Violation from the term not being a string.", - "types:hashMethod": 1, - "types:hashValue": { - "@type": "xsd:hexBinary", - "@value": "da39a3ee5e6b4b0d3255bfef95601890afd80709" - } + "types:hashValue": "da39a3ee5e6b4b0d3255bfef95601890afd80709" } ] } diff --git a/tests/examples/test_validation.py b/tests/examples/test_validation.py index 6c4fc658..49f57ee7 100644 --- a/tests/examples/test_validation.py +++ b/tests/examples/test_validation.py @@ -283,19 +283,25 @@ def test_has_facet_inverse_functional_XFAIL() -> None: ) def test_hash_PASS() -> None: - g = load_validation_graph("hash_PASS_validation.ttl", True) - assert isinstance(g, rdflib.Graph) + confirm_validation_results( + "hash_PASS_validation.ttl", + True, + expected_focus_node_severities={ + ("1", str(NS_SH.Info)), + ("CUSTOM_hash", str(NS_SH.Info)), + ("SHA-1", str(NS_SH.Info)), + ("SHA1", str(NS_SH.Info)), + ("http://example.org/kb/hash-b7eca8de-142d-4aa9-b546-0796a268afa4", str(NS_SH.Warning)), + ("http://example.org/kb/hash-f46c714f-559a-4325-bf8a-4ef60c92c771", str(NS_SH.Warning)), + } + ) def test_hash_XFAIL() -> None: confirm_validation_results( "hash_XFAIL_validation.ttl", False, expected_focus_node_severities={ - ("http://example.org/kb/hash-04dcd1dc-6920-4977-a898-e242870249a4", str(NS_SH.Info)), - ("http://example.org/kb/hash-af4b0c85-b042-4e2d-a213-210b3d7f115c", str(NS_SH.Violation)), - ("http://example.org/kb/hash-e97431ea-6fb8-46d9-9c23-94be4b7cc977", str(NS_SH.Info)), - ("http://example.org/kb/hash-f46c714f-559a-4325-bf8a-4ef60c92c771", str(NS_SH.Info)), - ("http://example.org/kb/hash-f46c714f-559a-4325-bf8a-4ef60c92c771", str(NS_SH.Violation)) + ("http://example.org/kb/hash-66954988-aa9a-4f0d-8ad1-380700c830fc", str(NS_SH.Violation)) } )