From 00c3f84f40dc997e7e6f27b4e80e8c14ca39ea48 Mon Sep 17 00:00:00 2001
From: Greg Von Kuster
Date: Mon, 9 Nov 2009 23:00:55 -0500
Subject: [PATCH] Incorporate latest grid features into managing users, groups
and roles from the admin view.
---
lib/galaxy/web/controllers/admin.py | 436 +++++++++++++-----
.../dataset_security/deleted_groups.mako | 101 ----
.../admin/dataset_security/deleted_roles.mako | 103 -----
.../admin/dataset_security/group/grid.mako | 1 +
.../dataset_security/{ => group}/group.mako | 0
.../{ => group}/group_create.mako | 0
.../{ => group}/group_rename.mako | 2 +-
templates/admin/dataset_security/groups.mako | 107 -----
.../admin/dataset_security/role/grid.mako | 1 +
.../dataset_security/{ => role}/role.mako | 0
.../{ => role}/role_create.mako | 0
.../{ => role}/role_rename.mako | 2 +-
templates/admin/dataset_security/roles.mako | 109 -----
templates/admin/user/grid.mako | 225 +--------
templates/grid_base.mako | 11 +-
test/base/twilltestcase.py | 32 +-
test/functional/test_history_functions.py | 4 +-
.../functional/test_security_and_libraries.py | 102 ++--
tool_conf.xml.main | 52 ++-
19 files changed, 460 insertions(+), 828 deletions(-)
delete mode 100644 templates/admin/dataset_security/deleted_groups.mako
delete mode 100644 templates/admin/dataset_security/deleted_roles.mako
create mode 100644 templates/admin/dataset_security/group/grid.mako
rename templates/admin/dataset_security/{ => group}/group.mako (100%)
rename templates/admin/dataset_security/{ => group}/group_create.mako (100%)
rename templates/admin/dataset_security/{ => group}/group_rename.mako (92%)
delete mode 100644 templates/admin/dataset_security/groups.mako
create mode 100644 templates/admin/dataset_security/role/grid.mako
rename templates/admin/dataset_security/{ => role}/role.mako (100%)
rename templates/admin/dataset_security/{ => role}/role_create.mako (100%)
rename templates/admin/dataset_security/{ => role}/role_rename.mako (94%)
delete mode 100644 templates/admin/dataset_security/roles.mako
diff --git a/lib/galaxy/web/controllers/admin.py b/lib/galaxy/web/controllers/admin.py
index 866aff42ecc..21851e19c80 100644
--- a/lib/galaxy/web/controllers/admin.py
+++ b/lib/galaxy/web/controllers/admin.py
@@ -2,20 +2,31 @@ import string, sys
from datetime import datetime, timedelta
from galaxy import util, datatypes
from galaxy.web.base.controller import *
+from galaxy.util.odict import odict
from galaxy.model.orm import *
from galaxy.web.framework.helpers import time_ago, iff, grids
import logging
log = logging.getLogger( __name__ )
+# States for passing messages
+SUCCESS, INFO, WARNING, ERROR = "done", "info", "warning", "error"
+
class UserListGrid( grids.Grid ):
- class EmailColumn( grids.GridColumn ):
+ class EmailColumn( grids.TextColumn ):
def get_value( self, trans, grid, user ):
return user.email
- class UserNameColumn( grids.GridColumn ):
+ class UserNameColumn( grids.TextColumn ):
def get_value( self, trans, grid, user ):
if user.username:
return user.username
return 'not set'
+ class StatusColumn( grids.GridColumn ):
+ def get_value( self, trans, grid, user ):
+ if user.purged:
+ return "purged"
+ elif user.deleted:
+ return "deleted"
+ return ""
class GroupsColumn( grids.GridColumn ):
def get_value( self, trans, grid, user ):
if user.groups:
@@ -36,56 +47,242 @@ class UserListGrid( grids.Grid ):
if user.galaxy_sessions:
return self.format( user.galaxy_sessions[ 0 ].update_time )
return 'never'
+ class DeletedColumn( grids.GridColumn ):
+ def get_accepted_filters( self ):
+ """ Returns a list of accepted filters for this column. """
+ accepted_filter_labels_and_vals = { "active" : "False", "deleted" : "True", "all": "All" }
+ accepted_filters = []
+ for label, val in accepted_filter_labels_and_vals.items():
+ args = { self.key: val }
+ accepted_filters.append( grids.GridColumnFilter( label, args) )
+ return accepted_filters
+
# Grid definition
title = "Users"
model_class = model.User
template='/admin/user/grid.mako'
+ default_sort_key = "email"
columns = [
- EmailColumn( "Email", link=( lambda item: dict( operation="information", id=item.id ) ), attach_popup=True ),
- UserNameColumn( "User Name", attach_popup=False ),
+ EmailColumn( "Email",
+ key="email",
+ model_class=model.User,
+ link=( lambda item: dict( operation="information", id=item.id ) ),
+ attach_popup=True,
+ filterable="advanced" ),
+ UserNameColumn( "User Name",
+ key="username",
+ model_class=model.User,
+ attach_popup=False,
+ filterable="advanced" ),
GroupsColumn( "Groups", attach_popup=False ),
RolesColumn( "Roles", attach_popup=False ),
ExternalColumn( "External", attach_popup=False ),
LastLoginColumn( "Last Login", format=time_ago ),
- # Valid for filtering but invisible
- grids.GridColumn( "Deleted", key="deleted", visible=False )
+ StatusColumn( "Status", attach_popup=False ),
+ # Columns that are valid for filtering but are not visible.
+ DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" )
+ ]
+ columns.append( grids.MulticolFilterColumn( "Search",
+ cols_to_filter=[ columns[0], columns[1] ],
+ key="free-text-search",
+ visible=False,
+ filterable="standard" ) )
+ global_actions = [
+ grids.GridAction( "Create new user", dict( controller='admin', action='users', operation='create' ) )
]
operations = [
grids.GridOperation( "Manage Roles & Groups", condition=( lambda item: not item.deleted ), allow_multiple=False )
-
]
#TODO: enhance to account for trans.app.config.allow_user_deletion here so that we can eliminate these operations if
# the setting is False
operations.append( grids.GridOperation( "Reset Password", condition=( lambda item: not item.deleted ), allow_multiple=True, allow_popup=False ) )
operations.append( grids.GridOperation( "Delete", condition=( lambda item: not item.deleted ), allow_multiple=True ) )
- operations.append( grids.GridOperation( "Undelete", condition=( lambda item: item.deleted ), allow_multiple=True ) )
- operations.append( grids.GridOperation( "Purge", condition=( lambda item: item.deleted ), allow_multiple=True ) )
+ operations.append( grids.GridOperation( "Undelete", condition=( lambda item: item.deleted and not item.purged ), allow_multiple=True ) )
+ operations.append( grids.GridOperation( "Purge", condition=( lambda item: item.deleted and not item.purged ), allow_multiple=True ) )
+ standard_filters = [
+ grids.GridColumnFilter( "Active", args=dict( deleted=False ) ),
+ grids.GridColumnFilter( "Deleted", args=dict( deleted=True, purged=False ) ),
+ grids.GridColumnFilter( "Purged", args=dict( purged=True ) ),
+ grids.GridColumnFilter( "All", args=dict( deleted='All' ) )
+ ]
+ default_filter = dict( email="All", username="All", deleted="False", purged="False" )
+ num_rows_per_page = 50
+ preserve_state = False
+ use_paging = True
+ def get_current_item( self, trans ):
+ return trans.user
+ def build_initial_query( self, session ):
+ return session.query( self.model_class )
+
+class RoleListGrid( grids.Grid ):
+ class NameColumn( grids.TextColumn ):
+ def get_value( self, trans, grid, role ):
+ return role.name
+ class DescriptionColumn( grids.TextColumn ):
+ def get_value( self, trans, grid, role ):
+ if role.description:
+ return role.description
+ return ''
+ class TypeColumn( grids.TextColumn ):
+ def get_value( self, trans, grid, role ):
+ return role.type
+ class StatusColumn( grids.GridColumn ):
+ def get_value( self, trans, grid, role ):
+ if role.deleted:
+ return "deleted"
+ return ""
+ class DeletedColumn( grids.GridColumn ):
+ def get_accepted_filters( self ):
+ """ Returns a list of accepted filters for this column. """
+ accepted_filter_labels_and_vals = { "active" : "False", "deleted" : "True", "all": "All" }
+ accepted_filters = []
+ for label, val in accepted_filter_labels_and_vals.items():
+ args = { self.key: val }
+ accepted_filters.append( grids.GridColumnFilter( label, args) )
+ return accepted_filters
+ class GroupsColumn( grids.GridColumn ):
+ def get_value( self, trans, grid, role ):
+ if role.groups:
+ return len( role.groups )
+ return 0
+ class UsersColumn( grids.GridColumn ):
+ def get_value( self, trans, grid, role ):
+ if role.users:
+ return len( role.users )
+ return 0
+
+ # Grid definition
+ title = "Roles"
+ model_class = model.Role
+ template='/admin/dataset_security/role/grid.mako'
+ default_sort_key = "name"
+ columns = [
+ NameColumn( "Name",
+ key="name",
+ link=( lambda item: dict( controller="admin", action="role", id=item.id ) ),
+ model_class=model.Role,
+ attach_popup=True,
+ filterable="advanced" ),
+ DescriptionColumn( "Description",
+ key='description',
+ model_class=model.Role,
+ attach_popup=False,
+ filterable="advanced" ),
+ TypeColumn( "Type",
+ key='type',
+ model_class=model.Role,
+ attach_popup=False,
+ filterable="advanced" ),
+ GroupsColumn( "Groups", attach_popup=False ),
+ UsersColumn( "Users", attach_popup=False ),
+ StatusColumn( "Status", attach_popup=False ),
+ # Columns that are valid for filtering but are not visible.
+ DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" )
+ ]
+ columns.append( grids.MulticolFilterColumn( "Search",
+ cols_to_filter=[ columns[0], columns[1], columns[2] ],
+ key="free-text-search",
+ visible=False,
+ filterable="standard" ) )
+ global_actions = [
+ grids.GridAction( "Add new role", dict( controller='admin', action='roles', operation='create' ) )
+ ]
+ operations = [ grids.GridOperation( "Delete", condition=( lambda item: not item.deleted ), allow_multiple=True ),
+ grids.GridOperation( "Undelete", condition=( lambda item: item.deleted ), allow_multiple=True ),
+ grids.GridOperation( "Purge", condition=( lambda item: item.deleted ), allow_multiple=True ) ]
standard_filters = [
grids.GridColumnFilter( "Active", args=dict( deleted=False ) ),
grids.GridColumnFilter( "Deleted", args=dict( deleted=True ) ),
grids.GridColumnFilter( "All", args=dict( deleted='All' ) )
]
- default_filter = dict( deleted=False )
+ default_filter = dict( name="All", deleted="False", description="All", type="All" )
+ num_rows_per_page = 50
+ preserve_state = False
+ use_paging = True
def get_current_item( self, trans ):
- return trans.user
+ return None
def build_initial_query( self, session ):
return session.query( self.model_class )
def apply_default_filter( self, trans, query, **kwargs ):
- email_filter = kwargs.get( "email_filter", None )
- if email_filter:
- if email_filter == 'all':
- return query
- else:
- return query.filter( or_( trans.app.model.User.table.c.email.like( '%s' % email_filter.lower() + '%' ),
- trans.app.model.User.table.c.email.like( '%s' % email_filter.upper() + '%' ) ) )
- elif query.count() > 200:
- return query.filter( or_( trans.app.model.User.table.c.email.like( 'A%' ),
- trans.app.model.User.table.c.email.like( 'a%' ) ) )
- return query
+ return query.filter( model.Role.type != model.Role.types.PRIVATE )
+
+class GroupListGrid( grids.Grid ):
+ class NameColumn( grids.TextColumn ):
+ def get_value( self, trans, grid, group ):
+ return group.name
+ class StatusColumn( grids.GridColumn ):
+ def get_value( self, trans, grid, group ):
+ if group.deleted:
+ return "deleted"
+ return ""
+ class DeletedColumn( grids.GridColumn ):
+ def get_accepted_filters( self ):
+ """ Returns a list of accepted filters for this column. """
+ accepted_filter_labels_and_vals = { "active" : "False", "deleted" : "True", "all": "All" }
+ accepted_filters = []
+ for label, val in accepted_filter_labels_and_vals.items():
+ args = { self.key: val }
+ accepted_filters.append( grids.GridColumnFilter( label, args) )
+ return accepted_filters
+ class RolesColumn( grids.GridColumn ):
+ def get_value( self, trans, grid, group ):
+ if group.roles:
+ return len( group.roles )
+ return 0
+ class UsersColumn( grids.GridColumn ):
+ def get_value( self, trans, grid, group ):
+ if group.members:
+ return len( group.members )
+ return 0
+
+ # Grid definition
+ title = "Groups"
+ model_class = model.Group
+ template='/admin/dataset_security/group/grid.mako'
+ default_sort_key = "name"
+ columns = [
+ NameColumn( "Name",
+ key="name",
+ link=( lambda item: dict( controller="admin", action="group", id=item.id ) ),
+ model_class=model.Group,
+ attach_popup=True,
+ filterable="advanced" ),
+ UsersColumn( "Users", attach_popup=False ),
+ RolesColumn( "Roles", attach_popup=False ),
+ StatusColumn( "Status", attach_popup=False ),
+ # Columns that are valid for filtering but are not visible.
+ DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" )
+ ]
+ columns.append( grids.MulticolFilterColumn( "Search",
+ cols_to_filter=[ columns[0], columns[1], columns[2] ],
+ key="free-text-search",
+ visible=False,
+ filterable="standard" ) )
+ global_actions = [
+ grids.GridAction( "Add new group", dict( controller='admin', action='groups', operation='create' ) )
+ ]
+ operations = [ grids.GridOperation( "Delete", condition=( lambda item: not item.deleted ), allow_multiple=True ),
+ grids.GridOperation( "Undelete", condition=( lambda item: item.deleted ), allow_multiple=True ),
+ grids.GridOperation( "Purge", condition=( lambda item: item.deleted ), allow_multiple=True ) ]
+ standard_filters = [
+ grids.GridColumnFilter( "Active", args=dict( deleted=False ) ),
+ grids.GridColumnFilter( "Deleted", args=dict( deleted=True ) ),
+ grids.GridColumnFilter( "All", args=dict( deleted='All' ) )
+ ]
+ default_filter = dict( name="All", deleted="False" )
+ num_rows_per_page = 50
+ preserve_state = False
+ use_paging = True
+ def get_current_item( self, trans ):
+ return None
+ def build_initial_query( self, session ):
+ return session.query( self.model_class )
class Admin( BaseController ):
user_list_grid = UserListGrid()
+ role_list_grid = RoleListGrid()
+ group_list_grid = GroupListGrid()
@web.expose
@web.require_admin
@@ -117,17 +314,23 @@ class Admin( BaseController ):
# Galaxy Role Stuff
@web.expose
@web.require_admin
- def roles( self, trans, **kwd ):
- params = util.Params( kwd )
- msg = util.restore_text( params.get( 'msg', '' ) )
- messagetype = params.get( 'messagetype', 'done' )
- roles = trans.sa_session.query( trans.app.model.Role ).filter( and_( trans.app.model.Role.table.c.deleted==False,
- trans.app.model.Role.table.c.type != trans.app.model.Role.types.PRIVATE ) ) \
- .order_by( trans.app.model.Role.table.c.name )
- return trans.fill_template( '/admin/dataset_security/roles.mako',
- roles=roles,
- msg=msg,
- messagetype=messagetype )
+ def roles( self, trans, **kwargs ):
+ if 'operation' in kwargs:
+ operation = kwargs['operation'].lower()
+ if operation == "roles":
+ return self.role( trans, **kwargs )
+ if operation == "create":
+ return self.create_role( trans, **kwargs )
+ if operation == "delete":
+ return self.mark_role_deleted( trans, **kwargs )
+ if operation == "undelete":
+ return self.undelete_role( trans, **kwargs )
+ if operation == "purge":
+ return self.purge_role( trans, **kwargs )
+ if operation == "manage users & groups":
+ return self.role( trans, **kwargs )
+ # Render the list view
+ return self.role_list_grid( trans, **kwargs )
@web.expose
@web.require_admin
def create_role( self, trans, **kwd ):
@@ -164,7 +367,7 @@ class Admin( BaseController ):
( group.name, role.name, len( in_users ), len( in_groups ) )
else:
msg = "Role '%s' has been created with %d associated users and %d associated groups" % ( role.name, len( in_users ), len( in_groups ) )
- trans.response.send_redirect( web.url_for( controller='admin', action='roles', msg=util.sanitize_text( msg ), messagetype='done' ) )
+ trans.response.send_redirect( web.url_for( controller='admin', action='roles', message=util.sanitize_text( msg ), status='done' ) )
trans.response.send_redirect( web.url_for( controller='admin', action='create_role', msg=util.sanitize_text( msg ), messagetype='error' ) )
out_users = []
for user in trans.sa_session.query( trans.app.model.User ) \
@@ -176,7 +379,7 @@ class Admin( BaseController ):
.filter( trans.app.model.Group.table.c.deleted==False ) \
.order_by( trans.app.model.Group.table.c.name ):
out_groups.append( ( group.id, group.name ) )
- return trans.fill_template( '/admin/dataset_security/role_create.mako',
+ return trans.fill_template( '/admin/dataset_security/role/role_create.mako',
in_users=[],
out_users=out_users,
in_groups=[],
@@ -189,7 +392,7 @@ class Admin( BaseController ):
params = util.Params( kwd )
msg = util.restore_text( params.get( 'msg', '' ) )
messagetype = params.get( 'messagetype', 'done' )
- role = trans.sa_session.query( trans.app.model.Role ).get( int( params.role_id ) )
+ role = get_role( trans, params.id )
if params.get( 'role_members_edit_button', False ):
in_users = [ trans.sa_session.query( trans.app.model.User ).get( x ) for x in util.listify( params.in_users ) ]
for ura in role.users:
@@ -210,7 +413,7 @@ class Admin( BaseController ):
trans.app.security_agent.set_entity_role_associations( roles=[ role ], users=in_users, groups=in_groups )
trans.sa_session.refresh( role )
msg = "Role '%s' has been updated with %d associated users and %d associated groups" % ( role.name, len( in_users ), len( in_groups ) )
- trans.response.send_redirect( web.url_for( action='roles', msg=util.sanitize_text( msg ), messagetype=messagetype ) )
+ trans.response.send_redirect( web.url_for( action='roles', message=util.sanitize_text( msg ), status=messagetype ) )
elif params.get( 'rename', False ):
if params.rename == 'submitted':
old_name = role.name
@@ -218,17 +421,17 @@ class Admin( BaseController ):
new_description = util.restore_text( params.description )
if not new_name:
msg = 'Enter a valid name'
- return trans.fill_template( '/admin/dataset_security/role_rename.mako', role=role, msg=msg, messagetype='error' )
+ return trans.fill_template( '/admin/dataset_security/role/role_rename.mako', role=role, msg=msg, messagetype='error' )
elif trans.sa_session.query( trans.app.model.Role ).filter( trans.app.model.Role.table.c.name==new_name ).first():
msg = 'A role with that name already exists'
- return trans.fill_template( '/admin/dataset_security/role_rename.mako', role=role, msg=msg, messagetype='error' )
+ return trans.fill_template( '/admin/dataset_security/role/role_rename.mako', role=role, msg=msg, messagetype='error' )
else:
role.name = new_name
role.description = new_description
role.flush()
msg = "Role '%s' has been renamed to '%s'" % ( old_name, new_name )
- return trans.response.send_redirect( web.url_for( action='roles', msg=util.sanitize_text( msg ), messagetype='done' ) )
- return trans.fill_template( '/admin/dataset_security/role_rename.mako', role=role, msg=msg, messagetype=messagetype )
+ return trans.response.send_redirect( web.url_for( action='roles', message=util.sanitize_text( msg ), status='done' ) )
+ return trans.fill_template( '/admin/dataset_security/role/role_rename.mako', role=role, msg=msg, messagetype=messagetype )
in_users = []
out_users = []
in_groups = []
@@ -273,7 +476,7 @@ class Admin( BaseController ):
library_dataset_actions[ library ][ folder_path ].append( dp.action )
except:
library_dataset_actions[ library ][ folder_path ] = [ dp.action ]
- return trans.fill_template( '/admin/dataset_security/role.mako',
+ return trans.fill_template( '/admin/dataset_security/role/role.mako',
role=role,
in_users=in_users,
out_users=out_users,
@@ -286,33 +489,20 @@ class Admin( BaseController ):
@web.require_admin
def mark_role_deleted( self, trans, **kwd ):
params = util.Params( kwd )
- role = trans.sa_session.query( trans.app.model.Role ).get( int( params.role_id ) )
+ role = get_role( trans, params.id )
role.deleted = True
role.flush()
- msg = "Role '%s' has been marked as deleted." % role.name
- trans.response.send_redirect( web.url_for( action='roles', msg=util.sanitize_text( msg ), messagetype='done' ) )
- @web.expose
- @web.require_admin
- def deleted_roles( self, trans, **kwd ):
- params = util.Params( kwd )
- msg = util.restore_text( params.get( 'msg', '' ) )
- messagetype = params.get( 'messagetype', 'done' )
- roles = trans.sa_session.query( trans.app.model.Role ) \
- .filter( trans.app.model.Role.table.c.deleted==True ) \
- .order_by( trans.app.model.Role.table.c.name )
- return trans.fill_template( '/admin/dataset_security/deleted_roles.mako',
- roles=roles,
- msg=msg,
- messagetype=messagetype )
+ message = "Role '%s' has been marked as deleted." % role.name
+ trans.response.send_redirect( web.url_for( action='roles', message=util.sanitize_text( message ), status='done' ) )
@web.expose
@web.require_admin
def undelete_role( self, trans, **kwd ):
params = util.Params( kwd )
- role = trans.sa_session.query( trans.app.model.Role ).get( int( params.role_id ) )
+ role = get_role( trans, params.id )
role.deleted = False
role.flush()
- msg = "Role '%s' has been marked as not deleted." % role.name
- trans.response.send_redirect( web.url_for( action='roles', msg=util.sanitize_text( msg ), messagetype='done' ) )
+ message = "Role '%s' has been marked as not deleted." % role.name
+ trans.response.send_redirect( web.url_for( action='roles', message=util.sanitize_text( message ), status='done' ) )
@web.expose
@web.require_admin
def purge_role( self, trans, **kwd ):
@@ -324,11 +514,10 @@ class Admin( BaseController ):
# - GroupRoleAssociations where role_id == Role.id
# - DatasetPermissionss where role_id == Role.id
params = util.Params( kwd )
- role = trans.sa_session.query( trans.app.model.Role ).get( int( params.role_id ) )
+ role = get_role( trans, params.id )
if not role.deleted:
- # We should never reach here, but just in case there is a bug somewhere...
- msg = "Role '%s' has not been deleted, so it cannot be purged." % role.name
- trans.response.send_redirect( web.url_for( action='roles', msg=util.sanitize_text( msg ), messagetype='error' ) )
+ message = "Role '%s' has not been deleted, so it cannot be purged." % role.name
+ trans.response.send_redirect( web.url_for( action='roles', message=util.sanitize_text( message ), status='error' ) )
# Delete UserRoleAssociations
for ura in role.users:
user = trans.sa_session.query( trans.app.model.User ).get( ura.user_id )
@@ -353,54 +542,60 @@ class Admin( BaseController ):
for dp in role.dataset_actions:
trans.sa_session.delete( dp )
dp.flush()
- msg = "The following have been purged from the database for role '%s': " % role.name
- msg += "DefaultUserPermissions, DefaultHistoryPermissions, UserRoleAssociations, GroupRoleAssociations, DatasetPermissionss."
- trans.response.send_redirect( web.url_for( action='deleted_roles', msg=util.sanitize_text( msg ), messagetype='done' ) )
+ message = "The following have been purged from the database for role '%s': " % role.name
+ message += "DefaultUserPermissions, DefaultHistoryPermissions, UserRoleAssociations, GroupRoleAssociations, DatasetPermissionss."
+ trans.response.send_redirect( web.url_for( action='roles', message=util.sanitize_text( message ), status='done' ) )
# Galaxy Group Stuff
@web.expose
@web.require_admin
- def groups( self, trans, **kwd ):
- params = util.Params( kwd )
- msg = util.restore_text( params.get( 'msg', '' ) )
- messagetype = params.get( 'messagetype', 'done' )
- groups = trans.sa_session.query( trans.app.model.Group ) \
- .filter( trans.app.model.Group.table.c.deleted==False ) \
- .order_by( trans.app.model.Group.table.c.name )
- return trans.fill_template( '/admin/dataset_security/groups.mako',
- groups=groups,
- msg=msg,
- messagetype=messagetype )
+ def groups( self, trans, **kwargs ):
+ if 'operation' in kwargs:
+ operation = kwargs['operation'].lower()
+ if operation == "groups":
+ return self.group( trans, **kwargs )
+ if operation == "create":
+ return self.create_group( trans, **kwargs )
+ if operation == "delete":
+ return self.mark_group_deleted( trans, **kwargs )
+ if operation == "undelete":
+ return self.undelete_group( trans, **kwargs )
+ if operation == "purge":
+ return self.purge_group( trans, **kwargs )
+ if operation == "manage users & roles":
+ return self.group( trans, **kwargs )
+ # Render the list view
+ return self.group_list_grid( trans, **kwargs )
@web.expose
@web.require_admin
def group( self, trans, **kwd ):
params = util.Params( kwd )
msg = util.restore_text( params.get( 'msg', '' ) )
messagetype = params.get( 'messagetype', 'done' )
- group = trans.sa_session.query( trans.app.model.Group ).get( int( params.group_id ) )
+ group = get_group( trans, params.id )
if params.get( 'group_roles_users_edit_button', False ):
in_roles = [ trans.sa_session.query( trans.app.model.Role ).get( x ) for x in util.listify( params.in_roles ) ]
in_users = [ trans.sa_session.query( trans.app.model.User ).get( x ) for x in util.listify( params.in_users ) ]
trans.app.security_agent.set_entity_group_associations( groups=[ group ], roles=in_roles, users=in_users )
trans.sa_session.refresh( group )
msg += "Group '%s' has been updated with %d associated roles and %d associated users" % ( group.name, len( in_roles ), len( in_users ) )
- trans.response.send_redirect( web.url_for( action='groups', msg=util.sanitize_text( msg ), messagetype=messagetype ) )
+ trans.response.send_redirect( web.url_for( action='groups', message=util.sanitize_text( msg ), status=messagetype ) )
if params.get( 'rename', False ):
if params.rename == 'submitted':
old_name = group.name
new_name = util.restore_text( params.name )
if not new_name:
msg = 'Enter a valid name'
- return trans.fill_template( '/admin/dataset_security/group_rename.mako', group=group, msg=msg, messagetype='error' )
+ return trans.fill_template( '/admin/dataset_security/group/group_rename.mako', group=group, msg=msg, messagetype='error' )
elif trans.sa_session.query( trans.app.model.Group ).filter( trans.app.model.Group.table.c.name==new_name ).first():
msg = 'A group with that name already exists'
- return trans.fill_template( '/admin/dataset_security/group_rename.mako', group=group, msg=msg, messagetype='error' )
+ return trans.fill_template( '/admin/dataset_security/group/group_rename.mako', group=group, msg=msg, messagetype='error' )
else:
group.name = new_name
group.flush()
msg = "Group '%s' has been renamed to '%s'" % ( old_name, new_name )
return trans.response.send_redirect( web.url_for( action='groups', msg=util.sanitize_text( msg ), messagetype='done' ) )
- return trans.fill_template( '/admin/dataset_security/group_rename.mako', group=group, msg=msg, messagetype=messagetype )
+ return trans.fill_template( '/admin/dataset_security/group/group_rename.mako', group=group, msg=msg, messagetype=messagetype )
in_roles = []
out_roles = []
in_users = []
@@ -420,7 +615,7 @@ class Admin( BaseController ):
else:
out_users.append( ( user.id, user.email ) )
msg += 'Group %s is currently associated with %d roles and %d users' % ( group.name, len( in_roles ), len( in_users ) )
- return trans.fill_template( '/admin/dataset_security/group.mako',
+ return trans.fill_template( '/admin/dataset_security/group/group.mako',
group=group,
in_roles=in_roles,
out_roles=out_roles,
@@ -455,7 +650,7 @@ class Admin( BaseController ):
gra = trans.app.model.GroupRoleAssociation( group, role )
gra.flush()
msg = "Group '%s' has been created with %d associated users and %d associated roles" % ( name, len( in_users ), len( in_roles ) )
- trans.response.send_redirect( web.url_for( controller='admin', action='groups', msg=util.sanitize_text( msg ), messagetype='done' ) )
+ trans.response.send_redirect( web.url_for( controller='admin', action='groups', message=util.sanitize_text( msg ), status='done' ) )
trans.response.send_redirect( web.url_for( controller='admin', action='create_group', msg=util.sanitize_text( msg ), messagetype='error' ) )
out_users = []
for user in trans.sa_session.query( trans.app.model.User ) \
@@ -467,7 +662,7 @@ class Admin( BaseController ):
.filter( trans.app.model.Role.table.c.deleted==False ) \
.order_by( trans.app.model.Role.table.c.name ):
out_roles.append( ( role.id, role.name ) )
- return trans.fill_template( '/admin/dataset_security/group_create.mako',
+ return trans.fill_template( '/admin/dataset_security/group/group_create.mako',
in_users=[],
out_users=out_users,
in_roles=[],
@@ -478,44 +673,31 @@ class Admin( BaseController ):
@web.require_admin
def mark_group_deleted( self, trans, **kwd ):
params = util.Params( kwd )
- group = trans.sa_session.query( trans.app.model.Group ).get( int( params.group_id ) )
+ group = get_group( trans, params.id )
group.deleted = True
group.flush()
msg = "Group '%s' has been marked as deleted." % group.name
- trans.response.send_redirect( web.url_for( action='groups', msg=util.sanitize_text( msg ), messagetype='done' ) )
- @web.expose
- @web.require_admin
- def deleted_groups( self, trans, **kwd ):
- params = util.Params( kwd )
- msg = util.restore_text( params.get( 'msg', '' ) )
- messagetype = params.get( 'messagetype', 'done' )
- groups = trans.sa_session.query( trans.app.model.Group ) \
- .filter( trans.app.model.Group.table.c.deleted==True ) \
- .order_by( trans.app.model.Group.table.c.name )
- return trans.fill_template( '/admin/dataset_security/deleted_groups.mako',
- groups=groups,
- msg=msg,
- messagetype=messagetype )
+ trans.response.send_redirect( web.url_for( action='groups', message=util.sanitize_text( msg ), status='done' ) )
@web.expose
@web.require_admin
def undelete_group( self, trans, **kwd ):
params = util.Params( kwd )
- group = trans.sa_session.query( trans.app.model.Group ).get( int( params.group_id ) )
+ group = get_group( trans, params.id )
group.deleted = False
group.flush()
msg = "Group '%s' has been marked as not deleted." % group.name
- trans.response.send_redirect( web.url_for( action='groups', msg=util.sanitize_text( msg ), messagetype='done' ) )
+ trans.response.send_redirect( web.url_for( action='groups', message=util.sanitize_text( msg ), status='done' ) )
@web.expose
@web.require_admin
def purge_group( self, trans, **kwd ):
# This method should only be called for a Group that has previously been deleted.
# Purging a deleted Group simply deletes all UserGroupAssociations and GroupRoleAssociations.
params = util.Params( kwd )
- group = trans.sa_session.query( trans.app.model.Group ).get( int( params.group_id ) )
+ group = get_group( trans, params.id )
if not group.deleted:
# We should never reach here, but just in case there is a bug somewhere...
msg = "Group '%s' has not been deleted, so it cannot be purged." % group.name
- trans.response.send_redirect( web.url_for( action='groups', msg=util.sanitize_text( msg ), messagetype='error' ) )
+ trans.response.send_redirect( web.url_for( action='groups', message=util.sanitize_text( msg ), status='error' ) )
# Delete UserGroupAssociations
for uga in group.users:
trans.sa_session.delete( uga )
@@ -525,8 +707,8 @@ class Admin( BaseController ):
trans.sa_session.delete( gra )
gra.flush()
# Delete the Group
- msg = "The following have been purged from the database for group '%s': UserGroupAssociations, GroupRoleAssociations." % group.name
- trans.response.send_redirect( web.url_for( action='deleted_groups', msg=util.sanitize_text( msg ), messagetype='done' ) )
+ message = "The following have been purged from the database for group '%s': UserGroupAssociations, GroupRoleAssociations." % group.name
+ trans.response.send_redirect( web.url_for( action='groups', message=util.sanitize_text( message ), status='done' ) )
# Galaxy User Stuff
@web.expose
@@ -645,11 +827,12 @@ class Admin( BaseController ):
message = "No user ids received for deleting"
trans.response.send_redirect( web.url_for( action='users', message=message, status='error' ) )
ids = util.listify( id )
+ message = "Deleted %d users: " % len( ids )
for user_id in ids:
user = get_user( trans, user_id )
user.deleted = True
user.flush()
- message = "Deleted %d users" % len( ids )
+ message += " %s " % user.email
trans.response.send_redirect( web.url_for( action='users', message=util.sanitize_text( message ), status='done' ) )
@web.expose
@web.require_admin
@@ -660,13 +843,15 @@ class Admin( BaseController ):
trans.response.send_redirect( web.url_for( action='users', message=message, status='error' ) )
ids = util.listify( id )
count = 0
+ undeleted_users = ""
for user_id in ids:
user = get_user( trans, user_id )
if user.deleted:
user.deleted = False
user.flush()
count += 1
- message = "Undeleted %d users" % count
+ undeleted_users += " %s" % user.email
+ message = "Undeleted %d users: %s" % ( count, undeleted_users )
trans.response.send_redirect( web.url_for( action='users',
message=util.sanitize_text( message ),
status='done' ) )
@@ -691,6 +876,7 @@ class Admin( BaseController ):
message=util.sanitize_text( message ),
status='error' ) )
ids = util.listify( id )
+ message = "Purged %d users: " % len( ids )
for user_id in ids:
user = get_user( trans, user_id )
if not user.deleted:
@@ -726,7 +912,7 @@ class Admin( BaseController ):
# Purge the user
user.purged = True
user.flush()
- message = "Purged %d users" % len( ids )
+ message += "%s " % user.email
trans.response.send_redirect( web.url_for( controller='admin',
action='users',
message=util.sanitize_text( message ),
@@ -750,6 +936,8 @@ class Admin( BaseController ):
return self.create_new_user( trans, **kwargs )
if operation == "information":
return self.user_info( trans, **kwargs )
+ if operation == "manage roles & groups":
+ return self.user( trans, **kwargs )
# Render the list view
return self.user_list_grid( trans, **kwargs )
@web.expose
@@ -774,6 +962,14 @@ class Admin( BaseController ):
admin_view=True, **kwd ) )
@web.expose
@web.require_admin
+ def name_autocomplete_data( self, trans, q=None, limit=None, timestamp=None ):
+ """Return autocomplete data for user emails"""
+ ac_data = ""
+ for user in trans.sa_session.query( User ).filter_by( deleted=False ).filter( func.lower( User.email ).like( q.lower() + "%" ) ):
+ ac_data = ac_data + user.email + "\n"
+ return ac_data
+ @web.expose
+ @web.require_admin
def user( self, trans, **kwd ):
user_id = kwd.get( 'id', None )
message = ''
@@ -932,5 +1128,21 @@ def get_user( trans, id ):
id = trans.security.decode_id( id )
user = trans.sa_session.query( model.User ).get( id )
if not user:
- err+msg( "User not found" )
+ return trans.show_error_message( "User not found for id (%s)" % str( id ) )
return user
+def get_role( trans, id ):
+ """Get a Role from the database by id."""
+ # Load user from database
+ id = trans.security.decode_id( id )
+ role = trans.sa_session.query( model.Role ).get( id )
+ if not role:
+ return trans.show_error_message( "Role not found for id (%s)" % str( id ) )
+ return role
+def get_group( trans, id ):
+ """Get a Group from the database by id."""
+ # Load user from database
+ id = trans.security.decode_id( id )
+ group = trans.sa_session.query( model.Group ).get( id )
+ if not group:
+ return trans.show_error_message( "Group not found for id (%s)" % str( id ) )
+ return group
diff --git a/templates/admin/dataset_security/deleted_groups.mako b/templates/admin/dataset_security/deleted_groups.mako
deleted file mode 100644
index 63d17241d2d..00000000000
--- a/templates/admin/dataset_security/deleted_groups.mako
+++ /dev/null
@@ -1,101 +0,0 @@
-<%inherit file="/base.mako"/>
-<%namespace file="/message.mako" import="render_msg" />
-
-## Render a row
-<%def name="render_row( group, ctr, anchored, curr_anchor )">
- %if ctr % 2 == 1:
-
- %else:
-
- %endif
-
- ${group.name}
-
-
-
-
- ${len( group.members )}
-
-
- ${len( group.roles )}
- %if not anchored:
-
-
- %endif
-
-
-%def>
-
-Deleted Groups
-
-%if msg:
- ${render_msg( msg, messagetype )}
-%endif
-
-## TODO: make this a grid
-
-%if not groups:
- There are no deleted Galaxy groups
-%else:
-
- <%
- render_quick_find = groups.count() > 200
- ctr = 0
- %>
- %if render_quick_find:
- <%
- anchors = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
- anchor_loc = 0
- anchored = False
- curr_anchor = 'A'
- %>
-
-
- Jump to letter:
- %for a in anchors:
- | ${a}
- %endfor
-
-
- %endif
-
- %for ctr, group in enumerate( groups ):
- %if render_quick_find and not group.name.upper().startswith( curr_anchor ):
- <% anchored = False %>
- %endif
- %if render_quick_find and group.name.upper().startswith( curr_anchor ):
- %if not anchored:
- ${render_row( group, ctr, anchored, curr_anchor )}
- <% anchored = True %>
- %else:
- ${render_row( group, ctr, anchored, curr_anchor )}
- %endif
- %elif render_quick_find:
- %for anchor in anchors[ anchor_loc: ]:
- %if group.name.upper().startswith( anchor ):
- %if not anchored:
- <% curr_anchor = anchor %>
- ${render_row( group, ctr, anchored, curr_anchor )}
- <% anchored = True %>
- %else:
- ${render_row( group, ctr, anchored, curr_anchor )}
- %endif
- <%
- anchor_loc = anchors.index( anchor )
- break
- %>
- %endif
- %endfor
- %else:
- ${render_row( group, ctr, True, '' )}
- %endif
- %endfor
-
-%endif
diff --git a/templates/admin/dataset_security/deleted_roles.mako b/templates/admin/dataset_security/deleted_roles.mako
deleted file mode 100644
index 7cfa03b0ed4..00000000000
--- a/templates/admin/dataset_security/deleted_roles.mako
+++ /dev/null
@@ -1,103 +0,0 @@
-<%inherit file="/base.mako"/>
-<%namespace file="/message.mako" import="render_msg" />
-
-## Render a row
-<%def name="render_row( role, ctr, anchored, curr_anchor )">
- %if ctr % 2 == 1:
-
- %else:
-
- %endif
-
- ${role.name}
-
-
-
- ${role.description}
- ${role.type}
-
- ${len( role.users )}
-
-
- ${len( role.groups )}
- %if not anchored:
-
-
- %endif
-
-
-%def>
-
-Deleted Roles
-
-%if msg:
- ${render_msg( msg, messagetype )}
-%endif
-
-%if not roles:
- There are no deleted Galaxy roles
-%else:
-
- <%
- render_quick_find = roles.count() > 200
- ctr = 0
- %>
- %if render_quick_find:
- <%
- anchors = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
- anchor_loc = 0
- anchored = False
- curr_anchor = 'A'
- %>
-
-
- Jump to letter:
- %for a in anchors:
- | ${a}
- %endfor
-
-
- %endif
-
- %for ctr, role in enumerate( roles ):
- %if render_quick_find and not role.name.upper().startswith( curr_anchor ):
- <% anchored = False %>
- %endif
- %if render_quick_find and role.name.upper().startswith( curr_anchor ):
- %if not anchored:
- ${render_row( role, ctr, anchored, curr_anchor )}
- <% anchored = True %>
- %else:
- ${render_row( role, ctr, anchored, curr_anchor )}
- %endif
- %elif render_quick_find:
- %for anchor in anchors[ anchor_loc: ]:
- %if role.name.upper().startswith( anchor ):
- %if not anchored:
- <% curr_anchor = anchor %>
- ${render_row( role, ctr, anchored, curr_anchor )}
- <% anchored = True %>
- %else:
- ${render_row( role, ctr, anchored, curr_anchor )}
- %endif
- <%
- anchor_loc = anchors.index( anchor )
- break
- %>
- %endif
- %endfor
- %else:
- ${render_row( role, ctr, True, '' )}
- %endif
- %endfor
-
-%endif
diff --git a/templates/admin/dataset_security/group/grid.mako b/templates/admin/dataset_security/group/grid.mako
new file mode 100644
index 00000000000..6a41b688c5e
--- /dev/null
+++ b/templates/admin/dataset_security/group/grid.mako
@@ -0,0 +1 @@
+<%inherit file="/grid_base.mako"/>
diff --git a/templates/admin/dataset_security/group.mako b/templates/admin/dataset_security/group/group.mako
similarity index 100%
rename from templates/admin/dataset_security/group.mako
rename to templates/admin/dataset_security/group/group.mako
diff --git a/templates/admin/dataset_security/group_create.mako b/templates/admin/dataset_security/group/group_create.mako
similarity index 100%
rename from templates/admin/dataset_security/group_create.mako
rename to templates/admin/dataset_security/group/group_create.mako
diff --git a/templates/admin/dataset_security/group_rename.mako b/templates/admin/dataset_security/group/group_rename.mako
similarity index 92%
rename from templates/admin/dataset_security/group_rename.mako
rename to templates/admin/dataset_security/group/group_rename.mako
index 0e068f3ed3c..60c6b6d406d 100644
--- a/templates/admin/dataset_security/group_rename.mako
+++ b/templates/admin/dataset_security/group/group_rename.mako
@@ -24,7 +24,7 @@
diff --git a/templates/admin/dataset_security/groups.mako b/templates/admin/dataset_security/groups.mako
deleted file mode 100644
index 3551e5f051b..00000000000
--- a/templates/admin/dataset_security/groups.mako
+++ /dev/null
@@ -1,107 +0,0 @@
-<%inherit file="/base.mako"/>
-<%namespace file="/message.mako" import="render_msg" />
-
-## Render a row
-<%def name="render_row( group, ctr, anchored, curr_anchor )">
- %if ctr % 2 == 1:
-
- %else:
-
- %endif
-
- ${group.name}
-
-
-
-
- ${len( group.members )}
-
-
- ${len( group.roles )}
- %if not anchored:
-
-
- %endif
-
-
-%def>
-
-Groups
-
-
-
-%if msg:
- ${render_msg( msg, messagetype )}
-%endif
-
-## TODO: make this a grid
-
-%if not groups:
- There are no Galaxy groups
-%else:
-
- <%
- render_quick_find = groups.count() > 200
- ctr = 0
- %>
- %if render_quick_find:
- <%
- anchors = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
- anchor_loc = 0
- anchored = False
- curr_anchor = 'A'
- %>
-
-
- Jump to letter:
- %for a in anchors:
- | ${a}
- %endfor
-
-
- %endif
-
- %for ctr, group in enumerate( groups ):
- %if render_quick_find and not group.name.upper().startswith( curr_anchor ):
- <% anchored = False %>
- %endif
- %if render_quick_find and group.name.upper().startswith( curr_anchor ):
- %if not anchored:
- ${render_row( group, ctr, anchored, curr_anchor )}
- <% anchored = True %>
- %else:
- ${render_row( group, ctr, anchored, curr_anchor )}
- %endif
- %elif render_quick_find:
- %for anchor in anchors[ anchor_loc: ]:
- %if group.name.upper().startswith( anchor ):
- %if not anchored:
- <% curr_anchor = anchor %>
- ${render_row( group, ctr, anchored, curr_anchor )}
- <% anchored = True %>
- %else:
- ${render_row( group, ctr, anchored, curr_anchor )}
- %endif
- <%
- anchor_loc = anchors.index( anchor )
- break
- %>
- %endif
- %endfor
- %else:
- ${render_row( group, ctr, True, '' )}
- %endif
- %endfor
-
-%endif
diff --git a/templates/admin/dataset_security/role/grid.mako b/templates/admin/dataset_security/role/grid.mako
new file mode 100644
index 00000000000..6a41b688c5e
--- /dev/null
+++ b/templates/admin/dataset_security/role/grid.mako
@@ -0,0 +1 @@
+<%inherit file="/grid_base.mako"/>
diff --git a/templates/admin/dataset_security/role.mako b/templates/admin/dataset_security/role/role.mako
similarity index 100%
rename from templates/admin/dataset_security/role.mako
rename to templates/admin/dataset_security/role/role.mako
diff --git a/templates/admin/dataset_security/role_create.mako b/templates/admin/dataset_security/role/role_create.mako
similarity index 100%
rename from templates/admin/dataset_security/role_create.mako
rename to templates/admin/dataset_security/role/role_create.mako
diff --git a/templates/admin/dataset_security/role_rename.mako b/templates/admin/dataset_security/role/role_rename.mako
similarity index 94%
rename from templates/admin/dataset_security/role_rename.mako
rename to templates/admin/dataset_security/role/role_rename.mako
index d70844d6f55..e17265c35da 100644
--- a/templates/admin/dataset_security/role_rename.mako
+++ b/templates/admin/dataset_security/role/role_rename.mako
@@ -31,7 +31,7 @@
diff --git a/templates/admin/dataset_security/roles.mako b/templates/admin/dataset_security/roles.mako
deleted file mode 100644
index 5acf31ad278..00000000000
--- a/templates/admin/dataset_security/roles.mako
+++ /dev/null
@@ -1,109 +0,0 @@
-<%inherit file="/base.mako"/>
-<%namespace file="/message.mako" import="render_msg" />
-
-## Render a row
-<%def name="render_row( role, ctr, anchored, curr_anchor )">
- %if ctr % 2 == 1:
-
- %else:
-
- %endif
-
- ${role.name}
-
-
-
- ${role.description}
- ${role.type}
-
- ${len( role.users )}
-
-
- ${len( role.groups )}
- %if not anchored:
-
-
- %endif
-
-
-%def>
-
-Roles
-
-
-
-%if msg:
- ${render_msg( msg, messagetype )}
-%endif
-
-%if not roles:
- There are no non-private Galaxy roles
-%else:
-
- <%
- render_quick_find = roles.count() > 200
- ctr = 0
- %>
- %if render_quick_find:
- <%
- anchors = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
- anchor_loc = 0
- anchored = False
- curr_anchor = 'A'
- %>
-
-
- Jump to letter:
- %for a in anchors:
- | ${a}
- %endfor
-
-
- %endif
-
- %for ctr, role in enumerate( roles ):
- %if render_quick_find and not role.name.upper().startswith( curr_anchor ):
- <% anchored = False %>
- %endif
- %if render_quick_find and role.name.upper().startswith( curr_anchor ):
- %if not anchored:
- ${render_row( role, ctr, anchored, curr_anchor )}
- <% anchored = True %>
- %else:
- ${render_row( role, ctr, anchored, curr_anchor )}
- %endif
- %elif render_quick_find:
- %for anchor in anchors[ anchor_loc: ]:
- %if role.name.upper().startswith( anchor ):
- %if not anchored:
- <% curr_anchor = anchor %>
- ${render_row( role, ctr, anchored, curr_anchor )}
- <% anchored = True %>
- %else:
- ${render_row( role, ctr, anchored, curr_anchor )}
- %endif
- <%
- anchor_loc = anchors.index( anchor )
- break
- %>
- %endif
- %endfor
- %else:
- ${render_row( role, ctr, True, '' )}
- %endif
- %endfor
-
-%endif
diff --git a/templates/admin/user/grid.mako b/templates/admin/user/grid.mako
index 1aab076e48e..6a41b688c5e 100644
--- a/templates/admin/user/grid.mako
+++ b/templates/admin/user/grid.mako
@@ -1,224 +1 @@
-<%inherit file="/base.mako"/>
-<%def name="title()">${grid.title}%def>
-<% from galaxy import util %>
-
-%if message:
-
-
${util.restore_text( message )}
-
-
-%endif
-
-<%def name="javascripts()">
- ${parent.javascripts()}
- ${h.js("jquery.autocomplete", "autocomplete_tagging" )}
-
-%def>
-
-<%def name="stylesheets()">
- ${h.css( "base", "autocomplete_tagging" )}
-
-%def>
-
-%if grid.standard_filters:
-
-%endif
-
-
-
-%if query.count() == 0:
- No users were returned for the current query. Click the Show all users button or a letter below.
-%endif:
-<%
- letters = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']
-%>
-
+<%inherit file="/grid_base.mako"/>
diff --git a/templates/grid_base.mako b/templates/grid_base.mako
index 618e3a22b28..65df11e6743 100644
--- a/templates/grid_base.mako
+++ b/templates/grid_base.mako
@@ -1,5 +1,6 @@
<%!
- from galaxy.model import History, HistoryDatasetAssociation
+ from galaxy.model import History, HistoryDatasetAssociation, User, Role, Group
+ import galaxy.util
def inherit(context):
if context.get('use_panels'):
return '/base_panels.mako'
@@ -11,7 +12,7 @@
## Render the grid's basic elements. Each of these elements can be subclassed.
%if message:
-
${message}
+ ${util.restore_text( message )}
%endif
@@ -303,6 +304,12 @@ ${self.grid_table()}
items_plural = "histories"
elif grid.model_class == HistoryDatasetAssociation:
items_plural = "datasets"
+ elif grid.model_class == User:
+ items_plural = "users"
+ elif grid.model_class == Role:
+ items_plural = "roles"
+ elif grid.model_class == Group:
+ items_plural = "groups"
%>
%if num_pages > 1:
diff --git a/test/base/twilltestcase.py b/test/base/twilltestcase.py
index d4f7e53661a..8325d0e358c 100644
--- a/test/base/twilltestcase.py
+++ b/test/base/twilltestcase.py
@@ -672,7 +672,8 @@ class TwillTestCase( unittest.TestCase ):
self.check_page_for_string( "The user information has been updated with the changes." )
for value in info_values:
self.check_page_for_string( value )
- def user_set_default_permissions( self, permissions_out=[], permissions_in=[], role_id=2 ): # role.id = 2 is Private Role for test2@bx.psu.edu
+ def user_set_default_permissions( self, permissions_out=[], permissions_in=[], role_id='2' ):
+ # role.id = 2 is Private Role for test2@bx.psu.edu
# NOTE: Twill has a bug that requires the ~/user/permissions page to contain at least 1 option value
# in each select list or twill throws an exception, which is: ParseError: OPTION outside of SELECT
# Due to this bug, we'll bypass visiting the page, and simply pass the permissions on to the
@@ -921,6 +922,7 @@ class TwillTestCase( unittest.TestCase ):
# Tests associated with users
def create_new_account_as_admin( self, email='test4@bx.psu.edu', password='testuser' ):
"""Create a new account for another user"""
+ # TODO: fix this so that it uses the form rather than the following URL.
self.home()
self.visit_url( "%s/user/create?admin_view=True&email=%s&password=%s&confirm=%s&create_user_button=Submit&subscribe=False" \
% ( self.url, email, password, password ) )
@@ -983,7 +985,13 @@ class TwillTestCase( unittest.TestCase ):
self.home()
# Tests associated with roles
- def create_role( self, name='Role One', description="This is Role One", in_user_ids=[], in_group_ids=[], create_group_for_role='no', private_role='' ):
+ def create_role( self,
+ name='Role One',
+ description="This is Role One",
+ in_user_ids=[],
+ in_group_ids=[],
+ create_group_for_role='no',
+ private_role='' ):
"""Create a new role"""
url = "%s/admin/create_role?create_role_button=Save&name=%s&description=%s" % ( self.url, name.replace( ' ', '+' ), description.replace( ' ', '+' ) )
if in_user_ids:
@@ -1017,7 +1025,7 @@ class TwillTestCase( unittest.TestCase ):
def rename_role( self, role_id, name='Role One Renamed', description='This is Role One Re-described' ):
"""Rename a role"""
self.home()
- self.visit_url( "%s/admin/role?rename=True&role_id=%s" % ( self.url, role_id ) )
+ self.visit_url( "%s/admin/role?rename=True&id=%s" % ( self.url, role_id ) )
self.check_page_for_string( 'Change role name and description' )
tc.fv( "1", "name", name )
tc.fv( "1", "description", description )
@@ -1026,28 +1034,28 @@ class TwillTestCase( unittest.TestCase ):
def mark_role_deleted( self, role_id, role_name ):
"""Mark a role as deleted"""
self.home()
- self.visit_url( "%s/admin/mark_role_deleted?role_id=%s" % ( self.url, role_id ) )
+ self.visit_url( "%s/admin/roles?operation=delete&id=%s" % ( self.url, role_id ) )
check_str = "Role '%s' has been marked as deleted" % role_name
self.check_page_for_string( check_str )
self.home()
def undelete_role( self, role_id, role_name ):
"""Undelete an existing role"""
self.home()
- self.visit_url( "%s/admin/undelete_role?role_id=%s" % ( self.url, role_id ) )
+ self.visit_url( "%s/admin/roles?operation=undelete&id=%s" % ( self.url, role_id ) )
check_str = "Role '%s' has been marked as not deleted" % role_name
self.check_page_for_string( check_str )
self.home()
def purge_role( self, role_id, role_name ):
"""Purge an existing role"""
self.home()
- self.visit_url( "%s/admin/purge_role?role_id=%s" % ( self.url, role_id ) )
+ self.visit_url( "%s/admin/roles?operation=purge&id=%s" % ( self.url, role_id ) )
check_str = "The following have been purged from the database for role '%s': " % role_name
check_str += "DefaultUserPermissions, DefaultHistoryPermissions, UserRoleAssociations, GroupRoleAssociations, DatasetPermissionss."
self.check_page_for_string( check_str )
self.home()
def associate_users_and_groups_with_role( self, role_id, role_name, user_ids=[], group_ids=[] ):
self.home()
- url = "%s/admin/role?role_id=%s&role_members_edit_button=Save" % ( self.url, role_id )
+ url = "%s/admin/role?id=%s&role_members_edit_button=Save" % ( self.url, role_id )
if user_ids:
url += "&in_users=%s" % ','.join( user_ids )
if group_ids:
@@ -1076,14 +1084,14 @@ class TwillTestCase( unittest.TestCase ):
def rename_group( self, group_id, name='Group One Renamed' ):
"""Rename a group"""
self.home()
- self.visit_url( "%s/admin/group?rename=True&group_id=%s" % ( self.url, group_id ) )
+ self.visit_url( "%s/admin/group?rename=True&id=%s" % ( self.url, group_id ) )
self.check_page_for_string( 'Change group name' )
tc.fv( "1", "name", name )
tc.submit( "rename_group_button" )
self.home()
def associate_users_and_roles_with_group( self, group_id, group_name, user_ids=[], role_ids=[] ):
self.home()
- url = "%s/admin/group?group_id=%s&group_roles_users_edit_button=Save" % ( self.url, group_id )
+ url = "%s/admin/group?id=%s&group_roles_users_edit_button=Save" % ( self.url, group_id )
if user_ids:
url += "&in_users=%s" % ','.join( user_ids )
if role_ids:
@@ -1095,21 +1103,21 @@ class TwillTestCase( unittest.TestCase ):
def mark_group_deleted( self, group_id, group_name ):
"""Mark a group as deleted"""
self.home()
- self.visit_url( "%s/admin/mark_group_deleted?group_id=%s" % ( self.url, group_id ) )
+ self.visit_url( "%s/admin/groups?operation=delete&id=%s" % ( self.url, group_id ) )
check_str = "Group '%s' has been marked as deleted" % group_name
self.check_page_for_string( check_str )
self.home()
def undelete_group( self, group_id, group_name ):
"""Undelete an existing group"""
self.home()
- self.visit_url( "%s/admin/undelete_group?group_id=%s" % ( self.url, group_id ) )
+ self.visit_url( "%s/admin/groups?operation=undelete&id=%s" % ( self.url, group_id ) )
check_str = "Group '%s' has been marked as not deleted" % group_name
self.check_page_for_string( check_str )
self.home()
def purge_group( self, group_id, group_name ):
"""Purge an existing group"""
self.home()
- self.visit_url( "%s/admin/purge_group?group_id=%s" % ( self.url, group_id ) )
+ self.visit_url( "%s/admin/groups?operation=purge&id=%s" % ( self.url, group_id ) )
check_str = "The following have been purged from the database for group '%s': UserGroupAssociations, GroupRoleAssociations." % group_name
self.check_page_for_string( check_str )
self.home()
diff --git a/test/functional/test_history_functions.py b/test/functional/test_history_functions.py
index 6d7ccea9322..2d922055f29 100644
--- a/test/functional/test_history_functions.py
+++ b/test/functional/test_history_functions.py
@@ -780,8 +780,8 @@ class TestHistory( TwillTestCase ):
self.delete_history( id=self.security.encode_id( history4.id ) )
self.delete_history( id=self.security.encode_id( history5.id ) )
# Eliminate Sharing role for: test@bx.psu.edu, test2@bx.psu.edu
- self.mark_role_deleted( str( sharing_role.id ), sharing_role.name )
- self.purge_role( str( sharing_role.id ), sharing_role.name )
+ self.mark_role_deleted( self.security.encode_id( sharing_role.id ), sharing_role.name )
+ self.purge_role( self.security.encode_id( sharing_role.id ), sharing_role.name )
# Manually delete the sharing role from the database
sa_session.refresh( sharing_role )
sa_session.delete( sharing_role )
diff --git a/test/functional/test_security_and_libraries.py b/test/functional/test_security_and_libraries.py
index 745a942fe28..d70b7ccdf29 100644
--- a/test/functional/test_security_and_libraries.py
+++ b/test/functional/test_security_and_libraries.py
@@ -327,8 +327,12 @@ class TestSecurityAndLibraries( TwillTestCase ):
name = 'Role One'
description = "This is Role Ones description"
user_ids=[ str( admin_user.id ), str( regular_user1.id ), str( regular_user3.id ) ]
- self.create_role( name=name, description=description, in_user_ids=user_ids, in_group_ids=[],
- create_group_for_role='yes', private_role=admin_user.email )
+ self.create_role( name=name,
+ description=description,
+ in_user_ids=user_ids,
+ in_group_ids=[],
+ create_group_for_role='yes',
+ private_role=admin_user.email )
# Get the role object for later tests
global role_one
role_one = sa_session.query( galaxy.model.Role ).filter( galaxy.model.Role.table.c.name==name ).first()
@@ -352,13 +356,13 @@ class TestSecurityAndLibraries( TwillTestCase ):
# Rename the role
rename = "Role One's been Renamed"
redescription="This is Role One's Re-described"
- self.rename_role( str( role_one.id ), name=rename, description=redescription )
+ self.rename_role( self.security.encode_id( role_one.id ), name=rename, description=redescription )
self.home()
self.visit_page( 'admin/roles' )
self.check_page_for_string( rename )
self.check_page_for_string( redescription )
# Reset the role back to the original name and description
- self.rename_role( str( role_one.id ), name=name, description=description )
+ self.rename_role( self.security.encode_id( role_one.id ), name=name, description=description )
def test_050_create_group( self ):
"""Testing creating new group with 3 members and 1 associated role, then renaming it"""
name = "Group One's Name"
@@ -384,12 +388,12 @@ class TestSecurityAndLibraries( TwillTestCase ):
% ( len( group_one.roles ), group_one.id, len( role_ids ) ) )
# Rename the group
rename = "Group One's been Renamed"
- self.rename_group( str( group_one.id ), name=rename, )
+ self.rename_group( self.security.encode_id( group_one.id ), name=rename, )
self.home()
self.visit_page( 'admin/groups' )
self.check_page_for_string( rename )
# Reset the group back to the original name
- self.rename_group( str( group_one.id ), name=name )
+ self.rename_group( self.security.encode_id( group_one.id ), name=name )
def test_055_add_members_and_role_to_group( self ):
"""Testing editing user membership and role associations of an existing group"""
name = 'Group Two'
@@ -405,10 +409,12 @@ class TestSecurityAndLibraries( TwillTestCase ):
if group_two.roles:
raise AssertionError( '%d GroupRoleAssociations were created for group id %d when it was created ( should have been 0 )' \
% ( len( group_two.roles ), group_two.id ) )
- group_two_id = str( group_two.id )
user_ids = [ str( regular_user1.id ) ]
role_ids = [ str( role_one.id ) ]
- self.associate_users_and_roles_with_group( group_two.id, group_two.name, user_ids=user_ids, role_ids=role_ids )
+ self.associate_users_and_roles_with_group( self.security.encode_id( group_two.id ),
+ group_two.name,
+ user_ids=user_ids,
+ role_ids=role_ids )
def test_060_create_role_with_user_and_group_associations( self ):
"""Testing creating a role with user and group associations"""
# NOTE: To get this to work with twill, all select lists on the ~/admin/role page must contain at least
@@ -421,7 +427,11 @@ class TestSecurityAndLibraries( TwillTestCase ):
group_ids=[ str( group_two.id ) ]
private_role=admin_user.email
# Create the role
- self.create_role( name=name, description=description, in_user_ids=user_ids, in_group_ids=group_ids, private_role=private_role )
+ self.create_role( name=name,
+ description=description,
+ in_user_ids=user_ids,
+ in_group_ids=group_ids,
+ private_role=private_role )
# Get the role object for later tests
global role_two
role_two = sa_session.query( galaxy.model.Role ).filter( galaxy.model.Role.table.c.name==name ).first()
@@ -451,7 +461,11 @@ class TestSecurityAndLibraries( TwillTestCase ):
user_ids=[]
group_ids=[]
private_role=admin_user.email
- self.create_role( name=name, description=description, in_user_ids=user_ids, in_group_ids=group_ids, private_role=private_role )
+ self.create_role( name=name,
+ description=description,
+ in_user_ids=user_ids,
+ in_group_ids=group_ids,
+ private_role=private_role )
# Get the role object for later tests
global role_three
role_three = sa_session.query( galaxy.model.Role ).filter( galaxy.model.Role.table.c.name==name ).first()
@@ -466,8 +480,11 @@ class TestSecurityAndLibraries( TwillTestCase ):
for uga in admin_user.groups:
group_ids.append( str( uga.group_id ) )
check_str = "User '%s' has been updated with %d associated roles and %d associated groups" % ( admin_user.email, len( role_ids ), len( group_ids ) )
- self.associate_roles_and_groups_with_user( self.security.encode_id( admin_user.id ), str( admin_user.email ),
- in_role_ids=role_ids, in_group_ids=group_ids, check_str=check_str )
+ self.associate_roles_and_groups_with_user( self.security.encode_id( admin_user.id ),
+ str( admin_user.email ),
+ in_role_ids=role_ids,
+ in_group_ids=group_ids,
+ check_str=check_str )
sa_session.refresh( admin_user )
# admin_user should now be associated with 4 roles: private, role_one, role_two, role_three
if len( admin_user.roles ) != 4:
@@ -1374,7 +1391,7 @@ class TestSecurityAndLibraries( TwillTestCase ):
self.home()
self.visit_url( '%s/admin/groups' % self.url )
self.check_page_for_string( group_two.name )
- self.mark_group_deleted( str( group_two.id ), group_two.name )
+ self.mark_group_deleted( self.security.encode_id( group_two.id ), group_two.name )
sa_session.refresh( group_two )
if not group_two.deleted:
raise AssertionError( '%s was not correctly marked as deleted.' % group_two.name )
@@ -1386,7 +1403,7 @@ class TestSecurityAndLibraries( TwillTestCase ):
def test_175_undelete_group( self ):
"""Testing undeleting a deleted group"""
# Logged in as admin_user
- self.undelete_group( str( group_two.id ), group_two.name )
+ self.undelete_group( self.security.encode_id( group_two.id ), group_two.name )
sa_session.refresh( group_two )
if group_two.deleted:
raise AssertionError( '%s was not correctly marked as not deleted.' % group_two.name )
@@ -1396,7 +1413,7 @@ class TestSecurityAndLibraries( TwillTestCase ):
self.home()
self.visit_url( '%s/admin/roles' % self.url )
self.check_page_for_string( role_two.name )
- self.mark_role_deleted( str( role_two.id ), role_two.name )
+ self.mark_role_deleted( self.security.encode_id( role_two.id ), role_two.name )
sa_session.refresh( role_two )
if not role_two.deleted:
raise AssertionError( '%s was not correctly marked as deleted.' % role_two.name )
@@ -1408,7 +1425,7 @@ class TestSecurityAndLibraries( TwillTestCase ):
def test_185_undelete_role( self ):
"""Testing undeleting a deleted role"""
# Logged in as admin_user
- self.undelete_role( str( role_two.id ), role_two.name )
+ self.undelete_role( self.security.encode_id( role_two.id ), role_two.name )
def test_190_mark_dataset_deleted( self ):
"""Testing marking a library dataset as deleted"""
# Logged in as admin_user
@@ -1541,59 +1558,57 @@ class TestSecurityAndLibraries( TwillTestCase ):
def test_235_purge_group( self ):
"""Testing purging a group"""
# Logged in as admin_user
- group_id = str( group_two.id )
- self.mark_group_deleted( group_id, group_two.name )
- self.purge_group( group_id, group_two.name )
+ self.mark_group_deleted( self.security.encode_id( group_two.id ), group_two.name )
+ self.purge_group( self.security.encode_id( group_two.id ), group_two.name )
# Make sure there are no UserGroupAssociations
uga = sa_session.query( galaxy.model.UserGroupAssociation ) \
- .filter( galaxy.model.UserGroupAssociation.table.c.group_id == group_id ) \
+ .filter( galaxy.model.UserGroupAssociation.table.c.group_id == group_two.id ) \
.first()
if uga:
- raise AssertionError( "Purging the group did not delete the UserGroupAssociations for group_id '%s'" % group_id )
+ raise AssertionError( "Purging the group did not delete the UserGroupAssociations for group_id '%s'" % group_two.id )
# Make sure there are no GroupRoleAssociations
gra = sa_session.query( galaxy.model.GroupRoleAssociation ) \
- .filter( galaxy.model.GroupRoleAssociation.table.c.group_id == group_id ) \
+ .filter( galaxy.model.GroupRoleAssociation.table.c.group_id == group_two.id ) \
.first()
if gra:
- raise AssertionError( "Purging the group did not delete the GroupRoleAssociations for group_id '%s'" % group_id )
+ raise AssertionError( "Purging the group did not delete the GroupRoleAssociations for group_id '%s'" % group_two.id )
# Undelete the group for later test runs
- self.undelete_group( group_id, group_two.name )
+ self.undelete_group( self.security.encode_id( group_two.id ), group_two.name )
def test_240_purge_role( self ):
"""Testing purging a role"""
# Logged in as admin_user
- role_id = str( role_two.id )
- self.mark_role_deleted( role_id, role_two.name )
- self.purge_role( role_id, role_two.name )
+ self.mark_role_deleted( self.security.encode_id( role_two.id ), role_two.name )
+ self.purge_role( self.security.encode_id( role_two.id ), role_two.name )
# Make sure there are no UserRoleAssociations
uras = sa_session.query( galaxy.model.UserRoleAssociation ) \
- .filter( galaxy.model.UserRoleAssociation.table.c.role_id == role_id ) \
+ .filter( galaxy.model.UserRoleAssociation.table.c.role_id == role_two.id ) \
.all()
if uras:
- raise AssertionError( "Purging the role did not delete the UserRoleAssociations for role_id '%s'" % role_id )
+ raise AssertionError( "Purging the role did not delete the UserRoleAssociations for role_id '%s'" % role_two.id )
# Make sure there are no DefaultUserPermissions associated with the Role
dups = sa_session.query( galaxy.model.DefaultUserPermissions ) \
- .filter( galaxy.model.DefaultUserPermissions.table.c.role_id == role_id ) \
+ .filter( galaxy.model.DefaultUserPermissions.table.c.role_id == role_two.id ) \
.all()
if dups:
- raise AssertionError( "Purging the role did not delete the DefaultUserPermissions for role_id '%s'" % role_id )
+ raise AssertionError( "Purging the role did not delete the DefaultUserPermissions for role_id '%s'" % role_two.id )
# Make sure there are no DefaultHistoryPermissions associated with the Role
dhps = sa_session.query( galaxy.model.DefaultHistoryPermissions ) \
- .filter( galaxy.model.DefaultHistoryPermissions.table.c.role_id == role_id ) \
+ .filter( galaxy.model.DefaultHistoryPermissions.table.c.role_id == role_two.id ) \
.all()
if dhps:
- raise AssertionError( "Purging the role did not delete the DefaultHistoryPermissions for role_id '%s'" % role_id )
+ raise AssertionError( "Purging the role did not delete the DefaultHistoryPermissions for role_id '%s'" % role_two.id )
# Make sure there are no GroupRoleAssociations
gra = sa_session.query( galaxy.model.GroupRoleAssociation ) \
- .filter( galaxy.model.GroupRoleAssociation.table.c.role_id == role_id ) \
+ .filter( galaxy.model.GroupRoleAssociation.table.c.role_id == role_two.id ) \
.first()
if gra:
- raise AssertionError( "Purging the role did not delete the GroupRoleAssociations for role_id '%s'" % role_id )
+ raise AssertionError( "Purging the role did not delete the GroupRoleAssociations for role_id '%s'" % role_two.id )
# Make sure there are no DatasetPermissionss
dp = sa_session.query( galaxy.model.DatasetPermissions ) \
- .filter( galaxy.model.DatasetPermissions.table.c.role_id == role_id ) \
+ .filter( galaxy.model.DatasetPermissions.table.c.role_id == role_two.id ) \
.first()
if dp:
- raise AssertionError( "Purging the role did not delete the DatasetPermissionss for role_id '%s'" % role_id )
+ raise AssertionError( "Purging the role did not delete the DatasetPermissionss for role_id '%s'" % role_two.id )
def test_245_manually_unpurge_role( self ):
"""Testing manually un-purging a role"""
# Logged in as admin_user
@@ -1601,7 +1616,7 @@ class TestSecurityAndLibraries( TwillTestCase ):
# TODO: If we decide to implement the GUI feature for un-purging a role, replace this with a method call
role_two.purged = False
role_two.flush()
- self.undelete_role( str( role_two.id ), role_two.name )
+ self.undelete_role( self.security.encode_id( role_two.id ), role_two.name )
def test_250_purge_library( self ):
"""Testing purging a library"""
# Logged in as admin_user
@@ -1815,8 +1830,8 @@ class TestSecurityAndLibraries( TwillTestCase ):
# Eliminate all non-private roles
##################
for role in [ role_one, role_two, role_three ]:
- self.mark_role_deleted( str( role.id ), role.name )
- self.purge_role( str( role.id ), role.name )
+ self.mark_role_deleted( self.security.encode_id( role.id ), role.name )
+ self.purge_role( self.security.encode_id( role.id ), role.name )
# Manually delete the role from the database
sa_session.refresh( role )
sa_session.delete( role )
@@ -1825,8 +1840,8 @@ class TestSecurityAndLibraries( TwillTestCase ):
# Eliminate all groups
##################
for group in [ group_zero, group_one, group_two ]:
- self.mark_group_deleted( str( group.id ), group.name )
- self.purge_group( str( group.id ), group.name )
+ self.mark_group_deleted( self.security.encode_id( group.id ), group.name )
+ self.purge_group( self.security.encode_id( group.id ), group.name )
# Manually delete the group from the database
sa_session.refresh( group )
sa_session.delete( group )
@@ -1846,7 +1861,6 @@ class TestSecurityAndLibraries( TwillTestCase ):
# Change DefaultHistoryPermissions for regular_user1 back to the default
permissions_in = [ 'DATASET_MANAGE_PERMISSIONS' ]
permissions_out = [ 'DATASET_ACCESS' ]
- role_id = str( regular_user1_private_role.id )
- self.user_set_default_permissions( permissions_in=permissions_in, permissions_out=permissions_out, role_id=role_id )
+ self.user_set_default_permissions( permissions_in=permissions_in, permissions_out=permissions_out, role_id=str( regular_user1_private_role.id ) )
self.logout()
self.login( email=admin_user.email )
diff --git a/tool_conf.xml.main b/tool_conf.xml.main
index abaf3d994f6..18025ec3926 100644
--- a/tool_conf.xml.main
+++ b/tool_conf.xml.main
@@ -8,6 +8,7 @@
+
@@ -27,6 +28,7 @@
+
@@ -34,15 +36,17 @@
+
-
+
+
+
+