Commit Graph
208 Commits
Author SHA1 Message Date
Xavier-Do 52a2675ae8 [FIX] web: more robust test_image filename
The main purpose of this test is to ensure that line return are removed,
but all other special character are kept once the file is saved.

Unfortunately, werkzeug versions have different strategies on how to
quote the filename, removing less special character in latest versions
like after https://github.com/pallets/werkzeug/commit/babfc93b3834bcbb22163442a9af70141bcc5a81

This also changes after the changes that removed werkzeug urls methods
replacing them by urllib, making the behaviour different again.

This commit makes the test more robust by checking that the filename
correspond to the expeted one once unquoted, not comparing the quoted
versions.

Part-of: odoo/odoo#160842
2024-04-07 10:03:48 +00:00
Victor Piryns (pivi) 9117487844 [PERF] web: skip uid first in _name_search on res.users comodel
Description:
When searching with a domain that contains a relational field whos
comodel is `res.users`, with a *pathological* domain of `not ilike`
`'some_string'`, the ORM will call a `_name_search` on `res.users`
with no limit to resolve the leaf when calling `_where_calc`.
The current implementation in the `web` module overrides the
`_name_search` to implement a spec to propose the current user as a
first suggestion, but to do that it first execute the query
(the list conversion), and then manipulates the list of ids to insert
the current user first. (1c2ce8c213)

On large databases with many `res.users`, where the condition matches all
users besides 1, this is a probably Seq.Scan on the `res_users`
table. Then this gigantic list of `ids` will be injected by the ORM
into the main query to satisfy the original domain. This incurs not
only bandwidth costs, but also usually leads to bad plans, ending up
most likely into a Seq.Scan on the original table.
The worse of it, in the case of a `web_search_read`, there is a
`search_count`, so this whole fiasco is repeated once more.
The nail in the coffin, is that the result isn't even needed, when
resolving a comodel's `_name_search`, we care about the subset, the
internal order is irrelevant.

Solution:
The ORM calls the `_name_search` without a limit, while in general the
`name_search` is called with a limit from the front-end, therefor we
can use it as a discriminant -> If no limit, don't suggest `uid` first.

Affected versions:
saas-16.3 -> master (saas-17.2)

Reference:
task-3610657

closes odoo/odoo#154149

X-original-commit: 83aa46a4ab88c0226b1aa1dc36671d3208a0835a
Signed-off-by: Piryns Victor (pivi) <pivi@odoo.com>
2024-02-15 18:21:30 +00:00
Lucas Perais c0ab464dc7 [FIX] base, web (qweb): image field in raw data mode handles options
Commit[1] implemented a way to output an image as its raw representation
`<img src="data:image/png;base64......." />`
It is useful for integrating an image of a record not accessible publicly.

However the original commit forgot to allow the img node to handle the options
passed to the field. Classes in particular were absent

After this commit, the options are handled correctly, and the image in raw mode
has the right classes.

opw-3517861

[1]: f8b901d04b

closes odoo/odoo#151410

X-original-commit: dbb22351921629aad845e29ebfa8b4083b4e745a
Signed-off-by: Lucas Perais (lpe) <lpe@odoo.com>
2024-01-29 13:44:33 +00:00
Julien Castiaux 2a8dd60118 [FIX] core: HTTP 413 when restoring large backups
In #126914 a limit on the request size has been enforced, that limit is
by default 128MiB and can be configured via an ir.config_parameter. When
restoring a backup larger than 128MiB via the database manager, the
default limit was used and the request was cancelled with a Request
Entity Too Large (code 413) HTTP error.

It is now possible to define a default max content length per route,
that per-route limit takes over the `web.max_file_upload_size` ICP.

Moved the code from `get_http_params` to `pre_dispatch` to better align
with the httpocalypse new http stack.

Fixes: #144144
opw-3643475

closes odoo/odoo#147506

Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
2024-01-04 12:01:59 +00:00
Yannick Tivisse 533df43e67 [FIX] web: Make tests demo data independent
Part-of: odoo/odoo#146649
2023-12-18 23:32:05 +00:00
Xavier-Do 64bbef5bc1 [IMP] base, web: generate assets outside rendering
The generation inside the rendering has some drawbacks:

- `commit_assetsbundle` is needed for reports rendering because the
template rendering may generate some assets that will be accessed by
another transaction before the transaction is committed. But this
solution is not ideal since the transaction is committed in the middle
of the request

- when the first rendered page is a 404, the assets are not committed
and the page is broken.

- when starting, deleting an attachment can create a concurrent update
error and the request is retried. This will occur once per attachment
and for all worker trying to access the same resource. The whole
transaction is rollbacked, even the previously created assets bundle.

- The cold page load is a slower since there is more work to do.

- Implementing a readonly request is difficult because it could be
transformed to read write and re-executed if the assets bundle does not
exist.

Generating assets when needed solves those issues. The concurrency
when deleting an assets could still occur but only once per bundle, and
in a smaller transaction. This could be solved with a lock now that we
have more control on the transaction. The commit_assetsbundle can be
removed and 404 page should have a correct layout. The cold page load
could be a little faster because the assets bundle can be generated in
parallel requests instead of sequentially when rendering the page.

Part-of: odoo/odoo#131353
2023-10-27 11:34:52 +00:00
Xavier-Do d988030134 [REF] base: don't add id to assets bundle url
The main motivation is to be able to generate assets bundle outside
the t-call-assets call.
The need of an id in the url makes it mandatory to have an attachment
when adding the url in the page. Without this restriction, we can guess
the url without generating the assets.

This can also have other useful side effect:
There are corner case when a worked could have an invalid url in
cache because, if the transaction is rollbacked or if another request
generates the same attachment at the same time. This should be
partially solved by removing the id: The url remains valid even if the
attachment does not exist.

Note that the extra part of the url was made explicit, always there and
taking one / to remove complexity and ambiguity.

Note that an additional query appeared in .test_50_perf_sql_web_assets
because of the search, this but two of them were in _find_record. One of
them was an `exist`, not making much sense since we are not getting the
id from the attachment url anymore but from a search, and the other one
was prefetch of the "public field" since the call to _find_record does
not go in other cases (xmlid, website published, access token, ....). A
attachment of a asset is always public, and this part of the security
was moved to the search domain. The final result is one less query:
- one query to search
- one query to read the fields (_get_stream_from) (the prefetch could
actually be set to avoid prefetching everything)

Part-of: odoo/odoo#131353
2023-10-27 11:34:52 +00:00
Yannick Tivisse 7ebafb1eb7 [IMP] base: Remove manager rights to user demo
closes odoo/odoo#139731

Related: odoo/enterprise#49562
Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
2023-10-25 20:56:11 +00:00
Jorge Pinna Puissant ed3b4c5ab5 [FIX] web: clickbot set all filters
Since the new milk theme, the clickbot for click everywhere, didn't set
the filters on the views.

Now, the clickbot set all the filters on the views. This commit also add
a test suit, to avoid future downgrades. This commit transform the
clickbot to a module ES6.

task-id 3535596

X-original-commit: e2f531ec47e4f946cc37afee6b65531a637b5dfe
Part-of: odoo/odoo#139032
2023-10-20 11:22:13 +00:00
Dylan Kiss (dyki) 747a9fac78 [FIX] web: show branch hierarchy in switcher when no access to parent
Currently, when a user has access to a branch of a company, but not to
the company itself, the branch will not show up in the company switcher.
As a result, the user is not able to switch back to that branch when
logged in to another company.

To fix this, we now show the whole hierarchy of the branches you have
access to, disabling the companies/branches you don't have access to.

task-3503204

Part-of: odoo/odoo#138942
2023-10-18 12:05:25 +00:00
Martin Trigaux 22ab49e343 [IMP] *: use file_path and file_open
Replace all the calls to get_resource_path to the better file_path or
directly use file_open when not needed

Doing both a get_resource_path and file_open means checking twice that
the file exists.
Doing a simple path concatenation before a file_open is safe.
If given to another method (e.g. etree.parse), calling file_path is
the prefered method.

Note that get_resource_path used to return False when the file does
not exists while file_path/file_open raises a FileNotFoundException

closes odoo/odoo#135607

Related: odoo/upgrade#5187
Related: odoo/enterprise#47475
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
2023-10-06 14:33:43 +00:00
Julien Carion (juca) 2a2f53f7ce [FIX] web: fix translations for duplicate records
This commit ensures that changes in translated fields on a freshly
duplicated record will apply to all translation even when the user
language is not en_US.

Steps to reproduce:

-go to accounting -> configuration -> taxes in other language than en_US
-open any record in form view
-duplicate the record
-change the name of the record and save
-ensure that the name is the same in all languages

task-3339736

closes odoo/odoo#134481

Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
2023-09-27 01:50:52 +00:00
Shubham Thanki 66e8e65682 [IMP] web: allow users to download multiple vcards at once
This commit adds a download vCard server action in the list view of contacts,
making it possible to download multiple vCards at once.

Task-3385058

closes odoo/odoo#135435

Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
2023-09-18 10:14:06 +00:00
0903ef7bb2 [MOV] *: move all PWA to community
In this commit, we moved all features related to the PWA and the PWA
itself to the community.

This includes:
* PWA
* Web Push Notification
* VCARD

Note from original commits:
===========================

PWA (part 1)
------------
This commit adds a ServiceWorker to complement the WebManifest to
complete the setup of the backend as a Progressive Web App.

More precisely, it adds the route, registration and the most basic
ServiceWorker to allow the backend to be recognized as an installable
PWA.

References:
- https://web.dev/install-criteria/
- https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Installable_PWAs
- https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers

Task ID: 3063485

PWA (part 2)
------------
This commit adds a WebManifest as a first step toward setuping the
backend as a Progressive Web App.

In a nutshell:
- the web app's name is configurable through a config parameter
  (available in the Settings, in debug); defaulting to "Odoo".
- the web app's icon has been revamped to accommodate the required sizes;
  also its design matches the one from the Android app.
- "theme-color" is used to color part of the browser/system UI to match
  Enterprise brand color; also supports the dark mode.

References:
- https://web.dev/learn/pwa/web-app-manifest/
- https://web.dev/install-criteria/
- https://developer.mozilla.org/en-US/docs/Web/Manifest

Task ID: 3063485

PWA shortcuts
-------------
The main goal of this commit is like we did inside the `Android Odoo
Mobile App`, allowing users to have some Odoo application shortcuts.
We added the following apps in the key `shortcuts` on `web.manifest` in
these orders: `Discuss`, `CRM`, `Project`, `To-Do` (old `Notes`).

Links:
- https://w3c.github.io/manifest/#shortcuts-member
- https://developer.mozilla.org/en-US/docs/Web/Manifest/shortcuts

Task ID: 3123607

Offline mode
------------
This commit introduces a way to notify the user that he's "offline"
(aka. cannot reach its Odoo server) and that Odoo doesn't work in a
graceful way in this circumstance.

To do so, the Service-Worker will return the response of the
´web/offline´ route, which is cached at its setup.

Note: this screen is only show when launched while "offline" and fails
to load the requested page. It does not "interrupt" the WebClient to
show this screen when the connection drops off (cf. not a replacement
for the existing notification).

Task ID: 3203639

WebPush
-------

WebPush allows sending data to the user browser/app(PWA) even when
tab/app is closed. Web push is a "constant" link between the
ServiceWorker of browser/app and a WebPush server.

Note that each browser has its own custom WebPush server.
e.g.:
Chrome: https://fcm.googleapis.com/
Firefox: https://updates.push.services.mozilla.com/
Safari: https://web.push.apple.com/
Edge: https://wns2-ln2p.notify.windows.com/
WebPush introduces some cryptographic notion to ensure some the
reliability of the data sent:

VAPID: "Voluntary Application Server Identification" is the standard
used to generate the public and the private to sign the message
between the browser and the WebPush server
JWT: "JSON Web Token" is the standard used to sign the payload to the
WebPush server
ECE: "Encrypted Content-Encoding" is the standard used by WebPush to
encrypt the data of the payload to avoid sending RAW data
outside trusted network.
Simplified steps how to WebPush works:

The Javascript code of a web page subscribes to the WebPush server
(using the VAPID key generated at mail_entreprise install).
The WebPush server replay with a subscription (and some other info
like the unique URL endpoint per subscription where to send a
notification)
The application (odoo-bin in our case) sends a post request to the
WebPush server using the specific URL endpoint of the user (using JWT
and ECE).
The WebPush server sends back to the browser the encrypted payload.
The browser decrypts the payload and sends it to the ServiceWorker
linked to the subscription.
Here is a Sequence diagram of all interactions to process a web push
notification.
In Odoo, we use WebPush to send Notification to the user.

This commit aims to have a parity with the Android/iOS Mobile App at
the notification level.

Notes:

There are some ways to encrypt (ECE) the message for WebPush:

AESGCM128: this is a draft
AESGCM: very well documented
AES128GCM: RFC8188 Standard encoding
We implement only the RFC one as it is the only one implemented in all
major updated browsers (Chrome, Firefox, Safari, Edge, ...)
You need to allow the desktop "Notification" and "Push" inside your
browser. For iOS Devices, it only works on iOS 16.4+ and it's requiring
Odoo to first be added to the Home Screen. It's delivered silently,
meaning no sound, vibration, haptics or screen wake.

Note:
Notifications are sent directly if there are less than five
notifications, otherwise we use a cron triggered immediately.
Also, we have changed the value of the "QueryCount" as mail_enterprise
executes a new query to search the devices associated with the partner.

We have added a "try/except" for any Exception before the
push_to_end_point method as we want to avoid blocking a normal flow
just for a not mandatory push notification if something happens during
the push to the endpoint.
See: odoo/enterprise@d0ae70103d

Links:
https://www.rfc-editor.org/rfc/rfc8030
https://www.rfc-editor.org/rfc/rfc8188
https://www.rfc-editor.org/rfc/rfc8291
https://www.rfc-editor.org/rfc/rfc8292
https://w3c.github.io/push-api/index.html
https://autopush.readthedocs.io/en/latest/http.html
https://web.dev/push-notifications-web-push-protocol/
https://github.com/web-push-libs/encrypted-content-encoding
https://github.com/web-push-libs/pywebpush
https://github.com/web-push-libs/vapid
https://caniuse.com/push-api
Task ID: 3123678

VCARD
-----
In the process of replacing the native methods exposed in the mobile
apps, this commit implements the download of a vCard containing a
partner's information.

By using this standard format, both regular web users and mobile ones
are now able to save the partner's details to use them with their usual
address book software.

On a mobile device, the actual import of those informations is delegated
to the operating system.

References:
- https://datatracker.ietf.org/doc/html/rfc6350
- https://en.wikipedia.org/wiki/VCard
- https://github.com/eventable/vobject#vcards

Task ID: 2583916

===========
End of note
===========

Task ID: 3478014

closes odoo/odoo#133560

Related: odoo/enterprise#46530
Related: odoo/upgrade#5086
Signed-off-by: Adrien Dieudonné (adr) <adr@odoo.com>
Co-authored-by: Romeo Fragomeli <rfr@odoo.com>
Co-authored-by: Romain Estievenart <res@odoo.com>
Co-authored-by: Pierre Paridans <app@odoo.com>
2023-09-11 16:32:30 +00:00
Géry Debongnie e0fdb6a0b4 [IMP] *: rewrite module loader
This commit rewrite the module loader to simplify it and to improve error handling.
before this commit, you could have silent errors or "lucky" imports (import a module based on the fact that his asset will surely be load and if not, the error would be silent anyway).
e.g.: The tours cannot import modules extern to tours' bundle anymore. Or load module before your libs in assets.

TASK ID: 3266021

closes odoo/odoo#128502

Related: odoo/enterprise#44100
Signed-off-by: Bastien Pierre (ipb) <ipb@odoo.com>
2023-09-08 16:47:56 +00:00
std-odoo 88f4c4dd36 [IMP] base: properties, do not allow to select transient models
Purpose
=======
Do not allow to select transient models in relational properties.

Task-3032464

Part-of: odoo/odoo#103510
2023-09-08 09:46:56 +00:00
Aaron Bohy 2a121a32a2 [REF] *: rename unity_web_search_read into web_search_read
Part-of: odoo/odoo#133617
2023-08-31 09:04:58 +00:00
Aaron Bohy 1d71e35cde [REF] web: remove old web_search_read
as it will be replaced by unity_web_search_read

Part-of: odoo/odoo#133617
2023-08-31 09:04:58 +00:00
Bastien PIERRE 65242e31e9 [IMP] *: Remove alias in JS files
Rename all imports with alias old system to the new js module system
Task ID: 3266759

closes odoo/odoo#127414

Related: odoo/design-themes#671
Related: odoo/enterprise#43716
Signed-off-by: Bastien Pierre (ipb) <ipb@odoo.com>
2023-07-27 11:58:34 +02:00
william-andre 0eff29409d [IMP] web: manage hierarchy in company selector
In order to manage different branches, the usability of the company
selector is being improved
* display in a hierarchic manner
* when selecting a company, select all the available children with it

task-3371677

Part-of: odoo/odoo#125642
2023-07-20 11:49:05 +02:00
Mathieu Duckerts-AntoineandOliver Dony afdb546e44 [FIX] web: domain field: quick save after debug edit
When a domain field value is edited via the debug textarea, no
search_count is done for performance reasons. A single exception is done
when saving the record. Then we check the validity of the domain created
in the debug textarea in order to avoid to save an invalid domain in db
(and get tracebacks,..). The problem is that a search_count can take a
very long time to be executed if the domain is valid. Here we introduce
a route /web/domain/validate in order to quickly check the validity of a
domain and use it in domain field in order to fix the above mentionned
performance issue. Note that the search_count is still done if it useful
but does not have to be waited anymore.

X-original-commit: 40288221c39ff8fba41cd6ac231ab33600dc0cd4
Part-of: odoo/odoo#128913
Co-authored-by: Oliver Dony <odo@odoo.com>
Co-authored-by: Mathieu Duckerts-Antoine <dam@odoo.com>
2023-07-19 11:40:09 +02:00
Xavier-Do 595aa24843 [IMP] registry: multiple ormcache
One of the main issue with ormcache is that the invalidation clears
everything, meaning that some value, slow to compute but with a long
lifetime, can be removed from the cache because an easy to invalidate
value is cleared, like after writting or creating a product has an
example.

Most example in the code will try to invalidate the cache of the models
doing something like `env['ir.qweb'].clear_caches()` but it is
finally equivalent to `env.registry.clear_cache()`, and cross worker.

The idea is to have multiple cache, maybe with specific sizes for a
specific purpose.

Having one per model is maybe a bad idea because it will be difficult
to size the LRU correcly, and it is too dynamic. Checking invalidation
may be expensive.

The proposed solution is closed allow a limited number of named caches,
using onse sequence per cache. This is actually close to the
cache_longterm.

We want to discourage using a specific cache for one use case in
the buisness code. Adding a cache shouldn't be something easy, doable
in stable.

Note that we could also change the invalisation mecanism using an
insert only table. We an check the sequence of this table, but also
fetch all invalidation messages.
Another possible improvement, especially if we have more than x cache is
to have a global sequence, checking signaling would mean to check the
main sequence, and only the other ones if the main one changed.

Note that this poc is inspired from the long term cache but not all
use case where applie yet.

Part-of: odoo/odoo#119813
2023-07-18 11:42:26 +02:00
Xavier-Do 6d5d234f15 [IMP] base: better ormcache management
1. move cache to _get_asset_paths

The `_get_asset_content` cache has many cache key that are related to a
posprocessing of the `_get_asset_paths` result, the heavy part of this
method. Moving the cache to _get_asset_content will have the benefit
to create less duplicates entries in the ormcache as well as less cache
miss.

To simplify even further, the css and js parameters are removed since
they only filter the output of get_paths, the heavy part of globing the
file will be done before that. Anyway, they are both true when called
from _get_asset_content, and the only other call, in
`_get_related_bundle` don't really need to filter them since it is not
a critical part regarding performance, and the funtional result will
stay the same.

The initial orm cache key was using `_get_template_cache_keys`, a little
overkill and possibly creating duplicates entries again. The only
context key needed is website_id for `_get_related_assets`.

Note that it is not really enough, the orm cache key should actually
contain `request.session.get('force_website_id')` as well has
`request.httprequest.host`. This will be addressed latter since a nicer
solution would be to have website_id as a unique parameter computed
earlier.

2. better _get_asset_paths cache key

The orm cache key was simplified in previous point but there is still
one concern, the website_id depends on more parameters than that:
- request.session.get('force_website_id')
- request.httprequest.host
- existing websites

The idea here is to call `get_current_website` instead of using all
parameters that could define the webiste.

In the same spirit of `_get_template_cache_keys` `_assets_path_params`
can be overriden to give extra params that are usefull to list assets
path. Those params are computed before entering the method
`_get_asset_paths`. This may latter put at a higher level latter, in
get_asset_node, to simplify the _generate_asset_nodes_cache key.

3. better assets_node caches key

The main purpose of this part is to improve ormcache containing assets
nodes. The ormcache key contains
- to much context key
- missing session/host/env info
- unwanted boolean options.
- keys leading to the same cache value

The main goal being to reduce the size of the cache keys, decrease the
number of cache entries and improve the cache hit.
This will also make the behaviour more coherent and hopefully less bug
prone because of mismatch in parameters.

The main reason of the orm cache is the slowness of the validation of
the assets. This includes:
- listing files (dedicated orm cache)
- computing version

The cache key was depending on
- `debug`
The only relevant value for debug is "contains assets"
We dont need to differ between debug='', debug='1', debug='test',
and 'debug=assets', 'debug=tests,assets', ...
- `defer_load`, `lazy_load`, `media`
Those values are only useful to generate html node, a leightweight
operations that does not really needs to be in cache. `media` was also
used in the generation but it looks useless if we have the media on the
node. THIS NEEDS TO BE VALIDATED but in any case, since media is not
used to generate the url, it doesn't make sence to use it in the
generation.
The main idea to remove them from the ormcache key is simply to generate
the nodes outide the ormcached values.
-`async_load`
This one is similar to `defer_load` and `lazy_load` but it looks like
it wasn't used anymore. This was simply removed
- context.get('lang')
The only information needed is the direction, rtl or ltr. This means
en and fr languages, despite sharing the same css assets, will duplicate
the ormcache entries.
-`_get_template_cache_keys`
Only the lang and webiste where really relevant in this flow. Other
keys are actually useless in this flow.

Some information used in the generation where not in the orm cache key
- `self.env.user.lang` if there is no lang in the context
- `request.session.get('force_website_id')`
- `request.httprequest.host`
- ...

The proposed solution is to:
- extract any informùation needed from thecontext, request, environment
before entering the ormcache, reduce it to the minimal possible set of
values needed
```
    rtl = self.env['res.lang']._lang_get_direction(self.env.context.get('lang') or self.env.user.lang) == 'rtl'
    assets_params = self.env['ir.asset']._get_assets_params()  # website_id
    debug_assets = debug and 'assets' in debug
```

and remove a leightweight part of the logic

```
    def _get_asset_nodes(self, bundle, css=True, js=True, debug=False, defer_load=False, lazy_load=False, media=None):
        links = self._get_asset_links(bundle, css=css, js=js, debug=debug)
        return self._links_to_nodes(links, defer_load=defer_load, lazy_load=lazy_load, media=media)
```

Where _get_asset_links is the cached part, and _links_to_nodes is the
lightweight part generating the nodes based on the `defer_load`, ....

Additionnal notes:
- data-asset-version and data-asset-bundle are removed from the node
since they don't seem to be used anymore since 65d70acdbf
- async_load is removed since there is no occurence of this in the code.
- a small hack is still needed to pass javascript content instead of
links, this is only to manage css compile error and will hopefully be
removed in the future.
- a context key is still in use to generate the bundle, the
`commit_assetsbundle` but it has no impact on content and will hopefully
be removed in the future.

4. Add test for ormcache hit/miss

In this context, hit/miss is about having the same cache key for the
same result. This test demonstrates the current state, were entries are
create in the ormcache only if the key is really different and will lead
to a different result.

5. remove cache invalidation

This cache invalidation is quite agressive since everytime an
assetbundle is updated, all workers will clear their cache.

The concerned cache by this clear_cache is `_generate_asset_nodes_cache`
throug `_get_asset_nodes`.

The cache is ignored, both in dev=xml and debug=assets.

This clear cache was made conditionnal in 553ea82f81 but this does
not solve an issue we can have in production.

Lets imagine a clean solution
- all sources are updated
- all workers are restarted.

The orm caches are all empty, but since the sources
changed, all bundles will be recomputed. This means that every bundle
updated in database with save_attachement will invalidate the cache of
all workers. Rendering a pdf report of any kind using a specific bundle
will invalidate all cache. Starting a debug=assets for the first time
will invalidate all cache, even if the cache is not used in this case.

But for a regenerated bundle we would expect the ormcache to be:
- empty (did not generate the same bundle yet)
- have the same value (concurrent generation of the same bundle)

Having a different value would mean that the bundle was generated with
another version of the sources. In this case it is maybe even better not
to invalidate the cache since it could lead to an invalidation war
between two workers.

The only case where invalidating this cache is useful is when a bundle
changes, Usually if an ir_asset is created, modified, ...

There is still another rare but possible possibility to have a 404 if
the transaction is rollbacked after populating the assets node cache.
In this case, we only need to clear the cache locally in case of
rollback.

Part-of: odoo/odoo#121376
2023-06-10 11:14:11 +02:00
Pierre Masereel b5854af2b6 [FIX] base,web: get correct mimetype for menu item icon
Since changes made in https://github.com/odoo/enterprise/pull/41117 we
cannot provide icons for menus in an other format than png. As it was
allowed before to use SVG, we don't want to restrict to only one format.

Before, it was trying to gess the mimetype based on the image content
which is not also the best case.

So as the icon is a binary field store=True, we can just take the
mimetype from the attachment.

closes odoo/odoo#122580

X-original-commit: 044e6b680bc988708a9bbcc3c93dabf787c4a190
Related: odoo/enterprise#41529
Signed-off-by: Masereel Pierre <pim@odoo.com>
2023-05-26 10:29:10 +02:00
Christophe Monniez ebd31deee5 [FIX] web: avoid calling terminate_browser
As the ChromeBrowser API was simplified in 2b0d9fa6a9, the
terminate_browser method was removed but the shiny author forgot to
remove the call in the click_everywhere test.

closes odoo/odoo#122038

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2023-05-23 14:52:16 +02:00
Lucas Perais b2f648fb3e [FIX] web: test document layout should be post_install
Initialize a DB. Install website when it is initialized.
Launch tests of the class TestBaseDocumentLayout

Before this commit, there was a crash because those tests render the report_layout and its
assets.

The full explanation is that, the module website adds an ir.asset `website.s_badge_000_variables_scss`
that the report wants to fetch. But, the class of tests is executed at_install. Given the topological order
and the order of the modules installation, website is not in the registry at that point, but the ir.asset is retrieved
from the database.
The ir.asset algorithm determines at that point that `/website/` is not an admissible path and raise an exception.

This commit solves the problem by tagging this class of test "post_install" and not "at_install".

runbot-error-21203
runbot-error-21204
runbot-error-21205
runbot-error-21206
runbot-error-21207
runbot-error-21208
runbot-error-21352
runbot-error-21353
runbot-error-21354
runbot-error-21355
runbot-error-21356
runbot-error-21357

closes odoo/odoo#121998

X-original-commit: 48b833513ac8f76febbc4ca7b935260d7ea85522
Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
Signed-off-by: Lucas Perais (lpe) <lpe@odoo.com>
2023-05-23 06:37:44 +02:00
Xavier-Do 5594d8f191 [IMP] base, *: speedup assets unique computation
One of the most costly part of a page loading when the ormcache is cold
is computing the assets node, the unique identifier of an attachment to
validate whether the existing attachment is still valid with the current
version of the static files.

This operation needs to glob assets path in the filesystem,
get the modification date, check attachments, ...

Right now this task is not really optimized and can take some time
because of an excessive number of glob on the filesystem, unnecessary
exists to define absolute path, double computation of file list and
modified times when getting js and css bundle separately, ...

A list of modifications mainly discussed in the pr message are made
with this commit to speedup things.

- split css and js unique
- prepare api for an in memory glob
- change api to propagate absolute path and meta information through
`ir.asset._get_paths`-> _get_asset_paths -> `_get_asset_content` ->
`AssetsBundle`

closes odoo/odoo#121159

Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
2023-05-17 14:47:12 +02:00
Xavier Bol (xbo) 1c2ce8c213 [IMP] web: display the current user first in the result of name_search
Before this commit, when the user wants to self assign to a task for
instance, he has to write his name to be able to select himself.

This commit displays the current user first in the result of
`name_search` (the method called by relational widgets in JS).
If the current user does not satisfy the search condition then
he will not be in the result of the `name_search`.

task-3291745

closes odoo/odoo#121146

Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
2023-05-15 09:37:56 +02:00
Xavier-Do a61c6de00b [IMP] web: add assets generation time tests
Add a test_logs_assets_check_time test to make stats on the time needed
to validate all asset bundle (will be added to runbot stats)

Add a test_logs_pregenerate_time, mainly to profile this part during
devlopment. This test is -standard and will only run if requested.

closes odoo/odoo#120767

Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
2023-05-09 06:07:28 +02:00
Vincent Schippefilt 7d2baaa0c7 [IMP] web: project unity_read
Introduce an optimised way of reading a graph of data from the webclient.

Before this commit:
When reading data from the webclient it could at most read multiple ids of the same model in one RPC.
This mean that when reading x2many or specific information on many2one, that could only be done after the initial read (when the client knows the ids of the comodels) and model by model.

After this commit:
Introduce methods web_read and web_search_read_unity. Both method receive a specificiation for the fields instead of a list of fields. The specification can request fields from the model, as well as follow relations and request fields for each relations, recursively.

Example of web_read specification for account_move
```python
{'name': {}},
{'date': {}},
{'journal_id': {'fields': {'display_name':{}}}
},
...
{'invoice_line_ids' :
    {
        'fields': {
            'journal_id' : {'fields': {'display_name:{}}},
            'move_name' : {},
            ...
            'tax_ids' : {
                fields: {
                    'display_name':{},
                    ...
                }
            }
        }
    }
}
```

Result for this example with 2 invoice lines
```python
{
    'id': 1234,
    'name' : 'invoice name ABC',
    'journal_id: {
        'id': 999,
        'display_name': 'Customer Invoices'
    },
    ...
    'invoice_line_ids': [
        {
            'id': 666,
            'journal_id': {
                'id': 999,
                'display_name': 'Customer Invoices'
            },
            'move_name': 'a move name',
            'tax_ids': [
                {
                    'id': 333,
                    'display_name: "15% tax",
                    ...
                }
            ]
        },
        {
            'id': 667,
            'journal_id': {
                'id': 999,
                'display_name': 'Customer Invoices'
            },
            'move_name': 'another move name',
            'tax_ids': [
                {
                    'id': 334,
                    'display_name: "21% customer tax",
                    ...
                }
            ]
        }
    ]

}
```

closes odoo/odoo#119034

Signed-off-by: Vincent Schippefilt (vsc) <vsc@odoo.com>
2023-04-21 08:02:17 +02:00
valeriobelcastro a33dbdb5c7 [IMP] handle query parameters on /web route
closes odoo/odoo#117987

Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
2023-04-09 12:57:40 +02:00
Yolann Sabaux 3a177c448d [FIX] models: use localized first day of the week when grouping by week
Steps to reproduce:
- Make sure language preference is 'en_US'
- In accounting, in the dashboard click on bills
- Filter 'due_date' by week

Issue: The start day is Monday and should be, for 'en_US', Sunday as it
is the case in the dashboard view in accounting (see appendix).

Cause: The query uses the `date_trunc('week', date)` which in Postgres
retrieves the first day of the week as Monday (ISO week).

Solution: Create an offset in the query depending on the first day of
the locale variable.

Note: the `web/tests/test_read_progress_bar.py` has been modified: since
the default language is 'en_US' there will be an offset of one day.  To
make it less confusing, I used only two anglo-saxons countries so the
day offset is not the variable tested.  (for this matter, pleaser refer
to `test_read_group/tests/test_read_group_process_groupby.py`)

Appendix:
Language (english-US)

		VIEW (per week)			|		DASHBOARD
	___________________________________________________________________
	W23		->	06/05		|	05/29	->	06/04
	W24	06/06	->	06/12		|	06/05 	->	06/11
	W25	06/13	->			|	06/12	->	06/18

		(Monday - Sunday)			(Sunday - Saturday)

Language (french-BE)

		VIEW (per week)			|		DASHBOARD
	___________________________________________________________________
	W22		->	06/05		|	05/30	->	06/05
	W23	06/06	->	06/12		|	06/06 	->	06/12
	W24	06/13	->			|	06/13	->	06/19

		(Monday - Sunday)			(Monday - Sunday)

opw-2747066

closes odoo/odoo#93053

Related: odoo/enterprise#29539
Signed-off-by: Raphael Collet <rco@odoo.com>
2023-02-24 10:05:58 +01:00
Christophe Monniez fab86bbf8b [FIX] web: adapt test for werkzeug >= 2.2.2
In werkzeug 2.2.2, the following characters "$!'()*+,;" are now
considered as safe by url_quote. This makes the filename_secure test
fail with the hard coded expected string containing a single quote as
'%27'.

This commit adapt the filename_secure test in order to work with all
versions of werkzeug.

closes odoo/odoo#112298

Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
Signed-off-by: Christophe Monniez (moc) <moc@odoo.com>
2023-02-10 14:37:31 +01:00
Florian VranckxandJulien Castiaux 8c30699f2a [FIX] http: no rotate sid for unidentified user
This commit fixes a change in behavior between 15.2 and 15.3.

Previously, if an unidentified user tried to reach a route that had auth='user', it would simply redirect to the login page.

Currently, it redirects and invalidates the session_id.

This is an issue in the latest version of master after this PR https://github.com/odoo/enterprise/pull/36521
This commit changes the route of service-worker.js to auth='user'.

This route is called on the login page, which rotates the sid and therefore invalidates the csrf token. Making it impossible for a user to log in.

This is a race condition, meaning it would only appear if the user stayed on the login page for a few seconds, hence why the automated testing did not block the commit.

closes odoo/odoo#112239

X-original-commit: d5d80d172616afe02bd41934930ea18dc273c739
Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
Co-authored-by: Julien Castiaux <juc@odoo.com>
2023-02-08 21:45:53 +01:00
Laurent Smet d724f69a1d [FIX] web: Fix useless search_count with count_limit
When count_limit is set and lower than the current number of fetched records, making an extra search_count is useless.

closes odoo/odoo#111895

X-original-commit: 6f90d6924e24e700694111732ee85465f802b22f
Signed-off-by: Rémy Voet <ryv@odoo.com>
2023-02-03 17:41:15 +01:00
Jeremy Kersten fb8765b494 [FIX] base: ir.binary - return valid filename in Stream
Before this commit, if you have some special char like a return line \n,
or \r the get_stream_from method will crash with exception:

```
File "/home/odoo/src/odoo/odoo/addons/web/controllers/binary.py", line 163, in content_image
  return stream.get_response(**send_file_kwargs)
File "/home/odoo/src/odoo/odoo/odoo/http.py", line 578, in get_response
  res = _send_file(self.path, **send_file_kwargs)
File "/home/odoo/src/odoo/odoo/odoo/tools/_vendor/send_file.py", line 156, in send_file
  headers.set("Content-Disposition", value, **names)
File "/usr/local/lib/python3.9/dist-packages/werkzeug/datastructures.py", line 1218, in set
  self._validate_value(_value)
File "/usr/local/lib/python3.9/dist-packages/werkzeug/datastructures.py", line 1182, in _validate_value
  raise ValueError(

ValueError: Detected newline in header value.  This is a potential security problem
```

Now we replace `\n` `\r` by `_` before to serve the stream to avoid this
security exception from a safe way.
We decided to not use secure_filename from werzkeug because we want to
continue the support of non ascii char.

closes odoo/odoo#111851

X-original-commit: 95584e71a898017a92112f89e8a94315dd9235ac
Signed-off-by: Jérémy Kersten <jke@odoo.com>
2023-02-03 16:32:24 +01:00
Xavier-Do 503ed05029 [IMP] tests: add generic Basecase.start for patch
Using patcher.start() can easily lead to incorrect cleanup.
-> after a copy paste, patcher is working, but stop is forgotten
-> stop is present, but won't be called if something fails during the
test

This commit add an utility `start(patcher)` to always have the add
cleanup.

Using a standard way to start the patcher with an automated addCleanup
should prevent this kind of mistake. This is why this commit also
replaces all valid patch.start() (followed immediately by a addCleanup)

closes odoo/odoo#102873

X-original-commit: 7d5a193d86316965a0908c65cfacfb607dc3f3ad
Related: odoo/enterprise#32618
Signed-off-by: Christophe Monniez (moc) <moc@odoo.com>
Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
2022-10-10 16:11:01 +02:00
Jeremy Kersten 5490fcc27f [FIX] http: convert DEFAULT_SESSION as a function get_default_session
This commit avoid to have a dict by reference that will be global.
Now get_default_session return a new dict each time for the context key.
From this way the session.context['lang'] is not shared between several
users on the same worker.

To reproduce the bug, restart the server with 2 workers, make request in
lang A on these 2 workers. DEFAULT_SESSION['context']['lang'] now is set
to this lang A.
Now, make request to an url without lang in path and without cookies and
withtout session, you should be redirected to lang B (preferred lang
from the request header) but you will be redirect to lang A due to the
dict session.context that is shared for the worker...
When we initialize the new Session, we get the wrong lang A as value for
context.lang, so we don't recompute the expected lang for the end user.

X-original-commit: 62179de74862210fe2a055d15b367b1850c24263

fwd-port of #100102

closes odoo/odoo#100910

X-original-commit: 42e46b2d89dde276f796b980f29e33cc216e7cb2
Signed-off-by: Jérémy Kersten <jke@odoo.com>
2022-09-23 09:21:38 +02:00
John Laterre (jol) 78789cfc28 [FIX] account,base,web: fix "Send & Print" on invoices
The purpose of the task is twofold:

1. Remove empty lines in the company address.

Until now, the address format was fixed, which could
lead to empty lines if one or more field(s) were missing.
We are now removing empty fields to avoid that.

2. Make sure the external report layout is configured
before generating the PDF.

This will ensure that the company data will appear
in the file. If no layout is defined,
it would not be shown.

task-2834517

closes odoo/odoo#100936

X-original-commit: f36bb6acdacaaba26afdd8f62c48fd2c8784d1e1
Signed-off-by: Olivier Colson (oco) <oco@odoo.com>
Signed-off-by: John Laterre (jol) <jol@odoo.com>
2022-09-23 07:21:43 +02:00
Xavier-Do 395b30e39d [IMP] tests, web: improve test_js end catching
Since #99912 logging an error message doesn't always end qunit tests.
This was mainly to allow to failfast logging qunit errors earlier
without stopping the tests in order to test all qunit anyway.

The logic was to have an end message that stops the test.

Unfortunately some errors will prevent the qunit suite to start
and the test will wait a 1800 long timer. An example was because of
a Missing dependencies. https://runbot.odoo.com/runbot/build/19306352

This new approach will avoid to stop only if the message looks like a
qunit failure and the final message is not there (to be sure).

closes odoo/odoo#100238

Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
2022-09-16 20:52:08 +02:00
Gorash 5410b7c238 [IMP] base/web: XML templates are added into the asset bundles.
XML files are now declared in python module manifests. During the qweb
't-call-asset' directive, assetbundle will fetch the declared xml files,
apply the inheritance (t-inherit) and create a javascript service (for
eg: 'web.assets_backend.bundle.xml') which is added at the end of the
*.js mimifier file.

When the debug mode is activated, comments are added in the template
indicating which file the template comes from as well as the
inheritances applied to it.

****

JavaScript:

assets.js (module @web/core/assets) takes care of loading libraries,
javascripts and styles.
`loadJS(url)` (loads the javascript and returns a resolved promise when
the templates are also loaded via the '*.bundle.xml' service)
`loadCSS(url)` (loads the style a resolved promise when the file is
loaded)
`loadXML(xml, app=assets.defaultApp)` (load template into
application/owl, used by the `*.bundle.xml` services)
`getBundle(bundleName)` (get the bundle descriptor)
`loadBundle(desc)` (load the files and bundle from a descriptor)

templates (XML element content all owl templates)

A new `ready(serviceName)` method on boot.js lets you know when a
service is loaded are the require.

The xmlDependencies attribute no longer exists.

Python:

The xmls taken into account by assetbundle.py, applying `t-inherit`
inheritances and adding an `name_of_the_bundle.bundle.xml` service in
the generated JavaScript file.

****

Every manifest changes is into the next commit, except 'web_tour' in
this current commit as example.

Part-of: odoo/odoo#95500
2022-09-14 20:25:01 +02:00
Xavier-Do c764c38d7c [IMP] website: pregenerate frontend assets
closes odoo/odoo#99176

Signed-off-by: Christophe Monniez (moc) <moc@odoo.com>
2022-09-12 13:49:00 +02:00
Xavier-Do ae3e68c1f4 [IMP] web: add tests for bundle pregeneration.
Since bundle generations should be generated before post install tests,
a loading of a /web shouldn't try to save a new version

This is currently breaking for / because of the website_id added in the
extra part of the attachement. Even if the content is the same.

Part-of: odoo/odoo#99176
2022-09-12 13:48:59 +02:00
Xavier-Do 0a695ab6b2 [IMP] web: one log per qunit module.
Right now the qunit will log all results at the end.

This means that the runbot may wait for all qunit before detecting the
failure.

This also mean that all failure are in one ir.logging on runbot, making
the automated parsing difficult if multiple modules fails during the
same build.

We could also log all failure immediately, but grouping them my qunit
module will avoid duplicating logs for linked causes (one failure
leading to a `Expected %s assertions, but %s were run` message)

closes odoo/odoo#99912

Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
2022-09-10 01:54:12 +02:00
Xavier-Do e82c75c28b [FIX] web: static template performance test
Time comparison can always be slightly random (this is why this test
is a nightly one). The 20% margin left by the 12 ratio is not enough
in all cases. This test was sometime breaking with a
12.944994188420822 not less than or equal to 12

This is one of the max value found by quickly checking the builds.
A ratio of 14 should be hopefully enough.

closes odoo/odoo#99156

X-original-commit: cc86b80342d38913f7af79474c41f8764c8b2dd2
Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
2022-09-05 14:50:39 +02:00
std-odoo a740989ba5 [MOV] web: move the domain selector component to web
Purpose
=======

For security reason access on ir.model is not granted to internal suers. Due
to this constraint a component exists in spreadsheet to be able to select
the models for which we have a read access on the records of this model.

This is required for the properties fields feature, hence moving its code
to web.

Some renaming is performed to make it generic. This generates some changes
in other addons, notably some class renaming.el.

Task-2852259

Part-of: odoo/odoo#95184
2022-08-29 23:46:07 +02:00
Stanislas Sobieski 31de6e8454 [FIX] web: fix database manager test
Skip test on database manager rendered page when option
--no-database-list is used

closes odoo/odoo#98771

Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
2022-08-25 03:12:01 +02:00
Christophe Monniez c754838489 [FIX] web: fix clickbot click timeout inconsistency
The clickbot click default timeout was increased in #98495, but missed
the fact that the default was overridden for the "Settings" menu to a
lower value.

With this commit, the "Settings" exception is completely removed as the
default timeout is higher. Also, checking that the text contains
"Settings" was a bit weak.

While at it, the timeout for the global testing of an app is also
increased to 10 minutes instead of 5 as this limit is reached by the
Field Service app.

closes odoo/odoo#98617

X-original-commit: 0247e6f4abef4121b451c1373ae3c1ce184451c0
Signed-off-by: Christophe Monniez (moc) <moc@odoo.com>
2022-08-23 08:50:01 +02:00
Romeo Fragomeli a5d6b3cafd [FIX] project,web: 'bg-muted' doesn't exist anymore
`bg-muted` as been replaced by `bg-200` in odoo/odoo#97051, but there
are still non-converted ones.

closes odoo/odoo#98555

Related: odoo/enterprise#30635
Signed-off-by: Adrien Dieudonné (adr) <adr@odoo.com>
2022-08-22 16:48:57 +02:00
Xavier Morel d22cd89a60 [FIX] web: opt clickall out of form edition check
We can't really know where the clickall tour will end, and if it ends
on the settings action things are rather difficult as saving or
discarding the settings form returns to the edition mode.

Part-of: odoo/odoo#96517
2022-08-04 09:14:09 +02:00