Skip to content

Commit

Permalink
add API endpoint to un/mark library folder as deleted
Browse files Browse the repository at this point in the history
  • Loading branch information
martenson committed Dec 5, 2014
1 parent 61bf387 commit c14342b
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 17 deletions.
49 changes: 34 additions & 15 deletions lib/galaxy/managers/folders.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,14 @@ class FolderManager( object ):
Interface/service object for interacting with folders.
"""

def get( self, trans, decoded_folder_id, check_ownership=False, check_accessible=True):
def get( self, trans, decoded_folder_id, check_manageable=False, check_accessible=True):
"""
Get the folder from the DB.
:param decoded_folder_id: decoded folder id
:type decoded_folder_id: int
:param check_ownership: flag whether the check that user is owner
:type check_ownership: bool
:param check_manageable: flag whether the check that user can manage item
:type check_manageable: bool
:param check_accessible: flag whether to check that user can access item
:type check_accessible: bool
Expand All @@ -38,17 +38,17 @@ def get( self, trans, decoded_folder_id, check_ownership=False, check_accessible
raise exceptions.RequestParameterInvalidException( 'No folder found with the id provided.' )
except Exception, e:
raise exceptions.InternalServerError( 'Error loading from the database.' + str( e ) )
folder = self.secure( trans, folder, check_ownership, check_accessible )
folder = self.secure( trans, folder, check_manageable, check_accessible )
return folder

def secure( self, trans, folder, check_ownership=True, check_accessible=True ):
def secure( self, trans, folder, check_manageable=True, check_accessible=True ):
"""
Check if (a) user owns folder or (b) folder is accessible to user.
Check if (a) user can manage folder or (b) folder is accessible to user.
:param folder: folder item
:type folder: LibraryFolder
:param check_ownership: flag whether the check that user is owner
:type check_ownership: bool
:param check_manageable: flag whether to check that user can manage item
:type check_manageable: bool
:param check_accessible: flag whether to check that user can access item
:type check_accessible: bool
Expand All @@ -58,23 +58,26 @@ def secure( self, trans, folder, check_ownership=True, check_accessible=True ):
# all folders are accessible to an admin
if trans.user_is_admin():
return folder
if check_ownership:
folder = self.check_ownership( trans, folder )
if check_manageable:
folder = self.check_manageable( trans, folder )
if check_accessible:
folder = self.check_accessible( trans, folder )
return folder

def check_ownership( self, trans, folder ):
def check_manageable( self, trans, folder ):
"""
Check whether the user is owner of the folder.
Check whether the user can manage the folder.
:returns: the original folder
:rtype: LibraryFolder
:raises: AuthenticationRequired, InsufficientPermissionsException
"""
if not trans.user:
raise exceptions.AuthenticationRequired( "Must be logged in to manage Galaxy items", type='error' )
if folder.user != trans.user:
raise exceptions.ItemOwnershipException( "Folder is not owned by the current user", type='error' )
raise exceptions.AuthenticationRequired( "Must be logged in to manage Galaxy items.", type='error' )
current_user_roles = trans.get_current_user_roles()
if not trans.app.security_agent.can_manage_library_item( current_user_roles, folder ):
raise exceptions.InsufficientPermissionsException( "You don't have permissions to manage this folder.", type='error' )
else:
return folder

Expand Down Expand Up @@ -135,6 +138,22 @@ def create( self, trans, parent_folder_id, new_folder_name, new_folder_descripti
trans.app.security_agent.copy_library_permissions( trans, parent_folder, new_folder )
return new_folder

def delete( self, trans, folder, undelete=False ):
"""
Mark given folder deleted/undeleted based on the flag.
:raises: ItemAccessibilityException
"""
if not trans.user_is_admin():
folder = self.check_manageable( trans, folder )
if undelete:
folder.deleted = False
else:
folder.deleted = True
trans.sa_session.add( folder )
trans.sa_session.flush()
return folder

def get_current_roles( self, trans, folder ):
"""
Find all roles currently connected to relevant permissions
Expand Down
2 changes: 1 addition & 1 deletion lib/galaxy/model/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2192,7 +2192,7 @@ def get_access_roles( self, trans ):
return roles

class LibraryFolder( object, Dictifiable, HasName ):
dict_element_visible_keys = ( 'id', 'parent_id', 'name', 'description', 'item_count', 'genome_build', 'update_time' )
dict_element_visible_keys = ( 'id', 'parent_id', 'name', 'description', 'item_count', 'genome_build', 'update_time', 'deleted' )
def __init__( self, name=None, description=None, item_count=0, order_id=None ):
self.name = name or "Unnamed folder"
self.description = description
Expand Down
28 changes: 27 additions & 1 deletion lib/galaxy/webapps/galaxy/api/folders.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def show( self, trans, id, **kwd ):
:rtype: dict
"""
folder_id = self.folder_manager.cut_and_decode( trans, id )
folder = self.folder_manager.get( trans, folder_id, check_ownership=False, check_accessible=True )
folder = self.folder_manager.get( trans, folder_id, check_manageable=False, check_accessible=True )
return_dict = self.folder_manager.get_folder_dict( trans, folder )
return return_dict

Expand Down Expand Up @@ -229,6 +229,32 @@ def set_permissions( self, trans, encoded_folder_id, **kwd ):
'Allowed values are: "set_permissions"' )
return self.folder_manager.get_current_roles( trans, folder )

@expose_api
def delete( self, trans, id, **kwd ):
"""
delete( self, trans, id, **kwd )
* DELETE /api/folders/{id}
marks the folder with the given ``id`` as `deleted` (or removes the `deleted` mark if the `undelete` param is true)
.. note:: Currently, only admin users can un/delete folders.
:param id: the encoded id of the folder to un/delete
:type id: an encoded id string
:param undelete: (optional) flag specifying whether the item should be deleted or undeleted, defaults to false:
:type undelete: bool
:returns: detailed folder information
:rtype: dictionary
:raises: ItemAccessibilityException, MalformedId, ObjectNotFound
"""
folder = self.folder_manager.get( trans, self.folder_manager.cut_and_decode( trans, id ), True )
undelete = util.string_as_bool( kwd.get( 'undelete', False ) )
folder = self.folder_manager.delete( trans, folder, undelete )
folder_dict = self.folder_manager.get_folder_dict( trans, folder )
return folder_dict

@web.expose_api
def update( self, trans, id, library_id, payload, **kwd ):
"""
Expand Down

0 comments on commit c14342b

Please sign in to comment.