diff options
| author | Pedro M. Baeza <pedro.baeza@gmail.com> | 2018-08-27 23:36:33 +0200 |
|---|---|---|
| committer | Olivier Dony <odo@odoo.com> | 2018-10-03 17:48:01 +0200 |
| commit | 1be50fdeafcd2b94f7b2f47d6e5bc4b6ebaceadd (patch) | |
| tree | 4489771b5b5dcf02212a4dfdce4e8c2c80e3a6b5 /odoo/addons/test_new_api | |
| parent | 376361c15c8d2be15a2579ffd0432f31d745deb8 (diff) | |
[ADD] *: support SVG images
Introduce official support for SVG files in the framework, including the
following parts:
1. When client-side SVG images are uploaded, the content is displayed until
you save using data URI scheme according RFC 2397 [1]. This scheme requires
to specify content format. Using hardcoded "image/png" works for all images
types except SVG.
Type-sniffing is done using "magic byte" detection via the first base64
encode byte, so that the proper data URI scheme can be used.
This should not cause SVG-related security problems as the file is
displayed through `<img>` tag, which does not allow SVG scripting [2].
2. Make /web/image controller compatible with SVG
3. Add support for SVG files for company logo, which uses a dedicated
controller.
4. Resizing of SVG files is a no-op, as it makes little sense for a
vector-based format. We also want to avoid micro-alterations to the SVG
document (in "natural" viewport parameters) as we would store multiple
copies of the files in the filestore.
5. Because SVG files are inherently dangerous, upload of SVG files is
restricted to administrators, either by blocking it directly before
saving it in the database (binary fields with attachment=False), or by
neutering them to text/plain mimetype (for binary fields with
attachment=True)
6. Add tests for the SVG upload cases and for the non-admin uploads.
[1] https://tools.ietf.org/html/rfc2397
[2] https://www.w3.org/wiki/SVG_Security
Closes #26635
Diffstat (limited to 'odoo/addons/test_new_api')
| -rw-r--r-- | odoo/addons/test_new_api/ir.model.access.csv | 1 | ||||
| -rw-r--r-- | odoo/addons/test_new_api/models.py | 9 | ||||
| -rw-r--r-- | odoo/addons/test_new_api/tests/test_new_fields.py | 56 |
3 files changed, 66 insertions, 0 deletions
diff --git a/odoo/addons/test_new_api/ir.model.access.csv b/odoo/addons/test_new_api/ir.model.access.csv index 46a658c818d..c825fb51c59 100644 --- a/odoo/addons/test_new_api/ir.model.access.csv +++ b/odoo/addons/test_new_api/ir.model.access.csv @@ -21,3 +21,4 @@ access_test_new_api_compute_protected,access_test_new_api_compute_protected,mode access_test_new_api_multi_compute_inverse,access_test_new_api_multi_compute_inverse,model_test_new_api_multi_compute_inverse,,1,1,1,1 access_test_new_api_recursive,access_test_new_api_recursive,model_test_new_api_recursive,,1,1,1,1 access_test_new_api_cascade,access_test_new_api_cascade,model_test_new_api_cascade,,1,1,1,1 +access_test_new_api_binary_svg,access_test_new_api_binary_svg,model_test_new_api_binary_svg,,1,1,1,1 diff --git a/odoo/addons/test_new_api/models.py b/odoo/addons/test_new_api/models.py index bc0a3e45876..043ee8a0b7d 100644 --- a/odoo/addons/test_new_api/models.py +++ b/odoo/addons/test_new_api/models.py @@ -459,3 +459,12 @@ class ComputeCascade(models.Model): def _compute_baz(self): for record in self: record.baz = "<%s>" % (record.bar or "") + + +class BinarySvg(models.Model): + _name = 'test_new_api.binary_svg' + _description = 'Test SVG upload' + + name = fields.Char(required=True) + image_attachment = fields.Binary(attachment=True) + image_wo_attachment = fields.Binary(attachment=False) diff --git a/odoo/addons/test_new_api/tests/test_new_fields.py b/odoo/addons/test_new_api/tests/test_new_fields.py index 8284f4652c6..caa4eedf4bf 100644 --- a/odoo/addons/test_new_api/tests/test_new_fields.py +++ b/odoo/addons/test_new_api/tests/test_new_fields.py @@ -998,6 +998,62 @@ class TestFields(common.TransactionCase): self.assertEqual(count(message), 1) self.assertEqual(count(message1), 0) + def test_90_binary_svg(self): + from odoo.addons.base.tests.test_mimetypes import SVG + # This should work without problems + self.env['test_new_api.binary_svg'].create({ + 'name': 'Test without attachment', + 'image_wo_attachment': SVG, + }) + # And this gives error + with self.assertRaises(UserError): + self.env['test_new_api.binary_svg'].sudo( + self.env.ref('base.user_demo'), + ).create({ + 'name': 'Test without attachment', + 'image_wo_attachment': SVG, + }) + + def test_91_binary_svg_attachment(self): + from odoo.addons.base.tests.test_mimetypes import SVG + # This doesn't neuter SVG with admin + record = self.env['test_new_api.binary_svg'].create({ + 'name': 'Test without attachment', + 'image_attachment': SVG, + }) + attachment = self.env['ir.attachment'].search([ + ('res_model', '=', record._name), + ('res_field', '=', 'image_attachment'), + ('res_id', '=', record.id), + ]) + self.assertEqual(attachment.mimetype, 'image/svg+xml') + # ...but this should be neutered with demo user + record = self.env['test_new_api.binary_svg'].sudo( + self.env.ref('base.user_demo'), + ).create({ + 'name': 'Test without attachment', + 'image_attachment': SVG, + }) + attachment = self.env['ir.attachment'].search([ + ('res_model', '=', record._name), + ('res_field', '=', 'image_attachment'), + ('res_id', '=', record.id), + ]) + self.assertEqual(attachment.mimetype, 'text/plain') + + def test_92_binary_self_avatar_svg(self): + from odoo.addons.base.tests.test_mimetypes import SVG + demo_user = self.env.ref('base.user_demo') + # User demo changes his own avatar + demo_user.sudo(demo_user).image = SVG + # The SVG file should have been neutered + attachment = self.env['ir.attachment'].search([ + ('res_model', '=', demo_user.partner_id._name), + ('res_field', '=', 'image'), + ('res_id', '=', demo_user.partner_id.id), + ]) + self.assertEqual(attachment.mimetype, 'text/plain') + class TestX2many(common.TransactionCase): def test_search_many2many(self): |
