From bef705eb14511f65420c76965bcf2f7413144fef Mon Sep 17 00:00:00 2001 From: Greg Von Kuster Date: Fri, 20 Feb 2009 15:43:10 -0500 Subject: [PATCH] Separate information from permissions at the LibraryDataset level, and fix a whole slew of bugs. There are still a few known weaknesses / issues, but this rev is fairly close to concluding phase 1 of the new library features for Encode. --- lib/galaxy/web/controllers/admin.py | 310 +++++---- lib/galaxy/web/controllers/dataset.py | 4 + lib/galaxy/web/controllers/library.py | 654 +++++++++++------- templates/admin/library/browse_libraries.mako | 2 +- templates/admin/library/common.mako | 5 +- templates/admin/library/ldda_info.mako | 33 +- templates/admin/library/ldda_permissions.mako | 70 +- .../admin/library/library_dataset_info.mako | 51 ++ .../library/library_dataset_permissions.mako | 26 + .../library/library_dataset_versions.mako | 55 ++ .../admin/library/manage_library_dataset.mako | 73 -- templates/dataset/security_common.mako | 17 +- templates/library/browse_libraries.mako | 2 +- templates/library/common.mako | 3 + templates/library/ldda_info.mako | 37 +- templates/library/ldda_permissions.mako | 70 +- templates/library/library_dataset_info.mako | 69 ++ .../library/library_dataset_permissions.mako | 27 + .../library/library_dataset_versions.mako | 55 ++ templates/library/manage_library_dataset.mako | 98 --- .../functional/test_security_and_libraries.py | 6 +- 21 files changed, 1000 insertions(+), 667 deletions(-) create mode 100644 templates/admin/library/library_dataset_info.mako create mode 100644 templates/admin/library/library_dataset_permissions.mako create mode 100644 templates/admin/library/library_dataset_versions.mako delete mode 100644 templates/admin/library/manage_library_dataset.mako create mode 100644 templates/library/library_dataset_info.mako create mode 100644 templates/library/library_dataset_permissions.mako create mode 100644 templates/library/library_dataset_versions.mako delete mode 100644 templates/library/manage_library_dataset.mako diff --git a/lib/galaxy/web/controllers/admin.py b/lib/galaxy/web/controllers/admin.py index ed0dc5431ff..8b5b325a1f0 100644 --- a/lib/galaxy/web/controllers/admin.py +++ b/lib/galaxy/web/controllers/admin.py @@ -1108,6 +1108,13 @@ class Admin( BaseController ): params = util.Params( kwd ) msg = util.restore_text( params.get( 'msg', '' ) ) messagetype = params.get( 'messagetype', 'done' ) + if params.get( 'permissions', False ): + action = 'permissions' + elif params.get( 'versions', False ): + action = 'versions' + else: + # 'information' will be the default + action = 'information' library_dataset = trans.app.model.LibraryDataset.get( id ) if not library_dataset: msg = "Invalid library dataset specified, id: %s" %str( id ) @@ -1116,33 +1123,59 @@ class Admin( BaseController ): id=library_id, msg=util.sanitize_text( msg ), messagetype='error' ) ) - if params.get( 'edit_attributes_button', False ): - library_dataset.name = name - library_dataset.info = info - msg = 'Attributes updated for library dataset %s' % library_dataset.name - elif params.get( 'change_version', False ): - target_lda = trans.app.model.LibraryDatasetDatasetAssociation.get( kwd.get( 'set_lda_id' ) ) - library_dataset.library_dataset_dataset_association = target_lda - trans.app.model.flush() - msg = 'The current version of this library dataset has been updated to be %s' % target_lda.name - elif params.get( 'update_roles_button', False ): - # The user clicked the Save button on the 'Edit permissions and role associations' form - permissions = {} - for k, v in trans.app.model.Library.permitted_actions.items(): - in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( kwd.get( k + '_in', [] ) ) ] - permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles - trans.app.security_agent.set_all_library_permissions( library_dataset, permissions ) - library_dataset.refresh() - msg = 'Permissions and roles have been updated for library dataset %s' % library_dataset.name - return trans.fill_template( "/admin/library/manage_library_dataset.mako", - library_dataset=library_dataset, - library_id=library_id, - msg=msg, - messagetype=messagetype ) + if action == 'information': + if params.get( 'edit_attributes_button', False ): + old_name = library_dataset.name + new_name = util.restore_text( name ) + new_info = util.restore_text( info ) + if not new_name: + msg = 'Enter a valid name' + messagetype = 'error' + else: + library_dataset.name = new_name + library_dataset.info = new_info + library_dataset.flush() + msg = "Dataset '%s' has been renamed to '%s'" % ( old_name, new_name ) + messagetype = 'done' + return trans.fill_template( '/admin/library/library_dataset_info.mako', + library_dataset=library_dataset, + library_id=library_id, + msg=msg, + messagetype=messagetype ) + elif action == 'versions': + if params.get( 'change_version_button', False ): + target_lda = trans.app.model.LibraryDatasetDatasetAssociation.get( kwd.get( 'set_lda_id' ) ) + library_dataset.library_dataset_dataset_association = target_lda + trans.app.model.flush() + msg = 'The current version of this library dataset has been updated to be %s' % target_lda.name + return trans.fill_template( '/admin/library/library_dataset_versions.mako', + library_dataset=library_dataset, + library_id=library_id, + msg=msg, + messagetype=messagetype ) + elif action == 'permissions': + if params.get( 'update_roles_button', False ): + # The user clicked the Save button on the 'Edit permissions and role associations' form + permissions = {} + for k, v in trans.app.model.Library.permitted_actions.items(): + in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( kwd.get( k + '_in', [] ) ) ] + permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles + # Set the LIBRARY permissions on the LibraryDataset + # NOTE: the LibraryDataset and LibraryDatasetDatasetAssociation will be set with the same permissions + trans.app.security_agent.set_all_library_permissions( library_dataset, permissions ) + library_dataset.refresh() + # Set the LIBRARY permissions on the LibraryDatasetDatasetAssociation + trans.app.security_agent.set_all_library_permissions( library_dataset.library_dataset_dataset_association, permissions ) + library_dataset.library_dataset_dataset_association.refresh() + msg = 'Permissions and roles have been updated for library dataset %s' % library_dataset.name + return trans.fill_template( '/admin/library/library_dataset_permissions.mako', + library_dataset=library_dataset, + library_id=library_id, + msg=msg, + messagetype=messagetype ) @web.expose @web.require_admin - def library_dataset_dataset_association( self, trans, id=None, name="Unnamed", info='no info', - extension=None, folder_id=None, library_id=None, **kwd ): + def library_dataset_dataset_association( self, trans, id=None, name="Unnamed", info='no info', folder_id=None, library_id=None, **kwd ): params = util.Params( kwd ) msg = util.restore_text( params.get( 'msg', '' ) ) messagetype = params.get( 'messagetype', 'done' ) @@ -1151,14 +1184,20 @@ class Admin( BaseController ): last_used_build = dbkey[0] else: last_used_build = dbkey - if folder_id and not last_used_build: + if folder_id: folder = trans.app.model.LibraryFolder.get( folder_id ) + else: + folder = None + if folder and not last_used_build: last_used_build = folder.genome_build - data_files = [] try: replace_dataset = trans.app.model.LibraryDataset.get( params.get( 'replace_id', None ) ) except: replace_dataset = None + # Let's not overwrite the imported datatypes module with the variable datatypes? + # The built-in 'id' is overwritten in lots of places as well + ldatatypes = [ x for x in trans.app.datatypes_registry.datatypes_by_extension.iterkeys() ] + ldatatypes.sort() if params.get( 'new_dataset_button', False ): created_ldda_ids = upload_dataset( trans, controller='admin', @@ -1169,23 +1208,19 @@ class Admin( BaseController ): total_added = len( created_ldda_ids.split( ',' ) ) msg = "%i new datasets added to the library ( each is selected below ). " % total_added msg += "Click the Go button at the bottom of this page to edit the permissions on these datasets if necessary." - trans.response.send_redirect( web.url_for( controller='admin', - action='browse_library', - id=library_id, - created_ldda_ids=created_ldda_ids, - msg=util.sanitize_text( msg ), - messagetype='done' ) ) + messagetype='done' else: msg = "Upload failed" - trans.response.send_redirect( web.url_for( controller='admin', - action='browse_library', - id=library_id, - created_ldda_ids=created_ldda_ids, - msg=util.sanitize_text( msg ), - messagetype='error' ) ) + messagetype='error' + trans.response.send_redirect( web.url_for( controller='admin', + action='browse_library', + id=library_id, + created_ldda_ids=created_ldda_ids, + msg=util.sanitize_text( msg ), + messagetype=messagetype ) ) elif not id or replace_dataset: - # No dataset(s) specified, so display the upload form. - # Send list of data formats to the form so the "extension" select list can be populated dynamically + # No dataset(s) specified, so display the upload form. Send list of data formats to the form + # so the "extension" select list can be populated dynamically file_formats = trans.app.datatypes_registry.upload_file_formats # Send list of genome builds to the form so the "dbkey" select list can be populated dynamically def get_dbkey_options( last_used_build ): @@ -1194,7 +1229,7 @@ class Admin( BaseController ): dbkeys = get_dbkey_options( last_used_build ) # Send list of roles to the form so the dataset can be associated with 1 or more of them. roles = trans.app.model.Role.filter( trans.app.model.Role.table.c.deleted==False ).order_by( trans.app.model.Role.c.name ).all() - # Send the current history to enable importing datasets from history to library + # Send the current history to the form to enable importing datasets from history to library history = trans.get_history() history.refresh() return trans.fill_template( '/admin/library/new_dataset.mako', @@ -1236,35 +1271,38 @@ class Admin( BaseController ): for k, v in trans.app.model.Dataset.permitted_actions.items(): in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( params.get( k + '_in', [] ) ) ] permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles + # Set the DATASET permissions on the Dataset trans.app.security_agent.set_all_dataset_permissions( ldda.dataset, permissions ) - # Set/display library security info + ldda.dataset.refresh() permissions = {} for k, v in trans.app.model.Library.permitted_actions.items(): in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( kwd.get( k + '_in', [] ) ) ] permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles + # Set the LIBRARY permissions on the LibraryDataset + # NOTE: the LibraryDataset and LibraryDatasetDatasetAssociation will be set with the same permissions + trans.app.security_agent.set_all_library_permissions( ldda.library_dataset, permissions ) + ldda.library_dataset.refresh() + # Set the LIBRARY permissions on the LibraryDatasetDatasetAssociation trans.app.security_agent.set_all_library_permissions( ldda, permissions ) - ldda.dataset.refresh() + ldda.refresh() msg = "Permissions updated for dataset '%s'" % ldda.name - return trans.response.send_redirect( web.url_for( controller='admin', - action='library_dataset_dataset_association', - id=id, - permissions=True, - msg=util.sanitize_text( msg ), - messagetype='done' ) ) - return trans.fill_template( '/admin/library/ldda_permissions.mako', ldda=ldda, library_id=library_id, msg=msg, messagetype=messagetype ) + return trans.fill_template( '/admin/library/ldda_permissions.mako', + ldda=ldda, + library_id=library_id, + msg=msg, + messagetype=messagetype ) elif action == 'information': if params.get( 'change', False ): # The user clicked the Save button on the 'Change data type' form trans.app.datatypes_registry.change_datatype( ldda, params.datatype ) trans.app.model.flush() - msg = "Data type changed for dataset '%s'" % ldda.name - return trans.response.send_redirect( web.url_for( controller='admin', - action='library_dataset_dataset_association', - id=id, - library_id=library_id, - information=True, - msg=util.sanitize_text( msg ), - messagetype='done' ) ) + msg = "Data type changed for library dataset '%s'" % ldda.name + return trans.fill_template( "/admin/library/ldda_info.mako", + ldda=ldda, + library_id=library_id, + datatypes=ldatatypes, + msg=msg, + messagetype=messagetype ) elif params.get( 'save', False ): # The user clicked the Save button on the 'Edit Attributes' form ldda.name = name @@ -1282,14 +1320,13 @@ class Admin( BaseController ): ldda.metadata.dbkey = dbkey ldda.datatype.after_edit( ldda ) trans.app.model.flush() - msg = 'Attributes updated for dataset %s' % ldda.name - return trans.response.send_redirect( web.url_for( controller='admin', - action='library_dataset_dataset_association', - id=id, - library_id=library_id, - information=True, - msg=util.sanitize_text( msg ), - messagetype='done' ) ) + msg = 'Attributes updated for library dataset %s' % ldda.name + return trans.fill_template( "/admin/library/ldda_info.mako", + ldda=ldda, + library_id=library_id, + datatypes=ldatatypes, + msg=msg, + messagetype=messagetype ) elif params.get( 'detect', False ): # The user clicked the Auto-detect button on the 'Edit Attributes' form for name, spec in ldda.datatype.metadata_spec.items(): @@ -1300,25 +1337,25 @@ class Admin( BaseController ): ldda.datatype.set_meta( ldda ) ldda.datatype.after_edit( ldda ) trans.app.model.flush() - msg = 'Attributes updated for dataset %s' % ldda.name - return trans.response.send_redirect( web.url_for( controller='admin', - action='library_dataset_dataset_association', - id=id, - library_id=library_id, - information=True, - msg=util.sanitize_text( msg ), - messagetype='done' ) ) + msg = 'Attributes updated for library dataset %s' % ldda.name + return trans.fill_template( "/admin/library/ldda_info.mako", + ldda=ldda, + library_id=library_id, + datatypes=ldatatypes, + msg=msg, + messagetype=messagetype ) elif params.get( 'delete', False ): # TODO: need to revamp the way we remove datasets from disk. # The user selected the "Remove this dataset from the library" pop-up menu option ldda.deleted = True ldda.flush() msg = 'Dataset %s has been removed from this library' % ldda.name - trans.response.send_redirect( web.url_for( controller='admin', - action='browse_library', - id=library_id, - msg=util.sanitize_text( msg ), - messagetype='done' ) ) + return trans.fill_template( "/admin/library/ldda_info.mako", + ldda=ldda, + library_id=library_id, + datatypes=ldatatypes, + msg=msg, + messagetype=messagetype ) ldda.datatype.before_edit( ldda ) if "dbkey" in ldda.datatype.metadata_spec and not ldda.metadata.dbkey: # Copy dbkey into metadata, for backwards compatability @@ -1327,10 +1364,6 @@ class Admin( BaseController ): # case it resorts to the old dbkey. Setting the dbkey # sets it properly in the metadata ldda.metadata.dbkey = ldda.dbkey - # let's not overwrite the imported datatypes module with the variable datatypes? - ### the built-in 'id' is overwritten in lots of places as well - ldatatypes = [x for x in trans.app.datatypes_registry.datatypes_by_extension.iterkeys()] - ldatatypes.sort() return trans.fill_template( "/admin/library/ldda_info.mako", ldda=ldda, library_id=library_id, @@ -1359,14 +1392,26 @@ class Admin( BaseController ): messagetype='error' ) ) if action == 'permissions': if params.get( 'update_roles_button', False ): - #p = util.Params( kwd ) permissions = {} for k, v in trans.app.model.Dataset.permitted_actions.items(): in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( params.get( k + '_in', [] ) ) ] permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles for ldda in lddas: + # Set the DATASET permissions on the Dataset trans.app.security_agent.set_all_dataset_permissions( ldda.dataset, permissions ) ldda.dataset.refresh() + permissions = {} + for k, v in trans.app.model.Library.permitted_actions.items(): + in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( kwd.get( k + '_in', [] ) ) ] + permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles + for ldda in lddas: + # Set the LIBRARY permissions on the LibraryDataset + # NOTE: the LibraryDataset and LibraryDatasetDatasetAssociation will be set with the same permissions + trans.app.security_agent.set_all_library_permissions( ldda.library_dataset, permissions ) + ldda.library_dataset.refresh() + # Set the LIBRARY permissions on the LibraryDatasetDatasetAssociation + trans.app.security_agent.set_all_library_permissions( ldda, permissions ) + ldda.refresh() msg = 'Permissions and roles have been updated on %d datasets' % len( lddas ) return trans.fill_template( "/admin/library/ldda_permissions.mako", ldda=lddas, @@ -1374,6 +1419,9 @@ class Admin( BaseController ): msg=msg, messagetype=messagetype ) # Ensure that the permissions across all datasets are identical. Otherwise, we can't update together. + # TODO: this doesn't really work as it should - we need to check permissions on associated + # LibraryDatasetDatasetAssociation and LibraryDataset as well. Improvement can also be made in the way + # we are checking... tmp = [] for ldda in lddas: perms = trans.app.security_agent.get_dataset_permissions( ldda.dataset ) @@ -1558,6 +1606,7 @@ class Admin( BaseController ): @web.expose @web.require_admin def library_item_info( self, trans, do_action='display', id=None, library_item_id=None, library_item_type=None, library_id=None, **kwd ): + # TODO: this needs to be cleaned up... params = util.Params( kwd ) msg = util.restore_text( params.get( 'msg', '' ) ) messagetype = params.get( 'messagetype', 'done' ) @@ -1595,54 +1644,49 @@ class Admin( BaseController ): messagetype=messagetype ) elif do_action == 'new_info': if library_item: - if trans.app.security_agent.allow_action( trans.user, - trans.app.security_agent.permitted_actions.LIBRARY_ADD, - library_item=library_item ): - if params.get( 'create_new_info_button', False ): - user = trans.get_user() - #create new info then send back to make more - library_item_info_template_id = params.get( 'library_item_info_template_id', None ) - library_item_info_template = trans.app.model.LibraryItemInfoTemplate.get( library_item_info_template_id ) - library_item_info = trans.app.model.LibraryItemInfo() - library_item_info.library_item_info_template = library_item_info_template - library_item_info.user = user - library_item_info.flush() - trans.app.security_agent.copy_library_permissions( library_item_info_template, library_item_info, user=user ) - for template_element in library_item_info_template.elements: - info_element_value = params.get( "info_element_%s_%s" % ( library_item_info_template.id, template_element.id), None ) - info_element = trans.app.model.LibraryItemInfoElement() - info_element.contents = info_element_value - info_element.library_item_info_template_element = template_element - info_element.library_item_info = library_item_info - info_element.flush() - info_association_class = None - for item_class, permission_class, info_association_class in trans.app.security_agent.library_item_assocs: - if isinstance( library_item, item_class ): - break - if info_association_class: - library_item_info_association = info_association_class() - library_item_info_association.set_library_item( library_item ) - library_item_info_association.library_item_info = library_item_info - library_item_info_association.user = user - library_item_info_association.flush() - else: - raise 'Invalid class (%s) specified for library_item (%s)' % ( library_item.__class__, library_item.__class__.__name__ ) - # TODO: make sure we don't need to set permissions on the association object. - msg = 'The information has been saved. You can add more information if necessary.' - return trans.response.send_redirect( web.url_for( controller='admin', - action=library_item_type, - id=library_item.id, - library_id=library_id, - msg=util.sanitize_text( msg ), - messagetype='done' ) ) - return trans.fill_template( "/admin/library/new_info.mako", - library_item=library_item, - library_item_type=library_item_type, - library_id=library_id, - msg=msg, - messagetype=messagetype ) - else: - return trans.show_error_message( "You do not have permission to add information to this library item." ) + if params.get( 'create_new_info_button', False ): + user = trans.get_user() + #create new info then send back to make more + library_item_info_template_id = params.get( 'library_item_info_template_id', None ) + library_item_info_template = trans.app.model.LibraryItemInfoTemplate.get( library_item_info_template_id ) + library_item_info = trans.app.model.LibraryItemInfo() + library_item_info.library_item_info_template = library_item_info_template + library_item_info.user = user + library_item_info.flush() + trans.app.security_agent.copy_library_permissions( library_item_info_template, library_item_info, user=user ) + for template_element in library_item_info_template.elements: + info_element_value = params.get( "info_element_%s_%s" % ( library_item_info_template.id, template_element.id), None ) + info_element = trans.app.model.LibraryItemInfoElement() + info_element.contents = info_element_value + info_element.library_item_info_template_element = template_element + info_element.library_item_info = library_item_info + info_element.flush() + info_association_class = None + for item_class, permission_class, info_association_class in trans.app.security_agent.library_item_assocs: + if isinstance( library_item, item_class ): + break + if info_association_class: + library_item_info_association = info_association_class() + library_item_info_association.set_library_item( library_item ) + library_item_info_association.library_item_info = library_item_info + library_item_info_association.user = user + library_item_info_association.flush() + else: + raise 'Invalid class (%s) specified for library_item (%s)' % ( library_item.__class__, library_item.__class__.__name__ ) + # TODO: make sure we don't need to set permissions on the association object. + msg = 'The information has been saved. You can add more information if necessary.' + return trans.response.send_redirect( web.url_for( controller='admin', + action=library_item_type, + id=library_item.id, + library_id=library_id, + msg=util.sanitize_text( msg ), + messagetype='done' ) ) + return trans.fill_template( "/admin/library/new_info.mako", + library_item=library_item, + library_item_type=library_item_type, + library_id=library_id, + msg=msg, + messagetype=messagetype ) # TODO: add more functionality -> user's should be able to edit/delete, etc, and create/delete and edit templates return trans.fill_template( "/admin/library/display_info.mako", item_info=item_info, diff --git a/lib/galaxy/web/controllers/dataset.py b/lib/galaxy/web/controllers/dataset.py index acb0866d76a..b6dfd4815e2 100644 --- a/lib/galaxy/web/controllers/dataset.py +++ b/lib/galaxy/web/controllers/dataset.py @@ -287,6 +287,10 @@ def add_file( trans, file_obj, name, extension, dbkey, roles, info='no info', sp library_dataset = trans.app.model.LibraryDataset( name=name, info=info, extension=data_type, dbkey=dbkey ) library_dataset.flush() if permission_source: + # permission_source is a LibraryFolder or a LibraryDataset + # TODO: we need to ensure we copy permissions on all 3 levels: + # LibraryDatasetDatasetAssociation, LibraryDataset, and Dataset + # This is currently not being done and must be fixed ASAP!! trans.app.security_agent.copy_library_permissions( permission_source, library_dataset, user=trans.get_user() ) ldda = trans.app.model.LibraryDatasetDatasetAssociation( name=name, info=info, diff --git a/lib/galaxy/web/controllers/library.py b/lib/galaxy/web/controllers/library.py index a5a0cba4251..e1b15cbedeb 100644 --- a/lib/galaxy/web/controllers/library.py +++ b/lib/galaxy/web/controllers/library.py @@ -53,6 +53,72 @@ class Library( BaseController ): msg=msg, messagetype=messagetype ) @web.expose + def library( self, trans, id=None, **kwd ): + params = util.Params( kwd ) + msg = util.restore_text( params.get( 'msg', '' ) ) + messagetype = params.get( 'messagetype', 'done' ) + if not id: + msg = "You must specify a library." + return trans.response.send_redirect( web.url_for( controller='library', + action='browse_libraries', + msg=util.sanitize_text( msg ), + messagetype='error' ) ) + library = trans.app.model.Library.get( int( id ) ) + if not library: + msg = "Invalid library id ( %s ) specified." % str( id ) + return trans.response.send_redirect( web.url_for( controller='library', + action='browse_libraries', + msg=util.sanitize_text( msg ), + messagetype='error' ) ) + if params.get( 'delete', False ): + action = 'delete' + elif params.get( 'permissions', False ): + action = 'permissions' + else: + # 'information' is the default + action = 'information' + if action == 'information': + if params.get( 'rename_library_button', False ): + old_name = library.name + new_name = util.restore_text( params.name ) + new_description = util.restore_text( params.description ) + if not new_name: + msg = 'Enter a valid name' + return trans.fill_template( '/library/library_info.mako', library=library, msg=msg, messagetype='error' ) + else: + if params.get( 'root_folder', False ): + root_folder = library.root_folder + root_folder.name = new_name + root_folder.flush() + library.name = new_name + library.description = new_description + library.flush() + msg = "Library '%s' has been renamed to '%s'" % ( old_name, new_name ) + return trans.response.send_redirect( web.url_for( controller='library', + action='library', + id=id, + information=True, + msg=util.sanitize_text( msg ), + messagetype='done' ) ) + return trans.fill_template( '/library/library_info.mako', library=library, msg=msg, messagetype=messagetype ) + elif action == 'permissions': + if params.get( 'update_roles_button', False ): + # The user clicked the Save button on the 'Associate With Roles' form + permissions = {} + for k, v in trans.app.model.Library.permitted_actions.items(): + in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( params.get( k + '_in', [] ) ) ] + permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles + trans.app.security_agent.set_all_library_permissions( library, permissions ) + library.refresh() + msg = "Permissions updated for library '%s'" % library.name + return trans.response.send_redirect( web.url_for( controller='library', + action='library', + id=id, + permissions=True, + msg=util.sanitize_text( msg ), + messagetype='done' ) ) + return trans.fill_template( '/library/manage_library_permissions.mako', library=library, msg=msg, messagetype=messagetype ) + @web.expose def datasets( self, trans, ldda_ids=[], library_id=None, **kwd ): # This method is used by the select list labeled "Perform action on selected datasets" # on the analysis library browser. @@ -214,8 +280,98 @@ class Library( BaseController ): msg=msg, messagetype='error' ) ) @web.expose - def library_dataset_dataset_association( self, trans, id=None, name=None, info=None, folder_id=None, - replace_id=None, refer_id=None, library_id=None, **kwd ): + def library_dataset( self, trans, id, name=None, info=None, library_id=None, **kwd ): + params = util.Params( kwd ) + msg = util.restore_text( params.get( 'msg', '' ) ) + messagetype = params.get( 'messagetype', 'done' ) + if params.get( 'permissions', False ): + action = 'permissions' + elif params.get( 'versions', False ): + action = 'versions' + else: + # 'information' will be the default + action = 'information' + library_dataset = trans.app.model.LibraryDataset.get( id ) + if not library_dataset: + msg = "Invalid library dataset specified, id: %s" %str( id ) + return trans.response.send_redirect( web.url_for( controller='library', + action='browse_library', + id=library_id, + msg=util.sanitize_text( msg ), + messagetype='error' ) ) + if action == 'information': + if params.get( 'edit_attributes_button', False ): + if trans.app.security_agent.allow_action( trans.user, + trans.app.security_agent.permitted_actions.LIBRARY_MODIFY, + library_item=library_dataset ): + if params.get( 'edit_attributes_button', False ): + old_name = library_dataset.name + new_name = util.restore_text( name ) + new_info = util.restore_text( info ) + if not new_name: + msg = 'Enter a valid name' + messagetype = 'error' + else: + library_dataset.name = new_name + library_dataset.info = new_info + library_dataset.flush() + msg = "Dataset '%s' has been renamed to '%s'" % ( old_name, new_name ) + messagetype = 'done' + else: + msg = "You are not authorized to change the attributes of this dataset" + messagetype = "error" + return trans.fill_template( '/library/library_dataset_info.mako', + library_dataset=library_dataset, + library_id=library_id, + msg=msg, + messagetype=messagetype ) + elif action == 'versions': + if params.get( 'change_version_button', False ): + if trans.app.security_agent.allow_action( trans.user, + trans.app.security_agent.permitted_actions.LIBRARY_MODIFY, + library_item=library_dataset ): + target_lda = trans.app.model.LibraryDatasetDatasetAssociation.get( kwd.get( 'set_lda_id' ) ) + library_dataset.library_dataset_dataset_association = target_lda + trans.app.model.flush() + msg = 'The current version of this library dataset has been updated to be %s' % target_lda.name + messagetype = 'done' + else: + msg = "You are not authorized to change the versions of this dataset" + messagetype = "error" + return trans.fill_template( '/library/library_dataset_versions.mako', + library_dataset=library_dataset, + library_id=library_id, + msg=msg, + messagetype=messagetype ) + elif action == 'permissions': + if params.get( 'update_roles_button', False ): + if trans.app.security_agent.allow_action( trans.user, + trans.app.security_agent.permitted_actions.LIBRARY_MANAGE, + library_item=library_dataset ): + # The user clicked the Save button on the 'Associate With Roles' form + permissions = {} + for k, v in trans.app.model.Library.permitted_actions.items(): + in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( kwd.get( k + '_in', [] ) ) ] + permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles + # Set the LIBRARY permissions on the LibraryDataset + # NOTE: the LibraryDataset and LibraryDatasetDatasetAssociation will be set with the same permissions + trans.app.security_agent.set_all_library_permissions( library_dataset, permissions ) + library_dataset.refresh() + # Set the LIBRARY permissions on the LibraryDatasetDatasetAssociation + trans.app.security_agent.set_all_library_permissions( library_dataset.library_dataset_dataset_association, permissions ) + library_dataset.library_dataset_dataset_association.refresh() + msg = 'Permissions and roles have been updated for library dataset %s' % library_dataset.name + messagetype = 'done' + else: + msg = "You are not authorized to managed the permissions of this dataset" + messagetype = "error" + return trans.fill_template( '/library/library_dataset_permissions.mako', + library_dataset=library_dataset, + library_id=library_id, + msg=msg, + messagetype=messagetype ) + @web.expose + def library_dataset_dataset_association( self, trans, id=None, name="Unnamed", info='no info', folder_id=None, library_id=None, **kwd ): params = util.Params( kwd ) msg = util.restore_text( params.get( 'msg', '' ) ) messagetype = params.get( 'messagetype', 'done' ) @@ -227,59 +383,184 @@ class Library( BaseController ): if not last_used_build: last_used_build = folder.genome_build permission_source = folder + # permission_source is a LibraryFolder or a LibraryDataset + # TODO: we need to ensure we copy permissions on all 3 levels: + # LibraryDatasetDatasetAssociation, LibraryDataset, and Dataset + # This is currently not being done and must be fixed ASAP!! try: replace_dataset = trans.app.model.LibraryDataset.get( params.get( 'replace_id', None ) ) if not last_used_build: last_used_build = replace_dataset.library_dataset_dataset_association.dbkey permission_source = replace_dataset + # permission_source is a LibraryFolder or a LibraryDataset + # TODO: we need to ensure we copy permissions on all 3 levels: + # LibraryDatasetDatasetAssociation, LibraryDataset, and Dataset + # This is currently not being done and must be fixed ASAP!! except: replace_dataset = None + # Let's not overwrite the imported datatypes module with the variable datatypes? + # The built-in 'id' is overwritten in lots of places as well + ldatatypes = [ x for x in trans.app.datatypes_registry.datatypes_by_extension.iterkeys() ] + ldatatypes.sort() if id: if params.get( 'permissions', False ): action = 'permissions' else: # 'information' will be the default action = 'information' - # The user is updating the permissions on 1 or more datasets if id.count( ',' ): ids = id.split( ',' ) id = None else: ids = None - if id: - # id specified, display attributes form - ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( id ) - if not ldda: - msg = "Invalid LibraryDatasetDatasetAssociation specified, id: %s" % str( id ) - return trans.response.send_redirect( web.url_for( controller='library', - action='browse_library', - id=library_id, - msg=util.sanitize_text( msg ), - messagetype='error' ) ) - if action == 'permissions': - if params.get( 'update_roles_button', False ): - # The user clicked the Save button on the 'Associate With Roles' form + else: + ids = None + if id: + # ldda_id specified, display attributes form + ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( id ) + if not ldda: + msg = "Invalid LibraryDatasetDatasetAssociation specified, id: %s" % str( id ) + return trans.response.send_redirect( web.url_for( controller='library', + action='browse_library', + id=library_id, + msg=util.sanitize_text( msg ), + messagetype='error' ) ) + if action == 'permissions': + if params.get( 'update_roles_button', False ): + # The user clicked the Save button on the 'Associate With Roles' form + if trans.app.security_agent.allow_action( trans.user, + trans.app.security_agent.permitted_actions.LIBRARY_MANAGE, + library_item=ldda ) and \ + trans.app.security_agent.allow_action( trans.user, + trans.app.security_agent.permitted_actions.LIBRARY_MANAGE, + library_item=ldda.library_dataset ) and \ + trans.app.security_agent.allow_action( trans.user, + trans.app.security_agent.permitted_actions.DATASET_MANAGE_PERMISSIONS, + dataset=ldda.dataset ): permissions = {} for k, v in trans.app.model.Dataset.permitted_actions.items(): in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( params.get( k + '_in', [] ) ) ] permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles + # Set the DATASET permissions on the Dataset trans.app.security_agent.set_all_dataset_permissions( ldda.dataset, permissions ) - # Set/display library security info + ldda.dataset.refresh() permissions = {} for k, v in trans.app.model.Library.permitted_actions.items(): - in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( params.get( k + '_in', [] ) ) ] + in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( kwd.get( k + '_in', [] ) ) ] permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles + # Set the LIBRARY permissions on the LibraryDataset + # NOTE: the LibraryDataset and LibraryDatasetDatasetAssociation will be set with the same permissions + trans.app.security_agent.set_all_library_permissions( ldda.library_dataset, permissions ) + ldda.library_dataset.refresh() + # Set the LIBRARY permissions on the LibraryDatasetDatasetAssociation trans.app.security_agent.set_all_library_permissions( ldda, permissions ) - ldda.dataset.refresh() + ldda.refresh() msg = "Permissions updated for dataset '%s'" % ldda.name - return trans.response.send_redirect( web.url_for( controller='library', - action='library_dataset_dataset_association', - id=id, - library_id=library_id, - msg=util.sanitize_text( msg ), - messagetype='done' ) ) - return trans.fill_template( '/library/ldda_permissions.mako', ldda=ldda, library_id=library_id, msg=msg, messagetype=messagetype ) - elif action == 'information': + messagetype = 'done' + else: + msg = "You are not authorized to change the permissions of dataset '%s'" % ldda.name + messagetype = 'error' + return trans.fill_template( '/library/ldda_permissions.mako', + ldda=ldda, + library_id=library_id, + msg=msg, + messagetype=messagetype ) + elif action == 'information': + if params.get( 'change', False ): + # The user clicked the Save button on the 'Change data type' form + if trans.app.security_agent.allow_action( trans.user, + trans.app.security_agent.permitted_actions.LIBRARY_MODIFY, + library_item=ldda ): + trans.app.datatypes_registry.change_datatype( ldda, params.datatype ) + trans.app.model.flush() + msg = "Data type changed for library dataset '%s'" % ldda.name + messagetype = 'done' + else: + msg = "You are not authorized to change the data type of dataset '%s'" % ldda.name + messagetype = 'error' + return trans.fill_template( "/library/ldda_info.mako", + ldda=ldda, + library_id=library_id, + datatypes=ldatatypes, + msg=msg, + messagetype=messagetype ) + elif params.get( 'save', False ): + # The user clicked the Save button on the 'Edit Attributes' form + if trans.app.security_agent.allow_action( trans.user, + trans.app.security_agent.permitted_actions.LIBRARY_MODIFY, + library_item=ldda ): + ldda.name = name + ldda.info = info + # The following for loop will save all metadata_spec items + for name, spec in ldda.datatype.metadata_spec.items(): + if spec.get("readonly"): + continue + optional = params.get( "is_" + name, None ) + if optional and optional == 'true': + # optional element... == 'true' actually means it is NOT checked (and therefore ommitted) + setattr( ldda.metadata, name, None ) + else: + setattr( ldda.metadata, name, spec.unwrap( params.get ( name, None ) ) ) + ldda.metadata.dbkey = dbkey + ldda.datatype.after_edit( ldda ) + trans.app.model.flush() + msg = 'Attributes updated for library dataset %s' % ldda.name + messagetype = 'done' + else: + msg = "you are not authorized to edit the attributes of dataset '%s'" % ldda.name + messagetype = 'error' + return trans.fill_template( "/library/ldda_info.mako", + ldda=ldda, + library_id=library_id, + datatypes=ldatatypes, + msg=msg, + messagetype=messagetype ) + elif params.get( 'detect', False ): + # The user clicked the Auto-detect button on the 'Edit Attributes' form + if trans.app.security_agent.allow_action( trans.user, + trans.app.security_agent.permitted_actions.LIBRARY_MODIFY, + library_item=ldda ): + for name, spec in ldda.datatype.metadata_spec.items(): + # We need to be careful about the attributes we are resetting + if name not in [ 'name', 'info', 'dbkey' ]: + if spec.get( 'default' ): + setattr( ldda.metadata, name, spec.unwrap( spec.get( 'default' ) ) ) + ldda.datatype.set_meta( ldda ) + ldda.datatype.after_edit( ldda ) + trans.app.model.flush() + msg = 'Attributes updated for library dataset %s' % ldda.name + messagetype = 'done' + else: + msg = "you are not authorized to edit the attributes of dataset '%s'" % ldda.name + messagetype = 'error' + return trans.fill_template( "/library/ldda_info.mako", + ldda=ldda, + library_id=library_id, + datatypes=ldatatypes, + msg=msg, + messagetype=messagetype ) + elif params.get( 'delete', False ): + # TODO: need to revamp the way we remove datasets from disk. + # The user selected the "Remove this dataset from the library" pop-up menu option + if trans.app.security_agent.allow_action( trans.user, + trans.app.security_agent.permitted_actions.LIBRARY_MODIFY, + library_item=folder ): + ldda.deleted = True + ldda.flush() + msg = 'Dataset %s has been removed from this library' % ldda.name + messagetype = 'done' + else: + msg = "you are not authorized to delete dataset '%s'" % ldda.name + messagetype = 'error' + return trans.fill_template( "/library/ldda_info.mako", + ldda=ldda, + library_id=library_id, + datatypes=ldatatypes, + msg=msg, + messagetype=messagetype ) + if trans.app.security_agent.allow_action( trans.user, + trans.app.security_agent.permitted_actions.LIBRARY_MODIFY, + library_item=ldda ): ldda.datatype.before_edit( ldda ) if "dbkey" in ldda.datatype.metadata_spec and not ldda.metadata.dbkey: # Copy dbkey into metadata, for backwards compatability @@ -288,72 +569,108 @@ class Library( BaseController ): # case it resorts to the old dbkey. Setting the dbkey # sets it properly in the metadata ldda.metadata.dbkey = ldda.dbkey - # let's not overwrite the imported datatypes module with the variable datatypes? - ### the built-in 'id' is overwritten in lots of places as well - ldatatypes = [x for x in trans.app.datatypes_registry.datatypes_by_extension.iterkeys()] - ldatatypes.sort() - return trans.fill_template( "/library/ldda_info.mako", - ldda=ldda, - library_id=library_id, - datatypes=ldatatypes, - msg=msg, - messagetype=messagetype ) - elif ids: - # Multiple ids specfied, display permission form, permissions will be updated for all simultaneously. - lddas = [] - for id in [ int( id ) for id in ids ]: - ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( id ) - if ldda is None: - msg = 'You specified an invalid LibraryDatasetDatasetAssociation id: %s' %str( id ) - trans.response.send_redirect( web.url_for( controller='library', - action='browse_library', - id=library_id, - msg=util.sanitize_text( msg ), - messagetype='error' ) ) - lddas.append( ldda ) - if len( lddas ) < 2: - msg = 'You must specify at least two datasets on which to modify permissions, ids you sent: %s' % str( ids ) + return trans.fill_template( "/library/ldda_info.mako", + ldda=ldda, + library_id=library_id, + datatypes=ldatatypes, + msg=msg, + messagetype=messagetype ) + elif ids: + # Multiple ids specfied, display permission form, permissions will be updated for all simultaneously. + lddas = [] + for id in [ int( id ) for id in ids ]: + ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( id ) + if ldda is None: + msg = 'You specified an invalid LibraryDatasetDatasetAssociation id: %s' %str( id ) trans.response.send_redirect( web.url_for( controller='library', action='browse_library', id=library_id, msg=util.sanitize_text( msg ), messagetype='error' ) ) - if action == 'permissions': - if params.get( 'update_roles_button', False ): + lddas.append( ldda ) + if len( lddas ) < 2: + msg = 'You must specify at least two datasets on which to modify permissions, ids you sent: %s' % str( ids ) + trans.response.send_redirect( web.url_for( controller='library', + action='browse_library', + id=library_id, + msg=util.sanitize_text( msg ), + messagetype='error' ) ) + if action == 'permissions': + if params.get( 'update_roles_button', False ): + if trans.app.security_agent.allow_action( trans.user, + trans.app.security_agent.permitted_actions.LIBRARY_MANAGE, + library_item=ldda ) and \ + trans.app.security_agent.allow_action( trans.user, + trans.app.security_agent.permitted_actions.LIBRARY_MANAGE, + library_item=ldda.library_dataset ) and \ + trans.app.security_agent.allow_action( trans.user, + trans.app.security_agent.permitted_actions.DATASET_MANAGE_PERMISSIONS, + dataset=ldda.dataset ): permissions = {} for k, v in trans.app.model.Dataset.permitted_actions.items(): in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( params.get( k + '_in', [] ) ) ] permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles for ldda in lddas: + # Set the DATASET permissions on the Dataset trans.app.security_agent.set_all_dataset_permissions( ldda.dataset, permissions ) ldda.dataset.refresh() + permissions = {} + for k, v in trans.app.model.Library.permitted_actions.items(): + in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( kwd.get( k + '_in', [] ) ) ] + permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles + for ldda in lddas: + # Set the LIBRARY permissions on the LibraryDataset + # NOTE: the LibraryDataset and LibraryDatasetDatasetAssociation will be set with the same permissions + trans.app.security_agent.set_all_library_permissions( ldda.library_dataset, permissions ) + ldda.library_dataset.refresh() + # Set the LIBRARY permissions on the LibraryDatasetDatasetAssociation + trans.app.security_agent.set_all_library_permissions( ldda, permissions ) + ldda.refresh() msg = 'Permissions and roles have been updated on %d datasets' % len( lddas ) - return trans.fill_template( "/library/ldda_permissions.mako", - ldda=lddas, - library_id=library_id, - msg=msg, - messagetype=messagetype ) - # Ensure that the permissions across all datasets are identical. Otherwise, we can't update together. - tmp = [] - for ldda in lddas: - perms = trans.app.security_agent.get_dataset_permissions( ldda.dataset ) - if perms not in tmp: - tmp.append( perms ) - if len( tmp ) != 1: - msg = 'The datasets you selected do not have identical permissions, so they can not be updated together' - trans.response.send_redirect( web.url_for( controller='library', - action='browse_library', - id=library_id, - msg=util.sanitize_text( msg ), - messagetype='error' ) ) - else: + messagetype = 'done' + else: + msg = "You are not authorized to change the permissions of dataset '%s'" % ldda.name + messagetype = 'error' return trans.fill_template( "/library/ldda_permissions.mako", ldda=lddas, library_id=library_id, msg=msg, messagetype=messagetype ) + if trans.app.security_agent.allow_action( trans.user, + trans.app.security_agent.permitted_actions.LIBRARY_MANAGE, + library_item=ldda ) and \ + trans.app.security_agent.allow_action( trans.user, + trans.app.security_agent.permitted_actions.LIBRARY_MANAGE, + library_item=ldda.library_dataset ) and \ + trans.app.security_agent.allow_action( trans.user, + trans.app.security_agent.permitted_actions.DATASET_MANAGE_PERMISSIONS, + dataset=ldda.dataset ): + # Ensure that the permissions across all datasets are identical. Otherwise, we can't update together. + # TODO: this doesn't really work as it should - we need to check permissions on associated + # LibraryDatasetDatasetAssociation and LibraryDataset as well. Improvement can also be made in the way + # we are checking... + tmp = [] + for ldda in lddas: + perms = trans.app.security_agent.get_dataset_permissions( ldda.dataset ) + if perms not in tmp: + tmp.append( perms ) + if len( tmp ) != 1: + msg = 'The datasets you selected do not have identical permissions, so they can not be updated together' + trans.response.send_redirect( web.url_for( controller='library', + action='browse_library', + id=library_id, + msg=util.sanitize_text( msg ), + messagetype='error' ) ) + else: + msg = "You are not authorized to change the permissions of dataset '%s'" % ldda.name + messagetype = 'error' + return trans.fill_template( "/library/ldda_permissions.mako", + ldda=lddas, + library_id=library_id, + msg=msg, + messagetype=messagetype ) if not folder and not replace_dataset: - msg = "Invalid library target specified (LibraryFolder id: %s, LibraryDataset id: %s)" % ( str( folder_id ), str( replace_id ) ) + msg = "Invalid library target specified ( LibraryFolder id: %s, LibraryDataset id: %s )" % ( str( folder_id ), str( replace_id ) ) return trans.response.send_redirect( web.url_for( controller='library', action='browse_library', id=library_id, @@ -399,7 +716,7 @@ class Library( BaseController ): created_ldda_ids=created_ldda_ids, msg=util.sanitize_text( msg ), messagetype='error' ) ) - elif params.get( "add_dataset_from_history_button", False): + elif params.get( "add_dataset_from_history_button", False ): # See if the current history is empty history = trans.get_history() history.refresh() @@ -447,100 +764,31 @@ class Library( BaseController ): id=library_id, msg=util.sanitize_text( msg ), messagetype='done' ) ) - else: - # No dataset(s) specified, display upload form - file_formats = trans.app.datatypes_registry.upload_file_formats - # Send list of genome builds to the form so the "dbkey" select list can be populated dynamically - def get_dbkey_options( last_used_build ): - for dbkey, build_name in util.dbnames: - yield build_name, dbkey, ( dbkey==last_used_build ) - dbkeys = get_dbkey_options( last_used_build ) - # Send list of roles to the form so the dataset can be associated with 1 or more of them. - roles = trans.app.model.Role.filter( trans.app.model.Role.table.c.deleted==False ).order_by( trans.app.model.Role.c.name ).all() - msg = 'Select at least one dataset from the list' - return trans.fill_template( "/library/new_dataset.mako", - history=history, - library_id=library_id, - folder_id=folder_id, - file_formats=file_formats, - dbkeys=dbkeys, - last_used_build=last_used_build, - roles=roles, - replace_dataset=replace_dataset, - msg=msg, - messagetype='error' ) - - #copied... - def get_dbkey_options( last_used_build ): - for dbkey, build_name in util.dbnames: - yield build_name, dbkey, ( dbkey==last_used_build ) - return trans.fill_template( "/library/new_dataset.mako", - library_id=library_id, - folder_id=folder_id, - replace_dataset=replace_dataset, - file_formats=trans.app.datatypes_registry.upload_file_formats, - dbkeys=get_dbkey_options( '?' ), - last_used_build=last_used_build, - msg=msg, - messagetype=messagetype ) - @web.expose - def library_dataset( self, trans, id, name=None, info=None, refer_id=None, library_id=None, **kwd ): - params = util.Params( kwd ) - msg = util.restore_text( params.get( 'msg', '' ) ) - messagetype = params.get( 'messagetype', 'done' ) - library_dataset = trans.app.model.LibraryDataset.get( id ) - if not library_dataset: - msg = "Invalid library dataset specified, id: %s" %str( id ) - return trans.response.send_redirect( web.url_for( controller='library', - action='browse_library', - id=library_id, - msg=util.sanitize_text( msg ), - messagetype='error' ) ) - if refer_id: - refered_lda = trans.app.model.LibraryDatasetDatasetAssociation.get( refer_id ) - else: - refered_lda=None - if params.get( 'save', False ): - if trans.app.security_agent.allow_action( trans.user, - trans.app.security_agent.permitted_actions.LIBRARY_MODIFY, - library_item=library_dataset ): - library_dataset.name = name - library_dataset.info = info - target_lda = trans.app.model.LibraryDatasetDatasetAssociation.get( params.get( 'set_lda_id' ) ) - library_dataset.library_dataset_dataset_association = target_lda - trans.app.model.flush() - msg = 'Attributes updated for library dataset %s' % library_dataset.name - messagetype = 'done' - else: - msg = "You are not authorized to changed the attributes of this dataset" - messagetype = "error" - return trans.response.send_redirect( web.url_for( controller='library', - action='library_dataset', - id=id, - library_id=library_id, - msg=util.sanitize_text( msg ), - messagetype=messagetype ) ) - elif 'update_roles_button' in kwd: - if trans.app.security_agent.allow_action( trans.user, - trans.app.security_agent.permitted_actions.LIBRARY_MANAGE, - library_item=library_dataset ): - # The user clicked the Save button on the 'Associate With Roles' form - permissions = {} - for k, v in trans.app.model.Library.permitted_actions.items(): - in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( params.get( k + '_in', [] ) ) ] - permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles - trans.app.security_agent.set_all_library_permissions( library_dataset, permissions ) - library_dataset.refresh() - msg = 'Permissions updated for library dataset %s' % library_dataset.name - else: - msg = "Permission Denied" - messagetype = "error" - return trans.fill_template( "/library/manage_library_dataset.mako", - library_dataset=library_dataset, - refered_lda=refered_lda, - library_id=library_id, - msg=msg, - messagetype=messagetype ) + if not id or replace_dataset: + # No dataset(s) specified, so display the upload form. Send list of data formats to the form + # so the "extension" select list can be populated dynamically + file_formats = trans.app.datatypes_registry.upload_file_formats + # Send list of genome builds to the form so the "dbkey" select list can be populated dynamically + def get_dbkey_options( last_used_build ): + for dbkey, build_name in util.dbnames: + yield build_name, dbkey, ( dbkey==last_used_build ) + dbkeys = get_dbkey_options( last_used_build ) + # Send list of roles to the form so the dataset can be associated with 1 or more of them. + roles = trans.app.model.Role.filter( trans.app.model.Role.table.c.deleted==False ).order_by( trans.app.model.Role.c.name ).all() + # Send the current history to the form to enable importing datasets from history to library + history = trans.get_history() + history.refresh() + return trans.fill_template( '/library/new_dataset.mako', + library_id=library_id, + folder_id=folder_id, + file_formats=file_formats, + dbkeys=dbkeys, + last_used_build=last_used_build, + roles=roles, + history=history, + msg=msg, + messagetype=messagetype, + replace_dataset=replace_dataset ) @web.expose def folder( self, trans, id, library_id, **kwd ): params = util.Params( kwd ) @@ -663,72 +911,6 @@ class Library( BaseController ): msg=msg, messagetype=messagetype ) @web.expose - def library( self, trans, id=None, **kwd ): - params = util.Params( kwd ) - msg = util.restore_text( params.get( 'msg', '' ) ) - messagetype = params.get( 'messagetype', 'done' ) - if not id: - msg = "You must specify a library." - return trans.response.send_redirect( web.url_for( controller='library', - action='browse_libraries', - msg=util.sanitize_text( msg ), - messagetype='error' ) ) - library = trans.app.model.Library.get( int( id ) ) - if not library: - msg = "Invalid library id ( %s ) specified." % str( id ) - return trans.response.send_redirect( web.url_for( controller='library', - action='browse_libraries', - msg=util.sanitize_text( msg ), - messagetype='error' ) ) - if params.get( 'delete', False ): - action = 'delete' - elif params.get( 'permissions', False ): - action = 'permissions' - else: - # 'information' is the default - action = 'information' - if action == 'information': - if params.get( 'rename_library_button', False ): - old_name = library.name - new_name = util.restore_text( params.name ) - new_description = util.restore_text( params.description ) - if not new_name: - msg = 'Enter a valid name' - return trans.fill_template( '/library/library_info.mako', library=library, msg=msg, messagetype='error' ) - else: - if params.get( 'root_folder', False ): - root_folder = library.root_folder - root_folder.name = new_name - root_folder.flush() - library.name = new_name - library.description = new_description - library.flush() - msg = "Library '%s' has been renamed to '%s'" % ( old_name, new_name ) - return trans.response.send_redirect( web.url_for( controller='library', - action='library', - id=id, - information=True, - msg=util.sanitize_text( msg ), - messagetype='done' ) ) - return trans.fill_template( '/library/library_info.mako', library=library, msg=msg, messagetype=messagetype ) - elif action == 'permissions': - if params.get( 'update_roles_button', False ): - # The user clicked the Save button on the 'Associate With Roles' form - permissions = {} - for k, v in trans.app.model.Library.permitted_actions.items(): - in_roles = [ trans.app.model.Role.get( x ) for x in util.listify( params.get( k + '_in', [] ) ) ] - permissions[ trans.app.security_agent.get_action( v.action ) ] = in_roles - trans.app.security_agent.set_all_library_permissions( library, permissions ) - library.refresh() - msg = "Permissions updated for library '%s'" % library.name - return trans.response.send_redirect( web.url_for( controller='library', - action='library', - id=id, - permissions=True, - msg=util.sanitize_text( msg ), - messagetype='done' ) ) - return trans.fill_template( '/admin/library/manage_library_permissions.mako', library=library, msg=msg, messagetype=messagetype ) - @web.expose def library_item_info_template( self, trans, id=None, new_element_count=0, library_id=None, folder_id=None, library_dataset_id=None, ldda_id=None, **kwd ): params = util.Params( kwd ) @@ -742,7 +924,7 @@ class Library( BaseController ): except: msg = "Invalid library info template specified, id: %s" % str( id ) # TODO: this should probably redirect to the library_dataset_dataset_association method... - return trans.response.send_redirect( web.url_for( controller='admin', + return trans.response.send_redirect( web.url_for( controller='library', action='browse_library', id=library_id, msg=util.sanitize_text( msg ), diff --git a/templates/admin/library/browse_libraries.mako b/templates/admin/library/browse_libraries.mako index 2412bea9937..1fde171e4bd 100644 --- a/templates/admin/library/browse_libraries.mako +++ b/templates/admin/library/browse_libraries.mako @@ -40,7 +40,7 @@ - %for i, library in enumerate( libraries ): + %for library in libraries: ${library.name} ${library.description} diff --git a/templates/admin/library/common.mako b/templates/admin/library/common.mako index 0882beb6bb5..63196d0edbe 100644 --- a/templates/admin/library/common.mako +++ b/templates/admin/library/common.mako @@ -28,7 +28,7 @@
Edit this dataset's information Edit this dataset's permissions - Manage this dataset's versions + Manage this dataset's versions %if data.has_data: Download this dataset %endif @@ -78,7 +78,8 @@ <%def name="render_existing_library_item_info( library_item )"> <% - library_item_type = None + library_item_type = 'unknown type' + library_item_desc = '' library_item_info_associations = [] if isinstance( library_item, trans.app.model.Library ): library_item_type = 'library' diff --git a/templates/admin/library/ldda_info.mako b/templates/admin/library/ldda_info.mako index afcb8a00221..ade71bad375 100644 --- a/templates/admin/library/ldda_info.mako +++ b/templates/admin/library/ldda_info.mako @@ -18,7 +18,13 @@ -

+%if ldda == ldda.library_dataset.library_dataset_dataset_association: + This is the latest version of this library dataset +%else: + This is an expired version of this library dataset +%endif +

+