details: http://www.bx.psu.edu/hg/galaxy/rev/df9814119044 changeset: 3042:df9814119044 user: Greg Von Kuster <greg@bx.psu.edu> date: Mon Nov 16 16:27:48 2009 -0500 description: Enhance history item error reports that are emailed - report form now defaults to include the users email address if they are logged in - email now includes the id of both the dataset and the history, the hid and hda.display_name(), and a link to the history - admin users now have "view" access to any history and dataset ( this uses the new ~/history/view?id=... feature ) diffstat: lib/galaxy/web/controllers/dataset.py | 61 +++++++++++++++++++----------- lib/galaxy/web/controllers/history.py | 12 ++---- lib/galaxy/web/controllers/user.py | 2 - lib/galaxy/web/framework/__init__.py | 10 +---- templates/dataset/errors.mako | 17 +++++--- templates/mobile/history/detail.mako | 2 +- templates/root/history_common.mako | 4 +- test/base/twilltestcase.py | 6 +++ test/functional/test_history_functions.py | 6 +++ 9 files changed, 70 insertions(+), 50 deletions(-) diffs (319 lines): diff -r 2eb1e3c4d143 -r df9814119044 lib/galaxy/web/controllers/dataset.py --- a/lib/galaxy/web/controllers/dataset.py Mon Nov 16 15:06:07 2009 -0500 +++ b/lib/galaxy/web/controllers/dataset.py Mon Nov 16 16:27:48 2009 -0500 @@ -20,25 +20,38 @@ This error report was sent from the Galaxy instance hosted on the server "${host}" ----------------------------------------------------------------------------- -This is in reference to output dataset ${dataset_id}. +This is in reference to dataset id ${dataset_id} from history id ${history_id} +----------------------------------------------------------------------------- +You should be able to view the history containing the related history item + +${hid}: ${history_item_name} + +by logging in as a Galaxy admin user to the Galaxy instance referenced above +and pointing your browser to the following link. + +${history_view_link} ----------------------------------------------------------------------------- The user '${email}' provided the following information: + ${message} ----------------------------------------------------------------------------- job id: ${job_id} -tool id: ${tool_id} +tool id: ${job_tool_id} +----------------------------------------------------------------------------- +job command line: +${job_command_line} ----------------------------------------------------------------------------- job stderr: -${stderr} +${job_stderr} ----------------------------------------------------------------------------- job stdout: -${stdout} +${job_stdout} ----------------------------------------------------------------------------- job info: -${info} +${job_info} ----------------------------------------------------------------------------- job traceback: -${traceback} +${job_traceback} ----------------------------------------------------------------------------- (This is an automated message). """ @@ -103,41 +116,45 @@ @web.expose def errors( self, trans, id ): - dataset = trans.sa_session.query( model.HistoryDatasetAssociation ).get( id ) - return trans.fill_template( "dataset/errors.mako", dataset=dataset ) - + hda = trans.sa_session.query( model.HistoryDatasetAssociation ).get( id ) + return trans.fill_template( "dataset/errors.mako", hda=hda ) @web.expose def stderr( self, trans, id ): dataset = trans.sa_session.query( model.HistoryDatasetAssociation ).get( id ) job = dataset.creating_job_associations[0].job trans.response.set_content_type( 'text/plain' ) return job.stderr - @web.expose def report_error( self, trans, id, email='', message="" ): smtp_server = trans.app.config.smtp_server if smtp_server is None: - return trans.show_error_message( "Sorry, mail is not configured for this galaxy instance" ) + return trans.show_error_message( "Mail is not configured for this galaxy instance" ) to_address = trans.app.config.error_email_to if to_address is None: - return trans.show_error_message( "Sorry, error reporting has been disabled for this galaxy instance" ) + return trans.show_error_message( "Error reporting has been disabled for this galaxy instance" ) # Get the dataset and associated job - dataset = trans.sa_session.query( model.HistoryDatasetAssociation ).get( id ) - job = dataset.creating_job_associations[0].job + hda = trans.sa_session.query( model.HistoryDatasetAssociation ).get( id ) + job = hda.creating_job_associations[0].job # Get the name of the server hosting the Galaxy instance from which this report originated host = trans.request.host + history_view_link = "%s/history/view?id=%s" % ( str( host ), trans.security.encode_id( hda.history_id ) ) # Build the email message msg = MIMEText( string.Template( error_report_template ) .safe_substitute( host=host, - dataset_id=dataset.id, + dataset_id=hda.dataset_id, + history_id=hda.history_id, + hid=hda.hid, + history_item_name=hda.get_display_name(), + history_view_link=history_view_link, + job_id=job.id, + job_tool_id=job.tool_id, + job_command_line=job.command_line, + job_stderr=job.stderr, + job_stdout=job.stdout, + job_info=job.info, + job_traceback=job.traceback, email=email, - message=message, - job_id=job.id, - tool_id=job.tool_id, - stderr=job.stderr, - stdout=job.stdout, - traceback=job.traceback, - info=job.info ) ) + message=message ) ) frm = to_address # Check email a bit email = email.strip() diff -r 2eb1e3c4d143 -r df9814119044 lib/galaxy/web/controllers/history.py --- a/lib/galaxy/web/controllers/history.py Mon Nov 16 15:06:07 2009 -0500 +++ b/lib/galaxy/web/controllers/history.py Mon Nov 16 16:27:48 2009 -0500 @@ -438,23 +438,20 @@ Warning! If you import this history, you will lose your current history. Click <a href="%s">here</a> to confirm. """ % web.url_for( id=id, confirm=True ) ) - @web.expose def view( self, trans, id=None ): """View a history. If a history is importable, then it is viewable by any user.""" - # Get history to view. if not id: return trans.show_error_message( "You must specify a history you want to view." ) history_to_view = get_history( trans, id, False) - # Integrity checks. if not history_to_view: - return trans.show_error_message( "The specified history does not exist.") + return trans.show_error_message( "The specified history does not exist." ) + # Admin users can view any history # TODO: Use a new flag to determine if history is viewable? - if not history_to_view.importable: - error( "The owner of this history has not published this history." ) - + if not trans.user_is_admin and not history_to_view.importable: + error( "Either you are not allowed to view this history or the owner of this history has not published it." ) # View history. query = trans.sa_session.query( model.HistoryDatasetAssociation ) \ .filter( model.HistoryDatasetAssociation.history == history_to_view ) \ @@ -469,7 +466,6 @@ datasets = query.all(), user_owns_history = user_owns_history, show_deleted = False ) - @web.expose @web.require_login( "share histories with other users" ) def share( self, trans, id=None, email="", **kwd ): diff -r 2eb1e3c4d143 -r df9814119044 lib/galaxy/web/controllers/user.py --- a/lib/galaxy/web/controllers/user.py Mon Nov 16 15:06:07 2009 -0500 +++ b/lib/galaxy/web/controllers/user.py Mon Nov 16 16:27:48 2009 -0500 @@ -181,9 +181,7 @@ refresh_frames = [ 'masthead', 'history' ] if not trans.app.config.allow_user_creation and not trans.user_is_admin(): return trans.show_error_message( 'User registration is disabled. Please contact your Galaxy administrator for an account.' ) - # # Create the user, save all the user info and login to Galaxy - # if params.get('create_user_button', None) == "Submit": # check email and password validity error = self.__validate(trans, params, email, password, confirm) diff -r 2eb1e3c4d143 -r df9814119044 lib/galaxy/web/framework/__init__.py --- a/lib/galaxy/web/framework/__init__.py Mon Nov 16 15:06:07 2009 -0500 +++ b/lib/galaxy/web/framework/__init__.py Mon Nov 16 16:27:48 2009 -0500 @@ -446,13 +446,11 @@ self.sa_session.flush() # This method is not called from the Galaxy reports, so the cookie will always be galaxysession self.__update_session_cookie( name='galaxysession' ) - def get_galaxy_session( self ): """ Return the current galaxy session """ return self.galaxy_session - def get_history( self, create=False ): """ Load the current history, creating a new one only if there is not @@ -497,7 +495,6 @@ self.sa_session.add_all( ( self.galaxy_session, history ) ) self.sa_session.flush() return history - def get_user( self ): """Return the current user if logged in or None.""" return self.galaxy_session.user @@ -507,7 +504,6 @@ self.sa_session.add( self.galaxy_session ) self.sa_session.flush() user = property( get_user, set_user ) - def get_user_and_roles( self ): user = self.get_user() if user: @@ -515,13 +511,9 @@ else: roles = [] return user, roles - def user_is_admin( self ): admin_users = self.app.config.get( "admin_users", "" ).split( "," ) - if self.user and admin_users and self.user.email in admin_users: - return True - return False - + return self.user and admin_users and self.user.email in admin_users def get_toolbox(self): """Returns the application toolbox""" return self.app.toolbox diff -r 2eb1e3c4d143 -r df9814119044 templates/dataset/errors.mako --- a/templates/dataset/errors.mako Mon Nov 16 15:06:07 2009 -0500 +++ b/templates/dataset/errors.mako Mon Nov 16 16:27:48 2009 -0500 @@ -18,10 +18,10 @@ <body> <h2>Dataset generation errors</h2> - <p><b>Dataset ${dataset.hid}: ${dataset.display_name()}</b></p> + <p><b>Dataset ${hda.hid}: ${hda.display_name()}</b></p> - %if dataset.creating_job_associations: - <% job = dataset.creating_job_associations[0].job %> + %if hda.creating_job_associations: + <% job = hda.creating_job_associations[0].job %> %if job.traceback: The Galaxy framework encountered the following error while attempting to run the tool: <pre>${job.traceback}</pre> @@ -43,7 +43,12 @@ %else: The tool did not create any additional job / error info. %endif - + <% + if trans.user: + user_email = trans.user.email + else: + user_email = '' + %> <h2>Report this error to the Galaxy Team</h2> <p> The Galaxy team regularly reviews errors that occur in the application. @@ -56,10 +61,10 @@ <div class="toolFormTitle">Error Report</div> <div class="toolFormBody"> <form name="report_error" action="${h.url_for( action='report_error')}" method="post" > - <input type="hidden" name="id" value="${dataset.id}" /> + <input type="hidden" name="id" value="${hda.id}" /> <div class="form-row"> <label>Your email</label> - <input type="text" name="email" size="40" /> + <input type="text" name="email" size="40" value="${user_email}" /> </div> <div class="form-row"> <label>Message</label> diff -r 2eb1e3c4d143 -r df9814119044 templates/mobile/history/detail.mako --- a/templates/mobile/history/detail.mako Mon Nov 16 15:06:07 2009 -0500 +++ b/templates/mobile/history/detail.mako Mon Nov 16 16:27:48 2009 -0500 @@ -37,7 +37,7 @@ <div class="secondary"> ## Body for history items, extra info and actions, data "peek" <% user, roles = trans.get_user_and_roles() %> - %if not trans.app.security_agent.can_access_dataset( roles, data.dataset ): + %if not trans.user_is_admin() and not trans.app.security_agent.can_access_dataset( roles, data.dataset ): <div>You do not have permission to view this dataset.</div> %elif data_state == "queued": <div>Job is waiting to run</div> diff -r 2eb1e3c4d143 -r df9814119044 templates/root/history_common.mako --- a/templates/root/history_common.mako Mon Nov 16 15:06:07 2009 -0500 +++ b/templates/root/history_common.mako Mon Nov 16 16:27:48 2009 -0500 @@ -9,7 +9,7 @@ data_state = data.state user, roles = trans.get_user_and_roles() %> - %if not trans.app.security_agent.can_access_dataset( roles, data.dataset ): + %if not trans.user_is_admin() and not trans.app.security_agent.can_access_dataset( roles, data.dataset ): <div class="historyItemWrapper historyItem historyItem-${data_state} historyItem-noPermission" id="historyItem-${data.id}"> %else: <div class="historyItemWrapper historyItem historyItem-${data_state}" id="historyItem-${data.id}"> @@ -49,7 +49,7 @@ ## Body for history items, extra info and actions, data "peek" <div id="info${data.id}" class="historyItemBody"> - %if not trans.app.security_agent.can_access_dataset( roles, data.dataset ): + %if not trans.user_is_admin() and not trans.app.security_agent.can_access_dataset( roles, data.dataset ): <div>You do not have permission to view this dataset.</div> %elif data_state == "upload": <div>Dataset is uploading</div> diff -r 2eb1e3c4d143 -r df9814119044 test/base/twilltestcase.py --- a/test/base/twilltestcase.py Mon Nov 16 15:06:07 2009 -0500 +++ b/test/base/twilltestcase.py Mon Nov 16 16:27:48 2009 -0500 @@ -430,6 +430,12 @@ if check_str: self.check_page_for_string( check_str ) self.home() + def view_history( self, history_id, check_str='' ): + """Displays a history for viewing""" + self.visit_url( '%s/history/view?id=%s' % ( self.url, self.security.encode_id( history_id ) ) ) + if check_str: + self.check_page_for_string( check_str ) + self.home() def edit_hda_attribute_info( self, hda_id, new_name='', new_info='', new_dbkey='', new_startcol='' ): """Edit history_dataset_association attribute information""" self.home() diff -r 2eb1e3c4d143 -r df9814119044 test/functional/test_history_functions.py --- a/test/functional/test_history_functions.py Mon Nov 16 15:06:07 2009 -0500 +++ b/test/functional/test_history_functions.py Mon Nov 16 16:27:48 2009 -0500 @@ -603,6 +603,12 @@ except: pass self.check_history_for_string( 'You do not have permission to view this dataset' ) + # Admin users can view all datasets ( using the history/view feature ), so make sure 2.bed is accessible to the admin + self.logout() + self.login( email=admin_user.email ) + self.view_history( str( hda_2_bed.history_id ), check_str='<td>NM_005997_cds_0_0_chr1_147962193_r</td>' ) + self.logout() + self.login( email=regular_user3.email ) # Delete the clone so the next test will be valid self.delete_history( id=self.security.encode_id( history5_clone4.id ) ) def test_065_sharing_private_history_by_choosing_to_not_share( self ):