def create(self, trans, parent_folder_id, new_folder_name, new_folder_description=''): """ Create a new folder under the given folder. :param parent_folder_id: decoded id :type parent_folder_id: int :param new_folder_name: name of the new folder :type new_folder_name: str :param new_folder_description: description of the folder (optional, defaults to empty string) :type new_folder_description: str :returns: the new folder :rtype: LibraryFolder :raises: InsufficientPermissionsException """ parent_folder = self.get(trans, parent_folder_id) current_user_roles = trans.get_current_user_roles() if not (trans.user_is_admin or trans.app.security_agent.can_add_library_item(current_user_roles, parent_folder)): raise InsufficientPermissionsException('You do not have proper permission to create folders under given folder.') new_folder = trans.app.model.LibraryFolder(name=new_folder_name, description=new_folder_description) # We are associating the last used genome build with folders, so we will always # initialize a new folder with the first dbkey in genome builds list which is currently # ? unspecified (?) new_folder.genome_build = trans.app.genome_builds.default_value parent_folder.add_folder(new_folder) trans.sa_session.add(new_folder) trans.sa_session.flush() # New folders default to having the same permissions as their parent folder trans.app.security_agent.copy_library_permissions(trans, parent_folder, new_folder) return new_folder
def update(self, trans, folder, name=None, description=None): """ Update the given folder's name or description. :param folder: the model object :type folder: LibraryFolder :param name: new name for the library folder :type name: str :param description: new description for the library folder :type description: str :returns: the folder :rtype: LibraryFolder :raises: ItemAccessibilityException, InsufficientPermissionsException """ changed = False if not trans.user_is_admin: if not self.check_manageable(trans, folder): raise InsufficientPermissionsException("You do not have proper permission to update the library folder.") if folder.deleted is True: raise ItemAccessibilityException("You cannot update a deleted library folder. Undelete it first.") if name is not None and name != folder.name: folder.name = name changed = True if description is not None and description != folder.description: folder.description = description changed = True if changed: trans.sa_session.add(folder) trans.sa_session.flush() return folder
def get_permissions(self, trans, encoded_folder_id, scope=None, page=None, page_limit=None, query=None): """ Load all permissions for the given folder id and return it. :param encoded_folder_id: the encoded id of the folder :type encoded_folder_id: an encoded id string :param scope: either 'current' or 'available' :type scope: string :returns: dictionary with all applicable permissions' values :rtype: dictionary :raises: InsufficientPermissionsException """ current_user_roles = trans.get_current_user_roles() is_admin = trans.user_is_admin decoded_folder_id = self.folder_manager.cut_and_decode( trans, encoded_folder_id) folder = self.folder_manager.get(trans, decoded_folder_id) if not (is_admin or trans.app.security_agent.can_manage_library_item( current_user_roles, folder)): raise InsufficientPermissionsException( 'You do not have proper permission to access permissions of this folder.' ) if scope == 'current' or scope is None: return self.folder_manager.get_current_roles(trans, folder) # Return roles that are available to select. elif scope == 'available': if page is not None: page = int(page) else: page = 1 if page_limit is not None: page_limit = int(page_limit) else: page_limit = 10 roles, total_roles = trans.app.security_agent.get_valid_roles( trans, folder, query, page, page_limit) return_roles = [] for role in roles: role_id = trans.security.encode_id(role.id) return_roles.append( dict(id=role_id, name=role.name, type=role.type)) return dict(roles=return_roles, page=page, page_limit=page_limit, total=total_roles) else: raise RequestParameterInvalidException( "The value of 'scope' parameter is invalid. Alllowed values: current, available" )
def get_permissions( self, trans, encoded_folder_id: EncodedDatabaseIdField, scope: Optional[LibraryPermissionScope] = LibraryPermissionScope. current, page: Optional[int] = 1, page_limit: Optional[int] = 10, query: Optional[str] = None, ) -> Union[LibraryFolderCurrentPermissions, LibraryAvailablePermissions]: """ Load all permissions for the given folder id and return it. :param encoded_folder_id: the encoded id of the folder :type encoded_folder_id: an encoded id string :param scope: either 'current' or 'available' :type scope: string :returns: dictionary with all applicable permissions' values :rtype: dictionary :raises: InsufficientPermissionsException """ current_user_roles = trans.get_current_user_roles() is_admin = trans.user_is_admin decoded_folder_id = self.folder_manager.cut_and_decode( trans, encoded_folder_id) folder = self.folder_manager.get(trans, decoded_folder_id) if not (is_admin or trans.app.security_agent.can_manage_library_item( current_user_roles, folder)): raise InsufficientPermissionsException( 'You do not have proper permission to access permissions of this folder.' ) if scope is None or scope == LibraryPermissionScope.current: current_permissions = self.folder_manager.get_current_roles( trans, folder) return LibraryFolderCurrentPermissions.parse_obj( current_permissions) # Return roles that are available to select. elif scope == LibraryPermissionScope.available: roles, total_roles = trans.app.security_agent.get_valid_roles( trans, folder, query, page, page_limit) return_roles = [] for role in roles: role_id = trans.security.encode_id(role.id) return_roles.append( dict(id=role_id, name=role.name, type=role.type)) return LibraryAvailablePermissions(roles=return_roles, page=page, page_limit=page_limit, total=total_roles) else: raise RequestParameterInvalidException( "The value of 'scope' parameter is invalid. Allowed values: current, available" )
def update( self, trans, id, **kwd ): """ PATCH /api/repositories/{encoded_repository_id} Updates information about a repository in the Tool Shed. :param id: the encoded id of the Repository object :param payload: dictionary structure containing:: 'name': repo's name (optional) 'synopsis': repo's synopsis (optional) 'description': repo's description (optional) 'remote_repository_url': repo's remote repo (optional) 'homepage_url': repo's homepage url (optional) 'category_ids': list of existing encoded TS category ids the updated repo should be associated with (optional) :type payload: dict :returns: detailed repository information :rtype: dict :raises: RequestParameterInvalidException, InsufficientPermissionsException """ payload = kwd.get( 'payload', None ) if not payload: raise RequestParameterMissingException( "You did not specify any payload." ) name = payload.get( 'name', None ) synopsis = payload.get( 'synopsis', None ) description = payload.get( 'description', None ) remote_repository_url = payload.get( 'remote_repository_url', None ) homepage_url = payload.get( 'homepage_url', None ) category_ids = payload.get( 'category_ids', None ) if category_ids is not None: # We need to know if it was actually passed, and listify turns None into [] category_ids = util.listify( category_ids ) update_kwds = dict( name=name, description=synopsis, long_description=description, remote_repository_url=remote_repository_url, homepage_url=homepage_url, category_ids=category_ids, ) repo, message = repository_util.update_repository( app=trans.app, trans=trans, id=id, **update_kwds ) if repo is None: if "You are not the owner" in message: raise InsufficientPermissionsException( message ) else: raise ActionInputError( message ) repository_dict = repo.to_dict( view='element', value_mapper=self.__get_value_mapper( trans ) ) repository_dict[ 'category_ids' ] = \ [ trans.security.encode_id( x.category.id ) for x in repo.categories ] return repository_dict
def check_manageable(self, trans, folder): """ Check whether the user can manage the folder. :returns: the original folder :rtype: LibraryFolder :raises: AuthenticationRequired, InsufficientPermissionsException """ if not trans.user: raise 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 InsufficientPermissionsException("You don't have permissions to manage this folder.", type='error') else: return folder
def check_modifiable(self, trans, ld): """ Check whether the current user has permissions to modify library dataset. :param ld: library dataset :type ld: galaxy.model.LibraryDataset :returns: the original library dataset :rtype: galaxy.model.LibraryDataset :raises: ObjectNotFound """ if ld.deleted: raise ObjectNotFound('Library dataset with the id provided is deleted.') elif trans.user_is_admin: return ld if not trans.app.security_agent.can_modify_library_item(trans.get_current_user_roles(), ld): raise InsufficientPermissionsException('You do not have proper permission to modify this library dataset.') else: return ld
def set_permissions(self, trans, encoded_folder_id: EncodedDatabaseIdField, payload: dict) -> LibraryFolderCurrentPermissions: """ Set permissions of the given folder to the given role ids. :param encoded_folder_id: the encoded id of the folder to set the permissions of :type encoded_folder_id: an encoded id string :param payload: dictionary structure containing: :param action: (required) describes what action should be performed :type action: string :param add_ids[]: list of Role.id defining roles that should have add item permission on the folder :type add_ids[]: string or list :param manage_ids[]: list of Role.id defining roles that should have manage permission on the folder :type manage_ids[]: string or list :param modify_ids[]: list of Role.id defining roles that should have modify permission on the folder :type modify_ids[]: string or list :type dictionary :returns: dict of current roles for all available permission types. :rtype: dictionary :raises: RequestParameterInvalidException, InsufficientPermissionsException, RequestParameterMissingException """ is_admin = trans.user_is_admin current_user_roles = trans.get_current_user_roles() decoded_folder_id = self.folder_manager.cut_and_decode( trans, encoded_folder_id) folder = self.folder_manager.get(trans, decoded_folder_id) if not (is_admin or trans.app.security_agent.can_manage_library_item( current_user_roles, folder)): raise InsufficientPermissionsException( 'You do not have proper permission to modify permissions of this folder.' ) new_add_roles_ids = util.listify(payload.get('add_ids[]', None)) new_manage_roles_ids = util.listify(payload.get('manage_ids[]', None)) new_modify_roles_ids = util.listify(payload.get('modify_ids[]', None)) action = payload.get('action', None) if action is None: raise RequestParameterMissingException( 'The mandatory parameter "action" is missing.') elif action == 'set_permissions': # ADD TO LIBRARY ROLES valid_add_roles = [] invalid_add_roles_names = [] for role_id in new_add_roles_ids: role = self.role_manager.get( trans, trans.security.decode_id(role_id, object_name='role')) # Check whether role is in the set of allowed roles valid_roles, total_roles = trans.app.security_agent.get_valid_roles( trans, folder) if role in valid_roles: valid_add_roles.append(role) else: invalid_add_roles_names.append(role_id) if len(invalid_add_roles_names) > 0: log.warning( f"The following roles could not be added to the add library item permission: {str(invalid_add_roles_names)}" ) # MANAGE FOLDER ROLES valid_manage_roles = [] invalid_manage_roles_names = [] for role_id in new_manage_roles_ids: role = self.role_manager.get( trans, trans.security.decode_id(role_id, object_name='role')) # Check whether role is in the set of allowed roles valid_roles, total_roles = trans.app.security_agent.get_valid_roles( trans, folder) if role in valid_roles: valid_manage_roles.append(role) else: invalid_manage_roles_names.append(role_id) if len(invalid_manage_roles_names) > 0: log.warning( f"The following roles could not be added to the manage folder permission: {str(invalid_manage_roles_names)}" ) # MODIFY FOLDER ROLES valid_modify_roles = [] invalid_modify_roles_names = [] for role_id in new_modify_roles_ids: role = self.role_manager.get( trans, trans.security.decode_id(role_id, object_name='role')) # Check whether role is in the set of allowed roles valid_roles, total_roles = trans.app.security_agent.get_valid_roles( trans, folder) if role in valid_roles: valid_modify_roles.append(role) else: invalid_modify_roles_names.append(role_id) if len(invalid_modify_roles_names) > 0: log.warning( f"The following roles could not be added to the modify folder permission: {str(invalid_modify_roles_names)}" ) permissions = { trans.app.security_agent.permitted_actions.LIBRARY_ADD: valid_add_roles } permissions.update({ trans.app.security_agent.permitted_actions.LIBRARY_MANAGE: valid_manage_roles }) permissions.update({ trans.app.security_agent.permitted_actions.LIBRARY_MODIFY: valid_modify_roles }) trans.app.security_agent.set_all_library_permissions( trans, folder, permissions) else: raise RequestParameterInvalidException( 'The mandatory parameter "action" has an invalid value.' 'Allowed values are: "set_permissions"') current_permissions = self.folder_manager.get_current_roles( trans, folder) return LibraryFolderCurrentPermissions.parse_obj(current_permissions)