Enhance the Tool Shed API to provide information about users that is public (i.e., public username) and to include a function for creating a new user. Add a Tool Shed API script that retrieves all of the pubic information about users from a Tool Shed, automatically generates test email accounts and test passwords, and creates the list of users in another Tool Shed. This script streamlines the process of populating a development Tool Shed with users, enabling import of a repository capsule exportied from the specified Tool Shed. This simplifies the process of developing new repository hierarchies in a local development Tool Shed.

This commit is contained in:
Greg Von Kuster
2014-05-01 16:07:48 -04:00
parent 3e64390c13
commit 2028fb12fd
5 changed files with 199 additions and 4 deletions
+128
View File
@@ -0,0 +1,128 @@
import logging
import os
from galaxy import util
from galaxy import web
from galaxy.web.base.controller import BaseAPIController
from galaxy.security.validate_user_input import validate_email
from galaxy.security.validate_user_input import validate_publicname
from galaxy.security.validate_user_input import validate_password
import tool_shed.util.shed_util_common as suc
log = logging.getLogger( __name__ )
class UsersController( BaseAPIController ):
"""RESTful controller for interactions with users in the Tool Shed."""
@web.expose_api
def create_user( self, trans, payload, **kwd ):
"""
POST /api/users/create_user
Returns a dictionary of information about the created user.
: param key: the current Galaxy admin user's API key
The following parameters are included in the payload.
:param username (required): the public username of the user
"""
user_dict = dict( message = '',
status = 'ok' )
# Make sure the current user's API key proves he is an admin user in this Tool Shed.
if trans.user_is_admin():
# Get the information about the user to be created from the payload.
email = payload.get( 'email', '' )
password = payload.get( 'password', '' )
username = payload.get( 'username', '' )
message = self.__validate( trans,
email=email,
password=password,
confirm=password,
username=username )
if message:
message = 'email: %s, username: %s - %s' % ( email, username, message )
user_dict[ 'message' ] = message
user_dict[ 'status' ] = 'error'
else:
# Create the user.
user = self.__create_user( trans, email, username, password )
user_dict = user.to_dict( view='element',
value_mapper=self.__get_value_mapper( trans ) )
user_dict[ 'message' ] = "User '%s' has been created." % str( user.username )
user_dict[ 'url' ] = web.url_for( controller='users',
action='show',
id=trans.security.encode_id( user.id ) )
else:
user_dict[ 'message' ] = 'You are not authorized to create a user in this Tool Shed.'
user_dict[ 'status' ] = 'error'
return user_dict
def __create_user( self, trans, email, username, password ):
user = trans.app.model.User( email=email )
user.set_password_cleartext( password )
user.username = username
if trans.app.config.user_activation_on:
user.active = False
else:
user.active = True # Activation is off, every new user is active by default.
trans.sa_session.add( user )
trans.sa_session.flush()
trans.app.security_agent.create_private_user_role( user )
return user
def __get_value_mapper( self, trans ):
value_mapper = { 'id' : trans.security.encode_id }
return value_mapper
@web.expose_api_anonymous
def index( self, trans, deleted=False, **kwd ):
"""
GET /api/users
Returns a list of dictionaries that contain information about each user.
"""
# Example URL: http://localhost:9009/api/users
user_dicts = []
deleted = util.asbool( deleted )
for user in trans.sa_session.query( trans.app.model.User ) \
.filter( trans.app.model.User.table.c.deleted == deleted ) \
.order_by( trans.app.model.User.table.c.username ):
user_dict = user.to_dict( view='collection',
value_mapper=self.__get_value_mapper( trans ) )
user_dict[ 'url' ] = web.url_for( controller='users',
action='show',
id=trans.security.encode_id( user.id ) )
user_dicts.append( user_dict )
return user_dicts
@web.expose_api_anonymous
def show( self, trans, id, **kwd ):
"""
GET /api/users/{encoded_user_id}
Returns a dictionary of information about a user.
:param id: the encoded id of the User object.
"""
# Example URL: http://localhost:9009/api/users/f9cad7b01a472135
user = suc.get_user( trans, id )
if user is None:
user_dict = dict( message = 'Unable to locate user record for id %s.' % ( str( id ) ),
status = 'error' )
return user_dict
user_dict = user.to_dict( view='element',
value_mapper=self.__get_value_mapper( trans ) )
user_dict[ 'url' ] = web.url_for( controller='users',
action='show',
id=trans.security.encode_id( user.id ) )
return user_dict
def __validate( self, trans, email, password, confirm, username ):
if not username:
return "A public user name is required in the Tool Shed."
if username in [ 'repos' ]:
return "The term <b>%s</b> is a reserved word in the Tool Shed, so it cannot be used as a public user name." % username
message = validate_email( trans, email )
if not message:
message = validate_password( trans, password, confirm )
if not message and username:
message = validate_publicname( trans, username )
return message
+7
View File
@@ -107,6 +107,13 @@ def app_factory( global_conf, **kwargs ):
name_prefix='repository_revision_',
path_prefix='/api',
parent_resources=dict( member_name='repository_revision', collection_name='repository_revisions' ) )
webapp.mapper.resource( 'user',
'users',
controller='users',
name_prefix='user_',
path_prefix='/api',
new={ 'create_user' : 'POST' },
parent_resources=dict( member_name='user', collection_name='users' ) )
webapp.finalize_config()
# Wrap the webapp in some useful middleware
if kwargs.get( 'middleware', True ):
@@ -20,8 +20,8 @@ class APIKeys( object ):
class User( object, Dictifiable ):
dict_collection_visible_keys = ( 'id', 'email' )
dict_element_visible_keys = ( 'id', 'email', 'username' )
dict_collection_visible_keys = ( 'id', 'username' )
dict_element_visible_keys = ( 'id', 'username' )
def __init__( self, email=None, password=None ):
self.email = email
@@ -9,10 +9,10 @@ will not be affected.
This script is very useful for populating a new development Tool Shed with the set of categories that
currently exist in either the test or main public Galaxy Tool Sheds. This will streamline building
new repository hierarchies in the development Tool Shed and exportin gthem into a capsule that can be
new repository hierarchies in the development Tool Shed and exporting them into a capsule that can be
imported into one of the public Tool Sheds.
Here is a working example of how to use this script to retrieve the current set of repositories that are
Here is a working example of how to use this script to retrieve the current set of categories that are
available in the test public Tool Shed and create each of them in a local development Tool Shed.
./create_categories.py -a <api key> -f http://testtoolshed.g2.bx.psu.edu -t http://localhost:9009
+60
View File
@@ -0,0 +1,60 @@
#!/usr/bin/env python
"""
This script will retrieve a list of dictionaries (one for each user) from the Tool Shed defined
by the --from_tool_shed parameter, which should be a base Tool Shed URL. It will retrieve the
username from each dictionary and create a new user with that username in the Tool Shed defined
by the --to_tool_shed parameter (a different base Tool Shed URL). An email and password value
will automatically be provided for each user. Email addresses will be <username>@test.org and
passwords will be testuser. Users that already exist with a specified username in the Tool Shed
in which the users are being created will not be affected.
This script is very useful for populating a new development Tool Shed with the set of users that
currently exist in either the test or main public Galaxy Tool Sheds. This will streamline building
new repository hierarchies in the development Tool Shed and exporting them into a capsule that can
be imported into one of the public Tool Sheds.
Here is a working example of how to use this script to retrieve the current set of users that
are available in the test public Tool Shed and create each of them in a local development Tool Shed.
./create_users.py -a <api key> -f http://testtoolshed.g2.bx.psu.edu -t http://localhost:9009
"""
import os
import sys
import argparse
sys.path.insert( 0, os.path.dirname( __file__ ) )
from common import get
from common import submit
def main( options ):
api_key = options.api
from_tool_shed = options.from_tool_shed.rstrip( '/' )
to_tool_shed = options.to_tool_shed.rstrip( '/' )
# Get the users from the specified Tool Shed.
url = '%s/api/users' % from_tool_shed
user_dicts = get( url )
create_response_dicts = []
for user_dict in user_dicts:
username = user_dict.get( 'username', None )
if username is not None:
email = '%s@test.org' % username
password = 'testuser'
data = dict( email=email,
password=password,
username=username )
url = '%s/api/users/new/create_user' % to_tool_shed
try:
response = submit( url, data, api_key )
except Exception, e:
response = str( e )
log.exception( str( e ) )
create_response_dict = dict( response=response )
create_response_dicts.append( create_response_dict )
if __name__ == '__main__':
parser = argparse.ArgumentParser( description='Retrieve a list of users from a Tool Shed and create them in another Tool Shed.' )
parser.add_argument( "-a", "--api", dest="api", required=True, help="API Key for Tool Shed in which users will be created" )
parser.add_argument( "-f", "--from_tool_shed", dest="from_tool_shed", required=True, help="URL of Tool Shed from which to retrieve the users" )
parser.add_argument( "-t", "--to_tool_shed", dest="to_tool_shed", required=True, help="URL of Tool Shed in which to create the users" )
options = parser.parse_args()
main( options )