Repository: zimeon/ocfl-py

Issue:
URN Object IDs flagged as validation warning
OCFL objects with an `id` such as: "URN-3:HUL.DRS.OBJECT:100775205", are flagged as validation warnings. I believe these should be valid.. as URNs are valid URIs and the above URN-3 scheme is a valid URN.

See: https://www.iana.org/assignments/urn-informal/urn-3

Discussion:
zimeon: ```
(py38) simeon@RottenApple ocfl-py> cat fixtures/1.0/good-objects/minimal_no_content/inventory.json | perl -pe 's#http://example.org/minimal_no_content#URN-3:HUL.DRS.OBJECT:100775205#' > /tmp/inv

(py38) simeon@RottenApple ocfl-py> git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
(py38) simeon@RottenApple ocfl-py> ./ocfl-validate.py /tmp/inv 
[W005] OCFL Object standalone inventory id SHOULD be a URI (got URN-3:HUL.DRS.OBJECT:100775205) (see https://ocfl.io/1.0/spec/#W005)
INFO:ocfl.object:Standalone OCFL inventory at /tmp/inv is VALID

(py38) simeon@RottenApple ocfl-py> git checkout issue-75
Switched to branch 'issue-75'
Your branch is up to date with 'origin/issue-75'.
(py38) simeon@RottenApple ocfl-py> ./ocfl-validate.py /tmp/inv 
INFO:ocfl.object:Standalone OCFL inventory at /tmp/inv is VALID

Patch:
diff --git a/CHANGES.md b/CHANGES.md
index 7be9540..b6f1827 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -5,6 +5,7 @@
   * Additional validation improvements:
     * Checks between version state in different version inventories
     * Check to see is extra directories look like version directories
+    * Fix URI scheme syntax check
   * Use additional fixtures in https://github.com/OCFL/fixtures for tests
 
 ## 2021-04-26 v1.2.2
diff --git a/ocfl/inventory_validator.py b/ocfl/inventory_validator.py
index 2dbe328..27eb807 100644
--- a/ocfl/inventory_validator.py
+++ b/ocfl/inventory_validator.py
@@ -65,7 +65,9 @@ class InventoryValidator():
             if not isinstance(iid, str) or iid == '':
                 self.error("E037a")
             else:
-                if not re.match(r'''(\w+):.+''', iid):
+                # URI syntax https://www.rfc-editor.org/rfc/rfc3986.html#section-3.1 :
+                # scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+                if not re.match(r'''[a-z][a-z\d\+\-\.]*:.+''', iid, re.IGNORECASE):
                     self.warning("W005", id=iid)
                 self.id = iid
         else:


Test patch:
diff --git a/tests/test_inventory_validator.py b/tests/test_inventory_validator.py
index 6070546..37519a6 100644
--- a/tests/test_inventory_validator.py
+++ b/tests/test_inventory_validator.py
@@ -52,6 +52,17 @@ class TestAll(unittest.TestCase):
         iv.validate({"id": []})
         self.assertIn('E037a', log.errors)
         log.clear()
+        # Valid and invalid URIs
+        iv.validate({"id": "scheme:rest", "digestAlgorithm": "sha512"})
+        self.assertNotIn('W005', log.warns)
+        log.clear()
+        iv.validate({"id": "URN-3:rest", "digestAlgorithm": "sha512"})
+        self.assertNotIn('W005', log.warns)
+        log.clear()
+        iv.validate({"id": "a1+2-3z.:rest", "digestAlgorithm": "sha512"})
+        self.assertNotIn('W005', log.warns)
+        self.assertNotIn('W004', log.warns)
+        log.clear()
         iv.validate({"id": "not_a_uri", "digestAlgorithm": "sha256"})
         self.assertIn('W005', log.warns)
         self.assertIn('W004', log.warns)