From ddb290d58f0a07b1429c2e54f3f4bb980d46a227 Mon Sep 17 00:00:00 2001 From: Mark Carroll Date: Wed, 25 May 2016 12:01:06 +0100 Subject: [PATCH] make OMERO repository cleanse an admin-only function corrects critical data loss bug: for context see https://www.openmicroscopy.org/community/viewtopic.php?f=11&t=8060 and https://github.com/openmicroscopy/openmicroscopy/pull/4683 --- lib/python/omero/plugins/admin.py | 9 +++++-- lib/python/omero/util/cleanse.py | 28 +++++++++++++--------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/lib/python/omero/plugins/admin.py b/lib/python/omero/plugins/admin.py index 321a91b..7d1930f 100755 --- a/lib/python/omero/plugins/admin.py +++ b/lib/python/omero/plugins/admin.py @@ -27,6 +27,7 @@ from path import path import omero import omero.config +from omero.cli import admin_only from omero.cli import CLI from omero.cli import DirectoryType from omero.cli import NonZeroReturnCode @@ -159,7 +160,8 @@ already be running. This may automatically restart some server components.""") "ice", "Drop user into icegridadmin console or execute arguments") fixpyramids = Action( - "fixpyramids", "Remove empty pyramid pixels files").parser + "fixpyramids", + "Remove empty pyramid pixels files (admins only)").parser # See cleanse options below diagnostics = Action( @@ -361,7 +363,7 @@ dt_socket,address=8787,suspend=y" \\ "sessionlist", "List currently running sessions").parser sessionlist.add_login_arguments() - cleanse = Action("cleanse", """Remove binary data files from OMERO + cleanse = Action("cleanse", """Remove binary data files from OMERO (admins only) Deleting an object from OMERO currently may not remove all the binary data. Use this command either manually or in a cron job periodically to remove @@ -955,6 +957,7 @@ present, the user will enter a console""") else: self.ctx.call(command) + @admin_only @with_config def fixpyramids(self, args, config): self.check_access() @@ -962,6 +965,7 @@ present, the user will enter a console""") client = self.ctx.conn(args) client.getSessionId() fixpyramids(data_dir=args.data_dir, dry_run=args.dry_run, + admin_service=client.sf.getAdminService(), query_service=client.sf.getQueryService(), config_service=client.sf.getConfigService()) @@ -1784,6 +1788,7 @@ OMERO Diagnostics %s " regenerated. Use the omero.ports.xxx configuration properties" " instead.") + @admin_only def cleanse(self, args): self.check_access() from omero.util.cleanse import cleanse diff --git a/lib/python/omero/util/cleanse.py b/lib/python/omero/util/cleanse.py index 7d2ef08..e840447 100644 --- a/lib/python/omero/util/cleanse.py +++ b/lib/python/omero/util/cleanse.py @@ -55,7 +55,7 @@ def usage(error): """ cmd = sys.argv[0] print """%s -Usage: %s [-dry-run] [-u username | -k] +Usage: %s [--dry-run] [-u username | -k] Cleanses files in the OMERO data directory that have no reference in the OMERO database. NOTE: As this script is designed to be run via cron or in a scheduled manner it produces NO output unless a dry run is performed. @@ -189,7 +189,14 @@ class Cleanser(object): (len(self.cleansed), self.bytes_cleansed) -def initial_check(config_service): +def initial_check(config_service, admin_service=None): + if admin_service is None: + raise Exception("No admin service provided!") + + ctx = admin_service.getEventContext() + if not ctx.isAdmin: + raise Exception('SecurityViolation: Admins only!') + # # Compare server versions. See ticket #3123 # @@ -209,11 +216,12 @@ def initial_check(config_service): def cleanse(data_dir, client, dry_run=False): client.getImplicitContext().put(omero.constants.GROUP, '-1') + admin_service = client.sf.getAdminService() query_service = client.sf.getQueryService() config_service = client.sf.getConfigService() shared_resources = client.sf.sharedResources() - initial_check(config_service) + initial_check(config_service, admin_service) try: cleanser = "" @@ -293,8 +301,9 @@ def is_empty_dir(repo, directory, may_delete_dir, to_delete): return is_empty -def fixpyramids(data_dir, query_service, dry_run=False, config_service=None): - initial_check(config_service) +def fixpyramids(data_dir, query_service, + dry_run=False, config_service=None, admin_service=None): + initial_check(config_service, admin_service) # look for any pyramid files with length 0 # if there is no matching .*.tmp or .*.pyr_lock file, then @@ -357,20 +366,17 @@ def main(): try: client = omero.client('localhost') client.setAgent("OMERO.cleanse") - session = None if session_key is None: - session = client.createSession(username, password) + client.createSession(username, password) else: - session = client.createSession(session_key) + client.createSession(session_key) except PermissionDeniedException: print "%s: Permission denied" % sys.argv[0] print "Sorry." sys.exit(1) - query_service = session.getQueryService() - config_service = session.getConfigService() try: - cleanse(data_dir, query_service, dry_run, config_service) + cleanse(data_dir, client, dry_run) finally: if session_key is None: client.closeSession() -- 2.1.4