Skip to content

Commit 0196dc9

Browse files
committed
feat(checks): ✨ handle UNAUTHORIZED/UNCHECKABLE web data entities as warnings
Use AvailabilityStatus in the SHOULD web-data-entity check so auth-protected and non-natively-checkable resources are reported as recommendation-level issues, not validation failures; skip them in the contentSize check.
1 parent 75d0442 commit 0196dc9

1 file changed

Lines changed: 33 additions & 2 deletions

File tree

rocrate_validator/profiles/ro-crate/should/5_web_data_entity_metadata.py

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from rocrate_validator.models import ValidationContext
1717
from rocrate_validator.requirements.python import (PyFunctionCheck, check,
1818
requirement)
19+
from rocrate_validator.utils.uri import AvailabilityStatus
1920

2021
# set up logging
2122
logger = logging.getLogger(__name__)
@@ -32,13 +33,37 @@ class WebDataEntityRecommendedChecker(PyFunctionCheck):
3233
def check_availability(self, context: ValidationContext) -> bool:
3334
"""
3435
Check if the Web-based Data Entity is directly downloadable
35-
by a simple retrieval (e.g. HTTP GET) permitting redirection and HTTP/HTTPS URIs
36+
by a simple retrieval (e.g. HTTP GET) permitting redirection and HTTP/HTTPS URIs.
37+
38+
Resources that cannot be natively retrieved by the validator (e.g.
39+
`scp://`, `s3://`, `sftp://`) or that are protected by an authorization
40+
mechanism (HTTP 401/403) are reported as recommendation-level issues
41+
and logged as warnings, without invalidating the validation.
3642
"""
3743
result = True
3844
for entity in context.ro_crate.metadata.get_web_data_entities():
3945
assert entity.id is not None, "Entity has no @id"
4046
try:
41-
if not entity.is_available():
47+
status = entity.check_availability()
48+
if status == AvailabilityStatus.AVAILABLE:
49+
continue
50+
if status == AvailabilityStatus.UNAUTHORIZED:
51+
msg = (
52+
f"Web-based Data Entity {entity.id} is protected by an "
53+
f"authorization mechanism; availability could not be verified"
54+
)
55+
logger.warning(msg)
56+
context.result.add_issue(msg, self)
57+
elif status == AvailabilityStatus.UNCHECKABLE:
58+
scheme = entity.id_as_uri.scheme
59+
msg = (
60+
f"Web-based Data Entity {entity.id} uses scheme "
61+
f"'{scheme}' which is not natively supported by the "
62+
f"validator; availability could not be verified"
63+
)
64+
logger.warning(msg)
65+
context.result.add_issue(msg, self)
66+
else:
4267
context.result.add_issue(
4368
f'Web-based Data Entity {entity.id} is not available', self)
4469
result = False
@@ -59,6 +84,12 @@ def check_content_size(self, context: ValidationContext) -> bool:
5984
result = True
6085
for entity in context.ro_crate.metadata.get_web_data_entities():
6186
assert entity.id is not None, "Entity has no @id"
87+
# Skip entities whose scheme the validator cannot natively fetch
88+
# (e.g. scp://, s3://): without retrieving the content there is
89+
# no actual size to compare `contentSize` against. Reachability
90+
# is then checked separately via `is_available()` below.
91+
if not entity.id_as_uri.is_natively_checkable():
92+
continue
6293
if entity.is_available():
6394
content_size = entity.get_property("contentSize")
6495
if content_size and int(content_size) != context.ro_crate.get_external_file_size(entity.id):

0 commit comments

Comments
 (0)