From a9523262c56036be25b2d4f806889dd47dcf01a5 Mon Sep 17 00:00:00 2001 From: Maximilian Moser <maximilian.moser@tuwien.ac.at> Date: Wed, 28 Apr 2021 14:16:02 +0200 Subject: [PATCH] Update ownership management to InvenioRDM 2.0 --- invenio_utilities_tuw/cli/drafts.py | 21 +++++++------- invenio_utilities_tuw/cli/records.py | 14 ++++++---- invenio_utilities_tuw/cli/utils.py | 42 +++++++++++++++++----------- 3 files changed, 44 insertions(+), 33 deletions(-) diff --git a/invenio_utilities_tuw/cli/drafts.py b/invenio_utilities_tuw/cli/drafts.py index 59a7790..937aaab 100644 --- a/invenio_utilities_tuw/cli/drafts.py +++ b/invenio_utilities_tuw/cli/drafts.py @@ -31,6 +31,7 @@ from .utils import ( convert_to_recid, create_record_from_metadata, get_identity_for_user, + get_user_by_identifier, patch_metadata, read_metadata, set_creatibutor_names, @@ -93,14 +94,9 @@ def create_draft(metadata_path, publish, user, owners, vanity_pid): """ recid = None identity = get_identity_for_user(user) - if owners: - owners = [get_identity_for_user(owner) for owner in owners] if isfile(metadata_path): metadata = read_metadata(metadata_path) - if owners: - metadata = set_record_owners(metadata, owners) - metadata = set_creatibutor_names(metadata) draft = create_record_from_metadata(metadata, identity, vanity_pid=vanity_pid) recid = draft["id"] @@ -112,12 +108,10 @@ def create_draft(metadata_path, publish, user, owners, vanity_pid): raise Exception("metadata file does not exist: %s" % metadata_file_path) metadata = read_metadata(metadata_file_path) - if owners: - metadata = set_record_owners(metadata, owners) - metadata = set_creatibutor_names(metadata) draft = create_record_from_metadata(metadata, identity) recid = draft["id"] + file_names = [] if isdir(deposit_files_path): exists = lambda fn: isfile(join(deposit_files_path, fn)) @@ -145,6 +139,11 @@ def create_draft(metadata_path, publish, user, owners, vanity_pid): else: raise Exception("neither a file nor a directory: %s" % metadata_path) + if owners: + actual_draft = draft._record if hasattr(draft, "_record") else draft + owners = [get_user_by_identifier(owner) for owner in owners] + set_record_owners(actual_draft, owners) + if publish: service = get_record_service() service.publish(id_=recid, identity=identity) @@ -199,8 +198,10 @@ def update_draft(metadata_file, pid, pid_type, user, patch, owners): metadata = patch_metadata(draft_data, metadata) if owners: - owners = [get_identity_for_user(owner) for owner in owners] - metadata = set_record_owners(metadata, owners) + draft = service.read_draft(id_=pid, identity=identity) + actual_draft = draft._record if hasattr(draft, "_record") else draft + owners = [get_user_by_identifier(owner) for owner in owners] + set_record_owners(actual_draft, owners) metadata = set_creatibutor_names(metadata) service.update_draft(id_=pid, identity=identity, data=metadata) diff --git a/invenio_utilities_tuw/cli/records.py b/invenio_utilities_tuw/cli/records.py index 3ec28d8..2cd49d2 100644 --- a/invenio_utilities_tuw/cli/records.py +++ b/invenio_utilities_tuw/cli/records.py @@ -13,7 +13,6 @@ import sys import click from flask.cli import with_appcontext -from invenio_accounts import current_accounts from invenio_db import db from invenio_files_rest.models import ObjectVersion @@ -31,6 +30,7 @@ from .utils import ( convert_to_recid, get_identity_for_user, get_object_uuid, + get_user_by_identifier, patch_metadata, set_creatibutor_names, set_record_owners, @@ -109,7 +109,7 @@ def show_record(pid, pid_type, user, pretty_print, raw): help=( "circumvent the record service, and thus permission checks, " "and update the record directly (not recommended)" - ) + ), ) @option_owners @with_appcontext @@ -124,10 +124,6 @@ def update_record(metadata_file, pid, pid_type, user, patch, owners, direct): record_data = service.read(id_=pid, identity=identity).data.copy() metadata = patch_metadata(record_data, metadata) - if owners: - owners = [get_identity_for_user(owner) for owner in owners] - metadata = set_record_owners(metadata, owners) - metadata = set_creatibutor_names(metadata) if direct: record = service.read(id_=pid, identity=identity)._record @@ -149,6 +145,12 @@ def update_record(metadata_file, pid, pid_type, user, patch, owners, direct): click.secho("trying with service.update()...", fg="yellow") service.update(id_=pid, identity=identity, data=metadata) + if owners: + record = service.read(id_=pid, identity=identity) + actual_record = record._record if hasattr(record, "_record") else record + owners = [get_user_by_identifier(owner) for owner in owners] + set_record_owners(actual_record, owners) + click.secho(pid, fg="green") diff --git a/invenio_utilities_tuw/cli/utils.py b/invenio_utilities_tuw/cli/utils.py index 20e4a6f..e8d9c57 100644 --- a/invenio_utilities_tuw/cli/utils.py +++ b/invenio_utilities_tuw/cli/utils.py @@ -10,8 +10,6 @@ import json -from flask_principal import Identity -from invenio_access import any_user from invenio_access.permissions import system_identity from invenio_access.utils import get_identity from invenio_accounts import current_accounts @@ -81,16 +79,25 @@ def patch_metadata(metadata: dict, patch: dict) -> dict: return metadata -def get_identity_for_user(user): - """Get the Identity for the user specified via email or ID.""" - if user is not None: +def get_user_by_identifier(id_or_email): + """Get the user specified via email or ID.""" + if id_or_email is not None: # note: this seems like the canonical way to go - # 'as_user' can be either an integer (id) or email address - u = current_accounts.datastore.get_user(user) + # 'id_or_email' can be either an integer (id) or email address + u = current_accounts.datastore.get_user(id_or_email) if u is not None: - return get_identity(u) + return u else: - raise LookupError("user not found: %s" % user) + raise LookupError("user not found: %s" % id_or_email) + + raise ValueError("id_or_email cannot be None") + + +def get_identity_for_user(user): + """Get the Identity for the user specified via email or ID.""" + if user is not None: + found_user = get_user_by_identifier(user) + return get_identity(found_user) return system_identity @@ -119,16 +126,17 @@ def convert_to_recid(pid_value, pid_type): return pid_value -def set_record_owners(record_metadata, owners): - """Set the record's owners, assuming an RDM-Records metadata schema.""" - metadata = record_metadata.copy() +def set_record_owners(record, owners, commit=True): + """Set the record's owners, assuming an RDMRecord-like record object.""" + parent = record.parent - owners = [{"user": owner.id} for owner in owners] - if "access" not in metadata: - metadata["access"] = {} + parent.access.owners.clear() + for owner in owners: + parent.access.owners.add(owner) - metadata["access"]["owned_by"] = owners - return metadata + if commit: + parent.commit() + db.session.commit() def _set_creatibutor_name(creatibutor): -- GitLab