Fix for preventing non-admins from running data managers via the api.

This commit is contained in:
Daniel Blankenberg
2015-02-02 16:21:00 -05:00
parent 43b2f4ffa1
commit 48f77dc742
4 changed files with 29 additions and 7 deletions
+19
View File
@@ -1388,6 +1388,12 @@ class Tool( object, Dictifiable ):
return section_id, section_name
return None, None
def allow_user_access( self, user ):
"""
:returns: bool -- Whether the user is allowed to access the tool.
"""
return True
def parse( self, root, guid=None ):
"""
Read tool configuration from the element `root` and fill in `self`.
@@ -3392,6 +3398,7 @@ class DataManagerTool( OutputParameterJSONTool ):
self.data_manager_id = self.id
def exec_after_process( self, app, inp_data, out_data, param_dict, job=None, **kwds ):
assert self.allow_user_access( job.user ), "You must be an admin to access this tool."
#run original exec_after_process
super( DataManagerTool, self ).exec_after_process( app, inp_data, out_data, param_dict, job=job, **kwds )
#process results of tool
@@ -3415,6 +3422,7 @@ class DataManagerTool( OutputParameterJSONTool ):
return history
user = trans.user
assert user, 'You must be logged in to use this tool.'
assert self.allow_user_access( user ), "You must be an admin to access this tool."
history = user.data_manager_histories
if not history:
#create
@@ -3434,6 +3442,17 @@ class DataManagerTool( OutputParameterJSONTool ):
history = None
return history
def allow_user_access( self, user ):
"""
:returns: bool -- Whether the user is allowed to access the tool.
Data Manager tools are only accessible to admins.
"""
if super( DataManagerTool, self ).allow_user_access( user ) and self.app.config.is_admin_user( user ):
return True
if user:
user = user.id
log.debug( "User (%s) attempted to access a data manager tool (%s), but is not an admin.", user, self.id )
return False
# Populate tool_type to ToolClass mappings
tool_types = {}
+1
View File
@@ -155,6 +155,7 @@ class DefaultToolAction( object ):
submitting the job to the job queue. If history is not specified, use
trans.history as destination for tool's output datasets.
"""
assert tool.allow_user_access( trans.user ), "User (%s) is not allowed to access this tool." % ( trans.user )
# Set history.
if not history:
history = tool.get_default_history_by_trans( trans, create=True )
+6 -6
View File
@@ -63,7 +63,7 @@ class ToolsController( BaseAPIController, UsesVisualizationMixin, UsesHistoryMix
"""
io_details = util.string_as_bool( kwd.get( 'io_details', False ) )
link_details = util.string_as_bool( kwd.get( 'link_details', False ) )
tool = self._get_tool( id )
tool = self._get_tool( id, user=trans.user )
return tool.to_dict( trans, io_details=io_details, link_details=link_details )
@_future_expose_api_anonymous
@@ -89,7 +89,7 @@ class ToolsController( BaseAPIController, UsesVisualizationMixin, UsesHistoryMix
@_future_expose_api_anonymous
def citations( self, trans, id, **kwds ):
tool = self._get_tool( id )
tool = self._get_tool( id, user=trans.user )
rval = []
for citation in tool.citations:
rval.append( citation.to_dict( 'bibtex' ) )
@@ -122,7 +122,7 @@ class ToolsController( BaseAPIController, UsesVisualizationMixin, UsesHistoryMix
# Get tool.
tool = trans.app.toolbox.get_tool( payload[ 'tool_id' ] ) if 'tool_id' in payload else None
if not tool:
if not tool or not tool.allow_user_access( trans.user ):
trans.response.status = 404
return { "message": { "type": "error", "text" : trans.app.model.Dataset.conversion_messages.NO_TOOL } }
@@ -212,10 +212,10 @@ class ToolsController( BaseAPIController, UsesVisualizationMixin, UsesHistoryMix
#
# -- Helper methods --
#
def _get_tool( self, id ):
def _get_tool( self, id, user=None ):
id = urllib.unquote_plus( id )
tool = self.app.toolbox.get_tool( id )
if not tool:
if not tool or not tool.allow_user_access( user ):
raise exceptions.ObjectNotFound("Could not find tool with id '%s'" % id)
return tool
@@ -281,7 +281,7 @@ class ToolsController( BaseAPIController, UsesVisualizationMixin, UsesHistoryMix
#
original_job = self.get_hda_job( original_dataset )
tool = trans.app.toolbox.get_tool( original_job.tool_id )
if not tool:
if not tool or not tool.allow_user_access( trans.user ):
return trans.app.model.Dataset.conversion_messages.NO_TOOL
tool_params = dict( [ ( p.name, p.value ) for p in original_job.parameters ] )
@@ -65,7 +65,7 @@ class ToolRunner( BaseUIController ):
get_loaded_tools_by_lineage=False,
set_selected=refreshed_on_change )
# No tool matching the tool id, display an error (shouldn't happen)
if not tool:
if not tool or not tool.allow_user_access( trans.user ):
log.error( "index called with tool id '%s' but no such tool exists", tool_id )
trans.log_event( "Tool id '%s' does not exist" % tool_id )
trans.response.status = 404
@@ -191,6 +191,8 @@ class ToolRunner( BaseUIController ):
# This is expected so not an exception.
tool_id_version_message = ''
error( "This dataset was created by an obsolete tool (%s). Can't re-run." % tool_id )
if not tool.allow_user_access( trans.user ):
error( "The requested tool is unknown." )
# Can't rerun upload, external data sources, et cetera. Workflow compatible will proxy this for now
if not tool.is_workflow_compatible:
error( "The '%s' tool does not currently support rerunning." % tool.name )