From 033bcecd0d0ec68cf9030993e3fef7d403c7f845 Mon Sep 17 00:00:00 2001 From: Greg Von Kuster Date: Mon, 24 May 2010 11:22:12 -0400 Subject: [PATCH] Send the web freamework ( trans ) to the grid's build_initial_query() method rather than the web framework's db session so that the method can take advantage of all of the web freamwork's attributes. Change the library controller to use grids for the data libraries display. --- lib/galaxy/web/controllers/admin.py | 12 +-- lib/galaxy/web/controllers/history.py | 8 +- lib/galaxy/web/controllers/library.py | 88 +++++++++++++++---- lib/galaxy/web/controllers/library_admin.py | 14 +-- lib/galaxy/web/controllers/page.py | 4 +- lib/galaxy/web/controllers/requests.py | 4 +- lib/galaxy/web/controllers/tracks.py | 4 +- lib/galaxy/web/controllers/visualization.py | 4 +- lib/galaxy/web/controllers/workflow.py | 4 +- lib/galaxy/web/framework/helpers/grids.py | 7 +- .../webapps/community/controllers/admin.py | 24 ++--- .../webapps/community/controllers/tool.py | 12 +-- templates/library/browse_libraries.mako | 31 ------- templates/library/grid.mako | 1 + test/functional/test_library_security.py | 2 +- 15 files changed, 121 insertions(+), 98 deletions(-) delete mode 100644 templates/library/browse_libraries.mako create mode 100644 templates/library/grid.mako diff --git a/lib/galaxy/web/controllers/admin.py b/lib/galaxy/web/controllers/admin.py index e0b1d2ca4f4..c47bd658f04 100644 --- a/lib/galaxy/web/controllers/admin.py +++ b/lib/galaxy/web/controllers/admin.py @@ -103,8 +103,8 @@ class UserListGrid( grids.Grid ): use_paging = True def get_current_item( self, trans ): return trans.user - def build_initial_query( self, session ): - return session.query( self.model_class ) + def build_initial_query( self, trans ): + return trans.sa_session.query( self.model_class ) class RoleListGrid( grids.Grid ): class NameColumn( grids.TextColumn ): @@ -197,8 +197,8 @@ class RoleListGrid( grids.Grid ): use_paging = True def get_current_item( self, trans ): return None - def build_initial_query( self, session ): - return session.query( self.model_class ) + def build_initial_query( self, trans ): + return trans.sa_session.query( self.model_class ) def apply_default_filter( self, trans, query, **kwargs ): return query.filter( model.Role.type != model.Role.types.PRIVATE ) @@ -275,8 +275,8 @@ class GroupListGrid( grids.Grid ): use_paging = True def get_current_item( self, trans ): return None - def build_initial_query( self, session ): - return session.query( self.model_class ) + def build_initial_query( self, trans ): + return trans.sa_session.query( self.model_class ) class AdminGalaxy( BaseController, Admin ): diff --git a/lib/galaxy/web/controllers/history.py b/lib/galaxy/web/controllers/history.py index 380ff43dc2d..74271c7c305 100644 --- a/lib/galaxy/web/controllers/history.py +++ b/lib/galaxy/web/controllers/history.py @@ -110,8 +110,8 @@ class SharedHistoryListGrid( grids.Grid ): grids.GridOperation( "Unshare" ) ] standard_filters = [] - def build_initial_query( self, session ): - return session.query( self.model_class ).join( 'users_shared_with' ) + def build_initial_query( self, trans ): + return trans.sa_session.query( self.model_class ).join( 'users_shared_with' ) def apply_default_filter( self, trans, query, **kwargs ): return query.filter( model.HistoryUserShareAssociation.user == trans.user ) @@ -138,9 +138,9 @@ class HistoryAllPublishedGrid( grids.Grid ): key="free-text-search", visible=False, filterable="standard" ) ) operations = [] - def build_initial_query( self, session ): + def build_initial_query( self, trans ): # Join so that searching history.user makes sense. - return session.query( self.model_class ).join( model.User.table ) + return trans.sa_session.query( self.model_class ).join( model.User.table ) def apply_default_filter( self, trans, query, **kwargs ): # A public history is published, has a slug, and is not deleted. return query.filter( self.model_class.published == True ).filter( self.model_class.slug != None ).filter( self.model_class.deleted == False ) diff --git a/lib/galaxy/web/controllers/library.py b/lib/galaxy/web/controllers/library.py index 1424fdf4600..1a98d61dc9e 100644 --- a/lib/galaxy/web/controllers/library.py +++ b/lib/galaxy/web/controllers/library.py @@ -1,12 +1,73 @@ from galaxy.web.base.controller import * +from galaxy.web.framework.helpers import time_ago, iff, grids from galaxy.model.orm import * from galaxy.datatypes import sniff -from galaxy import util +from galaxy import model, util from galaxy.util.odict import odict log = logging.getLogger( __name__ ) +class LibraryListGrid( grids.Grid ): + class NameColumn( grids.TextColumn ): + def get_value( self, trans, grid, library ): + return library.name + class DescriptionColumn( grids.TextColumn ): + def get_value( self, trans, grid, library ): + if library.description: + return library.description + return '' + # Grid definition + title = "Data Libraries" + model_class = model.Library + template='/library/grid.mako' + default_sort_key = "name" + columns = [ + NameColumn( "Name", + key="name", + model_class=model.Library, + link=( lambda library: dict( operation="browse", id=library.id ) ), + attach_popup=False, + filterable="advanced" ), + DescriptionColumn( "Description", + key="description", + model_class=model.Library, + attach_popup=False, + filterable="advanced" ), + ] + columns.append( grids.MulticolFilterColumn( "Search", + cols_to_filter=[ columns[0], columns[1] ], + key="free-text-search", + visible=False, + filterable="standard" ) ) + standard_filters = [] + default_filter = dict( name="All", description="All", deleted="False", purged="False" ) + num_rows_per_page = 50 + preserve_state = False + use_paging = True + def build_initial_query( self, trans ): + return trans.sa_session.query( self.model_class ).filter( self.model_class.table.c.deleted == False ) + def apply_default_filter( self, trans, query, **kwd ): + current_user_role_ids = [ role.id for role in trans.get_current_user_roles() ] + library_access_action = trans.app.security_agent.permitted_actions.LIBRARY_ACCESS.action + restricted_library_ids = [ lp.library_id for lp in trans.sa_session.query( trans.model.LibraryPermissions ) \ + .filter( trans.model.LibraryPermissions.table.c.action == library_access_action ) \ + .distinct() ] + accessible_restricted_library_ids = [ lp.library_id for lp in trans.sa_session.query( trans.model.LibraryPermissions ) \ + .filter( and_( trans.model.LibraryPermissions.table.c.action == library_access_action, + trans.model.LibraryPermissions.table.c.role_id.in_( current_user_role_ids ) ) ) ] + if not trans.user: + # Filter to get only public libraries, a library whose id + # is not in restricted_library_ids is a public library + return query.filter( not_( trans.model.Library.table.c.id.in_( restricted_library_ids ) ) ) + else: + # Filter to get libraries accessible by the current user, get both + # public libraries and restricted libraries accessible by the current user. + return query.filter( or_( not_( trans.model.Library.table.c.id.in_( restricted_library_ids ) ), + trans.model.Library.table.c.id.in_( accessible_restricted_library_ids ) ) ) class Library( BaseController ): + + library_list_grid = LibraryListGrid() + @web.expose def index( self, trans, **kwd ): params = util.Params( kwd ) @@ -18,19 +79,12 @@ class Library( BaseController ): status=status ) @web.expose def browse_libraries( self, trans, **kwd ): - params = util.Params( kwd ) - message = util.restore_text( params.get( 'message', '' ) ) - status = params.get( 'status', 'done' ) - current_user_roles = trans.get_current_user_roles() - all_libraries = trans.sa_session.query( trans.app.model.Library ) \ - .filter( trans.app.model.Library.table.c.deleted==False ) \ - .order_by( trans.app.model.Library.name ) - authorized_libraries = [] - for library in all_libraries: - if trans.app.security_agent.can_access_library( current_user_roles, library ): - authorized_libraries.append( library ) - return trans.fill_template( '/library/browse_libraries.mako', - libraries=authorized_libraries, - default_action=params.get( 'default_action', None ), - message=message, - status=status ) + if 'operation' in kwd: + operation = kwd['operation'].lower() + if operation == "browse": + return trans.response.send_redirect( web.url_for( controller='library_common', + action='browse_library', + cntrller='library', + **kwd ) ) + # Render the list view + return self.library_list_grid( trans, **kwd ) diff --git a/lib/galaxy/web/controllers/library_admin.py b/lib/galaxy/web/controllers/library_admin.py index b0a3d4b4b6f..3c7bff5f2c6 100644 --- a/lib/galaxy/web/controllers/library_admin.py +++ b/lib/galaxy/web/controllers/library_admin.py @@ -69,8 +69,8 @@ class LibraryListGrid( grids.Grid ): num_rows_per_page = 50 preserve_state = False use_paging = True - def build_initial_query( self, session ): - return session.query( self.model_class ) + def build_initial_query( self, trans ): + return trans.sa_session.query( self.model_class ) class LibraryAdmin( BaseController ): @@ -78,16 +78,16 @@ class LibraryAdmin( BaseController ): @web.expose @web.require_admin - def browse_libraries( self, trans, **kwargs ): - if 'operation' in kwargs: - operation = kwargs['operation'].lower() + def browse_libraries( self, trans, **kwd ): + if 'operation' in kwd: + operation = kwd['operation'].lower() if operation == "browse": return trans.response.send_redirect( web.url_for( controller='library_common', action='browse_library', cntrller='library_admin', - **kwargs ) ) + **kwd ) ) # Render the list view - return self.library_list_grid( trans, **kwargs ) + return self.library_list_grid( trans, **kwd ) @web.expose @web.require_admin def create_library( self, trans, **kwd ): diff --git a/lib/galaxy/web/controllers/page.py b/lib/galaxy/web/controllers/page.py index c44c1ee8a84..87b73919a05 100644 --- a/lib/galaxy/web/controllers/page.py +++ b/lib/galaxy/web/controllers/page.py @@ -71,9 +71,9 @@ class PageAllPublishedGrid( grids.Grid ): cols_to_filter=[ columns[0], columns[1], columns[2], columns[3] ], key="free-text-search", visible=False, filterable="standard" ) ) - def build_initial_query( self, session ): + def build_initial_query( self, trans ): # Join so that searching history.user makes sense. - return session.query( self.model_class ).join( model.User.table ) + return trans.sa_session.query( self.model_class ).join( model.User.table ) def apply_default_filter( self, trans, query, **kwargs ): return query.filter( self.model_class.deleted==False ).filter( self.model_class.published==True ) diff --git a/lib/galaxy/web/controllers/requests.py b/lib/galaxy/web/controllers/requests.py index 42f4ec57a3d..f2f9323f08d 100644 --- a/lib/galaxy/web/controllers/requests.py +++ b/lib/galaxy/web/controllers/requests.py @@ -126,8 +126,8 @@ class RequestsGrid( grids.Grid ): ] def apply_default_filter( self, trans, query, **kwd ): return query.filter_by( user=trans.user ) - def build_initial_query( self, session ): - return session.query( self.model_class ) + def build_initial_query( self, trans ): + return trans.sa_session.query( self.model_class ) class Requests( BaseController ): request_grid = RequestsGrid() diff --git a/lib/galaxy/web/controllers/tracks.py b/lib/galaxy/web/controllers/tracks.py index 76b1ad61197..f83e7a809ad 100644 --- a/lib/galaxy/web/controllers/tracks.py +++ b/lib/galaxy/web/controllers/tracks.py @@ -71,8 +71,8 @@ class DatasetSelectionGrid( grids.Grid ): DbKeyColumn( "Dbkey", key="dbkey", model_class=model.HistoryDatasetAssociation, visible=False ) ] - def build_initial_query( self, session ): - return session.query( self.model_class ).join( model.History.table).join( model.Dataset.table ) + def build_initial_query( self, trans ): + return trans.sa_session.query( self.model_class ).join( model.History.table).join( model.Dataset.table ) def apply_default_filter( self, trans, query, **kwargs ): if self.available_tracks is None: self.available_tracks = trans.app.datatypes_registry.get_available_tracks() diff --git a/lib/galaxy/web/controllers/visualization.py b/lib/galaxy/web/controllers/visualization.py index 9f90bee010f..00f3afa0afe 100644 --- a/lib/galaxy/web/controllers/visualization.py +++ b/lib/galaxy/web/controllers/visualization.py @@ -55,9 +55,9 @@ class VisualizationAllPublishedGrid( grids.Grid ): cols_to_filter=[ columns[0], columns[1], columns[2], columns[3] ], key="free-text-search", visible=False, filterable="standard" ) ) - def build_initial_query( self, session ): + def build_initial_query( self, trans ): # Join so that searching history.user makes sense. - return session.query( self.model_class ).join( model.User.table ) + return trans.sa_session.query( self.model_class ).join( model.User.table ) def apply_default_filter( self, trans, query, **kwargs ): return query.filter( self.model_class.deleted==False ).filter( self.model_class.published==True ) diff --git a/lib/galaxy/web/controllers/workflow.py b/lib/galaxy/web/controllers/workflow.py index 444359cf5ca..fcd1abd601f 100644 --- a/lib/galaxy/web/controllers/workflow.py +++ b/lib/galaxy/web/controllers/workflow.py @@ -75,9 +75,9 @@ class StoredWorkflowAllPublishedGrid( grids.Grid ): key="free-text-search", visible=False, filterable="standard" ) ) operations = [] - def build_initial_query( self, session ): + def build_initial_query( self, trans ): # Join so that searching stored_workflow.user makes sense. - return session.query( self.model_class ).join( model.User.table ) + return trans.sa_session.query( self.model_class ).join( model.User.table ) def apply_default_filter( self, trans, query, **kwargs ): # A public workflow is published, has a slug, and is not deleted. return query.filter( self.model_class.published==True ).filter( self.model_class.slug != None ).filter( self.model_class.deleted == False ) diff --git a/lib/galaxy/web/framework/helpers/grids.py b/lib/galaxy/web/framework/helpers/grids.py index f6c354d9d84..9e4f2e33bcd 100644 --- a/lib/galaxy/web/framework/helpers/grids.py +++ b/lib/galaxy/web/framework/helpers/grids.py @@ -45,7 +45,6 @@ class Grid( object ): webapp = kwargs.get( 'webapp', 'galaxy' ) status = kwargs.get( 'status', None ) message = kwargs.get( 'message', None ) - session = trans.sa_session # Build a base filter and sort key that is the combination of the saved state and defaults. Saved state takes preference over defaults. base_filter = {} if self.default_filter: @@ -60,7 +59,7 @@ class Grid( object ): if pref_name in trans.get_user().preferences: base_sort_key = from_json_string( trans.get_user().preferences[pref_name] ) # Build initial query - query = self.build_initial_query( session ) + query = self.build_initial_query( trans ) query = self.apply_default_filter( trans, query, **kwargs ) # Maintain sort state in generated urls extra_url_args = {} @@ -258,8 +257,8 @@ class Grid( object ): pass def get_current_item( self, trans ): return None - def build_initial_query( self, session ): - return session.query( self.model_class ) + def build_initial_query( self, trans ): + return trans.sa_session.query( self.model_class ) def apply_default_filter( self, trans, query, **kwargs): return query diff --git a/lib/galaxy/webapps/community/controllers/admin.py b/lib/galaxy/webapps/community/controllers/admin.py index b49eb6d0bea..5b9149f4eef 100644 --- a/lib/galaxy/webapps/community/controllers/admin.py +++ b/lib/galaxy/webapps/community/controllers/admin.py @@ -113,8 +113,8 @@ class UserListGrid( grids.Grid ): use_paging = True def get_current_item( self, trans ): return trans.user - def build_initial_query( self, session ): - return session.query( self.model_class ) + def build_initial_query( self, trans ): + return trans.sa_session.query( self.model_class ) class RoleListGrid( grids.Grid ): class NameColumn( grids.TextColumn ): @@ -211,8 +211,8 @@ class RoleListGrid( grids.Grid ): use_paging = True def get_current_item( self, trans ): return None - def build_initial_query( self, session ): - return session.query( self.model_class ) + def build_initial_query( self, trans ): + return trans.sa_session.query( self.model_class ) def apply_default_filter( self, trans, query, **kwd ): return query.filter( model.Role.type != model.Role.types.PRIVATE ) @@ -294,8 +294,8 @@ class GroupListGrid( grids.Grid ): use_paging = True def get_current_item( self, trans ): return None - def build_initial_query( self, session ): - return session.query( self.model_class ) + def build_initial_query( self, trans ): + return trans.sa_session.query( self.model_class ) class ManageCategoryListGrid( grids.Grid ): class NameColumn( grids.TextColumn ): @@ -360,8 +360,8 @@ class ManageCategoryListGrid( grids.Grid ): use_paging = True def get_current_item( self, trans ): return None - def build_initial_query( self, session ): - return session.query( self.model_class ) + def build_initial_query( self, trans ): + return trans.sa_session.query( self.model_class ) class ToolsByCategoryListGrid( grids.Grid ): class NameColumn( grids.TextColumn ): @@ -423,8 +423,8 @@ class ToolsByCategoryListGrid( grids.Grid ): num_rows_per_page = 50 preserve_state = False use_paging = True - def build_initial_query( self, session ): - return session.query( self.model_class ) + def build_initial_query( self, trans ): + return trans.sa_session.query( self.model_class ) def apply_default_filter( self, trans, query, **kwd ): ids = kwd.get( 'ids', False ) if ids: @@ -546,8 +546,8 @@ class ToolListGrid( grids.Grid ): num_rows_per_page = 50 preserve_state = False use_paging = True - def build_initial_query( self, session ): - return session.query( self.model_class ) + def build_initial_query( self, trans ): + return trans.sa_session.query( self.model_class ) def apply_default_filter( self, trans, query, **kwd ): ids = kwd.get( 'ids', False ) if ids: diff --git a/lib/galaxy/webapps/community/controllers/tool.py b/lib/galaxy/webapps/community/controllers/tool.py index 5056fae0883..0758cd56412 100644 --- a/lib/galaxy/webapps/community/controllers/tool.py +++ b/lib/galaxy/webapps/community/controllers/tool.py @@ -94,8 +94,8 @@ class ToolListGrid( grids.Grid ): num_rows_per_page = 50 preserve_state = False use_paging = True - def build_initial_query( self, session ): - return session.query( self.model_class ) + def build_initial_query( self, trans ): + return trans.sa_session.query( self.model_class ) def apply_default_filter( self, trans, query, **kwd ): ids = kwd.get( 'ids', False ) if not ids: @@ -218,8 +218,8 @@ class ToolsByUserListGrid( grids.Grid ): num_rows_per_page = 50 preserve_state = False use_paging = True - def build_initial_query( self, session ): - return session.query( self.model_class ) + def build_initial_query( self, trans ): + return trans.sa_session.query( self.model_class ) def apply_default_filter( self, trans, query, **kwd ): ids = kwd.get( 'ids', False ) if not ids: @@ -295,8 +295,8 @@ class ToolsByCategoryListGrid( grids.Grid ): num_rows_per_page = 50 preserve_state = False use_paging = True - def build_initial_query( self, session ): - return session.query( self.model_class ) + def build_initial_query( self, trans ): + return trans.sa_session.query( self.model_class ) class ToolController( BaseController ): diff --git a/templates/library/browse_libraries.mako b/templates/library/browse_libraries.mako deleted file mode 100644 index 921ad54d7e9..00000000000 --- a/templates/library/browse_libraries.mako +++ /dev/null @@ -1,31 +0,0 @@ -<%inherit file="/base.mako"/> -<%namespace file="/message.mako" import="render_msg" /> - -<%def name="title()">Browse Data Libraries - -

Data Libraries

- -%if message: - ${render_msg( message, status )} -%endif - -%if not libraries: - You are not authorized to access any libraries -%else: - - - - - - - - - %for library in libraries: - - - - - %endfor - -
NameDescription
${library.name}${library.description}
-%endif diff --git a/templates/library/grid.mako b/templates/library/grid.mako new file mode 100644 index 00000000000..6a41b688c5e --- /dev/null +++ b/templates/library/grid.mako @@ -0,0 +1 @@ +<%inherit file="/grid_base.mako"/> diff --git a/test/functional/test_library_security.py b/test/functional/test_library_security.py index d7829044e02..3c9ec372839 100644 --- a/test/functional/test_library_security.py +++ b/test/functional/test_library_security.py @@ -192,7 +192,7 @@ class TestLibrarySecurity( TwillTestCase ): # regular_user2 should not be to see the library since they do not have # Role One which is associated with the LIBRARY_ACCESS permission self.login( email=regular_user2.email ) - self.browse_libraries_regular_user( check_str1="You are not authorized to access any libraries" ) + self.browse_libraries_regular_user( check_str1="No Items" ) self.logout() # regular_user3 should not be able to see 1.bed from the analysis view's access librarys self.login( email=regular_user3.email )