Require invited login and private downloads for the company pilot
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
This commit is contained in:
parent
56bf193193
commit
b7d7828f30
27 changed files with 584 additions and 111 deletions
23
vergabe_teilnahme/apps/dokumente/downloads.py
Normal file
23
vergabe_teilnahme/apps/dokumente/downloads.py
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
from pathlib import Path
|
||||
|
||||
from django.conf import settings
|
||||
from django.http import FileResponse, Http404
|
||||
from django.views.decorators.http import require_safe
|
||||
|
||||
|
||||
@require_safe
|
||||
def protected_media(request, path):
|
||||
"""Download company uploads through the application authentication gate.
|
||||
|
||||
The invited pilot has one company per deployment. MEDIA_ROOT must contain
|
||||
uploads only; operational databases and credentials live outside this root.
|
||||
"""
|
||||
root = Path(settings.MEDIA_ROOT).resolve()
|
||||
try:
|
||||
target = (root / path).resolve()
|
||||
if not target.is_relative_to(root) or not target.is_file():
|
||||
raise Http404
|
||||
file = target.open('rb')
|
||||
except (OSError, RuntimeError, ValueError) as exc:
|
||||
raise Http404 from exc
|
||||
return FileResponse(file, as_attachment=True, filename=target.name)
|
||||
|
|
@ -26,46 +26,46 @@ def _pdf_file(name='test.pdf'):
|
|||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_dokument_upload_valid(client, tmp_path, settings):
|
||||
def test_dokument_upload_valid(admitted_client, tmp_path, settings):
|
||||
settings.MEDIA_ROOT = tmp_path
|
||||
a = AusschreibungFactory()
|
||||
url = reverse('ausschreibungen:dokumente:upload', kwargs={'ausschreibung_id': a.pk})
|
||||
response = client.post(url, {'datei': _pdf_file(), 'kategorie': 'intern', 'version': '1.0'})
|
||||
response = admitted_client.post(url, {'datei': _pdf_file(), 'kategorie': 'intern', 'version': '1.0'})
|
||||
assert response.status_code == 302
|
||||
assert Dokument.objects.filter(ausschreibung=a).exists()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_dokument_upload_invalid_extension(client, tmp_path, settings):
|
||||
def test_dokument_upload_invalid_extension(admitted_client, tmp_path, settings):
|
||||
settings.MEDIA_ROOT = tmp_path
|
||||
a = AusschreibungFactory()
|
||||
url = reverse('ausschreibungen:dokumente:upload', kwargs={'ausschreibung_id': a.pk})
|
||||
bad_file = SimpleUploadedFile('malware.exe', b'MZ bad', content_type='application/octet-stream')
|
||||
response = client.post(url, {'datei': bad_file, 'kategorie': 'intern', 'version': '1.0'})
|
||||
response = admitted_client.post(url, {'datei': bad_file, 'kategorie': 'intern', 'version': '1.0'})
|
||||
assert response.status_code == 200
|
||||
assert not Dokument.objects.filter(ausschreibung=a).exists()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_dokument_upload_too_large(client, tmp_path, settings):
|
||||
def test_dokument_upload_too_large(admitted_client, tmp_path, settings):
|
||||
settings.MEDIA_ROOT = tmp_path
|
||||
settings.MAX_UPLOAD_SIZE = 10
|
||||
a = AusschreibungFactory()
|
||||
url = reverse('ausschreibungen:dokumente:upload', kwargs={'ausschreibung_id': a.pk})
|
||||
big_file = SimpleUploadedFile('big.pdf', b'%PDF' + b'x' * 100, content_type='application/pdf')
|
||||
response = client.post(url, {'datei': big_file, 'kategorie': 'intern', 'version': '1.0'})
|
||||
response = admitted_client.post(url, {'datei': big_file, 'kategorie': 'intern', 'version': '1.0'})
|
||||
assert response.status_code == 200
|
||||
assert not Dokument.objects.filter(ausschreibung=a).exists()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_dokument_neue_version(client, tmp_path, settings):
|
||||
def test_dokument_neue_version(admitted_client, tmp_path, settings):
|
||||
settings.MEDIA_ROOT = tmp_path
|
||||
altes_dok = DokumentFactory(version='1.0')
|
||||
a = altes_dok.ausschreibung
|
||||
url = reverse('ausschreibungen:dokumente:neue_version',
|
||||
kwargs={'ausschreibung_id': a.pk, 'pk': altes_dok.pk})
|
||||
response = client.post(url, {'datei': _pdf_file('v2.pdf'), 'version': '2.0'})
|
||||
response = admitted_client.post(url, {'datei': _pdf_file('v2.pdf'), 'version': '2.0'})
|
||||
assert response.status_code == 302
|
||||
altes_dok.refresh_from_db()
|
||||
assert altes_dok.status == 'ersetzt'
|
||||
|
|
@ -73,12 +73,12 @@ def test_dokument_neue_version(client, tmp_path, settings):
|
|||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_dokument_finale_version(client):
|
||||
def test_dokument_finale_version(admitted_client):
|
||||
dok = DokumentFactory(status='freigegeben')
|
||||
a = dok.ausschreibung
|
||||
url = reverse('ausschreibungen:dokumente:finale_version',
|
||||
kwargs={'ausschreibung_id': a.pk, 'pk': dok.pk})
|
||||
response = client.post(url)
|
||||
response = admitted_client.post(url)
|
||||
assert response.status_code == 200
|
||||
dok.refresh_from_db()
|
||||
assert dok.finale_abgabeversion is True
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue