From a042851853c82f6ebcc2c6eaad31fc4966fc8815 Mon Sep 17 00:00:00 2001 From: Benoit Socias Date: Mon, 14 Mar 2022 09:50:57 +0000 Subject: [PATCH] [FIX] web_editor: fallback on URL search when shape not found from slug Since [1] illustration shapes are only obtained from their slug. Before they were obtained from their URL. After this commit the old behavior is restored as a fallback in case the illustration shape cannot be found from its slug. This is needed to allow importing shapes into the system from data files. [1]: https://github.com/odoo/odoo/commit/bde8abcfeb57c74438943e44215a7c8cb822329f task-2793073 closes odoo/odoo#86858 X-original-commit: 91f2a989ddd7961f92a377b1bf74cc741dcbd3d0 Signed-off-by: Quentin Smetz (qsm) --- addons/web_editor/controllers/main.py | 10 +++- addons/web_editor/tests/test_controller.py | 54 ++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/addons/web_editor/controllers/main.py b/addons/web_editor/controllers/main.py index db7bab818e8..fce4ab4a393 100644 --- a/addons/web_editor/controllers/main.py +++ b/addons/web_editor/controllers/main.py @@ -587,7 +587,15 @@ class Web_Editor(http.Controller): or attachment.type != 'binary' or not attachment.public or not attachment.url.startswith(request.httprequest.path)): - raise werkzeug.exceptions.NotFound() + # Fallback to URL lookup to allow using shapes that were + # imported from data files. + attachment = request.env['ir.attachment'].sudo().search([ + ('type', '=', 'binary'), + ('public', '=', True), + ('url', '=', request.httprequest.path), + ], limit=1) + if not attachment: + raise werkzeug.exceptions.NotFound() svg = attachment.raw.decode('utf-8') else: svg = self._get_shape_svg(module, 'shapes', filename) diff --git a/addons/web_editor/tests/test_controller.py b/addons/web_editor/tests/test_controller.py index a2188bf29b4..ce3553a2158 100644 --- a/addons/web_editor/tests/test_controller.py +++ b/addons/web_editor/tests/test_controller.py @@ -1,7 +1,10 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +import binascii + from odoo.tools.json import scriptsafe as json_safe +from odoo.addons.http_routing.models.ir_http import slug import odoo.tests from odoo.tests.common import HttpCase @@ -30,3 +33,54 @@ class TestController(HttpCase): ) self.assertEqual(200, response.status_code, 'Expect response') self.assertEqual(b'Hello world', response.content, 'Expect raw content') + + def test_02_illustration_shape(self): + self.authenticate('admin', 'admin') + # SVG with all replaceable colors. + svg = b""" + + + + + + + + """ + # Need to bypass security check to write image with mimetype image/svg+xml + context = {'binary_field_real_user': self.env['res.users'].sudo().browse([1])} + attachment = self.env['ir.attachment'].sudo().with_context(context).create({ + 'name': 'test.svg', + 'mimetype': 'image/svg+xml', + 'datas': binascii.b2a_base64(svg, newline=False), + 'public': True, + 'res_model': 'ir.ui.view', + 'res_id': 0, + }) + # Shape illustration with slug. + url = '/web_editor/shape/illustration/%s' % slug(attachment) + palette = 'c1=%233AADAA&c2=%237C6576&&c3=%23F6F6F6&&c4=%23FFFFFF&&c5=%23383E45' + attachment['url'] = '%s?%s' % (url, palette) + + response = self.url_open(url) + self.assertEqual(200, response.status_code, 'Expect response') + self.assertEqual(svg, response.content, 'Expect unchanged SVG') + + response = self.url_open(url + '?c1=%23ABCDEF') + self.assertEqual(200, response.status_code, 'Expect response') + self.assertEqual(len(svg), len(response.content), 'Expect same length as original') + self.assertTrue('ABCDEF' in str(response.content), 'Expect patched c1') + self.assertTrue('3AADAA' not in str(response.content), 'Old c1 should not be there anymore') + + # Shape illustration without slug. + url = '/web_editor/shape/illustration/noslug' + attachment['url'] = url + + response = self.url_open(url) + self.assertEqual(200, response.status_code, 'Expect response') + self.assertEqual(svg, response.content, 'Expect unchanged SVG') + + response = self.url_open(url + '?c1=%23ABCDEF') + self.assertEqual(200, response.status_code, 'Expect response') + self.assertEqual(len(svg), len(response.content), 'Expect same length as original') + self.assertTrue('ABCDEF' in str(response.content), 'Expect patched c1') + self.assertTrue('3AADAA' not in str(response.content), 'Old c1 should not be there anymore')