From f9e9250095c74bef568ecd905f1a7dc8857d1f63 Mon Sep 17 00:00:00 2001
From: Maximilian Moser <maximilian.moser@tuwien.ac.at>
Date: Fri, 29 Jan 2021 16:50:47 +0100
Subject: [PATCH] cli: add commands for verifying the integrity of deposits

---
 invenio_utilities_tuw/cli/drafts.py  | 29 +++++++++++++++++++++
 invenio_utilities_tuw/cli/records.py | 38 +++++++++++++++++++++++++++-
 2 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/invenio_utilities_tuw/cli/drafts.py b/invenio_utilities_tuw/cli/drafts.py
index 50f5479..014f27d 100644
--- a/invenio_utilities_tuw/cli/drafts.py
+++ b/invenio_utilities_tuw/cli/drafts.py
@@ -317,3 +317,32 @@ def list_files(pid, pid_type, user):
         ov = ObjectVersion.get(f["bucket_id"], f["key"], f["version_id"])
         fi = ov.file
         click.secho("{}\t{}\t{}".format(ov.key, fi.uri, fi.checksum), fg="green")
+
+
+@files.command("verify")
+@option_pid_value
+@option_pid_type
+@option_as_user
+@with_appcontext
+def verify_files(pid, pid_type, user):
+    """Verify the checksums for each of the draft's files."""
+    recid = convert_to_recid(pid, pid_type)
+    identity = get_identity_for_user(user)
+    service = get_record_service()
+    service.require_permission(identity, "read_files")
+    draft = service.read_draft(id_=recid, identity=identity)
+    draft = draft._record if hasattr(draft, "_record") else draft
+    num_errors = 0
+
+    for name, rec_file in draft.files.entries.items():
+        if rec_file.file.verify_checksum():
+            click.secho(name, fg="green")
+        else:
+            click.secho("{}: failed checksum verification".format(name), fg="red")
+            num_errors += 1
+
+    if num_errors > 0:
+        click.secho(
+            "{} files failed the checksum verification".format(num_errors), fg="red"
+        )
+        sys.exit(1)
diff --git a/invenio_utilities_tuw/cli/records.py b/invenio_utilities_tuw/cli/records.py
index 9db3c37..319e12d 100644
--- a/invenio_utilities_tuw/cli/records.py
+++ b/invenio_utilities_tuw/cli/records.py
@@ -9,6 +9,7 @@
 """Management commands for records."""
 
 import json
+import sys
 
 import click
 from flask.cli import with_appcontext
@@ -131,7 +132,13 @@ def delete_record(pid, pid_type, user):
     click.secho(recid, fg="red")
 
 
-@records.command("files")
+@records.group()
+def files():
+    """Manage files deposited with the record."""
+    pass
+
+
+@files.command("list")
 @option_pid_value
 @option_pid_type
 @option_as_user
@@ -148,6 +155,35 @@ def list_files(pid, pid_type, user):
         click.secho("{}\t{}\t{}".format(ov.key, fi.uri, fi.checksum), fg="green")
 
 
+@files.command("verify")
+@option_pid_value
+@option_pid_type
+@option_as_user
+@with_appcontext
+def verify_files(pid, pid_type, user):
+    """Verify the checksums for each of the record's files."""
+    recid = convert_to_recid(pid, pid_type)
+    identity = get_identity_for_user(user)
+    service = get_record_file_service()
+    service.require_permission(identity, "read_files")
+    record = service.read(id_=recid, identity=identity)
+    record = record._record if hasattr(record, "_record") else record
+    num_errors = 0
+
+    for name, rec_file in record.files.entries.items():
+        if rec_file.file.verify_checksum():
+            click.secho(name, fg="green")
+        else:
+            click.secho("{}: failed checksum verification".format(name), fg="red")
+            num_errors += 1
+
+    if num_errors > 0:
+        click.secho(
+            "{} files failed the checksum verification".format(num_errors), fg="red"
+        )
+        sys.exit(1)
+
+
 @records.command("reindex")
 @option_pid_values
 @option_pid_type
-- 
GitLab