mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Fixes and new features for data security and libraries, requires db schema change and new config setting.
- add ability for an admin to reset another user's password - add ability for an admin user to delete another user's account ( requires config setting to display feature ) - add ability for an admin user to manage deleted users ( undelete / purge ) - more code cleanup in the admin controller - several new functional tests and existing functional test improvements SQL commands to alter db schema: ALTER TABLE galaxy_user ADD COLUMN deleted BOOLEAN DEFAULT FALSE; CREATE INDEX ix_galaxy_user_deleted ON galaxy_user USING btree (deleted); ALTER TABLE galaxy_user ADD COLUMN purged BOOLEAN DEFAULT FALSE; CREATE INDEX ix_galaxy_user_purged ON galaxy_user USING btree (purged); New config setting: # Can an admin user delete user accounts? #allow_user_deletion = False
This commit is contained in:
@@ -40,6 +40,7 @@ class Configuration( object ):
|
||||
self.remote_user_maildomain = kwargs.get( "remote_user_maildomain", None )
|
||||
self.require_login = string_as_bool( kwargs.get( "require_login", "False" ) )
|
||||
self.allow_user_creation = string_as_bool( kwargs.get( "allow_user_creation", "True" ) )
|
||||
self.allow_user_deletion = string_as_bool( kwargs.get( "allow_user_deletion", "False" ) )
|
||||
self.template_path = resolve_path( kwargs.get( "template_path", "templates" ), self.root )
|
||||
self.template_cache = resolve_path( kwargs.get( "template_cache_path", "database/compiled_templates" ), self.root )
|
||||
self.local_job_queue_workers = int( kwargs.get( "local_job_queue_workers", "5" ) )
|
||||
@@ -58,10 +59,10 @@ class Configuration( object ):
|
||||
self.pbs_dataset_server = kwargs.get('pbs_dataset_server', "" )
|
||||
self.pbs_dataset_path = kwargs.get('pbs_dataset_path', "" )
|
||||
self.pbs_stage_path = kwargs.get('pbs_stage_path', "" )
|
||||
self.use_heartbeat = string_as_bool( kwargs.get( 'use_heartbeat', False ) )
|
||||
self.use_memdump = string_as_bool( kwargs.get( 'use_memdump', False ) )
|
||||
self.log_memory_usage = string_as_bool( kwargs.get( 'log_memory_usage', False ) )
|
||||
self.log_events = string_as_bool( kwargs.get( 'log_events', False ) )
|
||||
self.use_heartbeat = string_as_bool( kwargs.get( 'use_heartbeat', 'False' ) )
|
||||
self.use_memdump = string_as_bool( kwargs.get( 'use_memdump', 'False' ) )
|
||||
self.log_memory_usage = string_as_bool( kwargs.get( 'log_memory_usage', 'False' ) )
|
||||
self.log_events = string_as_bool( kwargs.get( 'log_events', 'False' ) )
|
||||
self.ucsc_display_sites = kwargs.get( 'ucsc_display_sites', "main,test,archaea" ).lower().split(",")
|
||||
self.gbrowse_display_sites = kwargs.get( 'gbrowse_display_sites', "wormbase,flybase,elegans" ).lower().split(",")
|
||||
self.brand = kwargs.get( 'brand', None )
|
||||
|
||||
@@ -32,6 +32,8 @@ class User( object ):
|
||||
self.email = email
|
||||
self.password = password
|
||||
self.external = False
|
||||
self.deleted = False
|
||||
self.purged = False
|
||||
# Relationships
|
||||
self.histories = []
|
||||
|
||||
@@ -143,6 +145,7 @@ class Group( object ):
|
||||
permitted_actions = galaxy.security.get_permitted_actions( 'GROUP' )
|
||||
def __init__( self, name = None ):
|
||||
self.name = name
|
||||
self.deleted = False
|
||||
|
||||
class UserGroupAssociation( object ):
|
||||
def __init__( self, user, group ):
|
||||
|
||||
@@ -43,7 +43,9 @@ User.table = Table( "galaxy_user", metadata,
|
||||
Column( "update_time", DateTime, default=now, onupdate=now ),
|
||||
Column( "email", TrimmedString( 255 ), nullable=False ),
|
||||
Column( "password", TrimmedString( 40 ), nullable=False ),
|
||||
Column( "external", Boolean, default=False ) )
|
||||
Column( "external", Boolean, default=False ),
|
||||
Column( "deleted", Boolean, index=True, default=False ),
|
||||
Column( "purged", Boolean, index=True, default=False ) )
|
||||
|
||||
History.table = Table( "history", metadata,
|
||||
Column( "id", Integer, primary_key=True),
|
||||
|
||||
+253
-103
@@ -3,12 +3,7 @@ from galaxy import util, datatypes
|
||||
from galaxy.web.base.controller import *
|
||||
from galaxy.datatypes import sniff
|
||||
from galaxy.security import RBACAgent
|
||||
import galaxy.model
|
||||
from galaxy.model.orm import *
|
||||
from xml.sax.saxutils import escape, unescape
|
||||
import pkg_resources
|
||||
pkg_resources.require( "SQLAlchemy >= 0.4" )
|
||||
import sqlalchemy as sa
|
||||
|
||||
import logging
|
||||
log = logging.getLogger( __name__ )
|
||||
@@ -60,9 +55,9 @@ class Admin( BaseController ):
|
||||
params = util.Params( kwd )
|
||||
msg = params.msg
|
||||
messagetype = params.get( 'messagetype', 'done' )
|
||||
users=trans.app.model.User.query().order_by( trans.app.model.User.table.c.email ).all()
|
||||
users = trans.app.model.User.filter( trans.app.model.User.table.c.deleted==False ).order_by( trans.app.model.User.table.c.email ).all()
|
||||
groups = trans.app.model.Group.query() \
|
||||
.filter( galaxy.model.Group.table.c.deleted==False ) \
|
||||
.filter( trans.app.model.Group.table.c.deleted==False ) \
|
||||
.order_by( trans.app.model.Group.table.c.name ) \
|
||||
.all()
|
||||
return trans.fill_template( '/admin/dataset_security/role_create.mako',
|
||||
@@ -84,23 +79,21 @@ class Admin( BaseController ):
|
||||
trans.response.send_redirect( web.url_for( action='create_role', msg=msg, messagetype='error' ) )
|
||||
else:
|
||||
# Create the role
|
||||
role = galaxy.model.Role( name=name,
|
||||
description=description,
|
||||
type=trans.app.model.Role.types.ADMIN )
|
||||
role = trans.app.model.Role( name=name, description=description, type=trans.app.model.Role.types.ADMIN )
|
||||
role.flush()
|
||||
# Add the users
|
||||
users = util.listify( params.users )
|
||||
for user_id in users:
|
||||
user = galaxy.model.User.get( user_id )
|
||||
user = trans.app.model.User.get( user_id )
|
||||
# Create the UserRoleAssociation
|
||||
ura = galaxy.model.UserRoleAssociation( user, role )
|
||||
ura = trans.app.model.UserRoleAssociation( user, role )
|
||||
ura.flush()
|
||||
# Add the groups
|
||||
groups = util.listify( params.groups )
|
||||
for group_id in groups:
|
||||
group = galaxy.model.Group.get( group_id )
|
||||
group = trans.app.model.Group.get( group_id )
|
||||
# Create the GroupRoleAssociation
|
||||
gra = galaxy.model.GroupRoleAssociation( group, role )
|
||||
gra = trans.app.model.GroupRoleAssociation( group, role )
|
||||
gra.flush()
|
||||
msg = "The new role has been created with %s associated users and %s associated groups" % ( str( len( users ) ), str( len( groups ) ) )
|
||||
trans.response.send_redirect( web.url_for( action='roles', msg=msg, messagetype='done' ) )
|
||||
@@ -115,7 +108,7 @@ class Admin( BaseController ):
|
||||
out_users = []
|
||||
in_groups = []
|
||||
out_groups = []
|
||||
for user in trans.app.model.User.query().order_by( trans.app.model.User.table.c.email ).all():
|
||||
for user in trans.app.model.User.filter( trans.app.model.User.table.c.deleted==False ).order_by( trans.app.model.User.table.c.email ).all():
|
||||
if user in [ x.user for x in role.users ]:
|
||||
in_users.append( ( user.id, user.email ) )
|
||||
else:
|
||||
@@ -163,7 +156,7 @@ class Admin( BaseController ):
|
||||
@web.require_admin
|
||||
def role_members_edit( self, trans, **kwd ):
|
||||
params = util.Params( kwd )
|
||||
role = galaxy.model.Role.get( int( params.role_id ) )
|
||||
role = trans.app.model.Role.get( int( params.role_id ) )
|
||||
in_users = [ trans.app.model.User.get( x ) for x in util.listify( params.in_users ) ]
|
||||
for ura in role.users:
|
||||
user = trans.app.model.User.get( ura.user_id )
|
||||
@@ -188,7 +181,7 @@ class Admin( BaseController ):
|
||||
@web.require_admin
|
||||
def mark_role_deleted( self, trans, **kwd ):
|
||||
params = util.Params( kwd )
|
||||
role = galaxy.model.Role.get( int( params.role_id ) )
|
||||
role = trans.app.model.Role.get( int( params.role_id ) )
|
||||
role.deleted = True
|
||||
role.flush()
|
||||
msg = "The role has been marked as deleted."
|
||||
@@ -202,17 +195,17 @@ class Admin( BaseController ):
|
||||
# Build a list of tuples which are roles followed by lists of groups and users
|
||||
# [ ( role, [ group, group, group ], [ user, user ] ), ( role, [ group, group ], [ user ] ) ]
|
||||
roles_groups_users = []
|
||||
roles = galaxy.model.Role.query() \
|
||||
.filter( galaxy.model.Role.table.c.deleted==True ) \
|
||||
.order_by( galaxy.model.Role.table.c.name ) \
|
||||
roles = trans.app.model.Role.query() \
|
||||
.filter( trans.app.model.Role.table.c.deleted==True ) \
|
||||
.order_by( trans.app.model.Role.table.c.name ) \
|
||||
.all()
|
||||
for role in roles:
|
||||
groups = []
|
||||
for gra in role.groups:
|
||||
groups.append( galaxy.model.Group.get( gra.group_id ) )
|
||||
groups.append( trans.app.model.Group.get( gra.group_id ) )
|
||||
users = []
|
||||
for ura in role.users:
|
||||
users.append( galaxy.model.User.get( ura.user_id ) )
|
||||
users.append( trans.app.model.User.get( ura.user_id ) )
|
||||
roles_groups_users.append( ( role, groups, users ) )
|
||||
return trans.fill_template( '/admin/dataset_security/deleted_roles.mako',
|
||||
roles_groups_users=roles_groups_users,
|
||||
@@ -222,7 +215,7 @@ class Admin( BaseController ):
|
||||
@web.require_admin
|
||||
def undelete_role( self, trans, **kwd ):
|
||||
params = util.Params( kwd )
|
||||
role = galaxy.model.Role.get( int( params.role_id ) )
|
||||
role = trans.app.model.Role.get( int( params.role_id ) )
|
||||
role.deleted = False
|
||||
role.flush()
|
||||
msg = "The role has been marked as not deleted."
|
||||
@@ -230,8 +223,19 @@ class Admin( BaseController ):
|
||||
@web.expose
|
||||
@web.require_admin
|
||||
def purge_role( self, trans, **kwd ):
|
||||
# This method should only be called for a Role that has previously been deleted.
|
||||
# Purging a deleted Role deletes all of the following from the database:
|
||||
# - UserRoleAssociations where role_id == Role.id
|
||||
# - DefaultUserPermissions where role_id == Role.id
|
||||
# - DefaultHistoryPermissions where role_id == Role.id
|
||||
# - GroupRoleAssociations where role_id == Role.id
|
||||
# - ActionDatasetRoleAssociations where role_id == Role.id
|
||||
params = util.Params( kwd )
|
||||
role = galaxy.model.Role.get( int( params.role_id ) )
|
||||
role = trans.app.model.Role.get( int( params.role_id ) )
|
||||
if not role.deleted:
|
||||
# We should never reach here, but just in case there is a bug somewhere...
|
||||
msg = "The role has not been deleted, so it cannot be purged."
|
||||
trans.response.send_redirect( web.url_for( action='roles', msg=msg, messagetype='error' ) )
|
||||
# Delete UserRoleAssociations
|
||||
for ura in role.users:
|
||||
user = trans.app.model.User.get( ura.user_id )
|
||||
@@ -252,10 +256,12 @@ class Admin( BaseController ):
|
||||
for gra in role.groups:
|
||||
gra.delete()
|
||||
gra.flush()
|
||||
# Delete the Role
|
||||
role.delete()
|
||||
role.flush()
|
||||
msg = "The role has been purged from the database."
|
||||
# Delete ActionDatasetRoleAssociations
|
||||
for adra in role.actions:
|
||||
adra.delete()
|
||||
adra.flush()
|
||||
msg = "The following have been purged from the database for the role: "
|
||||
msg += "DefaultUserPermissions, DefaultHistoryPermissions, UserRoleAssociations, GroupRoleAssociations, ActionDatasetRoleAssociations."
|
||||
trans.response.send_redirect( web.url_for( action='deleted_roles', msg=msg, messagetype='done' ) )
|
||||
|
||||
# Galaxy Group Stuff
|
||||
@@ -268,17 +274,17 @@ class Admin( BaseController ):
|
||||
# Build a list of tuples which are groups followed by lists of members and roles
|
||||
# [ ( group, [ member, member, member ], [ role, role ] ), ( group, [ member, member ], [ role ] ) ]
|
||||
groups_members_roles = []
|
||||
groups = galaxy.model.Group.query() \
|
||||
.filter( galaxy.model.Group.table.c.deleted==False ) \
|
||||
.order_by( galaxy.model.Group.table.c.name ) \
|
||||
groups = trans.app.model.Group.query() \
|
||||
.filter( trans.app.model.Group.table.c.deleted==False ) \
|
||||
.order_by( trans.app.model.Group.table.c.name ) \
|
||||
.all()
|
||||
for group in groups:
|
||||
members = []
|
||||
for uga in group.members:
|
||||
members.append( galaxy.model.User.get( uga.user_id ) )
|
||||
members.append( trans.app.model.User.get( uga.user_id ) )
|
||||
roles = []
|
||||
for gra in group.roles:
|
||||
roles.append( galaxy.model.Role.get( gra.role_id ) )
|
||||
roles.append( trans.app.model.Role.get( gra.role_id ) )
|
||||
groups_members_roles.append( ( group, members, roles ) )
|
||||
return trans.fill_template( '/admin/dataset_security/groups.mako',
|
||||
groups_members_roles=groups_members_roles,
|
||||
@@ -290,10 +296,10 @@ class Admin( BaseController ):
|
||||
params = util.Params( kwd )
|
||||
msg = params.msg
|
||||
messagetype = params.get( 'messagetype', 'done' )
|
||||
users=trans.app.model.User.query().order_by( trans.app.model.User.table.c.email ).all()
|
||||
users = trans.app.model.User.filter( trans.app.model.User.table.c.deleted==False ).order_by( trans.app.model.User.table.c.email ).all()
|
||||
roles = trans.app.model.Role.query() \
|
||||
.filter( and_( galaxy.model.Role.table.c.deleted == False,
|
||||
galaxy.model.Role.table.c.type != trans.app.model.Role.types.PRIVATE ) ) \
|
||||
.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 ) \
|
||||
.all()
|
||||
return trans.fill_template( '/admin/dataset_security/group_create.mako',
|
||||
@@ -314,14 +320,14 @@ class Admin( BaseController ):
|
||||
trans.response.send_redirect( web.url_for( action='create_group', msg=msg, messagetype='error' ) )
|
||||
else:
|
||||
# Create the group
|
||||
group = galaxy.model.Group( name )
|
||||
group = trans.app.model.Group( name )
|
||||
group.flush()
|
||||
# Add the members
|
||||
members = util.listify( params.members )
|
||||
for user_id in members:
|
||||
user = galaxy.model.User.get( user_id )
|
||||
user = trans.app.model.User.get( user_id )
|
||||
# Create the UserGroupAssociation
|
||||
uga = galaxy.model.UserGroupAssociation( user, group )
|
||||
uga = trans.app.model.UserGroupAssociation( user, group )
|
||||
uga.flush()
|
||||
# Add the roles
|
||||
roles = params.roles
|
||||
@@ -330,9 +336,9 @@ class Admin( BaseController ):
|
||||
elif roles is None:
|
||||
roles = []
|
||||
for role_id in roles:
|
||||
role = galaxy.model.Role.get( role_id )
|
||||
role = trans.app.model.Role.get( role_id )
|
||||
# Create the GroupRoleAssociation
|
||||
gra = galaxy.model.GroupRoleAssociation( group, role )
|
||||
gra = trans.app.model.GroupRoleAssociation( group, role )
|
||||
gra.flush()
|
||||
msg = "The new group has been created with %s members and %s associated roles" % ( str( len( members ) ), str( len( roles ) ) )
|
||||
trans.response.send_redirect( web.url_for( action='groups', msg=msg, messagetype='done' ) )
|
||||
@@ -342,14 +348,15 @@ class Admin( BaseController ):
|
||||
params = util.Params( kwd )
|
||||
msg = params.msg
|
||||
messagetype = params.get( 'messagetype', 'done' )
|
||||
group = galaxy.model.Group.get( int( params.group_id ) )
|
||||
group = trans.app.model.Group.get( int( params.group_id ) )
|
||||
members = []
|
||||
for uga in group.members:
|
||||
members.append ( galaxy.model.User.get( uga.user_id ) )
|
||||
members.append ( trans.app.model.User.get( uga.user_id ) )
|
||||
users = trans.app.model.User.filter( trans.app.model.User.table.c.deleted==False ).order_by( trans.app.model.User.table.c.email ).all()
|
||||
return trans.fill_template( '/admin/dataset_security/group_members_edit.mako',
|
||||
group=group,
|
||||
members=members,
|
||||
users=galaxy.model.User.query().order_by( galaxy.model.User.table.c.email ).all(),
|
||||
users=users,
|
||||
msg=msg,
|
||||
messagetype=messagetype )
|
||||
@web.expose
|
||||
@@ -358,7 +365,7 @@ class Admin( BaseController ):
|
||||
params = util.Params( kwd )
|
||||
group_id = int( params.group_id )
|
||||
members = util.listify( params.members )
|
||||
group = galaxy.model.Group.get( group_id )
|
||||
group = trans.app.model.Group.get( group_id )
|
||||
# This is tricky since we have default association tables with
|
||||
# records referring to members of this group. Because of this,
|
||||
# we'll need to handle changes to the member list rather than the
|
||||
@@ -372,9 +379,9 @@ class Admin( BaseController ):
|
||||
uga.flush()
|
||||
# Then add all new members to the group
|
||||
for user_id in members:
|
||||
user = galaxy.model.User.get( user_id )
|
||||
user = trans.app.model.User.get( user_id )
|
||||
if user not in group.members:
|
||||
uga = galaxy.model.UserGroupAssociation( user, group )
|
||||
uga = trans.app.model.UserGroupAssociation( user, group )
|
||||
uga.flush()
|
||||
msg = "Group membership has been updated with a total of %s members" % len( members )
|
||||
trans.response.send_redirect( web.url_for( action='groups', msg=msg, messagetype='done' ) )
|
||||
@@ -386,14 +393,14 @@ class Admin( BaseController ):
|
||||
params = util.Params( kwd )
|
||||
msg = params.msg
|
||||
messagetype = params.get( 'messagetype', 'done' )
|
||||
group = galaxy.model.Group.get( int( params.group_id ) )
|
||||
group = trans.app.model.Group.get( int( params.group_id ) )
|
||||
group_roles = []
|
||||
for gra in group.roles:
|
||||
group_roles.append ( galaxy.model.Role.get( gra.role_id ) )
|
||||
group_roles.append ( trans.app.model.Role.get( gra.role_id ) )
|
||||
return trans.fill_template( '/admin/dataset_security/group_roles_edit.mako',
|
||||
group=group,
|
||||
group_roles=group_roles,
|
||||
roles=galaxy.model.Role.query().order_by( galaxy.model.Role.table.c.name ).all(),
|
||||
roles=trans.app.model.Role.query().order_by( trans.app.model.Role.table.c.name ).all(),
|
||||
msg=msg,
|
||||
messagetype=messagetype )
|
||||
@web.expose
|
||||
@@ -402,7 +409,7 @@ class Admin( BaseController ):
|
||||
params = util.Params( kwd )
|
||||
group_id = int( params.group_id )
|
||||
roles = util.listify( params.roles )
|
||||
group = galaxy.model.Group.get( group_id )
|
||||
group = trans.app.model.Group.get( group_id )
|
||||
# This is tricky since we have default association tables with
|
||||
# records referring to members of this group. Because of this,
|
||||
# we'll need to handle changes to the member list rather than the
|
||||
@@ -416,9 +423,9 @@ class Admin( BaseController ):
|
||||
gra.flush()
|
||||
# Then add all new roles to the group
|
||||
for role_id in roles:
|
||||
role = galaxy.model.Role.get( role_id )
|
||||
role = trans.app.model.Role.get( role_id )
|
||||
if role not in group.roles:
|
||||
gra = galaxy.model.GroupRoleAssociation( group, role )
|
||||
gra = trans.app.model.GroupRoleAssociation( group, role )
|
||||
gra.flush()
|
||||
msg = "Group updated with a total of %s associated roles" % len( roles )
|
||||
trans.response.send_redirect( web.url_for( action='groups', msg=msg, messagetype='done' ) )
|
||||
@@ -426,7 +433,7 @@ class Admin( BaseController ):
|
||||
@web.require_admin
|
||||
def mark_group_deleted( self, trans, **kwd ):
|
||||
params = util.Params( kwd )
|
||||
group = galaxy.model.Group.get( int( params.group_id ) )
|
||||
group = trans.app.model.Group.get( int( params.group_id ) )
|
||||
group.deleted = True
|
||||
group.flush()
|
||||
msg = "The group has been marked as deleted."
|
||||
@@ -440,17 +447,17 @@ class Admin( BaseController ):
|
||||
# Build a list of tuples which are groups followed by lists of members and roles
|
||||
# [ ( group, [ member, member, member ], [ role, role ] ), ( group, [ member, member ], [ role ] ) ]
|
||||
groups_members_roles = []
|
||||
groups = galaxy.model.Group.query() \
|
||||
.filter( galaxy.model.Group.table.c.deleted==True ) \
|
||||
.order_by( galaxy.model.Group.table.c.name ) \
|
||||
groups = trans.app.model.Group.query() \
|
||||
.filter( trans.app.model.Group.table.c.deleted==True ) \
|
||||
.order_by( trans.app.model.Group.table.c.name ) \
|
||||
.all()
|
||||
for group in groups:
|
||||
members = []
|
||||
for uga in group.members:
|
||||
members.append( galaxy.model.User.get( uga.user_id ) )
|
||||
members.append( trans.app.model.User.get( uga.user_id ) )
|
||||
roles = []
|
||||
for gra in group.roles:
|
||||
roles.append( galaxy.model.Role.get( gra.role_id ) )
|
||||
roles.append( trans.app.model.Role.get( gra.role_id ) )
|
||||
groups_members_roles.append( ( group, members, roles ) )
|
||||
return trans.fill_template( '/admin/dataset_security/deleted_groups.mako',
|
||||
groups_members_roles=groups_members_roles,
|
||||
@@ -460,7 +467,7 @@ class Admin( BaseController ):
|
||||
@web.require_admin
|
||||
def undelete_group( self, trans, **kwd ):
|
||||
params = util.Params( kwd )
|
||||
group = galaxy.model.Group.get( int( params.group_id ) )
|
||||
group = trans.app.model.Group.get( int( params.group_id ) )
|
||||
group.deleted = False
|
||||
group.flush()
|
||||
msg = "The group has been marked as not deleted."
|
||||
@@ -468,8 +475,14 @@ class Admin( BaseController ):
|
||||
@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 = galaxy.model.Group.get( int( params.group_id ) )
|
||||
group = trans.app.model.Group.get( int( params.group_id ) )
|
||||
if not group.deleted:
|
||||
# We should never reach here, but just in case there is a bug somewhere...
|
||||
msg = "The group has not been deleted, so it cannot be purged."
|
||||
trans.response.send_redirect( web.url_for( action='groups', msg=msg, messagetype='error' ) )
|
||||
# Delete UserGroupAssociations
|
||||
for uga in group.users:
|
||||
uga.delete()
|
||||
@@ -479,27 +492,40 @@ class Admin( BaseController ):
|
||||
gra.delete()
|
||||
gra.flush()
|
||||
# Delete the Group
|
||||
group.delete()
|
||||
group.flush()
|
||||
msg = "The group has been purged from the database."
|
||||
msg = "The following have been purged from the database for the group: UserGroupAssociations, GroupRoleAssociations."
|
||||
trans.response.send_redirect( web.url_for( action='deleted_groups', msg=msg, messagetype='done' ) )
|
||||
|
||||
# Galaxy User Stuff
|
||||
@web.expose
|
||||
@web.require_admin
|
||||
def create_new_user( self, trans, email='', password='', confirm='', subscribe=False ):
|
||||
email_error = password_error = confirm_error = None
|
||||
if email:
|
||||
def create_new_user( self, trans, **kwd ):
|
||||
params = util.Params( kwd )
|
||||
msg = params.msg
|
||||
email = ''
|
||||
password = ''
|
||||
confirm = ''
|
||||
subscribe = False
|
||||
messagetype = params.get( 'messagetype', 'done' )
|
||||
if 'user_create_button' in kwd:
|
||||
if 'email' in kwd:
|
||||
email = kwd[ 'email' ]
|
||||
if 'password' in kwd:
|
||||
password = kwd[ 'password' ]
|
||||
if 'confirm' in kwd:
|
||||
confirm = kwd[ 'confirm' ]
|
||||
if 'subscribe' in kwd:
|
||||
subscribe = kwd[ 'subscribe' ]
|
||||
messagetype = 'error'
|
||||
if len( email ) == 0 or "@" not in email or "." not in email:
|
||||
email_error = "Please enter a real email address"
|
||||
msg = "Please enter a real email address"
|
||||
elif len( email) > 255:
|
||||
email_error = "Email address exceeds maximum allowable length"
|
||||
elif trans.app.model.User.filter_by( email=email ).first():
|
||||
email_error = "User with that email already exists"
|
||||
msg = "Email address exceeds maximum allowable length"
|
||||
elif trans.app.model.User.filter( trans.app.model.User.table.c.email==email ).first():
|
||||
msg = "User with that email already exists"
|
||||
elif len( password ) < 6:
|
||||
password_error = "Please use a password of at least 6 characters"
|
||||
msg = "Please use a password of at least 6 characters"
|
||||
elif password != confirm:
|
||||
confirm_error = "Passwords do not match"
|
||||
msg = "Passwords do not match"
|
||||
else:
|
||||
user = trans.app.model.User( email=email )
|
||||
user.set_password_cleartext( password )
|
||||
@@ -507,25 +533,147 @@ class Admin( BaseController ):
|
||||
trans.app.security_agent.create_private_user_role( user )
|
||||
trans.app.security_agent.user_set_default_permissions( user, history=False, dataset=False )
|
||||
trans.log_event( "Admin created a new account for user %s" % email )
|
||||
msg = 'Created new account'
|
||||
msg = 'Created new user account'
|
||||
messagetype = 'done'
|
||||
#subscribe user to email list
|
||||
if subscribe:
|
||||
mail = os.popen( "%s -t" % trans.app.config.sendmail_path, 'w' )
|
||||
mail.write( "To: %s\nFrom: %s\nSubject: Join Mailing List\n\nJoin Mailing list." % ( trans.app.config.mailing_join_addr,email ) )
|
||||
mail.write( "To: %s\nFrom: %s\nSubject: Join Mailing List\n\nJoin Mailing list." % ( trans.app.config.mailing_join_addr, email ) )
|
||||
if mail.close():
|
||||
msg + ". However, subscribing to the mailing list has failed."
|
||||
messagetype = 'error'
|
||||
trans.response.send_redirect( web.url_for( action='users', msg=msg, messagetype=messagetype ) )
|
||||
# TODO: make this a mako template
|
||||
return trans.show_form(
|
||||
web.FormBuilder( web.url_for(), "Create account", submit_text="Create" )
|
||||
.add_text( "email", "Email address", value=email, error=email_error )
|
||||
.add_password( "password", "Password", value='', error=password_error )
|
||||
.add_password( "confirm", "Confirm password", value='', error=confirm_error )
|
||||
.add_input( "checkbox","Subscribe To Mailing List","subscribe", value='subscribe' ) )
|
||||
|
||||
|
||||
trans.response.send_redirect( web.url_for( action='users', msg=msg, messagetype=messagetype ) )
|
||||
return trans.fill_template( '/admin/user/create.mako',
|
||||
msg=msg,
|
||||
messagetype=messagetype,
|
||||
email=email,
|
||||
password=password,
|
||||
confirm=confirm,
|
||||
subscribe=subscribe )
|
||||
@web.expose
|
||||
@web.require_admin
|
||||
def reset_user_password( self, trans, **kwd ):
|
||||
params = util.Params( kwd )
|
||||
msg = params.msg
|
||||
user_id = int( params.user_id )
|
||||
user = trans.app.model.User.filter( trans.app.model.User.table.c.id==user_id ).first()
|
||||
password = ''
|
||||
confirm = ''
|
||||
messagetype = params.get( 'messagetype', 'done' )
|
||||
if 'reset_user_password_button' in kwd:
|
||||
if 'password' in kwd:
|
||||
password = kwd[ 'password' ]
|
||||
if 'confirm' in kwd:
|
||||
confirm = kwd[ 'confirm' ]
|
||||
messagetype = 'error'
|
||||
if len( password ) < 6:
|
||||
msg = "Please use a password of at least 6 characters"
|
||||
elif password != confirm:
|
||||
msg = "Passwords do not match"
|
||||
else:
|
||||
user.set_password_cleartext( password )
|
||||
user.flush()
|
||||
trans.log_event( "Admin reset password for user %s" % user.email )
|
||||
msg = 'Password reset'
|
||||
messagetype = 'done'
|
||||
trans.response.send_redirect( web.url_for( action='users', msg=msg, messagetype=messagetype ) )
|
||||
return trans.fill_template( '/admin/user/reset_password.mako',
|
||||
msg=msg,
|
||||
messagetype=messagetype,
|
||||
user=user,
|
||||
password=password,
|
||||
confirm=confirm )
|
||||
@web.expose
|
||||
@web.require_admin
|
||||
def mark_user_deleted( self, trans, **kwd ):
|
||||
params = util.Params( kwd )
|
||||
msg = params.msg
|
||||
messagetype = params.get( 'messagetype', 'done' )
|
||||
user = trans.app.model.User.get( int( params.user_id ) )
|
||||
user.deleted = True
|
||||
user.flush()
|
||||
msg = "The user has been marked as deleted."
|
||||
trans.response.send_redirect( web.url_for( action='users', msg=msg, messagetype='done' ) )
|
||||
@web.expose
|
||||
@web.require_admin
|
||||
def undelete_user( self, trans, **kwd ):
|
||||
params = util.Params( kwd )
|
||||
user = trans.app.model.User.get( int( params.user_id ) )
|
||||
user.deleted = False
|
||||
user.flush()
|
||||
msg = "The user has been marked as not deleted."
|
||||
trans.response.send_redirect( web.url_for( action='users', msg=msg, messagetype='done' ) )
|
||||
@web.expose
|
||||
@web.require_admin
|
||||
def purge_user( self, trans, **kwd ):
|
||||
# This method should only be called for a User that has previously been deleted.
|
||||
# We keep the User in the database ( marked as purged ), and stuff associated
|
||||
# with the user's private role in case we want the ability to unpurge the user
|
||||
# some time in the future.
|
||||
# Purging a deleted User deletes all of the following:
|
||||
# - DefaultUserPermissions where user_id == User.id EXCEPT FOR THE PRIVATE ROLE
|
||||
# - History where user_id = User.id
|
||||
# - DefaultHistoryPermissions where history_id == History.id EXCEPT FOR THE PRIVATE ROLE
|
||||
# - HistoryDatasetAssociation where history_id = History.id
|
||||
# - Dataset where HistoryDatasetAssociation.dataset_id = Dataset.id
|
||||
# - UserGroupAssociation where user_id == User.id
|
||||
# - UserRoleAssociation where user_id == User.id EXCEPT FOR THE PRIVATE ROLE
|
||||
# Purging Histories and Datasets must be handled via the cleanup_datasets.py script
|
||||
params = util.Params( kwd )
|
||||
user = trans.app.model.User.get( int( params.user_id ) )
|
||||
if not user.deleted:
|
||||
# We should never reach here, but just in case there is a bug somewhere...
|
||||
msg = "The account has not been deleted, so it cannot be purged."
|
||||
trans.response.send_redirect( web.url_for( action='users', msg=msg, messagetype='error' ) )
|
||||
private_role = trans.app.security_agent.get_private_user_role( user )
|
||||
# Delete DefaultUserPermissions EXCEPT FOR THE PRIVATE ROLE
|
||||
for dup in user.default_permissions:
|
||||
if dup.role_id != private_role.id:
|
||||
dup.delete()
|
||||
dup.flush()
|
||||
# Delete History
|
||||
for h in user.active_histories:
|
||||
h.refresh()
|
||||
# Delete DefaultHistoryPermissions EXCEPT FOR THE PRIVATE ROLE
|
||||
for dp in h.default_permissions:
|
||||
if dp.role_id != private_role.id:
|
||||
dp.delete()
|
||||
dp.flush()
|
||||
for hda in h.active_datasets:
|
||||
# Delete HistoryDatasetAssociation
|
||||
d = trans.app.model.Dataset.get( hda.dataset_id )
|
||||
# Delete Dataset
|
||||
if not d.deleted:
|
||||
d.deleted = True
|
||||
d.flush()
|
||||
hda.deleted = True
|
||||
hda.flush()
|
||||
h.deleted = True
|
||||
h.flush()
|
||||
# Delete UserGroupAssociations
|
||||
for uga in user.groups:
|
||||
uga.delete()
|
||||
uga.flush()
|
||||
# Delete UserRoleAssociations EXCEPT FOR THE PRIVATE ROLE
|
||||
for ura in user.roles:
|
||||
if ura.role_id != private_role.id:
|
||||
ura.delete()
|
||||
ura.flush()
|
||||
# Purge the user
|
||||
user.purged = True
|
||||
user.flush()
|
||||
msg = "The user has been marked as purged."
|
||||
trans.response.send_redirect( web.url_for( action='deleted_users', msg=msg, messagetype='done' ) )
|
||||
@web.expose
|
||||
@web.require_admin
|
||||
def deleted_users( self, trans, **kwd ):
|
||||
params = util.Params( kwd )
|
||||
msg = params.msg
|
||||
messagetype = params.get( 'messagetype', 'done' )
|
||||
users = trans.app.model.User.filter( and_( trans.app.model.User.table.c.deleted==True, trans.app.model.User.table.c.purged==False ) ) \
|
||||
.order_by( trans.app.model.User.table.c.email ) \
|
||||
.all()
|
||||
return trans.fill_template( '/admin/user/deleted_users.mako', users=users, msg=msg, messagetype=messagetype )
|
||||
@web.expose
|
||||
@web.require_admin
|
||||
def users( self, trans, **kwd ):
|
||||
@@ -535,24 +683,25 @@ class Admin( BaseController ):
|
||||
# Build a list of tuples which are users followed by lists of groups and roles
|
||||
# [ ( user, [ group, group, group ], [ role, role ] ), ( user, [ group, group ], [ role ] ) ]
|
||||
users_groups_roles = []
|
||||
users = trans.app.model.User.query().order_by( trans.app.model.User.table.c.email ).all()
|
||||
users = trans.app.model.User.filter( trans.app.model.User.table.c.deleted==False ).order_by( trans.app.model.User.table.c.email ).all()
|
||||
for user in users:
|
||||
groups = []
|
||||
for uga in user.groups:
|
||||
groups.append( galaxy.model.Group.get( uga.group_id ) )
|
||||
groups.append( trans.app.model.Group.get( uga.group_id ) )
|
||||
roles = []
|
||||
for ura in user.non_private_roles:
|
||||
roles.append( galaxy.model.Role.get( ura.role_id ) )
|
||||
roles.append( trans.app.model.Role.get( ura.role_id ) )
|
||||
users_groups_roles.append( ( user, groups, roles ) )
|
||||
return trans.fill_template( '/admin/dataset_security/users.mako',
|
||||
users_groups_roles=users_groups_roles,
|
||||
allow_user_deletion=trans.app.config.allow_user_deletion,
|
||||
msg=msg,
|
||||
messagetype=messagetype )
|
||||
@web.expose
|
||||
@web.require_admin
|
||||
def user( self, trans, **kwd ):
|
||||
params = util.Params( kwd )
|
||||
user_id = params.user_id
|
||||
user_id = int( params.user_id )
|
||||
msg = params.msg
|
||||
messagetype = params.get( 'messagetype', 'done' )
|
||||
user = trans.app.model.User.get( user_id )
|
||||
@@ -560,7 +709,7 @@ class Admin( BaseController ):
|
||||
groups = trans.app.model.Group.query() \
|
||||
.select_from( ( outerjoin( trans.app.model.Group, trans.app.model.UserGroupAssociation ) ) \
|
||||
.outerjoin( trans.app.model.User ) ) \
|
||||
.filter( and_( trans.app.model.Group.deleted == False, trans.app.model.User.id == user_id ) ) \
|
||||
.filter( and_( trans.app.model.Group.deleted==False, trans.app.model.User.id==user_id ) ) \
|
||||
.order_by( trans.app.model.Group.table.c.name ) \
|
||||
.all()
|
||||
roles = user.all_roles()
|
||||
@@ -576,13 +725,13 @@ class Admin( BaseController ):
|
||||
params = util.Params( kwd )
|
||||
msg = params.msg
|
||||
messagetype = params.get( 'messagetype', 'done' )
|
||||
user = galaxy.model.User.get( int( params.user_id ) )
|
||||
user = trans.app.model.User.get( int( params.user_id ) )
|
||||
user_groups = []
|
||||
for uga in user.groups:
|
||||
user_groups.append ( galaxy.model.Group.get( uga.group_id ) )
|
||||
groups = galaxy.model.Group.query() \
|
||||
.filter( galaxy.model.Group.table.c.deleted==False ) \
|
||||
.order_by( galaxy.model.Group.table.c.name ) \
|
||||
user_groups.append ( trans.app.model.Group.get( uga.group_id ) )
|
||||
groups = trans.app.model.Group.query() \
|
||||
.filter( trans.app.model.Group.table.c.deleted==False ) \
|
||||
.order_by( trans.app.model.Group.table.c.name ) \
|
||||
.all()
|
||||
return trans.fill_template( '/admin/dataset_security/user_groups_edit.mako',
|
||||
user=user,
|
||||
@@ -596,7 +745,7 @@ class Admin( BaseController ):
|
||||
params = util.Params( kwd )
|
||||
user_id = int( params.user_id )
|
||||
groups = util.listify( params.groups )
|
||||
user = galaxy.model.User.get( user_id )
|
||||
user = trans.app.model.User.get( user_id )
|
||||
# First remove existing UserGroupAssociations that are not in the received groups param
|
||||
for uga in user.groups:
|
||||
if uga.group_id not in groups:
|
||||
@@ -605,9 +754,9 @@ class Admin( BaseController ):
|
||||
uga.flush()
|
||||
# Then add all new groups to the user
|
||||
for group_id in groups:
|
||||
group = galaxy.model.Group.get( group_id )
|
||||
group = trans.app.model.Group.get( group_id )
|
||||
if group not in user.groups:
|
||||
uga = galaxy.model.UserGroupAssociation( user, group )
|
||||
uga = trans.app.model.UserGroupAssociation( user, group )
|
||||
uga.flush()
|
||||
msg = "The user now belongs to a total of %s groups" % len( groups )
|
||||
trans.response.send_redirect( web.url_for( action='users', msg=msg, messagetype='done' ) )
|
||||
@@ -713,7 +862,7 @@ class Admin( BaseController ):
|
||||
@web.require_admin
|
||||
def undelete_library( self, trans, **kwd ):
|
||||
params = util.Params( kwd )
|
||||
library = galaxy.model.Library.get( int( params.id ) )
|
||||
library = trans.app.model.Library.get( int( params.id ) )
|
||||
def undelete_folder( library_folder ):
|
||||
for folder in library_folder.folders:
|
||||
undelete_folder( folder )
|
||||
@@ -731,7 +880,7 @@ class Admin( BaseController ):
|
||||
@web.require_admin
|
||||
def purge_library( self, trans, **kwd ):
|
||||
params = util.Params( kwd )
|
||||
library = galaxy.model.Library.get( int( params.id ) )
|
||||
library = trans.app.model.Library.get( int( params.id ) )
|
||||
def purge_folder( library_folder ):
|
||||
for lf in library_folder.folders:
|
||||
purge_folder( lf )
|
||||
@@ -877,7 +1026,7 @@ class Admin( BaseController ):
|
||||
dataset.flush()
|
||||
if roles:
|
||||
for role in roles:
|
||||
adra = galaxy.model.ActionDatasetRoleAssociation( RBACAgent.permitted_actions.DATASET_ACCESS.action, dataset.dataset, role )
|
||||
adra = trans.app.model.ActionDatasetRoleAssociation( RBACAgent.permitted_actions.DATASET_ACCESS.action, dataset.dataset, role )
|
||||
adra.flush()
|
||||
shutil.move( temp_name, dataset.dataset.file_name )
|
||||
dataset.dataset.state = dataset.dataset.states.OK
|
||||
@@ -914,7 +1063,7 @@ class Admin( BaseController ):
|
||||
roles = []
|
||||
role_ids = params.get( 'roles', [] )
|
||||
for role_id in util.listify( role_ids ):
|
||||
roles.append( galaxy.model.Role.get( role_id ) )
|
||||
roles.append( trans.app.model.Role.get( role_id ) )
|
||||
temp_name = ""
|
||||
data_list = []
|
||||
created_lfda_ids = ''
|
||||
@@ -1139,7 +1288,8 @@ class Admin( BaseController ):
|
||||
msg = params.get( 'msg', None )
|
||||
messagetype = params.get( 'messagetype', 'done' )
|
||||
# See if the current history is empty
|
||||
history=trans.get_history()
|
||||
history = trans.get_history()
|
||||
history.refresh()
|
||||
if not history.active_datasets:
|
||||
msg = 'Your current history is empty'
|
||||
return trans.response.send_redirect( web.url_for( action='library_browser', msg=msg, messagetype='error' ) )
|
||||
|
||||
@@ -527,7 +527,7 @@ class RootController( BaseController ):
|
||||
if not email:
|
||||
return trans.fill_template("/history/share.mako", histories=histories, email=email, send_to_err=send_to_err)
|
||||
user = trans.get_user()
|
||||
send_to_user = trans.app.model.User.filter_by( email=email ).first()
|
||||
send_to_user = trans.app.model.User.filter( trans.app.model.User.table.c.email==email ).first()
|
||||
p = util.Params( kwd )
|
||||
if p.action and p.action == "no_share":
|
||||
trans.response.send_redirect( url_for( action='history_options' ) )
|
||||
|
||||
@@ -88,12 +88,13 @@ class User( BaseController ):
|
||||
else:
|
||||
refresh_frames = [ 'masthead', 'history' ]
|
||||
if email or password:
|
||||
user = trans.app.model.User.filter_by( email=email ).first()
|
||||
user = trans.app.model.User.filter( trans.app.model.User.table.c.email==email ).first()
|
||||
if not user:
|
||||
email_error = "No such user"
|
||||
elif user.deleted:
|
||||
email_error = "This account has been marked deleted, contact your Galaxy administrator to restore the account."
|
||||
elif user.external:
|
||||
return trans.show_error_message( "This account was created for use with an external authentication "
|
||||
+ "method. Please contact your local Galaxy administrator to activate it." )
|
||||
email_error = "This account was created for use with an external authentication method, contact your local Galaxy administrator to activate it."
|
||||
elif not user.check_password( password ):
|
||||
password_error = "Invalid password"
|
||||
else:
|
||||
@@ -118,9 +119,6 @@ class User( BaseController ):
|
||||
|
||||
@web.expose
|
||||
def logout( self, trans ):
|
||||
if trans.app.memory_usage:
|
||||
# Keep track of memory usage
|
||||
m0 = trans.app.memory_usage.memory()
|
||||
if trans.app.config.require_login:
|
||||
refresh_frames = [ 'masthead', 'history', 'tools' ]
|
||||
else:
|
||||
@@ -128,9 +126,6 @@ class User( BaseController ):
|
||||
# Since logging an event requires a session, we'll log prior to ending the session
|
||||
trans.log_event( "User logged out" )
|
||||
trans.handle_user_logout()
|
||||
if trans.app.memory_usage:
|
||||
m1 = trans.app.memory_usage.memory( m0, pretty=True )
|
||||
log.info( "End of user/logout, memory used increased by %s" % m1 )
|
||||
msg = "You are no longer logged in."
|
||||
if trans.app.config.require_login:
|
||||
msg += ' <a href="%s">Click here</a> to return to the login page.' % web.url_for( controller='user', action='login' )
|
||||
@@ -148,9 +143,10 @@ class User( BaseController ):
|
||||
if email:
|
||||
if len( email ) == 0 or "@" not in email or "." not in email:
|
||||
email_error = "Please enter a real email address"
|
||||
elif len( email) > 255:
|
||||
elif len( email ) > 255:
|
||||
email_error = "Email address exceeds maximum allowable length"
|
||||
elif trans.app.model.User.filter_by( email=email ).first():
|
||||
elif trans.app.model.User.filter( and_( trans.app.model.User.table.c.email==email,
|
||||
trans.app.model.User.table.c.deleted==False ) ).first():
|
||||
email_error = "User with that email already exists"
|
||||
elif len( password ) < 6:
|
||||
password_error = "Please use a password of at least 6 characters"
|
||||
@@ -182,11 +178,11 @@ class User( BaseController ):
|
||||
@web.expose
|
||||
def reset_password( self, trans, email=None, **kwd ):
|
||||
error = ''
|
||||
reset_user = trans.app.model.User.filter_by( email=email ).first()
|
||||
reset_user = trans.app.model.User.filter( trans.app.model.User.table.c.email==email ).first()
|
||||
user = trans.get_user()
|
||||
if reset_user:
|
||||
if user and user.id != reset_user.id:
|
||||
error = "You may only reset your own password"
|
||||
error = "You may only reset your own password"
|
||||
else:
|
||||
chars = string.letters + string.digits
|
||||
new_pass = ""
|
||||
|
||||
@@ -13,6 +13,7 @@ from galaxy.util.bunch import Bunch
|
||||
from galaxy.util.topsort import topsort, topsort_levels, CycleError
|
||||
from galaxy.workflow.modules import *
|
||||
from galaxy.model.mapping import desc
|
||||
from galaxy.model.orm import *
|
||||
|
||||
class WorkflowController( BaseController ):
|
||||
|
||||
@@ -48,7 +49,8 @@ class WorkflowController( BaseController ):
|
||||
# Load workflow from database
|
||||
stored = get_stored_workflow( trans, id )
|
||||
if email:
|
||||
other = model.User.filter_by( email=email ).first()
|
||||
other = model.User.filter( and_( model.user.table.c.email==email,
|
||||
model.User.table.c.deleted==False ) ).first()
|
||||
if not other:
|
||||
mtype = "error"
|
||||
msg = ( "User '%s' does not exist" % email )
|
||||
|
||||
@@ -221,8 +221,7 @@ class UniverseWebTransaction( base.DefaultWebTransaction ):
|
||||
galaxy_session.user = self.__get_or_create_remote_user( remote_user_email )
|
||||
galaxy_session_requires_flush = True
|
||||
elif galaxy_session.user.email != remote_user_email:
|
||||
# Session exists but is not associated with the correct
|
||||
# remote user
|
||||
# Session exists but is not associated with the correct remote user
|
||||
invalidate_existing_session = True
|
||||
user_for_new_session = self.__get_or_create_remote_user( remote_user_email )
|
||||
log.warning( "User logged in as '%s' externally, but has a cookie as '%s' invalidating session",
|
||||
@@ -293,16 +292,27 @@ class UniverseWebTransaction( base.DefaultWebTransaction ):
|
||||
def __get_or_create_remote_user( self, remote_user_email ):
|
||||
"""
|
||||
Return the user in $HTTP_REMOTE_USER and create if necessary
|
||||
|
||||
Caller is responsible for flushing the returned user.
|
||||
"""
|
||||
# remote_user middleware ensures HTTP_REMOTE_USER exists
|
||||
user = self.app.model.User.filter_by( email=remote_user_email ).first()
|
||||
user = self.app.model.User.filter( self.app.model.User.table.c.email==remote_user_email ).first()
|
||||
if user is None:
|
||||
user = self.app.model.User( email=remote_user_email )
|
||||
user.set_password_cleartext( 'external' )
|
||||
user.external = True
|
||||
self.log_event( "Automatically created account '%s'", user.email )
|
||||
# TODO: make sure this correctly handles deleted / purged users
|
||||
elif user.deleted:
|
||||
if user.purged:
|
||||
# If the user has been purged, all associations have been deleted except for the private role
|
||||
# and the DefaultUserPermissions and DefaultHistoryPermissions associated with it. We'll
|
||||
# restore the user, but all of their previous histories and other associations will have been
|
||||
# deleted.
|
||||
user.purged = False
|
||||
# If the user was not purged, the state of all of their associations at the time they were deleted
|
||||
# will have been preserved.
|
||||
user.deleted = False
|
||||
user.flush()
|
||||
return user
|
||||
def __update_session_cookie( self ):
|
||||
"""
|
||||
|
||||
@@ -16,7 +16,11 @@
|
||||
<a href="${h.url_for( controller='admin', action='user', user_id=user.id )}">${user.email}</a>
|
||||
<a id="user-${user.id}-popup" class="popup-arrow" style="display: none;">▼</a>
|
||||
<div popupmenu="user-${user.id}-popup">
|
||||
<a class="action-button" href="${h.url_for( action='reset_user_password', user_id=user.id )}">Reset password</a>
|
||||
<a class="action-button" href="${h.url_for( action='user_groups_edit', user_id=user.id )}">Change associated groups</a>
|
||||
%if allow_user_deletion:
|
||||
<a class="action-button" href="${h.url_for( action='mark_user_deleted', user_id=user.id )}">Mark user deleted</a>
|
||||
%endif
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
@@ -44,6 +48,9 @@
|
||||
|
||||
<ul class="manage-table-actions">
|
||||
<li><a class="action-button" href="${h.url_for( controller='admin', action='create_new_user' )}">Create a new user</a></li>
|
||||
%if allow_user_deletion:
|
||||
<li><a class="action-button" href="${h.url_for( controller='admin', action='deleted_users' )}">Manage deleted users</a></li>
|
||||
%endif
|
||||
</ul>
|
||||
|
||||
%if msg:
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
<a class="action-button" href="${h.url_for( action='folder', new=True, id=parent.id )}">Create a new sub-folder in this folder</a>
|
||||
<a class="action-button" href="${h.url_for( action='folder', rename=True, id=parent.id )}">Rename this folder</a>
|
||||
%if subfolder:
|
||||
<a class="action-button" confirm="Click OK to delete the folder '${parent.name}'?" href="${h.url_for( action='folder', delete=True, id=parent.id )}">Remove this folder and its contents from the library</a>
|
||||
<a class="action-button" confirm="Click OK to delete the folder '${parent.name}'" href="${h.url_for( action='folder', delete=True, id=parent.id )}">Remove this folder and its contents from the library</a>
|
||||
%endif
|
||||
</div>
|
||||
%endif
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
<%namespace file="/message.mako" import="render_msg" />
|
||||
|
||||
%if msg:
|
||||
${render_msg( msg, messagetype )}
|
||||
%endif
|
||||
|
||||
<div class="toolForm">
|
||||
<div class="toolFormTitle">Create account</div>
|
||||
<div class="toolFormBody">
|
||||
<form name="form" action="/admin/create_new_user" method="post" >
|
||||
<div class="form-row">
|
||||
<label>Email address:</label>
|
||||
<div style="float: left; width: 250px; margin-right: 10px;">
|
||||
<input type="text" name="email" value="${email}" size="40">
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Password:</label>
|
||||
<div style="float: left; width: 250px; margin-right: 10px;">
|
||||
<input type="password" name="password" value="${password}" size="40">
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Confirm password:</label>
|
||||
<div style="float: left; width: 250px; margin-right: 10px;">
|
||||
<input type="password" name="confirm" value="${confirm}" size="40">
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Subscribe To Mailing List:</label>
|
||||
<div style="float: left; width: 250px; margin-right: 10px;">
|
||||
<input type="checkbox" name="subscribe" value="${subscribe}" size="40">
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<input type="submit" name="user_create_button" value="Create">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,91 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
<%namespace file="/message.mako" import="render_msg" />
|
||||
|
||||
## Render a row
|
||||
<%def name="render_row( user, ctr, anchored, curr_anchor )">
|
||||
%if ctr % 2 == 1:
|
||||
<tr class="odd_row">
|
||||
%else:
|
||||
<tr>
|
||||
%endif
|
||||
<td>
|
||||
${user.email}
|
||||
<a id="user-${user.id}-popup" class="popup-arrow" style="display: none;">▼</a>
|
||||
<div popupmenu="user-${user.id}-popup">
|
||||
<a class="action-button" href="${h.url_for( controller="admin", action='undelete_user', user_id=user.id )}">Undelete</a>
|
||||
<a class="action-button" confirm="Purging a user will delete all of their histories, datasets, and group and role associations. Click OK to purge the user '${user.email}'" href="${h.url_for( controller="admin", action='purge_user', user_id=user.id )}">Purge</a>
|
||||
</div>
|
||||
%if not anchored:
|
||||
<a name="${curr_anchor}"></a>
|
||||
<div style="float: right;"><a href="#TOP">top</a></div>
|
||||
%endif
|
||||
</td>
|
||||
</tr>
|
||||
</%def>
|
||||
|
||||
<a name="TOP"><h2>Deleted Users</h2></a>
|
||||
|
||||
%if msg:
|
||||
${render_msg( msg, messagetype )}
|
||||
%endif
|
||||
|
||||
%if len( users ) == 0:
|
||||
There are no deleted Galaxy users
|
||||
%else:
|
||||
<table class="manage-table colored" border="0" cellspacing="0" cellpadding="0" width="100%">
|
||||
<%
|
||||
render_quick_find = len( users ) > 50
|
||||
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'
|
||||
%>
|
||||
<tr style="background: #EEE">
|
||||
<td colspan="3" style="text-align: center; border-bottom: 1px solid #D8B365">
|
||||
Jump to letter:
|
||||
%for a in anchors:
|
||||
| <a href="#${a}">${a}</a>
|
||||
%endfor
|
||||
</td>
|
||||
</tr>
|
||||
%endif
|
||||
<tr class="header">
|
||||
<td>Email</td>
|
||||
</tr>
|
||||
%for ctr, user in enumerate( users ):
|
||||
%if render_quick_find and not user.email.upper().startswith( curr_anchor ):
|
||||
<% anchored = False %>
|
||||
%endif
|
||||
%if render_quick_find and user.email.upper().startswith( curr_anchor ):
|
||||
%if not anchored:
|
||||
${render_row( user, ctr, anchored, curr_anchor )}
|
||||
<% anchored = True %>
|
||||
%else:
|
||||
${render_row( user, ctr, anchored, curr_anchor )}
|
||||
%endif
|
||||
%elif render_quick_find:
|
||||
%for anchor in anchors[ anchor_loc: ]:
|
||||
%if user.email.upper().startswith( anchor ):
|
||||
%if not anchored:
|
||||
<% curr_anchor = anchor %>
|
||||
${render_row( user, ctr, anchored, curr_anchor )}
|
||||
<% anchored = True %>
|
||||
%else:
|
||||
${render_row( user, ctr, anchored, curr_anchor )}
|
||||
%endif
|
||||
<%
|
||||
anchor_loc = anchors.index( anchor )
|
||||
break
|
||||
%>
|
||||
%endif
|
||||
%endfor
|
||||
%else:
|
||||
${render_row( user, ctr, True, '' )}
|
||||
%endif
|
||||
%endfor
|
||||
</table>
|
||||
%endif
|
||||
@@ -0,0 +1,35 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
<%namespace file="/message.mako" import="render_msg" />
|
||||
|
||||
%if msg:
|
||||
${render_msg( msg, messagetype )}
|
||||
%endif
|
||||
|
||||
<div class="toolForm">
|
||||
<div class="toolFormTitle">Reset user password</div>
|
||||
<div class="toolFormBody">
|
||||
<form name="form" action="/admin/reset_user_password" method="post" >
|
||||
<input type="hidden" name="user_id" value="${user.id}" size="40">
|
||||
<div class="form-row">
|
||||
<label>Email address:</label>
|
||||
${user.email}
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Password:</label>
|
||||
<div style="float: left; width: 250px; margin-right: 10px;">
|
||||
<input type="password" name="password" value="${password}" size="40">
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<label>Confirm password:</label>
|
||||
<div style="float: left; width: 250px; margin-right: 10px;">
|
||||
<input type="password" name="confirm" value="${confirm}" size="40">
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
</div>
|
||||
<input type="submit" name="reset_user_password_button" value="Reset">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
+71
-44
@@ -362,16 +362,13 @@ class TwillTestCase( unittest.TestCase ):
|
||||
self.assertTrue( genome_build == dbkey )
|
||||
|
||||
# Functions associated with user accounts
|
||||
def create( self, email='test@bx.psu.edu', password='testuser', confirm='testuser' ):
|
||||
self.visit_page( "user/create?email=%s&password=%s&confirm=%s" %(email, password, confirm) )
|
||||
try:
|
||||
self.check_page_for_string( "User with that email already exists" )
|
||||
except:
|
||||
self.check_page_for_string( "Now logged in as %s" %email )
|
||||
self.home()
|
||||
# Make sure a new private role was created for the user
|
||||
self.visit_page( "user/set_default_permissions" )
|
||||
self.check_page_for_string( email )
|
||||
def create( self, email='test@bx.psu.edu', password='testuser' ):
|
||||
self.visit_page( "user/create?email=%s&password=%s&confirm=%s" % ( email, password, password ) )
|
||||
self.check_page_for_string( "Now logged in as %s" %email )
|
||||
self.home()
|
||||
# Make sure a new private role was created for the user
|
||||
self.visit_page( "user/set_default_permissions" )
|
||||
self.check_page_for_string( email )
|
||||
self.home()
|
||||
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
|
||||
@@ -405,14 +402,19 @@ class TwillTestCase( unittest.TestCase ):
|
||||
self.last_page()
|
||||
self.check_page_for_string( 'Default history permissions have been changed.' )
|
||||
self.home()
|
||||
def login( self, email='test@bx.psu.edu', password='testuser'):
|
||||
def login( self, email='test@bx.psu.edu', password='testuser' ):
|
||||
# test@bx.psu.edu is configured as an admin user
|
||||
self.create( email=email, password=password, confirm=password )
|
||||
self.visit_page( "user/login?email=%s&password=%s" % (email, password) )
|
||||
self.check_page_for_string( "Now logged in as %s" %email )
|
||||
self.home()
|
||||
try:
|
||||
self.create( email=email, password=password )
|
||||
except:
|
||||
self.home()
|
||||
self.visit_page( "user/login?email=%s&password=%s" % ( email, password ) )
|
||||
self.last_page()
|
||||
self.check_page_for_string( "Now logged in as %s" %email )
|
||||
self.home()
|
||||
def logout( self ):
|
||||
self.visit_page( "user/logout" )
|
||||
self.last_page()
|
||||
self.check_page_for_string( "You are no longer logged in" )
|
||||
self.home()
|
||||
# Functions associated with browsers, cookies, HTML forms and page visits
|
||||
@@ -581,7 +583,41 @@ class TwillTestCase( unittest.TestCase ):
|
||||
self.assertNotEqual(count, maxiter)
|
||||
|
||||
# Dataset Security stuff
|
||||
def create_role( self, name='New Test Role', description="Very cool new test role", user_ids=[], group_ids=[], private_role='' ):
|
||||
def create_new_account_as_admin( self, email='test4@bx.psu.edu', password='testuser' ):
|
||||
"""Create a new account for another user"""
|
||||
self.visit_url( "%s/admin/create_new_user?email=%s&password=%s&confirm=%s&user_create_button=%s" \
|
||||
% ( self.url, email, password, password, 'Create' ) )
|
||||
self.last_page()
|
||||
self.check_page_for_string( "Created new user account" )
|
||||
self.home()
|
||||
def reset_password_as_admin( self, user_id=4, password='testreset' ):
|
||||
"""Reset a user password"""
|
||||
self.visit_url( "%s/admin/reset_user_password?user_id=%s" % ( self.url, str( user_id ) ) )
|
||||
tc.fv( "1", "password", password )
|
||||
tc.fv( "1", "confirm", password )
|
||||
tc.submit( "reset_user_password_button" )
|
||||
self.last_page()
|
||||
self.check_page_for_string( "Password reset" )
|
||||
self.home()
|
||||
def mark_user_deleted( self, user_id=4 ):
|
||||
"""Mark a user as deleted"""
|
||||
self.visit_url( "%s/admin/mark_user_deleted?user_id=%s" % ( self.url, str( user_id ) ) )
|
||||
self.last_page()
|
||||
self.check_page_for_string( "The user has been marked as deleted." )
|
||||
self.home()
|
||||
def undelete_user( self, user_id ):
|
||||
"""Undelete a user"""
|
||||
self.visit_url( "%s/admin/undelete_user?user_id=%s" % ( self.url, user_id ) )
|
||||
self.last_page()
|
||||
self.check_page_for_string( 'The user has been marked as not deleted' )
|
||||
self.home()
|
||||
def purge_user( self, user_id ):
|
||||
"""Purge a user account"""
|
||||
self.visit_url( "%s/admin/purge_user?user_id=%s" % ( self.url, user_id ) )
|
||||
self.last_page()
|
||||
self.check_page_for_string( 'The user has been marked as purged.' )
|
||||
self.home()
|
||||
def create_role( self, name='Role One', description="This is Role One", user_ids=[], group_ids=[], private_role='' ):
|
||||
"""Create a new role"""
|
||||
self.visit_url( "%s/admin/create_role" % self.url )
|
||||
form = tc.show()
|
||||
@@ -632,15 +668,15 @@ class TwillTestCase( unittest.TestCase ):
|
||||
self.last_page()
|
||||
self.check_page_for_string( 'The role has been marked as not deleted' )
|
||||
self.home()
|
||||
def purge_role( self, role_id, deleted=False ):
|
||||
def purge_role( self, role_id ):
|
||||
"""Purge an existing role"""
|
||||
if not deleted:
|
||||
self.mark_role_deleted( role_id )
|
||||
self.visit_url( "%s/admin/purge_role?role_id=%s" % ( self.url, role_id ) )
|
||||
self.last_page()
|
||||
self.check_page_for_string( 'The role has been purged from the database' )
|
||||
msg = "The following have been purged from the database for the role: "
|
||||
msg += "DefaultUserPermissions, DefaultHistoryPermissions, UserRoleAssociations, GroupRoleAssociations, ActionDatasetRoleAssociations."
|
||||
self.check_page_for_string( msg )
|
||||
self.home()
|
||||
def create_group( self, name='New Test Group', user_ids=[], role_ids=[] ):
|
||||
def create_group( self, name='Group One', user_ids=[], role_ids=[] ):
|
||||
"""Create a new group with 2 members and 1 associated role"""
|
||||
self.visit_url( "%s/admin/create_group" % self.url )
|
||||
form = tc.show()
|
||||
@@ -685,23 +721,17 @@ class TwillTestCase( unittest.TestCase ):
|
||||
self.home()
|
||||
raise AssertionError( 'Exception caught attempting to create group: %s' % str( err ) )
|
||||
self.home()
|
||||
def associate_groups_with_role( self, role_id, group_ids=[] ):
|
||||
def associate_groups_with_role( self, role_id, group_names=[] ):
|
||||
"""Add groups to an existing role"""
|
||||
# NOTE: To get this to work with twill, all select lists must contain at least 1 option value
|
||||
# or twill throws an exception, which is: ParseError: OPTION outside of SELECT
|
||||
# before tc.submit or twill throws an exception, which is: ParseError: OPTION outside of SELECT
|
||||
self.visit_url( "%s/admin/role?role_id=%s" % ( self.url, role_id ) )
|
||||
self.check_page_for_string( 'Groups associated with' )
|
||||
# All groups must be in the out_groups form field
|
||||
try:
|
||||
for group in groups:
|
||||
tc.fv( "1", "7", group_id ) # form field 7 is the select list named out_groups, note the buttons...
|
||||
tc.submit( "groups_add_button" )
|
||||
tc.submit( "role_button" )
|
||||
except AssertionError, err:
|
||||
self.home()
|
||||
raise AssertionError( 'Exception caught attempting to associated groups with a role: %s' % str( err ) )
|
||||
except:
|
||||
pass
|
||||
# All group_ids passed in MUST be in the out_groups form field
|
||||
for group_name in group_names:
|
||||
tc.fv( "1", "out_groups", group_name ) # note the buttons...
|
||||
tc.submit( "groups_add_button" )
|
||||
tc.submit( "role_button" )
|
||||
self.home()
|
||||
def mark_group_deleted( self, group_id ):
|
||||
"""Mark a group as deleted"""
|
||||
@@ -715,17 +745,15 @@ class TwillTestCase( unittest.TestCase ):
|
||||
self.last_page()
|
||||
self.check_page_for_string( 'The group has been marked as not deleted' )
|
||||
self.home()
|
||||
def purge_group( self, group_id, deleted=False ):
|
||||
def purge_group( self, group_id ):
|
||||
"""Purge an existing group"""
|
||||
if not deleted:
|
||||
self.mark_group_deleted( group_id )
|
||||
self.visit_url( "%s/admin/purge_group?group_id=%s" % ( self.url, group_id ) )
|
||||
self.last_page()
|
||||
self.check_page_for_string( 'The group has been purged from the database' )
|
||||
self.check_page_for_string( "The following have been purged from the database for the group: UserGroupAssociations, GroupRoleAssociations." )
|
||||
self.home()
|
||||
|
||||
# Library stuff
|
||||
def create_library( self, name='New Test Library', description='New Test Library Description' ):
|
||||
def create_library( self, name='Library One', description='This is Library One' ):
|
||||
"""Create a new library"""
|
||||
try:
|
||||
self.visit_url( "%s/admin/library?new=True" % self.url )
|
||||
@@ -738,7 +766,7 @@ class TwillTestCase( unittest.TestCase ):
|
||||
self.home()
|
||||
raise AssertionError( 'Exception caught attempting to create library: %s' % str( err ) )
|
||||
self.home()
|
||||
def rename_library( self, library_id, name='New Test Library Renamed', description='New Test Library Description Re-described', root_folder='' ):
|
||||
def rename_library( self, library_id, name='Library One Renamed', description='This is Library One Re-described', root_folder='' ):
|
||||
"""Rename a library"""
|
||||
try:
|
||||
self.visit_url( "%s/admin/library?rename=True&id=%s" % ( self.url, library_id ) )
|
||||
@@ -759,7 +787,7 @@ class TwillTestCase( unittest.TestCase ):
|
||||
self.home()
|
||||
raise AssertionError( 'Exception caught attempting to rename a library: %s' % str( err ) )
|
||||
self.home()
|
||||
def add_folder( self, folder_id, name='New Test Folder', description='New Test Folder Description' ):
|
||||
def add_folder( self, folder_id, name='Folder One', description='NThis is Folder One' ):
|
||||
"""Create a new folder"""
|
||||
try:
|
||||
self.visit_url( "%s/admin/folder?id=%s&new=True" % ( self.url, folder_id ) )
|
||||
@@ -772,7 +800,7 @@ class TwillTestCase( unittest.TestCase ):
|
||||
self.home()
|
||||
raise AssertionError( 'Exception caught attempting to create a new folder: %s' % str( err ) )
|
||||
self.home()
|
||||
def rename_folder( self, folder_id, name='New Test Folder Renamed', description='New Test Folder Description Re-described' ):
|
||||
def rename_folder( self, folder_id, name='Folder One Renamed', description='This is Folder One Re-described' ):
|
||||
"""Rename a Folder"""
|
||||
try:
|
||||
self.visit_url( "%s/admin/folder?rename=True&id=%s" % ( self.url, folder_id ) )
|
||||
@@ -811,7 +839,6 @@ class TwillTestCase( unittest.TestCase ):
|
||||
# Create a new history
|
||||
self.new_history()
|
||||
self.upload_file( "1.bed" )
|
||||
self.verify_dataset_correctness( "1.bed" )
|
||||
self.visit_url( "%s/admin/add_dataset_to_folder_from_history?folder_id=%s" % ( self.url, folder_id ) )
|
||||
self.last_page()
|
||||
self.check_page_for_string( 'Active datasets in your current history' )
|
||||
@@ -822,7 +849,7 @@ class TwillTestCase( unittest.TestCase ):
|
||||
self.check_page_for_string( 'Added the following datasets to the library folder: 1.bed' )
|
||||
except AssertionError, err:
|
||||
self.home()
|
||||
raise AssertionError( 'Exception caught attempting to create add a dataset to a folder: %s' % str( err ) )
|
||||
raise AssertionError( 'Exception caught attempting to add a dataset to a folder: %s' % str( err ) )
|
||||
self.home()
|
||||
def add_datasets_from_library_dir( self, folder_id, extension='auto', dbkey='hg18', roles_tuple=[] ):
|
||||
"""Add a directory of datasets to a folder"""
|
||||
|
||||
@@ -37,7 +37,6 @@ def setup():
|
||||
galaxy_test_port = os.environ.get( 'GALAXY_TEST_PORT', default_galaxy_test_port )
|
||||
|
||||
start_server = 'GALAXY_TEST_EXTERNAL' not in os.environ
|
||||
|
||||
if start_server:
|
||||
if 'GALAXY_TEST_DBPATH' in os.environ:
|
||||
db_path = os.environ['GALAXY_TEST_DBPATH']
|
||||
@@ -73,10 +72,12 @@ def setup():
|
||||
tool_path = "tools",
|
||||
test_conf = "test.conf",
|
||||
log_destination = "stdout",
|
||||
use_heartbeat=False,
|
||||
use_heartbeat = False,
|
||||
allow_user_creation = True,
|
||||
allow_user_deletion = True,
|
||||
admin_users = 'test@bx.psu.edu',
|
||||
library_import_dir = galaxy_test_file_dir,
|
||||
global_conf= { "__file__": "universe_wsgi.ini.sample" } )
|
||||
global_conf = { "__file__": "universe_wsgi.ini.sample" } )
|
||||
|
||||
log.info( "Embedded Universe application started" )
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import sys
|
||||
import galaxy.model
|
||||
from galaxy.model.orm import *
|
||||
from base.twilltestcase import *
|
||||
@@ -6,7 +5,7 @@ from base.twilltestcase import *
|
||||
not_logged_in_security_msg = 'You must be logged in as an administrator to access this feature.'
|
||||
logged_in_security_msg = 'You must be an administrator to access this feature.'
|
||||
|
||||
class TestHistory( TwillTestCase ):
|
||||
class TestSecurityAndLibraries( TwillTestCase ):
|
||||
def test_00_admin_features_when_not_logged_in( self ):
|
||||
"""Testing admin_features when not logged in"""
|
||||
self.logout()
|
||||
@@ -113,9 +112,11 @@ class TestHistory( TwillTestCase ):
|
||||
self.new_history()
|
||||
latest_history = galaxy.model.History.query().order_by( desc( galaxy.model.History.table.c.create_time ) ).first()
|
||||
if not latest_history.default_permissions:
|
||||
raise AssertionError( 'No DefaultHistoryPermissions were created for history id %d when DefaultHistoryPermissions were changed' % latest_history.id )
|
||||
raise AssertionError( 'No DefaultHistoryPermissions were created for history id %d when DefaultHistoryPermissions were changed' % \
|
||||
latest_history.id )
|
||||
if len( latest_history.default_permissions ) != len( galaxy.model.Dataset.permitted_actions.items() ):
|
||||
raise AssertionError( '%d DefaultHistoryPermissions were created for history id %d, should have been %d' % ( len( latest_history.default_permissions ), latest_history.id, len( galaxy.model.Dataset.permitted_actions ) ) )
|
||||
raise AssertionError( '%d DefaultHistoryPermissions were created for history id %d, should have been %d' % \
|
||||
( len( latest_history.default_permissions ), latest_history.id, len( galaxy.model.Dataset.permitted_actions ) ) )
|
||||
dhps = []
|
||||
for dhp in latest_history.default_permissions:
|
||||
dhps.append( dhp.action )
|
||||
@@ -131,7 +132,8 @@ class TestHistory( TwillTestCase ):
|
||||
if not latest_dataset.actions:
|
||||
raise AssertionError( 'No ActionDatasetRoleAssociations were created for dataset id %d when it was created' % latest_dataset.id )
|
||||
if len( latest_dataset.actions ) != len( latest_history.default_permissions ):
|
||||
raise AssertionError( '%d ActionDatasetRoleAssociations were created for dataset id %d when it was created ( should have been %d )' % ( len( latest_dataset.actions ), latest_dataset.id, len( latest_history.default_permissions ) ) )
|
||||
raise AssertionError( '%d ActionDatasetRoleAssociations were created for dataset id %d when it was created ( should have been %d )' % \
|
||||
( len( latest_dataset.actions ), latest_dataset.id, len( latest_history.default_permissions ) ) )
|
||||
adras = []
|
||||
for adra in latest_dataset.actions:
|
||||
adras.append( adra.action )
|
||||
@@ -171,7 +173,8 @@ class TestHistory( TwillTestCase ):
|
||||
# Change DefaultHistoryPermissions for the current history
|
||||
self.history_set_default_permissions( permissions_out=permissions_out, permissions_in=permissions_in, role_id=role_id )
|
||||
if not latest_history.default_permissions:
|
||||
raise AssertionError( 'No DefaultHistoryPermissions were created for history id %d when DefaultHistoryPermissions were changed' % latest_history.id )
|
||||
raise AssertionError( 'No DefaultHistoryPermissions were created for history id %d when DefaultHistoryPermissions were changed' % \
|
||||
latest_history.id )
|
||||
if len( latest_history.default_permissions ) != len( actions_in ):
|
||||
raise AssertionError( '%d DefaultHistoryPermissions were created for history id %d, should have been %d' \
|
||||
% ( len( latest_history.default_permissions ), latest_history.id, len( permissions_in ) ) )
|
||||
@@ -189,7 +192,8 @@ class TestHistory( TwillTestCase ):
|
||||
if not latest_dataset.actions:
|
||||
raise AssertionError( 'No ActionDatasetRoleAssociations were created for dataset id %d when it was created' % latest_dataset.id )
|
||||
if len( latest_dataset.actions ) != len( latest_history.default_permissions ):
|
||||
raise AssertionError( '%d ActionDatasetRoleAssociations were created for dataset id %d when it was created ( should have been %d )' % ( len( latest_dataset.actions ), latest_dataset.id, len( latest_history.default_permissions ) ) )
|
||||
raise AssertionError( '%d ActionDatasetRoleAssociations were created for dataset id %d when it was created ( should have been %d )' \
|
||||
% ( len( latest_dataset.actions ), latest_dataset.id, len( latest_history.default_permissions ) ) )
|
||||
adras = []
|
||||
for adra in latest_dataset.actions:
|
||||
adras.append( adra.action )
|
||||
@@ -197,55 +201,201 @@ class TestHistory( TwillTestCase ):
|
||||
adras.sort()
|
||||
self.home()
|
||||
self.logout()
|
||||
def test_12_create_role( self ):
|
||||
"""Testing creating new non-private role with 2 members"""
|
||||
self.login( email=testuser1.email )
|
||||
name = 'New Test Role'
|
||||
description = 'Very cool new test role'
|
||||
self.create_role( name=name, description=description, user_ids=[ str( testuser1.id ), str( testuser2.id ) ], private_role=testuser1.email )
|
||||
def test_12_create_new_user_account_as_admin( self ):
|
||||
"""Testing creating a new user account as admin"""
|
||||
self.login( email='test@bx.psu.edu' )
|
||||
email = 'test4@bx.psu.edu'
|
||||
password = 'testuser'
|
||||
self.create_new_account_as_admin( email=email, password=password )
|
||||
# Get the user object for later tests
|
||||
global testuser4
|
||||
testuser4 = galaxy.model.User.filter( galaxy.model.User.table.c.email=='test4@bx.psu.edu' ).first()
|
||||
# Make sure DefaultUserPermissions were created
|
||||
if not testuser4.default_permissions:
|
||||
raise AssertionError( 'No DefaultUserPermissions were created for user %s when the admin created the account' % email )
|
||||
# Make sure a private role was created for the user
|
||||
if not testuser4.roles:
|
||||
raise AssertionError( 'No UserRoleAssociations were created for user %s when the admin created the account' % email )
|
||||
if len( testuser4.roles ) != 1:
|
||||
raise AssertionError( '%d UserRoleAssociations were created for user %s when the admin created the account ( should have been 1 )' \
|
||||
% len( testuser4.roles ) )
|
||||
for ura in testuser4.roles:
|
||||
role = galaxy.model.Role.get( ura.role_id )
|
||||
if role.type != 'private':
|
||||
raise AssertionError( 'Role created for user %s when the admin created the account is not private, type is' \
|
||||
% str( role.type ) )
|
||||
# Make sure a history was not created
|
||||
histories = galaxy.model.History.filter( galaxy.model.History.table.c.user_id==testuser4.id ).all()
|
||||
if histories:
|
||||
raise AssertionError( 'Histories were incorrectly created for user %s when the admin created the account' % email )
|
||||
# Make sure the user was not associated with any groups
|
||||
if testuser4.groups:
|
||||
raise AssertionError( 'Groups were incorrectly associated with user %s when the admin created the account' % email )
|
||||
def test_15_reset_password_as_admin( self ):
|
||||
"""Testing reseting a user password as admin"""
|
||||
email = 'test4@bx.psu.edu'
|
||||
self.reset_password_as_admin( user_id=testuser4.id, password='testreset' )
|
||||
self.home()
|
||||
self.logout()
|
||||
def test_18_login_after_password_reset( self ):
|
||||
"""Testing logging in after an admin reset a password - tests DefaultHistoryPermissions for accounts created by an admin"""
|
||||
self.login( email='test4@bx.psu.edu', password='testreset' )
|
||||
# Make sure a History and HistoryDefaultPermissions exist for the user
|
||||
latest_history = galaxy.model.History.query().order_by( desc( galaxy.model.History.table.c.create_time ) ).first()
|
||||
if not latest_history.user_id == testuser4.id:
|
||||
raise AssertionError( 'A history was not created for user %s when he logged in' % email )
|
||||
if not latest_history.default_permissions:
|
||||
raise AssertionError( 'No DefaultHistoryPermissions were created for history id %d when it was created' % latest_history.id )
|
||||
if len( latest_history.default_permissions ) > 1:
|
||||
raise AssertionError( 'More than 1 DefaultHistoryPermissions were created for history id %d when it was created' % latest_history.id )
|
||||
dhp = galaxy.model.DefaultHistoryPermissions.filter( galaxy.model.DefaultHistoryPermissions.table.c.history_id==latest_history.id ).first()
|
||||
if not dhp.action == galaxy.model.Dataset.permitted_actions.DATASET_MANAGE_PERMISSIONS.action:
|
||||
raise AssertionError( 'The DefaultHistoryPermission.action for history id %d is "%s", but it should be "%s"' \
|
||||
% ( latest_history.id, dhp.action, galaxy.model.Dataset.permitted_actions.DATASET_MANAGE_PERMISSIONS.action ) )
|
||||
# Upload a file to create a HistoryDatasetAssociation
|
||||
self.upload_file( '1.bed' )
|
||||
self.home()
|
||||
self.logout()
|
||||
def test_21_mark_user_deleted( self ):
|
||||
"""Testing marking a user account as deleted"""
|
||||
self.login( email='test@bx.psu.edu' )
|
||||
self.mark_user_deleted( user_id=testuser4.id )
|
||||
def test_24_undelete_user( self ):
|
||||
"""Testing undeleting a user account"""
|
||||
self.undelete_user( user_id=testuser4.id )
|
||||
def test_27_create_role( self ):
|
||||
"""Testing creating new non-private role with 3 members"""
|
||||
name = 'Role One'
|
||||
description = 'This is Role One'
|
||||
user_ids=[ str( testuser1.id ), str( testuser2.id ), str( testuser4.id ) ]
|
||||
self.create_role( name=name, description=description, user_ids=user_ids, private_role=testuser1.email )
|
||||
# Get the role object for later tests
|
||||
global new_test_role
|
||||
new_test_role = galaxy.model.Role.filter( galaxy.model.Role.table.c.name==name ).first()
|
||||
def test_15_create_group( self ):
|
||||
"""Testing creating new group with 2 members and 1 associated role"""
|
||||
name = 'New Test Group'
|
||||
self.create_group( name=name, user_ids=[ str( testuser1.id ), str( testuser2.id ) ], role_ids=[ str( new_test_role.id ) ] )
|
||||
global role_one
|
||||
role_one = galaxy.model.Role.filter( galaxy.model.Role.table.c.name==name ).first()
|
||||
# Make sure UserRoleAssociations are correct
|
||||
if not role_one.users:
|
||||
raise AssertionError( 'No UserRoleAssociations were created for role id %d when it was created with 3 members' % role_one.id )
|
||||
if len( role_one.users ) != len( user_ids ):
|
||||
raise AssertionError( '%d UserRoleAssociations were created for role id %d when it was created ( should have been %d )' \
|
||||
% ( len( role_one.users ), role_one.id, len( user_ids ) ) )
|
||||
# Each user should now have 2 role associations, their private role and role_one
|
||||
for user in [ testuser1, testuser2, testuser4 ]:
|
||||
user.refresh()
|
||||
if not user.roles:
|
||||
raise AssertionError( 'No UserRoleAssociations were created for user %s when a new role was created' % user.email )
|
||||
if len( user.roles ) != 2:
|
||||
raise AssertionError( '%d UserRoleAssociations are associated with user %s ( should be 2 )' % ( len( user.roles ), user.email ) )
|
||||
def test_30_create_group( self ):
|
||||
"""Testing creating new group with 3 members and 1 associated role"""
|
||||
name = 'Group One'
|
||||
user_ids=[ str( testuser1.id ), str( testuser2.id ), str( testuser4.id ) ]
|
||||
role_ids=[ str( role_one.id ) ]
|
||||
self.create_group( name=name, user_ids=user_ids, role_ids=role_ids )
|
||||
# Get the group object for later tests
|
||||
global new_test_group
|
||||
new_test_group = galaxy.model.Group.filter( galaxy.model.Group.table.c.name==name ).first()
|
||||
def test_18_add_group_member( self ):
|
||||
global group_one
|
||||
group_one = galaxy.model.Group.filter( galaxy.model.Group.table.c.name==name ).first()
|
||||
# Make sure UserGroupAssociations are correct
|
||||
if not group_one.users:
|
||||
raise AssertionError( 'No UserGroupAssociations were created for group id %d when it was created with 3 members' % group_one.id )
|
||||
if len( group_one.users ) != len( user_ids ):
|
||||
raise AssertionError( '%d UserGroupAssociations were created for group id %d when it was created ( should have been %d )' \
|
||||
% ( len( group_one.users ), group_one.id, len( user_ids ) ) )
|
||||
# Each user should now have 1 group association, group_one
|
||||
for user in [ testuser1, testuser2, testuser4 ]:
|
||||
user.refresh()
|
||||
if not user.groups:
|
||||
raise AssertionError( 'No UserGroupAssociations were created for user %s when a new group was created' % user.email )
|
||||
if len( user.groups ) != 1:
|
||||
raise AssertionError( '%d UserGroupAssociations are associated with user %s ( should be 1 )' % ( len( user.groups ), user.email ) )
|
||||
# Make sure GroupRoleAssociations are correct
|
||||
if not group_one.roles:
|
||||
raise AssertionError( 'No GroupRoleAssociations were created for group id %d when it was created with 3 members' % group_one.id )
|
||||
if len( group_one.roles ) != len( role_ids ):
|
||||
raise AssertionError( '%d GroupRoleAssociations were created for group id %d when it was created ( should have been %d )' \
|
||||
% ( len( group_one.roles ), group_one.id, len( role_ids ) ) )
|
||||
def test_33_add_group_member( self ):
|
||||
"""Testing editing membership of an existing group"""
|
||||
name = 'Another Test Group'
|
||||
name = 'Group Two'
|
||||
self.create_group( name=name )
|
||||
# Get the group object for later tests
|
||||
global another_test_group
|
||||
another_test_group = galaxy.model.Group.filter( galaxy.model.Group.table.c.name==name ).first()
|
||||
self.add_group_members( str( another_test_group.id ), [ str( testuser3.id ) ] )
|
||||
self.visit_url( "%s/admin/group_members_edit?group_id=%s" % ( self.url, str( another_test_group.id ) ) )
|
||||
global group_two
|
||||
group_two = galaxy.model.Group.filter( galaxy.model.Group.table.c.name==name ).first()
|
||||
user_ids = [ str( testuser3.id ) ]
|
||||
self.add_group_members( str( group_two.id ), user_ids )
|
||||
self.visit_url( "%s/admin/group_members_edit?group_id=%s" % ( self.url, str( group_two.id ) ) )
|
||||
self.check_page_for_string( testuser3.email )
|
||||
def test_21_associate_groups_with_role( self ):
|
||||
# Make sure UserGroupAssociations are correct
|
||||
if not group_two.users:
|
||||
raise AssertionError( 'No UserGroupAssociations were created for group id %d when %d members were added' \
|
||||
% ( group_two.id, len( user_ids ) ) )
|
||||
if len( group_two.users ) != len( user_ids ):
|
||||
raise AssertionError( '%d UserGroupAssociations were created for group id %d when %d members were added' \
|
||||
% ( len( group_two.users ), group_two.id, len( user_ids ) ) )
|
||||
# Create another group -needed for the following test
|
||||
name = 'Group Three'
|
||||
self.create_group( name=name )
|
||||
# Get the group object for later tests
|
||||
global group_three
|
||||
group_three = galaxy.model.Group.filter( galaxy.model.Group.table.c.name==name ).first()
|
||||
def test_36_associate_groups_with_role( self ):
|
||||
"""Testing adding existing groups to an existing role"""
|
||||
# NOTE: To get this to work with twill, all select lists on the ~/admin/role page must contain at least
|
||||
# 1 option value or twill throws an exception, which is: ParseError: OPTION outside of SELECT
|
||||
# Due to this bug in twill, we create the role, associating it with at least 1 user and 1 group...
|
||||
name = 'Another Test Role'
|
||||
description = 'Another cool new test role'
|
||||
# Due to this bug in twill, we create the role, associating it with at least 1 user and 1 group. We
|
||||
# also must ensure that each of the form fields will contain at least 1 value prior to submitting the form,
|
||||
# so we had to create group_three in the previous test
|
||||
name = 'Role Two'
|
||||
description = 'This is Role Two'
|
||||
user_ids=[ str( testuser1.id ) ]
|
||||
group_ids=[ str( group_two.id ) ]
|
||||
private_role=testuser1.email
|
||||
# STEP 1: create the role
|
||||
self.create_role( name=name,
|
||||
description=description,
|
||||
user_ids=[ str( testuser1.id ) ],
|
||||
group_ids=[ str( another_test_group.id ) ],
|
||||
private_role=testuser1.email )
|
||||
user_ids=user_ids,
|
||||
group_ids=group_ids,
|
||||
private_role=private_role )
|
||||
# Get the role object for later tests
|
||||
global another_test_role
|
||||
another_test_role = galaxy.model.Role.filter( galaxy.model.Role.table.c.name==name ).first()
|
||||
# ...and then we associate the role with a group not yet associated
|
||||
self.associate_groups_with_role( str( another_test_role.id ), group_ids=[ str( new_test_group.id ) ] )
|
||||
self.visit_page( 'admin/roles' )
|
||||
self.check_page_for_string( new_test_group.name )
|
||||
def test_24_create_library( self ):
|
||||
global role_two
|
||||
role_two = galaxy.model.Role.filter( galaxy.model.Role.table.c.name==name ).first()
|
||||
# Make sure UserRoleAssociations are correct
|
||||
if not role_two.users:
|
||||
raise AssertionError( 'No UserRoleAssociations were created for role id %d when it was created with %d members' \
|
||||
% ( role_two.id, len( user_ids ) ) )
|
||||
if len( role_two.users ) != len( user_ids ):
|
||||
raise AssertionError( '%d UserRoleAssociations were created for role id %d when it was created with %d members' \
|
||||
% ( len( role_two.users ), role_two.id, len( user_ids ) ) )
|
||||
# testuser1 should now have 3 role associations, private role, role_one, another+test_role
|
||||
for user in [ testuser1 ]:
|
||||
user.refresh()
|
||||
if not user.roles:
|
||||
raise AssertionError( 'No UserRoleAssociations were created for user %s when a new role was created' % user.email )
|
||||
if len( user.roles ) != 3:
|
||||
raise AssertionError( '%d UserRoleAssociations are associated with user %s ( should be 3 )' % ( len( user.roles ), user.email ) )
|
||||
# Make sure GroupRoleAssociations are correct
|
||||
if not role_two.groups:
|
||||
raise AssertionError( 'No GroupRoleAssociations were created for role id %d when it was created with %d groups' \
|
||||
% ( role_two.id, len( group_ids ) ) )
|
||||
if len( role_two.groups ) != len( group_ids ):
|
||||
raise AssertionError( '%d GroupRoleAssociations were created for role id %d when it was created ( should have been %d )' \
|
||||
% ( len( role_two.groups ), role_two.id, len( group_ids ) ) )
|
||||
# The group should also now be associated with 1 role
|
||||
for group in [ group_two ]:
|
||||
group.refresh()
|
||||
if not group.roles:
|
||||
raise AssertionError( 'No GroupRoleAssociations were created for group id %d when a new role was created' % group.id )
|
||||
if len( group.roles ) != 1:
|
||||
raise AssertionError( '%d GroupRoleAssociations are associated with group id %d ( should be 1 )' % ( len( group.roles ), group.id ) )
|
||||
# STEP 2: associate the role with a group not yet associated
|
||||
# TODO: Twill throws an exception on this...
|
||||
#group_names = [ group_one.name ]
|
||||
#self.associate_groups_with_role( str( role_two.id ), group_names=group_names )
|
||||
#self.visit_page( 'admin/roles' )
|
||||
#self.check_page_for_string( group_one.name )
|
||||
def test_39_create_library( self ):
|
||||
"""Testing creating new library"""
|
||||
name = 'New Test Library'
|
||||
description = 'New Test Library Description'
|
||||
name = 'Library One'
|
||||
description = 'This is Library One'
|
||||
self.create_library( name=name, description=description )
|
||||
self.visit_page( 'admin/libraries' )
|
||||
self.check_page_for_string( name )
|
||||
@@ -254,20 +404,20 @@ class TestHistory( TwillTestCase ):
|
||||
library = galaxy.model.Library.filter( and_( galaxy.model.Library.table.c.name==name,
|
||||
galaxy.model.Library.table.c.description==description,
|
||||
galaxy.model.Library.table.c.deleted==False ) ).first()
|
||||
def test_27_rename_library( self ):
|
||||
def test_42_rename_library( self ):
|
||||
"""Testing renaming a library"""
|
||||
self.rename_library( str( library.id ), name='New Test Library Renamed', description='New Test Library Description Re-described', root_folder='on' )
|
||||
self.rename_library( str( library.id ), name='Library One Renamed', description='This is Library One Re-described', root_folder='on' )
|
||||
self.visit_page( 'admin/libraries' )
|
||||
self.check_page_for_string( "New Test Library Renamed" )
|
||||
self.check_page_for_string( "Library One Renamed" )
|
||||
# Rename it back to what it was originally
|
||||
self.rename_library( str( library.id ), name='New Test Library', description='New Test Library Description', root_folder='on' )
|
||||
def test_30_rename_root_folder( self ):
|
||||
self.rename_library( str( library.id ), name='Library One', description='This is Library One', root_folder='on' )
|
||||
def test_45_rename_root_folder( self ):
|
||||
"""Testing renaming a library root folder"""
|
||||
folder = library.root_folder
|
||||
self.rename_folder( str( folder.id ), name='New Test Library Root Folder', description='New Test Library Root Folder Description' )
|
||||
self.rename_folder( str( folder.id ), name='Library One Root Folder', description='This is Library One root folder' )
|
||||
self.visit_page( 'admin/libraries' )
|
||||
self.check_page_for_string( "New Test Library Root Folder" )
|
||||
def test_33_add_public_dataset_to_root_folder( self ):
|
||||
self.check_page_for_string( "Library One Root Folder" )
|
||||
def test_48_add_public_dataset_to_root_folder( self ):
|
||||
"""Testing adding a public dataset to a library root folder"""
|
||||
folder = library.root_folder
|
||||
self.add_dataset( '1.bed', str( folder.id ), extension='bed', dbkey='hg18', roles=[] )
|
||||
@@ -275,7 +425,7 @@ class TestHistory( TwillTestCase ):
|
||||
self.check_page_for_string( "1.bed" )
|
||||
self.check_page_for_string( "bed" )
|
||||
self.check_page_for_string( "hg18" )
|
||||
def test_36_copy_dataset_from_history_to_root_folder( self ):
|
||||
def test_51_copy_dataset_from_history_to_root_folder( self ):
|
||||
"""Testing copying a dataset from the current history to a library root folder"""
|
||||
folder = library.root_folder
|
||||
self.add_dataset_to_folder_from_history( str( folder.id ) )
|
||||
@@ -289,40 +439,41 @@ class TestHistory( TwillTestCase ):
|
||||
raise AssertionError( 'More than 1 ActionDatasetRoleAssociations created for dataset id: %d' % last_dataset_created.id )
|
||||
for adra in adras:
|
||||
if not adra.action == 'manage permissions':
|
||||
raise AssertionError( 'ActionDatasetRoleAssociation.action "%s" is not the DefaultHistoryPermission setting, which is "manage permissions"' % str( adra.action ) )
|
||||
def test_39_add_new_folder( self ):
|
||||
raise AssertionError( 'ActionDatasetRoleAssociation.action "%s" is not the DefaultHistoryPermission setting, which is "manage permissions"' % \
|
||||
str( adra.action ) )
|
||||
def test_54_add_new_folder( self ):
|
||||
"""Testing adding a folder to a library root folder"""
|
||||
root_folder = library.root_folder
|
||||
name = 'New Test Folder'
|
||||
description = 'New Test Folder Description'
|
||||
name = 'Folder One'
|
||||
description = 'This is Folder One'
|
||||
self.add_folder( str( root_folder.id ), name=name, description=description )
|
||||
global new_test_folder
|
||||
new_test_folder = galaxy.model.LibraryFolder.filter( and_( galaxy.model.LibraryFolder.table.c.parent_id==root_folder.id,
|
||||
galaxy.model.LibraryFolder.table.c.name==name,
|
||||
galaxy.model.LibraryFolder.table.c.description==description ) ).first()
|
||||
self.visit_page( 'admin/libraries' )
|
||||
self.check_page_for_string( "New Test Folder" )
|
||||
def test_42_add_datasets_from_library_dir( self ):
|
||||
self.check_page_for_string( "Folder One" )
|
||||
def test_57_add_datasets_from_library_dir( self ):
|
||||
"""Testing adding several datasets from library directory to sub-folder"""
|
||||
roles_tuple = [ ( str( new_test_role.id ), new_test_role.description ) ]
|
||||
roles_tuple = [ ( str( role_one.id ), role_one.description ) ]
|
||||
self.add_datasets_from_library_dir( str( new_test_folder.id ), roles_tuple=roles_tuple )
|
||||
def test_45_mark_group_deleted( self ):
|
||||
def test_60_mark_group_deleted( self ):
|
||||
"""Testing marking a group as deleted"""
|
||||
self.visit_page( "admin/groups" )
|
||||
self.check_page_for_string( another_test_group.name )
|
||||
self.mark_group_deleted( str( another_test_group.id ) )
|
||||
def test_48_undelete_group( self ):
|
||||
self.check_page_for_string( group_two.name )
|
||||
self.mark_group_deleted( str( group_two.id ) )
|
||||
def test_63_undelete_group( self ):
|
||||
"""Testing undeleting a deleted group"""
|
||||
self.undelete_group( str( another_test_group.id ) )
|
||||
def test_51_mark_role_deleted( self ):
|
||||
self.undelete_group( str( group_two.id ) )
|
||||
def test_66_mark_role_deleted( self ):
|
||||
"""Testing marking a role as deleted"""
|
||||
self.visit_page( "admin/roles" )
|
||||
self.check_page_for_string( another_test_role.description )
|
||||
self.mark_role_deleted( str( another_test_role.id ) )
|
||||
def test_54_undelete_role( self ):
|
||||
self.check_page_for_string( role_two.description )
|
||||
self.mark_role_deleted( str( role_two.id ) )
|
||||
def test_69_undelete_role( self ):
|
||||
"""Testing undeleting a deleted role"""
|
||||
self.undelete_role( str( another_test_role.id ) )
|
||||
def test_57_mark_library_deleted( self ):
|
||||
self.undelete_role( str( role_two.id ) )
|
||||
def test_72_mark_library_deleted( self ):
|
||||
"""Testing marking a library as deleted"""
|
||||
self.mark_library_deleted( str( library.id ) )
|
||||
# Make sure the library was deleted
|
||||
@@ -334,19 +485,21 @@ class TestHistory( TwillTestCase ):
|
||||
folder.refresh()
|
||||
# Make sure all of the library_folders are deleted
|
||||
if not folder.deleted:
|
||||
raise AssertionError( 'The library_folder named "%s" has not been marked as deleted ( library.id: %s ).' % ( folder.name, str( library.id ) ) )
|
||||
raise AssertionError( 'The library_folder named "%s" has not been marked as deleted ( library.id: %s ).' % \
|
||||
( folder.name, str( library.id ) ) )
|
||||
check_folder( folder )
|
||||
# Make sure all of the library_folder_dataset_associations are deleted
|
||||
for lfda in library_folder.datasets:
|
||||
lfda.refresh()
|
||||
if not lfda.deleted:
|
||||
raise AssertionError( 'The library_folder_dataset_association id %s named "%s" has not been marked as deleted ( library.id: %s ).' % ( str( lfda.id ), lfda.name, str( library.id ) ) )
|
||||
raise AssertionError( 'The library_folder_dataset_association id %s named "%s" has not been marked as deleted ( library.id: %s ).' % \
|
||||
( str( lfda.id ), lfda.name, str( library.id ) ) )
|
||||
# Make sure none of the datasets have been deleted since that should occur only when the library is purged
|
||||
lfda.dataset.refresh()
|
||||
if lfda.dataset.deleted:
|
||||
raise AssertionError( 'The dataset with id "%s" has been marked as deleted when it should not have been.' % lfda.dataset.id )
|
||||
check_folder( library.root_folder )
|
||||
def test_60_mark_library_undeleted( self ):
|
||||
def test_75_mark_library_undeleted( self ):
|
||||
"""Testing marking a library as not deleted"""
|
||||
self.mark_library_undeleted( str( library.id ) )
|
||||
# Make sure the library is undeleted
|
||||
@@ -358,13 +511,15 @@ class TestHistory( TwillTestCase ):
|
||||
folder.refresh()
|
||||
# Make sure all of the library_folders are undeleted
|
||||
if folder.deleted:
|
||||
raise AssertionError( 'The library_folder id %s named "%s" has not been marked as undeleted ( library.id: %s ).' % ( str( folder.id ), folder.name, str( library.id ) ) )
|
||||
raise AssertionError( 'The library_folder id %s named "%s" has not been marked as undeleted ( library.id: %s ).' % \
|
||||
( str( folder.id ), folder.name, str( library.id ) ) )
|
||||
check_folder( folder )
|
||||
# Make sure all of the library_folder_dataset_associations are undeleted
|
||||
for lfda in library_folder.datasets:
|
||||
lfda.refresh()
|
||||
if lfda.deleted:
|
||||
raise AssertionError( 'The library_folder_dataset_association id %s named "%s" has not been marked as undeleted ( library.id: %s ).' % ( str( lfda.id ), lfda.name, str( library.id ) ) )
|
||||
raise AssertionError( 'The library_folder_dataset_association id %s named "%s" has not been marked as undeleted ( library.id: %s ).' % \
|
||||
( str( lfda.id ), lfda.name, str( library.id ) ) )
|
||||
# Make sure all of the datasets have been undeleted
|
||||
if lfda.dataset.deleted:
|
||||
raise AssertionError( 'The dataset with id "%s" has not been marked as undeleted.' % lfda.dataset.id )
|
||||
@@ -374,10 +529,55 @@ class TestHistory( TwillTestCase ):
|
||||
# Make sure the library is deleted again
|
||||
library.refresh()
|
||||
if not library.deleted:
|
||||
raise AssertionError( 'The library id %s named "%s" has not been marked as deleted after it was undeleted.' % ( str( library.id ), library.name ) )
|
||||
def test_63_purge_group( self ):
|
||||
raise AssertionError( 'The library id %s named "%s" has not been marked as deleted after it was undeleted.' % \
|
||||
( str( library.id ), library.name ) )
|
||||
def test_78_purge_user( self ):
|
||||
"""Testing purging a user account"""
|
||||
self.mark_user_deleted( user_id=testuser4.id )
|
||||
self.purge_user( user_id=testuser4.id )
|
||||
testuser4.refresh()
|
||||
if not testuser4.purged:
|
||||
raise AssertionError( 'User %s was not marked as purged.' % testuser4.email )
|
||||
# Make sure DefaultUserPermissions deleted EXCEPT FOR THE PRIVATE ROLE
|
||||
if len( testuser4.default_permissions ) != 1:
|
||||
raise AssertionError( 'DefaultUserPermissions for user %s were not deleted.' % testuser4.email )
|
||||
for dup in testuser4.default_permissions:
|
||||
role = galaxy.model.Role.get( dup.role_id )
|
||||
if role.type != 'private':
|
||||
raise AssertionError( 'DefaultUserPermissions for user %s are not related with the private role.' % testuser4.email )
|
||||
# Make sure History deleted
|
||||
for history in testuser4.histories:
|
||||
if not history.deleted:
|
||||
raise AssertionError( 'User %s has active history id %d after their account was marked as purged.' % ( testuser4.email, hda.id ) )
|
||||
# Make sure DefaultHistoryPermissions deleted EXCEPT FOR THE PRIVATE ROLE
|
||||
if len( history.default_permissions ) != 1:
|
||||
raise AssertionError( 'DefaultHistoryPermissions for history id %d were not deleted.' % history.id )
|
||||
for dhp in history.default_permissions:
|
||||
role = galaxy.model.Role.get( dhp.role_id )
|
||||
if role.type != 'private':
|
||||
raise AssertionError( 'DefaultHistoryPermissions for history id %d are not related with the private role.' % history.id )
|
||||
# Make sure HistoryDatasetAssociation deleted
|
||||
for hda in history.datasets:
|
||||
if not hda.deleted:
|
||||
raise AssertionError( 'HistoryDatasetAssociation id %d was not deleted.' % hda.id )
|
||||
# Make sure Dataset deleted
|
||||
d = galaxy.model.Dataset.filter( galaxy.model.Dataset.table.c.id==hda.dataset_id ).first()
|
||||
if not d.deleted:
|
||||
raise AssertionError( 'Dataset id %d was not deleted.' % d.id )
|
||||
# Make sure UserGroupAssociations deleted
|
||||
if testuser4.groups:
|
||||
raise AssertionError( 'User %s has active group id %d after their account was marked as purged.' % ( testuser4.email, uga.id ) )
|
||||
# Make sure UserRoleAssociations deleted EXCEPT FOR THE PRIVATE ROLE
|
||||
if len( testuser4.roles ) != 1:
|
||||
raise AssertionError( 'UserRoleAssociations for user %s were not deleted.' % testuser4.email )
|
||||
for ura in testuser4.roles:
|
||||
role = galaxy.model.Role.get( ura.role_id )
|
||||
if role.type != 'private':
|
||||
raise AssertionError( 'UserRoleAssociations for user %s are not related with the private role.' % testuser4.email )
|
||||
def test_81_purge_group( self ):
|
||||
"""Testing purging a group"""
|
||||
group_id = str( another_test_group.id )
|
||||
group_id = str( group_two.id )
|
||||
self.mark_group_deleted( group_id )
|
||||
self.purge_group( group_id )
|
||||
# Make sure there are no UserGroupAssociations
|
||||
uga = galaxy.model.UserGroupAssociation.filter( galaxy.model.UserGroupAssociation.table.c.group_id == group_id ).all()
|
||||
@@ -387,10 +587,23 @@ class TestHistory( TwillTestCase ):
|
||||
gra = galaxy.model.GroupRoleAssociation.filter( galaxy.model.GroupRoleAssociation.table.c.group_id == group_id ).all()
|
||||
if gra:
|
||||
raise AssertionError( "Purging the group did not delete the GroupRoleAssociations for group_id '%s'" % group_id )
|
||||
def test_66_purge_role( self ):
|
||||
def test_84_purge_role( self ):
|
||||
"""Testing purging a role"""
|
||||
role_id = str( another_test_role.id )
|
||||
role_id = str( role_two.id )
|
||||
self.mark_role_deleted( role_id )
|
||||
self.purge_role( role_id )
|
||||
# Make sure there are no UserRoleAssociations
|
||||
uras = galaxy.model.UserRoleAssociation.filter( galaxy.model.UserRoleAssociation.table.c.role_id == role_id ).all()
|
||||
if uras:
|
||||
raise AssertionError( "Purging the role did not delete the UserRoleAssociations for role_id '%s'" % role_id )
|
||||
# Make sure there are no DefaultUserPermissions associated with the Role
|
||||
dups = galaxy.model.DefaultUserPermissions.filter( galaxy.model.DefaultUserPermissions.table.c.role_id == role_id ).all()
|
||||
if dups:
|
||||
raise AssertionError( "Purging the role did not delete the DefaultUserPermissions for role_id '%s'" % role_id )
|
||||
# Make sure there are no DefaultHistoryPermissions associated with the Role
|
||||
dhps = galaxy.model.DefaultHistoryPermissions.filter( galaxy.model.DefaultHistoryPermissions.table.c.role_id == role_id ).all()
|
||||
if dhps:
|
||||
raise AssertionError( "Purging the role did not delete the DefaultHistoryPermissions for role_id '%s'" % role_id )
|
||||
# Make sure there are no GroupRoleAssociations
|
||||
gra = galaxy.model.GroupRoleAssociation.filter( galaxy.model.GroupRoleAssociation.table.c.role_id == role_id ).all()
|
||||
if gra:
|
||||
@@ -399,7 +612,7 @@ class TestHistory( TwillTestCase ):
|
||||
adra = galaxy.model.ActionDatasetRoleAssociation.filter( galaxy.model.ActionDatasetRoleAssociation.table.c.role_id == role_id ).all()
|
||||
if adra:
|
||||
raise AssertionError( "Purging the role did not delete the ActionDatasetRoleAssociations for role_id '%s'" % role_id )
|
||||
def test_69_purge_library( self ):
|
||||
def test_87_purge_library( self ):
|
||||
"""Testing purging a library"""
|
||||
self.purge_library( str( library.id ) )
|
||||
# Make sure the library was purged
|
||||
@@ -417,10 +630,12 @@ class TestHistory( TwillTestCase ):
|
||||
for lfda in library_folder.datasets:
|
||||
lfda.refresh()
|
||||
if not lfda.deleted:
|
||||
raise AssertionError( 'The library_folder_dataset_association id %s named "%s" has not been marked as deleted.' % ( str( lfda.id ), lfda.name ) )
|
||||
raise AssertionError( 'The library_folder_dataset_association id %s named "%s" has not been marked as deleted.' % \
|
||||
( str( lfda.id ), lfda.name ) )
|
||||
# Make sure all of the datasets have been deleted
|
||||
dataset = lfda.dataset
|
||||
dataset.refresh()
|
||||
if not dataset.deleted:
|
||||
raise AssertionError( 'The dataset with id "%s" has not been marked as deleted when it should have been.' % str( lfda.dataset.id ) )
|
||||
raise AssertionError( 'The dataset with id "%s" has not been marked as deleted when it should have been.' % \
|
||||
str( lfda.dataset.id ) )
|
||||
check_folder( library.root_folder )
|
||||
|
||||
@@ -141,6 +141,9 @@ use_interactive = True
|
||||
# Can users register new accounts?
|
||||
#allow_user_creation = True
|
||||
|
||||
# Can an admin user delete user accounts?
|
||||
#allow_user_deletion = False
|
||||
|
||||
# ---- Job Execution --------------------------------------------------------
|
||||
|
||||
# Number of concurrent jobs to run (local job runner)
|
||||
|
||||
Reference in New Issue
Block a user