application: check icon from bundle before install (#88251)
gitea/hobo/pipeline/head This commit looks good
Details
gitea/hobo/pipeline/head This commit looks good
Details
This commit is contained in:
parent
159f93a783
commit
ad01d3d634
|
@ -32,6 +32,7 @@ from django.utils.timezone import localtime, now
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from django.views.generic import DetailView, FormView, ListView, RedirectView, TemplateView
|
||||
from django.views.generic.edit import CreateView, DeleteView, UpdateView
|
||||
from PIL import Image, UnidentifiedImageError
|
||||
|
||||
from hobo.environment.models import Variable
|
||||
|
||||
|
@ -463,6 +464,9 @@ class Install(FormView):
|
|||
_('Can not update this application, wrong slug (%s).') % manifest.get('slug'),
|
||||
)
|
||||
return self.form_invalid(form)
|
||||
icon = manifest.get('icon')
|
||||
if icon:
|
||||
Image.open(tar.extractfile(icon))
|
||||
app, created = Application.objects.get_or_create(
|
||||
slug=manifest.get('slug'), defaults={'name': manifest.get('application')}
|
||||
)
|
||||
|
@ -475,7 +479,6 @@ class Install(FormView):
|
|||
# overwriting a local application and keep on developing it.
|
||||
app.editable = False
|
||||
app.save()
|
||||
icon = manifest.get('icon')
|
||||
if icon:
|
||||
app.icon.save(icon, tar.extractfile(icon), save=True)
|
||||
else:
|
||||
|
@ -483,6 +486,9 @@ class Install(FormView):
|
|||
except tarfile.TarError:
|
||||
form.add_error('bundle', _('Invalid tar file.'))
|
||||
return self.form_invalid(form)
|
||||
except UnidentifiedImageError:
|
||||
form.add_error('bundle', _('Invalid icon file.'))
|
||||
return self.form_invalid(form)
|
||||
|
||||
# always create a new version on install or if previous version has not the same number
|
||||
version_number = manifest.get('version_number') or 'unknown'
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 558 B |
|
@ -1,7 +1,7 @@
|
|||
import base64
|
||||
import copy
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
import tarfile
|
||||
|
@ -29,6 +29,8 @@ from .test_manager import login
|
|||
|
||||
pytestmark = pytest.mark.django_db
|
||||
|
||||
TESTS_DATA_DIR = os.path.join(os.path.dirname(__file__), 'data')
|
||||
|
||||
|
||||
WCS_AVAILABLE_OBJECTS = {
|
||||
'data': [
|
||||
|
@ -373,18 +375,13 @@ def test_create_application(app, admin_user, settings, analyze):
|
|||
|
||||
# add an icon
|
||||
resp = app.get('/applications/manifest/test/metadata/')
|
||||
resp.form['icon'] = Upload(
|
||||
'foo.png',
|
||||
base64.decodebytes(
|
||||
b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVQI12NoAAAAggCB3UNq9AAAAABJRU5ErkJggg=='
|
||||
),
|
||||
'image/png',
|
||||
)
|
||||
with open(os.path.join(TESTS_DATA_DIR, 'black.jpeg'), mode='rb') as icon_fd:
|
||||
resp.form['icon'] = Upload('foo.jpeg', icon_fd.read(), 'image/jpeg')
|
||||
resp.form['documentation_url'] = '' # and reset documentation_url
|
||||
resp.form['visible'] = True
|
||||
resp = resp.form.submit().follow()
|
||||
application.refresh_from_db()
|
||||
assert re.match(r'applications/icons/foo(_\w+)?.png', application.icon.name)
|
||||
assert re.match(r'applications/icons/foo(_\w+)?.jpeg', application.icon.name)
|
||||
assert application.documentation_url == ''
|
||||
assert application.visible is True
|
||||
|
||||
|
@ -394,7 +391,7 @@ def test_create_application(app, admin_user, settings, analyze):
|
|||
resp = resp.form.submit()
|
||||
assert 'The icon must be in JPEG or PNG format' in resp
|
||||
application.refresh_from_db()
|
||||
assert re.match(r'applications/icons/foo(_\w+)?.png', application.icon.name)
|
||||
assert re.match(r'applications/icons/foo(_\w+)?.jpeg', application.icon.name)
|
||||
|
||||
resp = app.get('/applications/manifest/test/')
|
||||
resp = resp.click('Generate application bundle')
|
||||
|
@ -913,7 +910,7 @@ def get_bundle(with_icon=False):
|
|||
manifest_json = {
|
||||
'application': 'Test',
|
||||
'slug': 'test',
|
||||
'icon': 'foo.png' if with_icon else None,
|
||||
'icon': 'foo.jpeg' if with_icon else None,
|
||||
'description': '',
|
||||
'documentation_url': 'http://foo.bar',
|
||||
'version_number': '43.0' if with_icon else '42.0',
|
||||
|
@ -939,12 +936,10 @@ def get_bundle(with_icon=False):
|
|||
tarinfo.size = len(manifest_fd.getvalue())
|
||||
tar.addfile(tarinfo, fileobj=manifest_fd)
|
||||
if with_icon:
|
||||
icon_fd = io.BytesIO(
|
||||
b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQAAAAA3bvkkAAAACklEQVQI12NoAAAAggCB3UNq9AAAAABJRU5ErkJggg=='
|
||||
)
|
||||
tarinfo = tarfile.TarInfo('foo.png')
|
||||
tarinfo.size = len(icon_fd.getvalue())
|
||||
tar.addfile(tarinfo, fileobj=icon_fd)
|
||||
with open(os.path.join(TESTS_DATA_DIR, 'black.jpeg'), mode='rb') as icon_fd:
|
||||
tarinfo = tarfile.TarInfo(manifest_json['icon'])
|
||||
tarinfo.size = 558
|
||||
tar.addfile(tarinfo, fileobj=icon_fd)
|
||||
|
||||
return tar_io.getvalue()
|
||||
|
||||
|
@ -999,7 +994,7 @@ def test_deploy_application(app, admin_user, settings, app_bundle, app_bundle_wi
|
|||
application = Application.objects.get(slug='test')
|
||||
assert application.name == 'Test'
|
||||
if bundle == app_bundle_with_icon:
|
||||
assert re.match(r'applications/icons/foo(_\w+)?.png', application.icon.name)
|
||||
assert re.match(r'applications/icons/foo(_\w+)?.jpeg', application.icon.name)
|
||||
else:
|
||||
assert application.icon.name == ''
|
||||
assert application.documentation_url == 'http://foo.bar'
|
||||
|
@ -1182,6 +1177,39 @@ def test_deploy_application(app, admin_user, settings, app_bundle, app_bundle_wi
|
|||
resp = resp.form.submit()
|
||||
assert resp.context['form'].errors == {'bundle': ['Invalid tar file.']}
|
||||
|
||||
# bad icon file
|
||||
tar_io = io.BytesIO()
|
||||
with tarfile.open(mode='w', fileobj=tar_io) as tar:
|
||||
manifest_json = {
|
||||
'application': 'Test',
|
||||
'slug': 'test',
|
||||
'icon': 'foo.png',
|
||||
'description': '',
|
||||
'documentation_url': 'http://foo.bar',
|
||||
'version_number': '42.0',
|
||||
'version_notes': 'foo bar blah',
|
||||
'elements': [],
|
||||
}
|
||||
manifest_fd = io.BytesIO(json.dumps(manifest_json, indent=2).encode())
|
||||
tarinfo = tarfile.TarInfo('manifest.json')
|
||||
tarinfo.size = len(manifest_fd.getvalue())
|
||||
tar.addfile(tarinfo, fileobj=manifest_fd)
|
||||
icon_fd = io.BytesIO(b'garbage')
|
||||
tarinfo = tarfile.TarInfo('foo.png')
|
||||
tarinfo.size = len(icon_fd.getvalue())
|
||||
tar.addfile(tarinfo, fileobj=icon_fd)
|
||||
|
||||
bundle = tar_io.getvalue()
|
||||
|
||||
resp = app.get('/applications/')
|
||||
if action == 'Update':
|
||||
with StatefulHTTMock(mocked_http2):
|
||||
resp = resp.click(href='manifest/test/')
|
||||
resp = resp.click(action)
|
||||
resp.form['bundle'] = Upload('app.tar', bundle, 'application/x-tar')
|
||||
resp = resp.form.submit()
|
||||
assert resp.context['form'].errors == {'bundle': ['Invalid icon file.']}
|
||||
|
||||
|
||||
def test_update_application(app, admin_user, settings, app_bundle):
|
||||
Wcs.objects.create(base_url='https://wcs.example.invalid', slug='foobar', title='Foobar')
|
||||
|
|
Loading…
Reference in New Issue