Skip to content

Commit

Permalink
YDA-5747: script for granting read members access to vault packages
Browse files Browse the repository at this point in the history
  • Loading branch information
claravox authored Aug 2, 2024
1 parent 53cc432 commit a305ee1
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 2 deletions.
2 changes: 1 addition & 1 deletion browse.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ def transform(row):
if sort_on == 'modified':
cols = ['COLL_NAME', 'COLL_PARENT_NAME', 'MIN(COLL_CREATE_TIME)', 'ORDER(COLL_MODIFY_TIME)']
else:
cols = ['ORDER(COLL_NAME)', 'COLL_PARENT_NAME' 'MIN(COLL_CREATE_TIME)', 'MAX(COLL_MODIFY_TIME)']
cols = ['ORDER(COLL_NAME)', 'COLL_PARENT_NAME', 'MIN(COLL_CREATE_TIME)', 'MAX(COLL_MODIFY_TIME)']
where = "COLL_PARENT_NAME like '{}%%' AND COLL_NAME like '%%{}%%'".format("/" + zone + "/home", search_string)
elif search_type == 'metadata':
if sort_on == 'modified':
Expand Down
1 change: 0 additions & 1 deletion folder.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,6 @@ def set_can_modify(ctx, coll):
check_access_result = msi.check_access(ctx, coll, 'modify object', irods_types.BytesBuf())
modify_access = check_access_result['arguments'][2]
if modify_access != b'\x01':
# TODO set to a lower read?
# This allows us permission to copy the files
if not set_acl_check(ctx, "recursive", "admin:read", coll, "Could not set ACL (admin:read) for collection: {}".format(coll)):
return False
Expand Down
9 changes: 9 additions & 0 deletions tools/grant-readers-access-to-vault-packages.r
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/irule -F

grantReadersAccessVaultPackages {
# Grant read- groups access to corresponding vault packages
*return = "";
rule_vault_grant_readers_vault_access(*dryRun, *verbose, *return);
}
input *dryRun="", *verbose=""
output ruleExecOut
2 changes: 2 additions & 0 deletions tools/grant-readers-access-to-vault-packages.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/bin/bash
irule -r irods_rule_engine_plugin-irods_rule_language-instance -F /etc/irods/yoda-ruleset/tools/grant-readers-access-to-vault-packages.r '*dryRun="'$1'"' '*verbose="'$2'"'
134 changes: 134 additions & 0 deletions vault.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
'rule_vault_enable_indexing',
'rule_vault_disable_indexing',
'rule_vault_process_status_transitions',
'rule_vault_grant_readers_vault_access',
'api_vault_system_metadata',
'api_vault_collection_details',
'api_vault_get_package_by_reference',
Expand Down Expand Up @@ -1135,6 +1136,139 @@ def set_vault_permissions(ctx, coll, target):
return True


def reader_needs_access(ctx, group_name, coll):
"""Return if research group has access to this group but readers do not"""
iter = genquery.row_iterator(
"COLL_ACCESS_USER_ID",
"COLL_NAME = '" + coll + "'",
genquery.AS_LIST, ctx
)
reader_found = False
research_found = False

for row in iter:
user_id = row[0]
user_name = user.name_from_id(ctx, user_id)
# Check if there are *any* readers
if user_name.startswith('read-'):
reader_found = True
elif user_name == group_name:
research_found = True

return not reader_found and research_found


def set_reader_vault_permissions(ctx, group_name, zone, dry_run):
"""Given a research group name, give reader group access to
vault packages if they don't have that access already.
:param ctx: Combined type of a callback and rei struct
:param group_name: Research group name
:param zone: Zone
:param dry_run: Whether to only print which groups would be changed without changing them
:return: Boolean whether completed successfully or there were errors.
"""
parts = group_name.split('-')
base_name = '-'.join(parts[1:])
read_group_name = 'read-' + base_name
vault_group_name = constants.IIVAULTPREFIX + base_name
vault_path = "/" + zone + "/home/" + vault_group_name
no_errors = True

# Do not change the permissions if there aren't any vault packages in this vault.
if collection.empty(ctx, vault_path):
return True

if reader_needs_access(ctx, group_name, vault_path):
# Grant the research group readers read-only access to the collection
# to enable browsing through the vault.
try:
if dry_run:
log.write(ctx, "Would have granted " + read_group_name + " read access to " + vault_path)
else:
msi.set_acl(ctx, "default", "admin:read", read_group_name, vault_path)
log.write(ctx, "Granted " + read_group_name + " read access to " + vault_path)
except msi.Error:
no_errors = False
log.write(ctx, "Failed to grant " + read_group_name + " read access to " + vault_path)

iter = genquery.row_iterator(
"COLL_NAME",
"COLL_PARENT_NAME = '{}'".format(vault_path),
genquery.AS_LIST, ctx
)
for row in iter:
target = row[0]
if reader_needs_access(ctx, group_name, target):
try:
if dry_run:
log.write(ctx, "Would have granted " + read_group_name + " read access to " + target)
else:
msi.set_acl(ctx, "recursive", "admin:read", read_group_name, target)
log.write(ctx, "Granted " + read_group_name + " read access to " + target)
except Exception:
no_errors = False
log.write(ctx, "Failed to set read permissions for <{}> on coll <{}>".format(read_group_name, target))

return no_errors


@rule.make(inputs=[0, 1], outputs=[2])
def rule_vault_grant_readers_vault_access(ctx, dry_run, verbose):
"""Rule for granting reader members of research groups access to vault packages in their
group if they don't have access already
:param ctx: Combined type of a callback and rei struct
:param dry_run: Whether to only print which groups would be changed without making changes
:param verbose: Whether to be more verbose
:return: String status of completed successfully ('0') or there were errors ('1')
"""
dry_run = (dry_run == '1')
verbose = (verbose == '1')
no_errors = True

log.write(ctx, "grant_readers_vault_access started.")

if user.user_type(ctx) != 'rodsadmin':
log.write(ctx, "User is not rodsadmin")
return '1'

if dry_run or verbose:
modes = []
if dry_run:
modes.append("dry run")
if verbose:
modes.append("verbose")
log.write(ctx, "Running grant_readers_vault_access in {} mode.".format((" and ").join(modes)))

zone = user.zone(ctx)

# Get the group names
userIter = genquery.row_iterator(
"USER_GROUP_NAME",
"USER_TYPE = 'rodsgroup' AND USER_ZONE = '{}' AND USER_GROUP_NAME like 'research-%'".format(zone),
genquery.AS_LIST,
ctx)

for row in userIter:
name = row[0]
if verbose:
log.write(ctx, "{}: checking permissions".format(name))
if not set_reader_vault_permissions(ctx, name, zone, dry_run):
no_errors = False

message = ""
if no_errors:
message = "grant_readers_vault_access completed successfully."
else:
message = "grant_readers_vault_access completed, with errors."
log.write(ctx, message)

return '0' if no_errors else '1'


@rule.make(inputs=range(4), outputs=range(4, 6))
def rule_vault_process_status_transitions(ctx, coll, new_coll_status, actor, previous_version):
"""Rule interface for processing vault status transition request.
Expand Down

0 comments on commit a305ee1

Please sign in to comment.