[FIX] base, website: don't cleanup invalid bundle
Before this commit the clean_assetbundle could unlink invalid attachment, mostly when generating a no website assetbundle with a different version than a website one, the website assetbundle will be deleted. Generating a new asset bundle attachment /web/assets/439-b4c80c3/1/web.assets_frontend.min.css (id:439) Generating a new asset bundle attachment /web/assets/440-3723971/web.assets_frontend.min.css (id:440) Deleting attachments [439] (matching /web/assets/%-%/web.assets_frontend.min.css) because it was replaced with /web/assets/%-3723971/%%% The issue is that %-%/ will match 439-b4c80c3/1/ and not only 439-b4c80c3/ Note that it looks like this issue existed for a while but was invisible because before 16.4 clean_attachment was invalidating the ormcache, hiding the fact that a still valid asset was deleted and regenerated. The proposed fix replaces the domain with %-_______/. The unique is always 7 character long. Note that this change was already made in 17.0 when removing the id from the asset url so this doesn't need to be completely forward-ported. opw-3558552 closes odoo/odoo#145452 X-original-commit: 2ac466547e01bfd65415a53ae1efc9d45d9299fb Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
This commit is contained in:
@@ -100,6 +100,42 @@ class TestWebsiteAssets(odoo.tests.HttpCase):
|
||||
new_public_assets_links = re.findall(r'(/web/assets/\d+/\w{7}/web.assets_frontend\..+)"/>', page)
|
||||
self.assertEqual(new_admin_assets_links, new_public_assets_links, "t-cache should have been invalidated for public user too")
|
||||
|
||||
def test_invalid_unlink(self):
|
||||
self.env['ir.attachment'].search([('url', '=like', '/web/assets/%')]).unlink()
|
||||
|
||||
asset_bundle_xmlid = 'web.assets_frontend'
|
||||
website_default = self.env['website'].search([], limit=1)
|
||||
|
||||
code = b"document.body.dataset.hello = 'world';"
|
||||
attach = self.env['ir.attachment'].create({
|
||||
'name': 'EditorExtension.css',
|
||||
'mimetype': 'text/css',
|
||||
'raw': code,
|
||||
})
|
||||
custom_url = '/_custom/web/content/%s/%s' % (attach.id, attach.name)
|
||||
attach.url = custom_url
|
||||
|
||||
self.env['ir.asset'].create({
|
||||
'name': 'EditorExtension',
|
||||
'bundle': asset_bundle_xmlid,
|
||||
'path': custom_url,
|
||||
'website_id': website_default.id,
|
||||
})
|
||||
|
||||
website_bundle = self.env['ir.qweb']._get_asset_bundle(asset_bundle_xmlid, assets_params={'website_id': website_default.id})
|
||||
self.assertIn(custom_url, [f['url'] for f in website_bundle.files])
|
||||
base_website_css_version = website_bundle.get_version('css')
|
||||
|
||||
no_website_bundle = self.env['ir.qweb']._get_asset_bundle(asset_bundle_xmlid)
|
||||
self.assertNotIn(custom_url, [f['url'] for f in no_website_bundle.files])
|
||||
self.assertNotEqual(no_website_bundle.get_version('css'), base_website_css_version)
|
||||
|
||||
website_attach = website_bundle.css()
|
||||
self.assertTrue(website_attach.exists())
|
||||
no_website_bundle.css()
|
||||
self.assertTrue(website_attach.exists(), 'attachment for website should still exist after generating attachment for no website')
|
||||
|
||||
|
||||
@odoo.tests.tagged('-at_install', 'post_install')
|
||||
class TestWebAssets(odoo.tests.HttpCase):
|
||||
def test_assets_url_validation(self):
|
||||
|
||||
@@ -150,7 +150,7 @@ class AssetsBundle(object):
|
||||
self._checksum_cache[asset_type] = hashlib.sha512(unique_descriptor.encode()).hexdigest()[:64]
|
||||
return self._checksum_cache[asset_type]
|
||||
|
||||
def get_asset_url(self, unique='%', extension='%', ignore_params=False):
|
||||
def get_asset_url(self, unique=ANY_UNIQUE, extension='%', ignore_params=False):
|
||||
direction = '.rtl' if self.is_css(extension) and self.rtl else ''
|
||||
bundle_name = f"{self.name}{direction}.{extension}"
|
||||
return self.env['ir.asset']._get_asset_bundle_url(bundle_name, unique, self.assets_params, ignore_params)
|
||||
@@ -264,6 +264,7 @@ class AssetsBundle(object):
|
||||
}
|
||||
attachment = self.env['ir.attachment'].with_user(SUPERUSER_ID).create(values)
|
||||
attachment_id = attachment.id
|
||||
self.clean_attachments(extension)
|
||||
|
||||
return self.env['ir.attachment'].sudo().browse(attachment_id)
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import base64
|
||||
import odoo
|
||||
from odoo import api, http
|
||||
from odoo.addons import __path__ as ADDONS_PATH
|
||||
from odoo.addons.base.models.assetsbundle import AssetsBundle
|
||||
from odoo.addons.base.models.assetsbundle import AssetsBundle, ANY_UNIQUE
|
||||
from odoo.addons.base.models.ir_asset import AssetPaths
|
||||
from odoo.addons.base.models.ir_attachment import IrAttachment
|
||||
from odoo.modules.module import get_manifest
|
||||
@@ -147,7 +147,7 @@ class TestJavascriptAssetsBundle(FileTouchable):
|
||||
bundle = self.jsbundle_name if extension in ['js', 'min.js'] else self.cssbundle_name
|
||||
direction = '.rtl' if rtl else ''
|
||||
bundle_name = f"{bundle}{direction}.{extension}"
|
||||
url = self.env['ir.asset']._get_asset_bundle_url(bundle_name, '%', {})
|
||||
url = self.env['ir.asset']._get_asset_bundle_url(bundle_name, ANY_UNIQUE, {})
|
||||
domain = [('url', '=like', url)]
|
||||
return self.env['ir.attachment'].search(domain)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user