def __update_dataset( self, trans, history_id, id, payload, **kwd ): changed = {} # anon user if trans.user == None: if history_id != trans.security.encode_id( trans.history.id ): raise exceptions.AuthenticationRequired( 'You must be logged in to update this history' ) anon_allowed_payload = {} if 'deleted' in payload: anon_allowed_payload[ 'deleted' ] = payload[ 'deleted' ] if 'visible' in payload: anon_allowed_payload[ 'visible' ] = payload[ 'visible' ] payload = self._validate_and_parse_update_payload( anon_allowed_payload ) hda = self.mgrs.hdas.get( trans, self._decode_id( trans, id ), check_ownership=False, check_accessible=False ) hda = self.mgrs.hdas.err_if_uploading( trans, hda ) if hda.history != trans.history: raise exceptions.AuthenticationRequired( 'You must be logged in to update this dataset' ) else: payload = self._validate_and_parse_update_payload( payload ) # only check_state if not deleting, otherwise cannot delete uploading files check_state = not payload.get( 'deleted', False ) hda = self.mgrs.hdas.get( trans, self._decode_id( trans, id ), check_ownership=True, check_accessible=True ) if check_state: hda = self.mgrs.hdas.err_if_uploading( trans, hda ) #hda = self.get_dataset( trans, id, check_ownership=True, check_accessible=True, check_state=check_state ) if hda and isinstance( hda, trans.model.HistoryDatasetAssociation ): changed = self.set_hda_from_dict( trans, hda, payload ) if payload.get( 'deleted', False ): self.stop_hda_creating_job( hda ) return changed
def serialize_current_anonymous_user(self, user, keys, trans=None, **kwargs): # use the current history if any to get usage stats for trans' anonymous user # TODO: might be better as sep. Serializer class history = trans.history if not history: raise exceptions.AuthenticationRequired( 'No history for anonymous user usage stats') usage = self.app.quota_agent.get_usage(trans, history=trans.history) percent = self.app.quota_agent.get_percent(trans=trans, usage=usage) # a very small subset of keys available values = { 'id': None, 'total_disk_usage': float(usage), 'nice_total_disk_usage': util.nice_size(usage), 'quota_percent': percent, } serialized = {} for key in keys: if key in values: serialized[key] = values[key] return serialized
def set_password(self, trans, id, payload=None, **kwd): """ Allows to the logged-in user to change own password. """ payload = payload or {} user, message = self.user_manager.change_password(trans, id=id, **payload) if user is None: raise exceptions.AuthenticationRequired(message) return {"message": "Password has been changed."}
def create( self, trans: ProvidesHistoryContext, payload: CreateHistoryPayload, serialization_params: SerializationParams, ): """Create a new history from scratch, by copying an existing one or by importing from URL or File depending on the provided parameters in the payload. """ copy_this_history_id = payload.history_id if trans.anonymous and not copy_this_history_id: # Copying/Importing histories is allowed for anonymous users raise glx_exceptions.AuthenticationRequired("You need to be logged in to create histories.") if trans.user and trans.user.bootstrap_admin_user: raise glx_exceptions.RealUserRequiredException("Only real users can create histories.") hist_name = None if payload.name is not None: hist_name = restore_text(payload.name) if payload.archive_source is not None or hasattr(payload.archive_file, "file"): archive_source = payload.archive_source archive_file = payload.archive_file if archive_source: archive_type = payload.archive_type elif archive_file is not None and hasattr(archive_file, "file"): archive_source = archive_file.file.name archive_type = HistoryImportArchiveSourceType.file if isinstance(archive_file.file, SpooledTemporaryFile): archive_source = self._save_upload_file_tmp(archive_file) else: raise glx_exceptions.MessageException("Please provide a url or file.") job = self.manager.queue_history_import(trans, archive_type=archive_type, archive_source=archive_source) job_dict = job.to_dict() job_dict["message"] = f"Importing history from source '{archive_source}'. This history will be visible when the import is complete." job_dict = trans.security.encode_all_ids(job_dict) return JobImportHistoryResponse.parse_obj(job_dict) new_history = None # if a history id was passed, copy that history if copy_this_history_id: decoded_id = self.decode_id(copy_this_history_id) original_history = self.manager.get_accessible(decoded_id, trans.user, current_history=trans.history) hist_name = hist_name or (f"Copy of '{original_history.name}'") new_history = original_history.copy(name=hist_name, target_user=trans.user, all_datasets=payload.all_datasets) # otherwise, create a new empty history else: new_history = self.manager.create(user=trans.user, name=hist_name) trans.app.security_agent.history_set_default_permissions(new_history) trans.sa_session.add(new_history) trans.sa_session.flush() # an anonymous user can only have one history if self.user_manager.is_anonymous(trans.user): self.manager.set_current(trans, new_history) return self._serialize_history(trans, new_history, serialization_params)
def check_ownership( self, trans, history ): """ Raises error if the current user is not the owner of the history. """ if trans.user and trans.user_is_admin(): return history if not trans.user and not self.is_current( trans, history ): raise exceptions.AuthenticationRequired( "Must be logged in to manage Galaxy histories", type='error' ) if self.is_owner( trans, history ): return history raise exceptions.ItemOwnershipException( "History is not owned by the current user", type='error' )
def check_ownership( self, trans, folder ): """ Check whether the user is owner of the folder. :returns: the original folder :rtype: LibraryFolder """ 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' ) else: return folder
def __update_dataset(self, trans, history_id, id, payload, **kwd): # anon user: ensure that history ids match up and the history is the current, # check for uploading, and use only the subset of attribute keys manipulatable by anon users if trans.user is None: hda = self.hda_manager.by_id(self.decode_id(id)) if hda.history != trans.history: raise exceptions.AuthenticationRequired( 'API authentication required for this request') hda = self.hda_manager.error_if_uploading(hda) anon_allowed_payload = {} if 'deleted' in payload: anon_allowed_payload['deleted'] = payload['deleted'] if 'visible' in payload: anon_allowed_payload['visible'] = payload['visible'] payload = anon_allowed_payload # logged in user: use full payload, check state if deleting, and make sure the history is theirs else: hda = self.hda_manager.get_owned(self.decode_id(id), trans.user, current_history=trans.history) # only check_state if not deleting, otherwise cannot delete uploading files check_state = not payload.get('deleted', False) if check_state: hda = self.hda_manager.error_if_uploading(hda) # make the actual changes # TODO: is this if still needed? if hda and isinstance(hda, trans.model.HistoryDatasetAssociation): self.hda_deserializer.deserialize(hda, payload, user=trans.user, trans=trans) # TODO: this should be an effect of deleting the hda if payload.get('deleted', False): self.hda_manager.stop_creating_job(hda) return self.hda_serializer.serialize_to_view( hda, user=trans.user, trans=trans, **self._parse_serialization_params(kwd, 'detailed')) return {}
def check_ownership(self, trans, hda): """ Use history to see if current user owns HDA. """ if not trans.user: #if hda.history == trans.history: # return hda raise exceptions.AuthenticationRequired( "Must be logged in to manage Galaxy datasets", type='error') if trans.user_is_admin(): return hda # check for ownership of the containing history and accessibility of the underlying dataset if (self.histories_mgr.is_owner(trans, hda.history) and self.can_access_dataset(trans, hda)): return hda raise exceptions.ItemOwnershipException( "HistoryDatasetAssociation is not owned by the current user", type='error')
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 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