New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[FIX] web_editor, website: prevent deletion of used attachment #116839
base: 15.0
Are you sure you want to change the base?
Conversation
c70e2d5
to
3e5721c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So every time an an attachment gets removed we're going to trawl through every HTML field of the database, with a search which would have a hard time being less efficient?
For reference res.partner has an HTML field and we have so many partners the pager has been disabled.
And I don't know how many are non-empty, but I'm not sure postgres implements Boyer-Moore, let alone Commentz-Walter, so my baseline assumption is that it performs a naive full scan of every field for every LIKE
(since they're all virtually guaranteed not to match anything ever), of which there are 6. And since those are HTML fields, they would be rather large.
To put it differently: it seems we're trying to fix a corner-case problem with an invasive, hackish and badly performing solution. This is a bad trade-off and we generally stay away for that, to keep things simple. @bso-odoo Either we consider this an important problem and we design a clean solution (which will require some model/architecture changes, not this kind of hack), or we choose to not address it at all. |
This use case doesn't seem like a corner-case to me IMHO, far from that. I agree that most people are probably not cleaning/removing their unused image, but for those who do, it's a real use case to not let them break their pages without knowing it.
Note that this is not about any removal of any attachment but only when a user purposely remove an image he uploaded previously from the media dialog: he is clicking on a red trash "delete" icon. Since we have no way to figure where this image might have been used, we have to check every places which are exposed in the frontend: basically all HTML fields except a few ones we already excluded like mail.message etc. Clearly, while this behavior is mandatory and important (IMHO?), big databases should not be impacted performance wise. Note that this "badly designed" util method is the one we are using pretty much everywhere:
Performance is quite concerning, that's why we came up with 9816b2b (was badly designed in the first place 😬 ) etc. What do you have in mind when you are saying |
3e5721c
to
19f8f63
Compare
My point (see tl;dr: feature should ideally remain as is for small and medium companies (search everywhere, there won't be many records, exclude tables when needed like mail.message, ensure we provide a reliable warning) but should be tweaked for big ones to not impact perfs (do search_count first, if more than X records -> Don't do the search, just warn that we couldn't provide complete search due to heavy amount of records and link might be used somewhere -> but still do the search for pages/views/menus as it's the core feature). |
But then, this will be an "a posteriori" warning: "Attachment was removed but it might still have been used in a model that has many records: Product, Job Definition" ? |
I'd not prevent anything, just add the warning as a hint, as we do for redirects. So a "proceed anyway" I guess. |
5551983
to
f3542b6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed, summary:
- Missing sudo
- Missing active_test=False
- In 15.0 forward port, adapt your TODO with our utils
# TODO In 15.0, obtain additional fields from
website._get_html_fields.
- In 16.1 forward port, adapt
https://github.com/odoo/odoo/commit/15c350ae47332d28f64f6a552b5c5d6930054e7d
which will share the same code + fix the missing sudo+with_context=False - Find a way to detect links to non accessible records and replace the display_name by id to not leak info so everyone is happy. You will probably need to go with
exists()
on the recordset un-sudo or something.
I made a summary on the 16.1 fix attempt which was done at #123014 (comment) but which will be handled in this PR forward port instead
5de3b23
to
15f96da
Compare
@rdeodoo It seems I forgot to ping you when it was done. The changes are in a second commit to be fixup.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's try to merge it tomorrow, since this will need a few more hours to later handle the forward port.
Note that you don't especially need to apply this mini review before we discuss it.
@qsm-odoo Your input would be more than welcome tomorrow, let's try to discuss this PR and all the related context about it.
15f96da
to
be412e0
Compare
@rdeodoo Pushed a new version with:
Still to be discussed:
|
be412e0
to
14b4d20
Compare
Until now, the changes were done in Odoo 14 as:
Since @xmo-odoo and @odony were not convinced at all by the idea of auto discovering html field (because of obvious perf issues) but I was convinced we needed to have an accurate check of those "is the ressource used somewhere?", I actually thought about it again and tried to figure a possible improvement in master that would not impact perfs while still being as precise as possible. The idea is to have a new table which would keep track of every field modified through the website builder. The idea has been challenged and seems like a good compromise fitting those needs. Since it will require a deeper refactoring, it will only be done in master, making it ok to not consider the stable versions. As a reminder, the flow where we need to know where/if a ressource is used in some HTML field are:
|
The deletion of used attachments from the media dialog is prevented since [1]. It is possible that it worked at the time, but that it stopped working in [2] when the routes for attachments have been updated. Also, it only checked for the presence of attachments in views, ignoring other HTML fields. This commit fixes the existing mechanism and also limits the search on views to QWeb views, and adds the check across other HTML fields. The fields inside ir.action models and mail messages are explicitly blacklisted, similarly to what exists in 15.0. This commit also detects non-image attachments which are obtained through the `/web/content/...` route. It also adapts the link within the warning so that the website page of the blocking object is reached if there is one, otherwise it falls back onto the backend page of the object. In 15.0, the list of fields should be obtained from `website`'s `_get_html_fields` instead of duplicating its mechanism. In 16.0, apply the same principle to the menu dependencies which were restored by [3] and [4]. Steps to reproduce: - Drop a Text - Image block on a website page/a product page. - Upload an attachment in that block. - Save. - Edit another page. - In the media dialog, delete the uploaded attachment. => Attachment is deleted and page contains a missing image/document. [1]: odoo@e78a3b1 [2]: odoo@6baf611 [3]: odoo@11db2f6 [4]: odoo@6ac17b9 task-3223788
14b4d20
to
8cb3471
Compare
The deletion of used attachments from the media dialog is prevented
since 1. It is possible that it worked at the time, but that it
stopped working in 2 when the routes for attachments have been
updated.
Also, it only checked for the presence of attachments in views,
ignoring other HTML fields.
This commit fixes the existing mechanism and also limits the search on
views to QWeb views, and adds the check across other HTML fields.
The fields inside ir.action models and mail messages are explicitly
blacklisted, similarly to what exists in 15.0.
This commit also detects non-image attachments which are obtained
through the
/web/content/...
route.It also adapts the link within the warning so that the website page of
the blocking object is reached if there is one, otherwise it falls back
onto the backend page of the object.
In 15.0, the list of fields should be obtained from
website
's_get_html_fields
instead of duplicating its mechanism.In 16.0, apply the same principle to the menu dependencies which were
restored by 3 and 4.
Steps to reproduce:
=> Attachment is deleted and page contains a missing image/document.
task-3223788