Verified Commit 973a13a5 authored by Mattia Rizzolo's avatar Mattia Rizzolo

Merge branch 'resume-file-upload' of salsa.debian.org:lyknode-guest/debexpo into live

MR: !59Signed-off-by: Mattia Rizzolo's avatarMattia Rizzolo <mattia@debian.org>
parents 28016808 d535c7d5
Pipeline #44354 passed with stage
in 6 minutes and 3 seconds
......@@ -41,8 +41,11 @@ import os
import os.path
import logging
from glob import glob
from debexpo.lib.base import BaseController, abort, config, request
from debexpo.lib.filesystem import CheckFiles
from debexpo.lib.changes import Changes
log = logging.getLogger(__name__)
......@@ -52,6 +55,38 @@ class UploadController(BaseController):
Controller to handle uploading packages via HTTP PUT.
"""
def _queued_for_import(self, filename):
# File does not exist. Return now
if not os.path.exists(filename):
return False
log.debug("File already exists: {}".format(filename))
# Changes file can't be overwritten
if filename.endswith('.changes'):
log.debug("Changes file can't be overwritten. Abort upload.")
return True
# For each changes files...
for changes_file in glob(os.path.join(self.incoming_dir, '*.changes')):
try:
changes = Changes(filename=changes_file)
except Exception as e:
log.debug("Failed to parse changes file {}: "
"{}".format(changes_file, e))
continue
# ... check that filename is not referenced
for referenced_file in changes.get_files():
if referenced_file == os.path.basename(filename):
log.debug("File queued for importation. Abort upload.")
return True
# Look like an interrupted upload. Allow to reupload
log.debug("File not referenced by any changes. "
"Allowing overwrite.")
return False
def index(self, filename):
"""
Controller entry point. When dput uploads a package via `PUT`, the
......@@ -94,13 +129,13 @@ class UploadController(BaseController):
log.critical('debexpo.upload.incoming is not writable')
abort(500, 'The incoming directory has not been set up')
incoming_dir = os.path.join(config['debexpo.upload.incoming'], 'pub')
if not os.path.isdir(incoming_dir):
os.mkdir(incoming_dir)
save_path = os.path.join(incoming_dir, filename)
self.incoming_dir = os.path.join(config['debexpo.upload.incoming'],
'pub')
if not os.path.isdir(self.incoming_dir):
os.mkdir(self.incoming_dir)
save_path = os.path.join(self.incoming_dir, filename)
log.debug('Saving uploaded file to: %s', save_path)
if os.path.exists(save_path):
log.debug("Aborting. File already exists")
if self._queued_for_import(save_path):
abort(403, 'The file was already uploaded')
f = open(save_path, 'wb')
......
......@@ -45,6 +45,31 @@ import pylons.test
class TestUploadController(TestController):
_CHANGES_CONTENT = """
Format: 1.8
Date: Tue, 12 Mar 2019 17:31:31 +0100
Source: vitetris
Binary: vitetris vitetris-dbgsym
Architecture: source amd64
Version: 0.58.0-1
Distribution: unstable
Urgency: medium
Maintainer: Baptiste BEAUPLAT <lyknode@cilg.org>
Changed-By: Baptiste BEAUPLAT <lyknode@cilg.org>
Description:
vitetris - Virtual terminal *tris clone
Changes:
vitetris (0.58.0-1) unstable; urgency=medium
.
* New upstream version 0.58.0
Checksums-Sha1:
aaaa 1261 vitetris_0.58.0-1.dsc
Checksums-Sha256:
aaaa 1261 vitetris_0.58.0-1.dsc
Files:
aaaa 1261 games optional vitetris_0.58.0-1.dsc
"""
def __init__(self, *args, **kwargs):
"""
Sets up database with data to provide a database to test.
......@@ -125,26 +150,46 @@ class TestUploadController(TestController):
"""
Tests whether a re-uploads of the same file failed with error code 403.
"""
# First upload allowed
response = self.app.put(url(
controller='upload', action='index',
filename='testfile.dsc'),
filename='vitetris_0.58.0-1.dsc'),
params='contents', expect_errors=False)
self.assertEqual(response.status_int, 200)
# Upload a file not referenced allowed
response = self.app.put(url(
controller='upload', action='index',
filename='testfile.dsc'),
filename='testfile.changes'),
params=self._CHANGES_CONTENT, expect_errors=False)
self.assertEqual(response.status_int, 200)
# Second upload denined (.changes)
response = self.app.put(url(
controller='upload', action='index',
filename='testfile.changes'),
params=self._CHANGES_CONTENT, expect_errors=True)
self.assertEqual(response.status_int, 403)
# Second upload denined (others)
response = self.app.put(url(
controller='upload', action='index',
filename='vitetris_0.58.0-1.dsc'),
params='contents', expect_errors=True)
self.assertEqual(response.status_int, 403)
app_config = pylons.test.pylonsapp.config
if os.path.isfile(os.path.join(app_config['debexpo.upload.incoming'],
'pub', 'testfile.dsc')):
os.remove(os.path.join(app_config['debexpo.upload.incoming'],
'pub', 'testfile.dsc'))
for filename in (os.path.join(app_config['debexpo.upload.incoming'],
'pub', 'vitetris_0.58.0-1.dsc'),
os.path.join(app_config['debexpo.upload.incoming'],
'pub', 'testfile.changes')):
if os.path.isfile(filename):
os.remove(filename)
def testUploadWithoutConfig(self):
"""
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment