mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-10-24 02:04:04 +08:00
More documentation; minor fixes
This commit is contained in:
@@ -131,14 +131,15 @@ class ModelManager( object ):
|
||||
foreign_key_name = None
|
||||
|
||||
def __init__( self, app ):
|
||||
"""
|
||||
"""
|
||||
self.app = app
|
||||
|
||||
#NOTE: at this layer, all ids are expected to be decoded and in int form
|
||||
# ------------------------------------------------------------------------- get/read/query
|
||||
def query( self, trans, eagerloads=True, filters=None, order_by=None, limit=None, offset=None, **kwargs ):
|
||||
"""
|
||||
Return a basic query from model_class, filters, order_by, and limit and offset.
|
||||
|
||||
Set eagerloads to False to disable them for this query.
|
||||
"""
|
||||
#print 'query:', eagerloads, filters, order_by, limit, offset, kwargs
|
||||
query = trans.sa_session.query( self.model_class )
|
||||
@@ -154,6 +155,7 @@ class ModelManager( object ):
|
||||
|
||||
def _apply_filters( self, query, filters ):
|
||||
"""
|
||||
Add any filters to the given query.
|
||||
"""
|
||||
if filters is None:
|
||||
return query
|
||||
@@ -167,9 +169,11 @@ class ModelManager( object ):
|
||||
|
||||
def _munge_filters( self, filtersA, filtersB ):
|
||||
"""
|
||||
Combine two lists into a single list.
|
||||
|
||||
(While allowing them to be None, non-lists, or lists.)
|
||||
"""
|
||||
# ... which sounds like a euphamism for something
|
||||
final_filters = [ self.model_class.id == id ]
|
||||
if filtersA is None:
|
||||
return filtersB
|
||||
if filtersB is None:
|
||||
@@ -182,12 +186,16 @@ class ModelManager( object ):
|
||||
|
||||
def _apply_order_by_limit_offset( self, query, order_by, limit, offset ):
|
||||
"""
|
||||
Return the query after adding the order_by, limit, and offset clauses.
|
||||
"""
|
||||
query = self._apply_order_by( query, order_by )
|
||||
return self._apply_limit_offset( query, limit, offset )
|
||||
|
||||
def _apply_order_by( self, query, order_by ):
|
||||
"""
|
||||
Return the query after adding the order_by clauses.
|
||||
|
||||
Use the manager's default_order_by if order_by is None.
|
||||
"""
|
||||
if order_by is None:
|
||||
#TODO: allow non-tuple default_order_by
|
||||
@@ -199,6 +207,7 @@ class ModelManager( object ):
|
||||
|
||||
def _apply_limit_offset( self, query, limit, offset ):
|
||||
"""
|
||||
Return the query after applying the given limit and offset (if not None).
|
||||
"""
|
||||
if limit is not None:
|
||||
query = query.limit( limit )
|
||||
@@ -207,37 +216,47 @@ class ModelManager( object ):
|
||||
return query
|
||||
|
||||
# ......................................................................... common queries
|
||||
#TODO: needed?
|
||||
#TODO: needed?
|
||||
def one( self, trans, **kwargs ):
|
||||
"""
|
||||
Sends kwargs to build the query and returns one and only one model.
|
||||
|
||||
:raises exceptions.ObjectNotFound: if no model is found
|
||||
:raises exceptions.Conflict: if more than one model is found
|
||||
"""
|
||||
# overridden to raise serializable errors
|
||||
try:
|
||||
return self.query( trans, **kwargs ).one()
|
||||
# re-raise as serializable errors
|
||||
except sqlalchemy.orm.exc.NoResultFound, not_found:
|
||||
raise exceptions.ObjectNotFound( self.model_class.__name__ + ' not found' )
|
||||
#TODO: exceptions.InconsistentDatabase?
|
||||
except sqlalchemy.orm.exc.MultipleResultsFound, multi_found:
|
||||
raise exceptions.Conflict( 'found more than one ' + self.model_class.__name__ )
|
||||
|
||||
def list( self, trans, **kwargs ):
|
||||
def list( self, trans, query=None, **kwargs ):
|
||||
"""
|
||||
Sends kwargs to build the query return all models found.
|
||||
"""
|
||||
return self.query( trans, **kwargs ).all()
|
||||
query = query or self.query( trans, **kwargs )
|
||||
return query.all()
|
||||
|
||||
def by_id( self, trans, id, **kwargs ):
|
||||
"""
|
||||
Gets a model by primary id.
|
||||
"""
|
||||
id_filter = self.model_class.id == id
|
||||
return self.one( trans, filters=id_filter, **kwargs )
|
||||
|
||||
def _query_by_ids( self, trans, ids, filters=None, **kwargs ):
|
||||
"""
|
||||
Builds a query to find a list of models with the given list of `ids`.
|
||||
"""
|
||||
ids_filter = self.model_class.id.in_( ids )
|
||||
return self.query( trans, filters=self._munge_filters( ids_filter, filters ), **kwargs )
|
||||
|
||||
def by_ids( self, trans, ids, **kwargs ):
|
||||
"""
|
||||
Returns an in-order list of models with the matching ids in `ids`.
|
||||
"""
|
||||
found = self._query_by_ids( trans, ids, **kwargs ).all()
|
||||
#TODO: this does not order by the original 'ids' array
|
||||
@@ -277,7 +296,9 @@ class ModelManager( object ):
|
||||
# ------------------------------------------------------------------------- create
|
||||
def create( self, trans, flush=True, *args, **kwargs ):
|
||||
"""
|
||||
Generically create a new model.
|
||||
"""
|
||||
# override in subclasses
|
||||
item = self.model_class( *args, **kwargs )
|
||||
trans.sa_session.add( item )
|
||||
if flush:
|
||||
@@ -286,12 +307,16 @@ class ModelManager( object ):
|
||||
|
||||
def copy( self, trans, item, **kwargs ):
|
||||
"""
|
||||
Clone or copy an item.
|
||||
"""
|
||||
raise exceptions.NotImplemented( 'Abstract method' )
|
||||
|
||||
# ------------------------------------------------------------------------- update
|
||||
def update( self, trans, item, new_values, flush=True, **kwargs ):
|
||||
"""
|
||||
Given a dictionary of new values, update `item` and return it.
|
||||
|
||||
..note: NO validation or deserialization occurs here.
|
||||
"""
|
||||
trans.sa_session.add( item )
|
||||
for key, value in new_values.items():
|
||||
@@ -301,8 +326,10 @@ class ModelManager( object ):
|
||||
trans.sa_session.flush()
|
||||
return item
|
||||
|
||||
#TODO: yagni?
|
||||
def associate( self, trans, associate_with, item, foreign_key_name=None ):
|
||||
"""
|
||||
Generically associate `item` with `associate_with` based on `foreign_key_name`.
|
||||
"""
|
||||
foreign_key_name = foreign_key_name or self.foreign_key_name
|
||||
setattr( associate_with, foreign_key_name, item )
|
||||
@@ -310,6 +337,7 @@ class ModelManager( object ):
|
||||
|
||||
def query_associated( self, trans, associated_model_class, item, foreign_key_name=None ):
|
||||
"""
|
||||
Generically query other items that have been associated with this `item`.
|
||||
"""
|
||||
foreign_key_name = foreign_key_name or self.foreign_key_name
|
||||
foreign_key = getattr( associated_model_class, foreign_key_name )
|
||||
|
||||
@@ -32,6 +32,7 @@ class DatasetManager( base.ModelManager, base.AccessibleModelInterface, base.Pur
|
||||
# default to NEW state on new datasets
|
||||
kwargs.update( dict( state=( kwargs.get( 'state', model.Dataset.states.NEW ) ) ) )
|
||||
dataset = model.Dataset( **kwargs )
|
||||
|
||||
trans.sa_session.add( dataset )
|
||||
if flush:
|
||||
trans.sa_session.flush()
|
||||
@@ -54,6 +55,12 @@ class DatasetManager( base.ModelManager, base.AccessibleModelInterface, base.Pur
|
||||
pass
|
||||
|
||||
# ......................................................................... delete
|
||||
def error_unless_dataset_purge_allowed( self, trans, item, msg=None ):
|
||||
if not trans.app.config.allow_user_dataset_purge:
|
||||
msg = msg or 'This instance does not allow user dataset purging'
|
||||
raise exceptions.ConfigDoesNotAllowException( msg )
|
||||
return item
|
||||
|
||||
def purge( self, trans, dataset, flush=True ):
|
||||
"""
|
||||
"""
|
||||
@@ -78,42 +85,91 @@ class DatasetManager( base.ModelManager, base.AccessibleModelInterface, base.Pur
|
||||
return True
|
||||
return False
|
||||
|
||||
def _access_permission( self, trans, dataset, user=None, role=None ):
|
||||
"""
|
||||
"""
|
||||
security_agent = trans.app.security_agent
|
||||
access_action = security_agent.permitted_actions.DATASET_ACCESS.action
|
||||
|
||||
# get a list of role ids to check access for (defaulting to all_roles)
|
||||
user_roles = [ role ] if role else user.all_roles()
|
||||
user_role_ids = [ role.id for role in user_roles ]
|
||||
query = ( trans.sa_session.query( model.DatasetPermissions )
|
||||
.filter( model.DatasetPermissions.action == access_action )
|
||||
.filter( model.DatasetPermissions.dataset == dataset )
|
||||
.filter( model.DatasetPermissions.role_id.in_( user_role_ids ) ) )
|
||||
perms = query.all()
|
||||
if len( perms ):
|
||||
return perms[0]
|
||||
return None
|
||||
|
||||
def _create_access_permission( self, trans, dataset, role, flush=True ):
|
||||
"""
|
||||
"""
|
||||
access_action = trans.app.security_agent.permitted_actions.DATASET_ACCESS.action
|
||||
permission = model.DatasetPermissions( access_action, dataset, role )
|
||||
trans.sa_session.add( permission )
|
||||
if flush:
|
||||
trans.sa_session.flush()
|
||||
return permission
|
||||
|
||||
def has_access_permission( self, trans, dataset, user ):
|
||||
"""
|
||||
"""
|
||||
roles = user.roles if user else []
|
||||
|
||||
roles = user.all_roles() if user else []
|
||||
return trans.app.security_agent.can_access_dataset( roles, dataset )
|
||||
|
||||
def give_access_permission( self, trans, dataset, user ):
|
||||
"""
|
||||
"""
|
||||
#permission = {}
|
||||
##TODO:?? is this correct and reliable?
|
||||
#user_private_role = self.user_mgr.private_role( trans, user )
|
||||
#permission[ trans.app.security_agent.permitted_actions.DATASET_ACCESS ] = [ user_private_role ]
|
||||
#trans.app.security_agent.set_dataset_permission( dataset, permission )
|
||||
pass
|
||||
#TODO: this needs work
|
||||
#def give_access_permission( self, trans, dataset, user, flush=True ):
|
||||
# """
|
||||
# """
|
||||
# # for now, use the user's private role
|
||||
# security_agent = trans.app.security_agent
|
||||
# user_role = security_agent.get_private_user_role( user )
|
||||
#
|
||||
# existing_permission = self._access_permission( trans, dataset, role=user_role )
|
||||
# print 'existing access_perm:', existing_permission
|
||||
# if existing_permission:
|
||||
# return dataset
|
||||
#
|
||||
# permission = self._create_access_permission( trans, dataset, user_role )
|
||||
# print 'access_roles:', [ role.name for role in dataset.get_access_roles( trans ) ]
|
||||
#
|
||||
# #access_action = security_agent.permitted_actions.DATASET_ACCESS.action
|
||||
# #access_action = security_agent.get_action( access_action )
|
||||
# #permissions = { access_action : [ user_role ] }
|
||||
# #security_agent.set_dataset_permission( dataset, permissions )
|
||||
#
|
||||
# #trans.sa_session.add( dataset )
|
||||
# #if flush:
|
||||
# # trans.sa_session.flush()
|
||||
#
|
||||
# dbl_chk = self._access_permission( trans, dataset, role=user_role )
|
||||
# print 'access_perm:', dbl_chk
|
||||
#
|
||||
# return dataset
|
||||
|
||||
def remove_access_permission( self, trans, dataset, user ):
|
||||
"""
|
||||
"""
|
||||
pass
|
||||
#def remove_access_permission( self, trans, dataset, user ):
|
||||
# """
|
||||
# """
|
||||
# pass
|
||||
|
||||
# ......................................................................... manage/modify
|
||||
def has_manage_permission( self, trans, dataset, user ):
|
||||
"""
|
||||
"""
|
||||
pass
|
||||
|
||||
def give_manage_permission( self, trans, dataset, user ):
|
||||
"""
|
||||
"""
|
||||
pass
|
||||
|
||||
def remove_manage_permission( self, trans, dataset, user ):
|
||||
"""
|
||||
"""
|
||||
pass
|
||||
#def has_manage_permission( self, trans, dataset, user ):
|
||||
# """
|
||||
# """
|
||||
# pass
|
||||
#
|
||||
#def give_manage_permission( self, trans, dataset, user ):
|
||||
# """
|
||||
# """
|
||||
# pass
|
||||
#
|
||||
#def remove_manage_permission( self, trans, dataset, user ):
|
||||
# """
|
||||
# """
|
||||
# pass
|
||||
|
||||
#TODO: implement above for groups
|
||||
#TODO: datatypes?
|
||||
@@ -183,9 +239,11 @@ class DatasetAssociationManager( base.ModelManager, base.AccessibleModelInterfac
|
||||
def metadata( self, trans, dataset_assoc ):
|
||||
"""
|
||||
"""
|
||||
# get metadata
|
||||
pass
|
||||
|
||||
def is_being_used( self, trans, dataset_assoc ):
|
||||
"""
|
||||
"""
|
||||
#TODO: check history_associations, library_associations
|
||||
pass
|
||||
|
||||
@@ -37,11 +37,11 @@ class HDAManager( datasets.DatasetAssociationManager, base.OwnableModelInterface
|
||||
def is_accessible( self, trans, hda, user ):
|
||||
"""
|
||||
"""
|
||||
if self.is_owned( trans, hda, user ):
|
||||
if self.is_owner( trans, hda, user ):
|
||||
return True
|
||||
return super( HDAManager, self ).is_accessible( trans, hda, user )
|
||||
|
||||
def is_owned( self, trans, hda, user ):
|
||||
def is_owner( self, trans, hda, user ):
|
||||
"""
|
||||
Use history to see if current user owns HDA.
|
||||
"""
|
||||
@@ -116,7 +116,9 @@ class HDAManager( datasets.DatasetAssociationManager, base.OwnableModelInterface
|
||||
def purge( self, trans, hda ):
|
||||
"""
|
||||
"""
|
||||
self.error_unless_dataset_purge_allowed( trans, hda )
|
||||
# error here if disallowed - before jobs are stopped
|
||||
#TODO: poss. move to DatasetAssociationManager
|
||||
self.dataset_mgr.error_unless_dataset_purge_allowed( trans, hda )
|
||||
super( HDAManager, self ).purge( trans, hda, flush=True )
|
||||
|
||||
# signal to stop the creating job?
|
||||
|
||||
@@ -225,7 +225,7 @@ class HistoryManager( sharable.SharableModelManager, base.PurgableModelInterface
|
||||
|
||||
|
||||
## =============================================================================
|
||||
class HistorySerializer( base.ModelSerializer ):
|
||||
class HistorySerializer( sharable.SharableModelSerializer ):
|
||||
"""
|
||||
Interface/service object for serializing histories into dictionaries.
|
||||
"""
|
||||
@@ -321,7 +321,7 @@ class HistorySerializer( base.ModelSerializer ):
|
||||
|
||||
|
||||
# =============================================================================
|
||||
class HistoryDeserializer( base.ModelDeserializer ):
|
||||
class HistoryDeserializer( sharable.SharableModelDeserializer ):
|
||||
"""
|
||||
Interface/service object for validating and deserializing dictionaries into histories.
|
||||
"""
|
||||
|
||||
@@ -22,12 +22,12 @@ class SharableModelManager( base.ModelManager, base.OwnableModelInterface, base.
|
||||
can be published effectively making it available to all other Users
|
||||
can be rated
|
||||
"""
|
||||
# histories, pages, stored workflows, visualizations
|
||||
# e.g. histories, pages, stored workflows, visualizations
|
||||
|
||||
# the model used for UserShareAssociations with this model
|
||||
user_share_model = None
|
||||
|
||||
def __init__( self, app ):
|
||||
"""
|
||||
"""
|
||||
super( SharableModelManager, self ).__init__( app )
|
||||
# user manager is needed to check access/ownership/admin
|
||||
self.user_mgr = users.UserManager( app )
|
||||
@@ -40,22 +40,21 @@ class SharableModelManager( base.ModelManager, base.OwnableModelInterface, base.
|
||||
filters=self._munge_filters( user_filter, filters )
|
||||
return self.query( trans, filters=filters, **kwargs )
|
||||
|
||||
def by_user( self, trans, user, filters=None, **kwargs ):
|
||||
def by_user( self, trans, user, **kwargs ):
|
||||
"""
|
||||
"""
|
||||
user_filter = self.model_class.user_id == user.id
|
||||
filters=self._munge_filters( user_filter, filters )
|
||||
#note: no ownership check needed
|
||||
return self.list( trans, filters=filters, **kwargs )
|
||||
query = self._query_by_user( trans, user, **kwargs )
|
||||
return self.list( trans, query=query, **kwargs )
|
||||
|
||||
# ......................................................................... owned model interface
|
||||
# this really is more of a 'check_*editable/write*' - in essence that's what check_ownership boils down to often
|
||||
def is_owner( self, trans, item, user ):
|
||||
"""
|
||||
Return true if this sharable belongs to `user` (or `user` is an admin).
|
||||
"""
|
||||
if self.user_mgr.is_anonymous( user ):
|
||||
# note: this needs to be overridden in the case of anon users and session.current_history
|
||||
return False
|
||||
# ... effectively a good fit to have this here, but not semantically
|
||||
if self.user_mgr.is_admin( trans, user ):
|
||||
return True
|
||||
return item.user == user
|
||||
@@ -63,6 +62,8 @@ class SharableModelManager( base.ModelManager, base.OwnableModelInterface, base.
|
||||
# ......................................................................... accessible interface
|
||||
def is_accessible( self, trans, item, user ):
|
||||
"""
|
||||
If the item is importable, is owned by `user`, or (the valid) `user`
|
||||
is in 'users shared with' list for the item: return True.
|
||||
"""
|
||||
if item.importable:
|
||||
return True
|
||||
@@ -76,6 +77,8 @@ class SharableModelManager( base.ModelManager, base.OwnableModelInterface, base.
|
||||
return False
|
||||
|
||||
# ......................................................................... importable
|
||||
#TODO: the relationship between importable and published is ill defined
|
||||
#??: can a published item be non-importable?
|
||||
def make_importable( self, trans, item, flush=True ):
|
||||
"""
|
||||
Makes item accessible--viewable and importable--and sets item's slug.
|
||||
@@ -95,7 +98,6 @@ class SharableModelManager( base.ModelManager, base.OwnableModelInterface, base.
|
||||
Does not flush/commit changes, however. Item must have name, user,
|
||||
importable, and slug attributes.
|
||||
"""
|
||||
#??: can a published item be non-importable?
|
||||
#if item.published:
|
||||
# if unpublish:
|
||||
# self.unpublish( trans, item, flush=False )
|
||||
@@ -107,13 +109,21 @@ class SharableModelManager( base.ModelManager, base.OwnableModelInterface, base.
|
||||
trans.sa_session.flush()
|
||||
return item
|
||||
|
||||
def list_importable( self, trans, **kwargs ):
|
||||
#TODO:
|
||||
"""
|
||||
"""
|
||||
pass
|
||||
#def _query_importable( self, trans, filters=None, **kwargs ):
|
||||
# """
|
||||
# """
|
||||
# importable_filter = self.model_class.importable == True
|
||||
# filters = self._munge_filters( importable_filter, filters )
|
||||
# return self.list( trans, filters=filters, **kwargs )
|
||||
#
|
||||
#def list_importable( self, trans, **kwargs ):
|
||||
# """
|
||||
# """
|
||||
# query = self._query_importable( trans, user, **kwargs )
|
||||
# return self.list( trans, query=query, **kwargs )
|
||||
|
||||
# ......................................................................... published
|
||||
#TODO: the relationship between importable and published is ill defined
|
||||
#def publish( self, trans, item, make_accessible=True, flush=True ):
|
||||
# if not item.importable:
|
||||
# if make_accessible:
|
||||
@@ -124,6 +134,7 @@ class SharableModelManager( base.ModelManager, base.OwnableModelInterface, base.
|
||||
# a published item is also/already importable(=True) implicitly
|
||||
def publish( self, trans, item, flush=True ):
|
||||
"""
|
||||
Set both the importable and published flags on `item` to True.
|
||||
"""
|
||||
if not item.importable:
|
||||
self.make_importable( trans, item, flush=False )
|
||||
@@ -135,6 +146,7 @@ class SharableModelManager( base.ModelManager, base.OwnableModelInterface, base.
|
||||
|
||||
def unpublish( self, trans, item, flush=True ):
|
||||
"""
|
||||
Set the published flag on `item` to False.
|
||||
"""
|
||||
trans.sa_session.add( item )
|
||||
item.published = False
|
||||
@@ -142,11 +154,18 @@ class SharableModelManager( base.ModelManager, base.OwnableModelInterface, base.
|
||||
trans.sa_session.flush()
|
||||
return item
|
||||
|
||||
def list_published( self, trans, **kwargs ):
|
||||
#TODO:
|
||||
"""
|
||||
"""
|
||||
pass
|
||||
#def _query_published( self, trans, filters=None, **kwargs ):
|
||||
# """
|
||||
# """
|
||||
# published_filter = self.model_class.published == True
|
||||
# filters = self._munge_filters( published_filter, filters )
|
||||
# return self.list( trans, filters=filters, **kwargs )
|
||||
#
|
||||
#def list_published( self, trans, **kwargs ):
|
||||
# """
|
||||
# """
|
||||
# query = self._query_published( trans, user, **kwargs )
|
||||
# return self.list( trans, query=query, **kwargs )
|
||||
|
||||
# ......................................................................... user sharing
|
||||
# sharing is often done via a 3rd table btwn a User and an item -> a <Item>UserShareAssociation
|
||||
@@ -186,23 +205,31 @@ class SharableModelManager( base.ModelManager, base.OwnableModelInterface, base.
|
||||
trans.sa_session.flush()
|
||||
return item
|
||||
|
||||
def list_shared_with( self, trans, item, user, **kwargs ):
|
||||
#TODO:
|
||||
"""
|
||||
"""
|
||||
pass
|
||||
#def _query_shared_with( self, trans, user, filters=None, **kwargs ):
|
||||
##TODO:
|
||||
# """
|
||||
# """
|
||||
# pass
|
||||
|
||||
#def list_published( self, trans, user, **kwargs ):
|
||||
# """
|
||||
# """
|
||||
# query = self._query_shared_with( trans, user, **kwargs )
|
||||
# return self.list( trans, query=query, **kwargs )
|
||||
|
||||
# ......................................................................... slugs
|
||||
# slugs are human readable strings often used to link to sharable resources (replacing ids)
|
||||
#TODO: as validator, deserializer, etc. (maybe another object entirely?)
|
||||
def is_valid_slug( self, slug ):
|
||||
"""
|
||||
Returns true if slug is valid.
|
||||
Returns true if `slug` is valid.
|
||||
"""
|
||||
VALID_SLUG_RE = re.compile( "^[a-z0-9\-]+$" )
|
||||
return VALID_SLUG_RE.match( slug )
|
||||
|
||||
def set_slug( self, trans, item, new_slug, flush=True ):
|
||||
"""
|
||||
Validate and set the new slug for `item`.
|
||||
"""
|
||||
if not self.is_valid_slug( new_slug ):
|
||||
raise exceptions.RequestParameterInvalidException( "Invalid slug", slug=new_slug )
|
||||
@@ -228,6 +255,7 @@ class SharableModelManager( base.ModelManager, base.OwnableModelInterface, base.
|
||||
# Setup slug base.
|
||||
if cur_slug is None or cur_slug == "":
|
||||
# Item can have either a name or a title.
|
||||
#TODO: this depends on the model having name or title
|
||||
if hasattr( item, 'name' ):
|
||||
item_name = item.name
|
||||
elif hasattr( item, 'title' ):
|
||||
@@ -282,6 +310,16 @@ class SharableModelManager( base.ModelManager, base.OwnableModelInterface, base.
|
||||
# """ Returns item's name and link. """
|
||||
|
||||
|
||||
# =============================================================================
|
||||
class SharableModelSerializer( base.ModelSerializer ):
|
||||
pass
|
||||
|
||||
# the only ones that needs any fns:
|
||||
# user/user_id
|
||||
# user_shares?
|
||||
# username_and_slug?
|
||||
|
||||
|
||||
# =============================================================================
|
||||
class SharableModelDeserializer( base.ModelDeserializer ):
|
||||
|
||||
|
||||
@@ -161,9 +161,6 @@ class UserManager( base.ModelManager ):
|
||||
#TODO: catch NoResultFound
|
||||
return trans.sa_session.query( model.APIKeys ).filter_by( user=user ).one()
|
||||
|
||||
#TODO: there is quite a bit of functionality around the user (authentication, quotas, groups/roles)
|
||||
# most of which it may be unneccessary to have here
|
||||
|
||||
# ------------------------------------------------------------------------- roles
|
||||
def private_role( self, trans, user ):
|
||||
"""
|
||||
@@ -171,6 +168,9 @@ class UserManager( base.ModelManager ):
|
||||
#TODO: not sure we need to go through sec agent... it's just the first role of type private
|
||||
return trans.app.security_agent.get_private_user_role( user )
|
||||
|
||||
#TODO: there is quite a bit of functionality around the user (authentication, quotas, groups/roles)
|
||||
# most of which it may be unneccessary to have here
|
||||
|
||||
|
||||
# =============================================================================
|
||||
class UserSerializer( base.ModelSerializer ):
|
||||
|
||||
@@ -95,6 +95,30 @@ class DatasetManagerTestCase( BaseTestCase ):
|
||||
self.assertRaises( exceptions.ConfigDoesNotAllowException, self.dataset_mgr.purge, self.trans, item1 )
|
||||
self.assertFalse( item1.purged )
|
||||
|
||||
##TODO: I'm unclear as to how these work, so I'm kicking this down the road a bit....
|
||||
#def test_access_permission( self ):
|
||||
# owner = self.user_mgr.create( self.trans, **user2_data )
|
||||
# dataset = self.dataset_mgr.create( self.trans )
|
||||
# # giving one user access permission makes it non-public, removing access for anyone else
|
||||
# self.dataset_mgr.give_access_permission( self.trans, dataset, owner )
|
||||
#
|
||||
# user3 = self.user_mgr.create( self.trans, **user3_data )
|
||||
# user4 = self.user_mgr.create( self.trans,
|
||||
# email='user4@user4.user4', username='user4', password=default_password )
|
||||
#
|
||||
# self.assertTrue( self.dataset_mgr.has_access_permission( self.trans, dataset, owner ) )
|
||||
# self.assertFalse( self.dataset_mgr.has_access_permission( self.trans, dataset, user3 ) )
|
||||
# self.assertFalse( self.dataset_mgr.has_access_permission( self.trans, dataset, user4 ) )
|
||||
#
|
||||
# # should be able to progressively add more roles without removing the previous
|
||||
# self.dataset_mgr.give_access_permission( self.trans, dataset, user3 )
|
||||
# self.assertTrue( self.dataset_mgr.has_access_permission( self.trans, dataset, user3 ) )
|
||||
# self.assertTrue( self.dataset_mgr.has_access_permission( self.trans, dataset, owner ) )
|
||||
# self.assertFalse( self.dataset_mgr.has_access_permission( self.trans, dataset, user4 ) )
|
||||
#
|
||||
# #self.assertTrue( self.dataset_mgr.is_accessible( self.trans, dataset, owner ) )
|
||||
# #self.assertFalse( self.dataset_mgr.is_accessible( self.trans, dataset, non_owner ) )
|
||||
|
||||
def test_accessible( self ):
|
||||
owner = self.user_mgr.create( self.trans, **user2_data )
|
||||
non_owner = self.user_mgr.create( self.trans, **user3_data )
|
||||
@@ -105,11 +129,6 @@ class DatasetManagerTestCase( BaseTestCase ):
|
||||
for user in self.user_mgr.list( self.trans ):
|
||||
self.assertTrue( self.dataset_mgr.is_accessible( self.trans, dataset, user ) )
|
||||
|
||||
#TODO: this is ... not working...
|
||||
#self.dataset_mgr.give_access_permission( self.trans, dataset, owner )
|
||||
#self.assertTrue( self.dataset_mgr.is_accessible( self.trans, dataset, owner ) )
|
||||
#self.assertFalse( self.dataset_mgr.is_accessible( self.trans, dataset, non_owner ) )
|
||||
|
||||
|
||||
# =============================================================================
|
||||
class DatasetAssociationManagerTestCase( BaseTestCase ):
|
||||
|
||||
@@ -36,6 +36,33 @@ class HDAManagerTestCase( BaseTestCase ):
|
||||
self.dataset_mgr = DatasetManager( self.app )
|
||||
self.hda_mgr = HDAManager( self.app )
|
||||
|
||||
def test_base( self ):
|
||||
hda_model = model.HistoryDatasetAssociation
|
||||
owner = self.user_mgr.create( self.trans, **user2_data )
|
||||
history1 = self.history_mgr.create( self.trans, name='history1', user=owner )
|
||||
hda1 = self.hda_mgr.create( self.trans, history=history1, hid=1 )
|
||||
hda2 = self.hda_mgr.create( self.trans, history=history1, hid=2 )
|
||||
hda3 = self.hda_mgr.create( self.trans, history=history1, hid=3 )
|
||||
|
||||
self.log( "should be able to query" )
|
||||
hdas = self.trans.sa_session.query( hda_model ).all()
|
||||
self.assertEqual( self.hda_mgr.list( self.trans ), hdas )
|
||||
self.assertEqual( self.hda_mgr.one( self.trans, filters=( hda_model.id == hda1.id ) ), hda1 )
|
||||
self.assertEqual( self.hda_mgr.by_id( self.trans, hda1.id ), hda1 )
|
||||
self.assertEqual( self.hda_mgr.by_ids( self.trans, [ hda2.id, hda1.id ] ), [ hda2, hda1 ] )
|
||||
|
||||
self.log( "should be able to limit and offset" )
|
||||
self.assertEqual( self.hda_mgr.list( self.trans, limit=1 ), hdas[0:1] )
|
||||
self.assertEqual( self.hda_mgr.list( self.trans, offset=1 ), hdas[1:] )
|
||||
self.assertEqual( self.hda_mgr.list( self.trans, limit=1, offset=1 ), hdas[1:2] )
|
||||
|
||||
self.assertEqual( self.hda_mgr.list( self.trans, limit=0 ), [] )
|
||||
self.assertEqual( self.hda_mgr.list( self.trans, offset=3 ), [] )
|
||||
|
||||
self.log( "should be able to order" )
|
||||
self.assertEqual( self.hda_mgr.list( self.trans, order_by=sqlalchemy.desc( hda_model.create_time ) ),
|
||||
[ hda3, hda2, hda1 ] )
|
||||
|
||||
def test_create( self ):
|
||||
owner = self.user_mgr.create( self.trans, **user2_data )
|
||||
non_owner = self.user_mgr.create( self.trans, **user3_data )
|
||||
@@ -87,33 +114,6 @@ class HDAManagerTestCase( BaseTestCase ):
|
||||
# self.log( "should be able to copy an HDA" )
|
||||
# hda2 = self.hda_mgr.copy_ldda( self.trans, history1, hda1 )
|
||||
|
||||
def test_base( self ):
|
||||
hda_model = model.HistoryDatasetAssociation
|
||||
owner = self.user_mgr.create( self.trans, **user2_data )
|
||||
history1 = self.history_mgr.create( self.trans, name='history1', user=owner )
|
||||
hda1 = self.hda_mgr.create( self.trans, history=history1, hid=1 )
|
||||
hda2 = self.hda_mgr.create( self.trans, history=history1, hid=2 )
|
||||
hda3 = self.hda_mgr.create( self.trans, history=history1, hid=3 )
|
||||
|
||||
self.log( "should be able to query" )
|
||||
hdas = self.trans.sa_session.query( hda_model ).all()
|
||||
self.assertEqual( self.hda_mgr.list( self.trans ), hdas )
|
||||
self.assertEqual( self.hda_mgr.one( self.trans, filters=( hda_model.id == hda1.id ) ), hda1 )
|
||||
self.assertEqual( self.hda_mgr.by_id( self.trans, hda1.id ), hda1 )
|
||||
self.assertEqual( self.hda_mgr.by_ids( self.trans, [ hda2.id, hda1.id ] ), [ hda2, hda1 ] )
|
||||
|
||||
self.log( "should be able to limit and offset" )
|
||||
self.assertEqual( self.hda_mgr.list( self.trans, limit=1 ), hdas[0:1] )
|
||||
self.assertEqual( self.hda_mgr.list( self.trans, offset=1 ), hdas[1:] )
|
||||
self.assertEqual( self.hda_mgr.list( self.trans, limit=1, offset=1 ), hdas[1:2] )
|
||||
|
||||
self.assertEqual( self.hda_mgr.list( self.trans, limit=0 ), [] )
|
||||
self.assertEqual( self.hda_mgr.list( self.trans, offset=3 ), [] )
|
||||
|
||||
self.log( "should be able to order" )
|
||||
self.assertEqual( self.hda_mgr.list( self.trans, order_by=sqlalchemy.desc( hda_model.create_time ) ),
|
||||
[ hda3, hda2, hda1 ] )
|
||||
|
||||
def test_delete( self ):
|
||||
owner = self.user_mgr.create( self.trans, **user2_data )
|
||||
history1 = self.history_mgr.create( self.trans, name='history1', user=owner )
|
||||
@@ -142,8 +142,6 @@ class HDAManagerTestCase( BaseTestCase ):
|
||||
|
||||
def test_purge_not_allowed( self ):
|
||||
self.trans.app.config.allow_user_dataset_purge = False
|
||||
self.assertRaises( exceptions.ConfigDoesNotAllowException,
|
||||
self.hda_mgr.error_unless_dataset_purge_allowed, self.trans, None )
|
||||
|
||||
owner = self.user_mgr.create( self.trans, **user2_data )
|
||||
history1 = self.history_mgr.create( self.trans, name='history1', user=owner )
|
||||
@@ -155,27 +153,31 @@ class HDAManagerTestCase( BaseTestCase ):
|
||||
self.assertRaises( exceptions.ConfigDoesNotAllowException, self.hda_mgr.purge, self.trans, item1 )
|
||||
self.assertFalse( item1.purged )
|
||||
|
||||
#def test_ownable( self ):
|
||||
# owner = self.user_mgr.create( self.trans, **user2_data )
|
||||
# non_owner = self.user_mgr.create( self.trans, **user3_data )
|
||||
#
|
||||
# history1 = self.history_mgr.create( self.trans, name='history1', user=owner )
|
||||
# dataset1 = self.dataset_mgr.create( self.trans )
|
||||
# item1 = self.hda_mgr.create( self.trans, history1, dataset1 )
|
||||
#
|
||||
# self.log( "should be able to poll whether a given user owns an item" )
|
||||
# self.assertTrue( self.hda_mgr.is_owner( self.trans, item1, owner ) )
|
||||
# self.assertFalse( self.hda_mgr.is_owner( self.trans, item1, non_owner ) )
|
||||
#
|
||||
# self.log( "should raise an error when checking ownership with non-owner" )
|
||||
# self.assertRaises( exceptions.ItemOwnershipException,
|
||||
# self.hda_mgr.check_ownership, self.trans, item1, non_owner )
|
||||
#
|
||||
# self.log( "should not raise an error when checking ownership with owner" )
|
||||
# self.assertEqual( self.hda_mgr.check_ownership( self.trans, item1, owner ), item1 )
|
||||
#
|
||||
# #self.log( "should not raise an error when checking ownership with admin" )
|
||||
# #self.assertEqual( self.hda_mgr.check_ownership( self.trans, item1, self.admin_user ), item1 )
|
||||
def test_ownable( self ):
|
||||
owner = self.user_mgr.create( self.trans, **user2_data )
|
||||
non_owner = self.user_mgr.create( self.trans, **user3_data )
|
||||
|
||||
history1 = self.history_mgr.create( self.trans, name='history1', user=owner )
|
||||
dataset1 = self.dataset_mgr.create( self.trans )
|
||||
item1 = self.hda_mgr.create( self.trans, history1, dataset1 )
|
||||
|
||||
self.log( "should be able to poll whether a given user owns an item" )
|
||||
self.assertTrue( self.hda_mgr.is_owner( self.trans, item1, owner ) )
|
||||
self.assertFalse( self.hda_mgr.is_owner( self.trans, item1, non_owner ) )
|
||||
|
||||
self.log( "should raise an error when checking ownership with non-owner" )
|
||||
self.assertRaises( exceptions.ItemOwnershipException,
|
||||
self.hda_mgr.error_unless_owner, self.trans, item1, non_owner )
|
||||
|
||||
self.log( "should raise an error when checking ownership with anonymous" )
|
||||
self.assertRaises( exceptions.ItemOwnershipException,
|
||||
self.hda_mgr.error_unless_owner, self.trans, item1, None )
|
||||
|
||||
self.log( "should not raise an error when checking ownership with owner" )
|
||||
self.assertEqual( self.hda_mgr.error_unless_owner( self.trans, item1, owner ), item1 )
|
||||
|
||||
self.log( "should not raise an error when checking ownership with admin" )
|
||||
self.assertEqual( self.hda_mgr.error_unless_owner( self.trans, item1, self.admin_user ), item1 )
|
||||
|
||||
def test_accessible( self ):
|
||||
owner = self.user_mgr.create( self.trans, **user2_data )
|
||||
@@ -189,6 +191,26 @@ class HDAManagerTestCase( BaseTestCase ):
|
||||
for user in self.user_mgr.list( self.trans ):
|
||||
self.assertTrue( self.hda_mgr.is_accessible( self.trans, item1, user ) )
|
||||
|
||||
#TODO: set perms on underlying dataset and then test accessible
|
||||
|
||||
def test_anon( self ):
|
||||
anon_user = None
|
||||
self.trans.set_user( anon_user )
|
||||
|
||||
history1 = self.history_mgr.create( self.trans, name='anon_history', user=anon_user )
|
||||
self.trans.set_history( history1 )
|
||||
dataset1 = self.dataset_mgr.create( self.trans )
|
||||
item1 = self.hda_mgr.create( self.trans, history1, dataset1 )
|
||||
|
||||
self.log( "should not raise an error when checking ownership/access on anonymous' own dataset" )
|
||||
self.assertTrue( self.hda_mgr.is_accessible( self.trans, item1, anon_user ) )
|
||||
self.assertEqual( self.hda_mgr.error_unless_owner( self.trans, item1, anon_user ), item1 )
|
||||
|
||||
self.log( "should raise an error when checking ownership on anonymous' dataset with other user" )
|
||||
non_owner = self.user_mgr.create( self.trans, **user3_data )
|
||||
self.assertRaises( exceptions.ItemOwnershipException,
|
||||
self.hda_mgr.error_unless_owner, self.trans, item1, non_owner )
|
||||
|
||||
|
||||
# =============================================================================
|
||||
if __name__ == '__main__':
|
||||
|
||||
Reference in New Issue
Block a user