def validate(self, data): """Validates the request.""" action = data.get(":action") if action != "file_upload": raise serializers.ValidationError( _("We do not support the :action {}").format(action)) file = data.get("content") for ext, packagetype in DIST_EXTENSIONS.items(): if file.name.endswith(ext): break else: raise serializers.ValidationError( _("Extension on {} is not a valid python extension " "(.whl, .exe, .egg, .tar.gz, .tar.bz2, .zip)").format( file.name)) sha256 = data.get("sha256_digest") digests = {"sha256": sha256} if sha256 else None artifact = Artifact.init_and_validate(file, expected_digests=digests) try: artifact.save() except IntegrityError: artifact = Artifact.objects.get(sha256=artifact.sha256) log.info(f"Artifact for {file.name} already existed in database") data["content"] = (artifact, file.name) return data
def deferred_validate(self, data): """ Validate the python package data. Args: data (dict): Data to be validated Returns: dict: Data that has been validated """ data = super().deferred_validate(data) try: filename = data["relative_path"] except KeyError: raise serializers.ValidationError( detail={"relative_path": _('This field is required')}) if python_models.PythonPackageContent.objects.filter( filename=filename): raise serializers.ValidationError( detail={"relative_path": _('This field must be unique')}) # iterate through extensions since splitext does not support things like .tar.gz for ext, packagetype in DIST_EXTENSIONS.items(): if filename.endswith(ext): # Copy file to a temp directory under the user provided filename, we do this # because pkginfo validates that the filename has a valid extension before # reading it with tempfile.TemporaryDirectory() as td: temp_path = os.path.join(td, filename) artifact = data["artifact"] shutil.copy2(artifact.file.path, temp_path) metadata = DIST_TYPES[packagetype](temp_path) metadata.packagetype = packagetype break else: raise serializers.ValidationError( _("Extension on {} is not a valid python extension " "(.whl, .exe, .egg, .tar.gz, .tar.bz2, .zip)").format( filename)) _data = parse_project_metadata(vars(metadata)) _data['packagetype'] = metadata.packagetype _data['version'] = metadata.version _data['filename'] = filename data.update(_data) new_content = python_models.PythonPackageContent.objects.filter( filename=data['filename'], packagetype=data['packagetype'], name=data['name'], version=data['version']) if new_content.exists(): raise serializers.ValidationError( _("There is already a python package with relative path '{path}'." ).format(path=data["relative_path"])) return data
def deferred_validate(self, data): """ Validate the python package data. Args: data (dict): Data to be validated Returns: dict: Data that has been validated """ data = super().deferred_validate(data) try: filename = data["relative_path"] except KeyError: raise serializers.ValidationError( detail={"relative_path": _('This field is required')}) # iterate through extensions since splitext does not support things like .tar.gz for ext, packagetype in DIST_EXTENSIONS.items(): if filename.endswith(ext): # Copy file to a temp directory under the user provided filename, we do this # because pkginfo validates that the filename has a valid extension before # reading it with tempfile.NamedTemporaryFile('wb', suffix=filename) as temp_file: artifact = data["artifact"] artifact_file = storage.open(artifact.file.name) shutil.copyfileobj(artifact_file, temp_file) temp_file.flush() metadata = DIST_TYPES[packagetype](temp_file.name) metadata.packagetype = packagetype break else: raise serializers.ValidationError( _("Extension on {} is not a valid python extension " "(.whl, .exe, .egg, .tar.gz, .tar.bz2, .zip)").format( filename)) if data.get("sha256") and data["sha256"] != artifact.sha256: raise serializers.ValidationError( detail={ "sha256": _("The uploaded artifact's sha256 checksum does not match the one provided" ) }) sha256 = artifact.sha256 if sha256 and python_models.PythonPackageContent.objects.filter( sha256=sha256).exists(): raise serializers.ValidationError( detail={"sha256": _('This field must be unique')}) _data = parse_project_metadata(vars(metadata)) _data['packagetype'] = metadata.packagetype _data['version'] = metadata.version _data['filename'] = filename _data['sha256'] = sha256 data.update(_data) return data