Previously proposed formating was trying to normalize extra in one part
of the path. This means that no extra needed a placeholder.
The implementation was meant to be more generic and extendible since a
part of the logic has to be in website.
A suggestion was made to make it more restricted but explicite by
keeping the url simple in web/controllers/binary.py but adding a
controller in website to add this extra part.
The base extra direction is now in the extension, as the min part.
Initial urls:
/web/assets/{unique}/[{website_id}/][rtl/]{bundle_name}[.min].{extension}
New urls:
/web/assets/[{website_id}]/{unique}/{bundle_name}[.rtl][.min].{extension}
Managed by two routes:
/web/assets/<string:unique>/<string:filename>
/web/assets/<int:website_id>/<string:unique>/<string:filename>
Where filename is in the format {bundle_name}[.rtl][.min].{extension}
Multiple possibilities where proposed
- /web/assets/website/<int:website_id>/<string:unique>/<string:filename>
More explicit but prefixing by /website was considered
- /website/assets/<int:website_id>/<string:unique>/<string:filename>
This one is a litle painfull to match similar attachement, where
website is ignored.
- /website/<int:website_id>/assets/<string:unique>/<string:filename>
Almost accepted but subjective, and anyway two previous solution breaks
the cdn mecanism and would need a migration
- /web/assets/<int:website_id>/<string:unique>/<string:filename>
Almost accepted but subjective, and anyway two previous solution breaks
the cdn mecanism and would need a migration
This last solution was not ideal to match without unique
/web/assets/%/<string:filename> can match both
/web/assets/123456/<string:filename>
and
/web/assets/1/123456/<string:filename>
Anyway, matching without unique shouldn't be supported for al (even if
it is kind of supported with any right now) but it will work by changing
unique wildcard to a more specific one (_ * 7)
closesodoo/odoo#131353
Related: odoo/enterprise#47313
Related: odoo/design-themes#730
Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
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
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
This commit removes usages of jquery in database_manager and adapts the
code accordingly. Also improve the alert messages.
task-3508327
closesodoo/odoo#137670
Signed-off-by: Mathieu Duckerts-Antoine (dam) <dam@odoo.com>
Install auth_oauth and via the /web/login, click the "Log in using
Odoo.com" button. You are redirected on odoo.com which ask you for your
odoo.com login and password. When the login form on odoo.com is
submited, you are redirected back on your local database.
The problem is that, in case a new account was created on-the-fly, then
the login fails with a cryptic error. The actual error is that
`request.env.user._is_internal` fails because `user` is an empty
recordset where it should had been the just-authenticated user.
The problem is an inconsistent transaction state between the cursor of
the request, the cursor used with `auth_oauth` (which created a new
user) and the cursor used with `authenticate` (which authenticated the
new user). Yes, there are 3 cursors. The newly created user just isn't
present in the transaction of the request's cursor.
Here is the lifetime of the 3 cursors:
* request.env.cr, it begins when the http request enters Odoo, it is
commited when a http response exits Odoo.
* /auth_oauth/signin, it begins roughly at the beginning of the
controller, it is commited once after the user is created (so before
the authenticate transaction begins but AFTER the request transaction
begun), it is commited again when the controller exits.
* authenticate, begins when authenticate is called, is commited when it
returns.
Because the request transaction started before, it cannot access user
created by /auth_oauth/signin.
Because the route is `auth='none'`, if system administrators append the
`auth_oauth` module via `--load` (cli) or `server_wide_modules` (odoorc)
then the controller can be accessed without database. This is the reason
for the explicit registry/cursor/environment inside this controller, we
needed to make sure we are connected to a database, we cannot rely on
request.
The new approach used in this work is to benefit from `ensure_db()`, the
function that is used by various web `auth='none'` controllers such as
/web and /web/login. It makes sure that the database we want to connect
to is already present on the request, otherwise it repeats the request
but this time connecting it to the database. Using this approach we can
have a `auth='none'` controller whose request.env is guaranteed to be
connected on the right database. We can avoid to create explicit new
registry/cursor/environment within the controller and just use request's
ones.
Because the /auth_oauth/signin controller now simply use the request
transaction, the above point:
> Because the request transaction started before, it cannot access user
> created by /auth_oauth/signin.
just doesn't stand anymore as the user is created within the same
transaction. The extra `cr.commit()` must still be present for
`authenticate` to see the newly created user.
opw-3421701
closesodoo/odoo#138051
X-original-commit: e165568f9795af213c8467a7f17948ed781b0799
Signed-off-by: Olivier Dony (odo) <odo@odoo.com>
Co-authored-by: Julien Castiaux <juc@odoo.com>
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
closesodoo/odoo#135607
Related: odoo/upgrade#5187
Related: odoo/enterprise#47475
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
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
closesodoo/odoo#135435
Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
Steps to reproduce:
- Install Knowledge App
- Create a sub-article and add them as many properties as you want.
- Go to search to get the list view and export the article, adding both
of the properties field (`article_properties`,
`article_properties_definition`).
- Now try to import the file we just exported.
At this moment this issue affects knowledge properties and crm, leads
properties (for reference see: #122817) but the proper fix is still not
applied, and since it's implementation is complicated we are going to
remove the properties from the export when we tick the
"I want to update data (import-compatible export)." until the proper fix
is done.
opw-3346642
closesodoo/odoo#135406
X-original-commit: 16912d7bfa2bc618f2f5cc40f915728fc7e62cb3
Signed-off-by: Stéphane Debauche (std) <std@odoo.com>
Signed-off-by: Maruan Aguerdouh Mohtar (magm) <magm@odoo.com>
the comment 'openerp-web' has been deprecated since odoo/odoo#105589, and there
is only JAVASCRIPT_TRANSLATION_COMMENT in the most po files of the source code
repository
closesodoo/odoo#135277
X-original-commit: 4f84ea2be89f255846364c00a230463dce6ac773
Signed-off-by: Raphael Collet <rco@odoo.com>
Signed-off-by: Chong Wang (cwg) <cwg@odoo.com>
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/rfc8030https://www.rfc-editor.org/rfc/rfc8188https://www.rfc-editor.org/rfc/rfc8291https://www.rfc-editor.org/rfc/rfc8292https://w3c.github.io/push-api/index.htmlhttps://autopush.readthedocs.io/en/latest/http.htmlhttps://web.dev/push-notifications-web-push-protocol/https://github.com/web-push-libs/encrypted-content-encodinghttps://github.com/web-push-libs/pywebpushhttps://github.com/web-push-libs/vapidhttps://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
closesodoo/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>
When user access template at the time of export with deleted field.
The traceback will be generated.
To reproduce the issue(any model, here- 'account.move.line'):
- Install 'account_accountant' module
- Go to Settings > Technical > Database Structure > Fields
- Create a new field with model as 'Journal Item' and save
- Go to Accounting > Miscellaneous > Journal Items
- Select any record in list view and click on export and generate a new export
template with newly created field
- Go to 'ir.model.fields' and delete that field
- Go to 'Journal Items' and select that template while export
Error: A traceback appears: KeyError: 'tax_audit'
When a field gets deleted from 'ir.model.fields' but it does not get deleted
from export template. And selecting that template to export the records will
lead to traceback.
See -
https://github.com/odoo/odoo/blob/59669e9943158e51dcbb9ae69ad758df8f7c7976/addons/web/controllers/main.py#L1815-L1818
sentry-4331986723
closesodoo/odoo#134605
X-original-commit: e458a4c164820c3ccf00b0520c5f86c49238fb2a
Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
When there is an error in a report and user tries to
download that report a logger exception occurs.
Exception: Error while generating report
studio_customization.studio_report_docume_1c084f7d-9ac2-4dd4-9977
-03d87251392c
The error occurs from report_download controller -
https://github.com/odoo/odoo/blob/0d70e38ab4bab850ee4bddc7b21b4c6c10809294/addons/web/controllers/report.py#L136
The logger is updated to use the 'warning' level instead of the 'exception'
level when an error occurs while generating report.
sentry-4321014875
closesodoo/odoo#132528
X-original-commit: 1210e1c7bc97ea772df5d2230a3b8f42b13e9e10
Signed-off-by: Achraf Ben Azzouz (abz) <abz@odoo.com>
Signed-off-by: Saurabh Choraria (sauc) <sauc@odoo.com>
To Reproduce
============
- on project task add a property
- go back to list of tasks and try to export the modified task
an error is raised
Problem
=======
The property field is represented as dict (same for JSON fields)
Which is not expected in `write_cell`
Solution
========
handle `dict` type
opw-3431718
closesodoo/odoo#132303
X-original-commit: 1e9ed945c637e78b1003115dfd4042b3d87d8365
Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
Signed-off-by: Abdelouahab Laaroussi (abla) <abla@odoo.com>
Goal:
* Simplified modifiers to only have one way to define modifiers;
* Remove states attributes on python field;
* Use python expression in view `required`, `readonly`, `invisible`;
* More accurate validation of xml views.
This commit change the syntax to python expression. The next commit
will update/convert all xml views.
Before this commit:
* the `required`, `readonly` and `invisible` attributes can only have
values of `True`, `False`, 1, 0 or a python expression to use the
context;
* the `attrs` attribute define a dict. The key of this dict was
`required`, `readonly` and `invisible` and the values are the domain or
a string representing a domain to be evaluate as python expression.
This python expressions was evaluate by the javascript with view fields
and other contextual values as: context, uid, parent, active_id,
active_ids, active_model, allowed_company_ids, current_company_id.
* the `states` attribute in the view was a comma separated list of the
state. This list was combined with the `invisible` attribute;
* the `invisible` attribute on python field is used as default value;
* the `states` attribute on python field was dictionnary with state as
key and list of tuple. This structure was combined with `readonly` view
attribute.
* After combining, the resulting domains of the different attributes
`required`, `readonly` and `invisible` are evaluated with the values of
the fields. The `invisible` attributes is splitted into two use:
`invisible` and `column_invisible`.
After this commit:
* The attributes `required`, `readonly`, `invisible` and
`column_invisible` define python expression. This python expressions
are evaluate by the javascript with view fields and other contextual
values as: context, uid, parent, active_id, active_ids, active_model,
allowed_company_ids, current_company_id.
The domains can contains contextual value and will be evaluate by the
javascript.
```xml
<field name="field_a" readonly="not context.get('show_a')" attrs="{'readonly': [('field_b', '!=', False), ('field_c', '=', parent.c)]}"/>
<field name="field_b" states="draft"/>
```
will be replaced by
```xml
<field name="field_a" readonly="not context.get('show_a') or field_b and field_c == parent.c"/>
<field name="field_b" invisible="state != 'draft'"/>
```
Some inherited views will be modified differently in order to maintain
the previous behavior:
```xml
<field name="field_a" readonly="not context.get('show_a')" attrs="{'invisible': [('field_b', '!=', False)]}">
```
```xml
<field name="field_a" position="attributes">
<attribute name="attrs">{'readonly': [('field_c', '=', False)], 'invisible': [('field_d', '!=', '3')]}<attribute>
</field>
```
will be replaced by
```xml
<field name="field_a" readonly="not context.get('show_a')" invisible="field_b">
```
```xml
<field name="field_a" position="attributes">
<attribute name="readonly" add="(not field_c)" separator=" or "/>
<attribute name="invisible">field_d != 3<attribute>
</field>
```
Validation:
A stricter control is made on the level of the attributes (modifiers)
and the fields necessary for these. The use of the previous attributes
'attr' and 'states' triggers an error (these no longer exist after the
application of the migration script)
task-2495504
Part-of: odoo/odoo#104741
The limit was only enforced by the front-end, meaning that anybody could
forge a request with a huge file and get it processed by Odoo. According
to the documentation of werkzeug[^1], such limit should be enforced by
the server server instead of the wsgi application. It is the case for
Odoo Online but on-premise customers might not configure their servers.
The `web.max_file_upload_size` system paramter is now enforced upon
parsing the content of the request. It defaults at 128 MiB which is
enough for most documents and images. We do not want to host large
files (e.g. videos) in the Odoo filestore.
[^1]: https://werkzeug.palletsprojects.com/en/2.0.x/request_data/Fixes: #124646
Part-of: odoo/odoo#126914
With this commit, it is possible to load the web client in a language
different than the user by using the `lang=` query string in the url:
For example, `/web?lang=en_US`
This is useful when we need to quickly check something, without changing
the current user settings. Note that it will only work if the url lang
has been installed on the database (if lang does not exist, it will fall
back to en_us).
closes odoo/odoo#128121
Taskid: #3420252
Signed-off-by: Samuel Degueldre (sad) <sad@odoo.com>
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>
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
Steps to reproduce:
- Install `CRM` for test purpose
- Go to `CRM > Pipeline` and open any lead
- Add a new property and set a value
- Go back and open list view
- Group by `Salesperson`
- Select all records and click on `Export` in action menu
- Add 'Properties' field
- Export
Issue:
Traceback raised. No issue if not grouped.
Cause:
The properties value is a list of dict. When grouped, the properties
value is not converted to string (like it is done for list and tuples
in the non-grouped flow).
Solution:
Move the code that convert list and tuples to string in the
non-grouped flow directly to the `write_cell` method so that it is
applied in both cases.
opw-3338564
closesodoo/odoo#128682
X-original-commit: f380c56bb13773eee0e19462ba7283b04d54183b
Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
Web lacked a default route for /robots.txt meaning that if you didn't
installed website (which comes with a full fledged robots.txt) you would
get a 404 page not found.
closesodoo/odoo#127402
Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
THese are rarely intended for all users but often intended only for
employees.
account:
account.incoterms: only used within internal business models
account.journal.group: same as account.journal, add sudo in computed field
account_edi: need access to accounting objects
base_address_extended:
res.city: only employees should access address data
board: only employees uses this (old) module
crm:
crm.stage: internal users business object
hr_recruitment: employees can read
im_livechat: apply same as for the steps
l10n_ar: used on partner, not only invoices
l10n_ec: accessed only through account.move
l10n_latam: accessed on res.partner
mail:
publisher.warrenty.contract: no data, only static models
mail.channel: group_user has already his own rule
mail.group: group_user has already his own rule
mail.message.subtype: group_user has already his own rule
mail.message.all: remove, already has a portal and employee rule
partner_autocomplete: no interaction with public
project:
project.tags: only needed for project sharing
sale_management:
sale.order.option: same as sale.order
utm: employee already has write access
web_editor: test models that have nothing to do here
web_tour: only employees uses tours
website_sale:
product.ribbon: add sudo for access
base:
ir.default: only employees uses set (could probably be converted to group_system)
ir.ui.view.custom: same as ir.ui.view, add sudo when needed
report.*: portal users don't configure reports
res.users.log: create in sudo, no access needed (adapt test to use another model)
res.lang: still needed for public
closesodoo/odoo#118701
Related: odoo/enterprise#41285
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
Before this PR:
The only way to neutralize the database is running cli command neutralize
After this PR:
There is a new checkbox "neutralize database" in Duplicate database and Restore database dialog that neutralize the database after duplication/restore.
I also moved the neutralization code to the external module so it can be called also outside the cli .
closesodoo/odoo#122185
X-original-commit: 616740e9d09b3d0376be43ed1489e390f6f5823e
Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
Before this revision, when you pass `context` in the arguments
of a JSON routes, this one gets automatically injected
in the environment context.
This is not the case for regular HTTP routes.
It makes sense to propagate the context for the JSONRPC protocol,
JSON routes used by the backend, such as `call_kw`,
but it doesn't make sense to pass this context automatically
for any other kind of routes, such as front-end routes
or routes used by custom Javascript widgets.
This change brings a more unified behavior for routes
of types HTTP and JSON.
In addition, most developers were not aware of this "feautre",
that passing `context` in the arguments of a JSON route leaded
to the injection of this context in the environment context.
This is actually reflected by the diff size this changes required,
only a dozens of routes needed to be adapted, to manually
add the context in their route arguments and to inject it
in their environment context.
closesodoo/odoo#121726
X-original-commit: a7a5655631e6d5b05fd2ba3d0c80617aae6d9cfe
Related: odoo/enterprise#41229
Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
Due to numerous client complaining about their automated scanner not
seeing the CSP header on the http request, we add it for good mesures
opw-2793379
closesodoo/odoo#121098
X-original-commit: 70a54ac604cf2aeef33d11b95851e35dd463727f
Signed-off-by: Vranckx Florian (flvr) <flvr@odoo.com>
Rationale
---------
Given the following domain:
['|',
('company_id.name', 'like', 'BE'),
('company_id.city', 'like', 'Brussels')]
The ORM would generate the following SQL query:
SELECT "res_partner"."id"
FROM "res_partner"
WHERE "res_partner"."company_id" IN (
SELECT "res_company"."id"
FROM "res_company"
WHERE "res_company"."name" like 'BE'
) OR "res_partner"."company_id" IN (
SELECT "res_company"."id"
FROM "res_company"
WHERE "res_company"."email" like 'help@odoo.com'
);
Which is sub-optiomal as the WHERE clause of the two subqueries could be
regrouped inside of a single query like so:
SELECT "res_partner"."id"
FROM "res_partner"
WHERE "res_partner"."company_id" IN (
SELECT "res_company"."id"
FROM "res_company" WHERE (
"res_company"."name" like 'BE'
OR "res_company"."email" like 'help@odoo.com'
)
);
Postgres-wise, it is faster to execute the latter query than the former
one. This commit is about optimizing the ORM so that it generates
queries where the WHERE clause of compatible subqueries are grouped
together.
Technical solution
------------------
The solution explored by this work is to replace the regular relational
field accesses (over a dotted path) by a new `any` operator that look as
follow:
(relational_field, 'any', domain)
For instance, the above `('company_id.name', 'like', 'BE')` leaf becomes
`('company_id', 'any', [('name', 'like', 'BE')]` using `any`.
Having a domain as right-hand-side allow for the combination of the
domains of same compatible relations:
[('company_id', 'any', ['|',
('name', 'like', 'BE'),
('city', 'like', 'Brussels')])
Having combined domains allows for generating better SQL queries with
minimal changes to the expression parsing algorithm, which can only
translate a single leaf at a time to SQL. With the new `any` operator,
it is still a single leaf but the right-hand-side contains the merged
domain, thus the combined SQL WHERE clause is immediately generated.
task-id-3234671
Part-of: odoo/odoo#118067
Co-authored-by: Raphaël Collet <rco@odoo.com>
before this commit, after running an older version,
lets say odoo 14 and trying to access 16 in the
same browser return traceback without redirecting
to db selector page
and this happens due to the missing env in request,
which returns as None.
after this commit, no traceback wont be shown and
will open the db selector page
closesodoo/odoo#118851
X-original-commit: 900303c18243e3b97414b3dbf5eb7ee5b8c9c080
Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
This issue was occurring while printing the count sheets in the 'update
quantity' section of products in 'Inventory' module.
Steps to Reproduce:
- Open Inventory module and go to any product.
- Click on update quantity button.
- Click create button, select the new record without saving it.
Then click Print > Count Sheet
To fix this we check whether it is integer or not, if it is integer then
only it will print the report.
sentry-3880400776
closesodoo/odoo#115186
X-original-commit: 2600c17859363f5ec8c1f50a73e9d1990aa762ba
Signed-off-by: Ivan Elizaryev (iel) <iel@odoo.com>
In Serbia there are two language codes and those are `sr_RS` (Cyrillic) and `sr@latin` (Latin). Inside of the `web/static/lib/moment/locale` folder, the two langs are registered as `sr-cyrl.js` and `sr.js` respectively. The `load_locale` controller wasn't loading the right langs for neither case.
X-original-commit: 65d5ab801f22b42a0f94fe4b86f68ace451ea184
Part-of: odoo/odoo#114565
*: base, http_routing, mass_mailing, web, web_editor, website_slides
In some situations `werkzeug.wrappers.Response` are used instead of
`odoo.http.Reponse` that extends it.
This is a problem because since [1] the calls to `set_cookie` expect it
to accept the `cookie_type` parameter, which is not the case in the base
werkzeug implementation.
This commit replaces the `werkzeug.wrappers.Response` by
`odoo.http.Response`.
[1]: https://github.com/odoo/odoo/commit/2cbda6c98ee947cea1d06c09880eee8c758304a8closesodoo/odoo#112827
X-original-commit: 28da08292b7028575e628c5ad846fc05d30498f2
Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
__Description of the issue:__
When something goes wrong while downloading a report file, a 500 error
is sent as JSON. However the frontend interprets this response as HTML
and then try to parse the text content as JSON.
Most of the time this works, but if the response contains any HTML tags,
like `<lambda>` from a Python stacktrace, the JSON response will get
misinterpreted as HTML instead of regular text, causing the subsequent
JSON interpretation to fail.
The end result for the user is that empty tracebacks will be displayed
instead of User Errors or actual tracebacks.
__Desired behavior:__
The JSON response is HTML escaped before being sent and will therefore
be correctly parsed and displayed to the user.
This basically restore what was done prior of #104594.
Enterprise: odoo/enterprise#36523
X-original-commit: 5999a7d336553053c5638f69344cdfbc84a8c681
Part-of: odoo/odoo#112453
Those views are no longer used and about to be removed. This
commit also removes the benchmark lib as it is no longer used.
Part of task 3168640
Part-of: odoo/odoo#111809
Export tool is based on ORM method `_export_rows`. The method has special
processing of m2m fields when user checked *Import compatible* option [1].
Before this commit the negative value of `import_compatible` parameter wasn't
passed when data are exported in grouping mode. This led to empty values in m2m
fields.
STEPS:
* Order some products via website and pay via wire transfer
* Open Orders menu in backend
* group order by any field
* expand group with the order
* add field *Transactions/Acquirer/Display Name*
[1]: https://github.com/odoo/odoo/blob/b28c44a38698018ebbbc420f6567c17b2b97c279/odoo/models.py#L894-L914
opw-2864737
closesodoo/odoo#110151
X-original-commit: 6647ac83467207f4f4ef23aac96ebaf5333b967b
Signed-off-by: Ivan Elizaryev (iel) <iel@odoo.com>
When overriding an existing controller route, developers can
easily c/p the route definition and call super() in the overridden method
when the route attributes are automatically deducted by odoo from the parent route.
Removing those redefined attributes simplifies the routes definition,
clearly highlighting what's changed by the override.
Also reduces unexpected behavior when modifying the base route without
noticing/considering the redefined attributes in a overridden route,
which overrides the changes made to the base route when the sub-module is installed.
This commit adds a test to catch routes attributes redefinition, and clean existing routes.
closesodoo/odoo#108512
Related: odoo/enterprise#35176
Signed-off-by: Victor Feyens (vfe) <vfe@odoo.com>
JSON content can be rendered nicely by browsers when using the
appropriate mimetype
closesodoo/odoo#107708
X-original-commit: 70153bbe233bb81d51752c5f1ed1766414eb875b
Signed-off-by: Olivier Dony (odo) <odo@odoo.com>
*: base_setup, hr_timesheet, mail, partner_autocomplete, web_tour
Start odoo without -d and with a --dbfilter that allows multiple
databases. Via JSON-RPC access the /web/session/authenticate route
providing a non-filtered database and valid credentials. Traceback,
`request.env` is None.
Since httpocalypse the initialization of the ORM (cursor, registry,
environment) is greedy. It means that the connection to the database is
established very early during the request routing or skip altogether in
case no dbname was known at that time. This contrast with prepocalypse
where the various ORM thingies were lazily setup the first time they
were accessed.
This changement has an important implication regarding authentication.
In prepocalypse, thanks to the lazy approache, a cursor/registry/env
would be setup on the database you just login upon using the
`request.env` for the first time. This was very nice in this regard but
had other problems.
Since httpocalypse such operation is no more possible. Devs must
initialize and use their own cursor/registry/env in case they
authenticate on another database than the one `request.cr` is (maybe)
connected to.
The `/web/session/authenticate` controller is an example of such case.
It crates its own cr/registry/environment after authentication. The
problem the controller uses `ir.http.session_info` and that not all
overrides were updated to use `self.env` (=the env created in the web
controller) instead of `request.env` (=the missing env of the request).
closesodoo/odoo#108063
X-original-commit: 7b9bd9d37731fae724dc5d91da656dab70aa9ad4
Related: odoo/enterprise#35012
Signed-off-by: Julien Castiaux <juc@odoo.com>
The /web/login route is historically defined to be auth=none, which
means that it is available even when no database is selected (yet), and
no db_filter is set to automatically select one.
This is done mainly to be able to redirect users to the database
selection screen (cfr ensure_db()) instead of showing them a 404 until
they manually go to the /web/database/selector page.
The conversion of this mechanism in odoo/odoo#87571 can cause
problems because the user environment used to render the login page uses
the superuser ID. In certain configurations of installed modules, it was
possible to have the /web/login page showing "OdooBot" as the logged in
user, despite no user being actually logged in at all.
To fix this, we override the env that was set by auth=none:
- with the current session user, if there is one (like `/web` does)
- with the public user otherwise (as auth=public would do)
closesodoo/odoo#107613
X-original-commit: 6e42a07d7637070d45be81dcbf7261eda08425b4
Signed-off-by: Julien Castiaux <juc@odoo.com>
Current behaviour:
When we are printing a report and then the report fails to generate
(for ex. wkhtmltopdf memory limit/timeout),
the incorrect state is committed to the database.
Expected behaviour:
We should rollback when generating reports fails, since it is an error state.
Steps to reproduce:
To reproduce the behaviour, we need to force an error state.
- In odoo/addons/base/models/ir_actions_report.py:`_run_wkhtmltopdf()`,
raise an exception before spawning the subprocess (for ex. adding a 1/0).
- In addons/web/controllers/main.py:`report_download()`#L2126,
add this little code snippet:
```python
ids = [int(x) for x in docids.split(",")]
report = request.env['ir.actions.report']._get_report_from_name(reportname)
obj = request.env[report.model].browse(ids)
if getattr(obj, 'message_post'):
obj.message_post(body='This report was committed!')
```
- Install Inventory
- Pick a delivery order and try to print it, there should be an error
(whatever exception you decided to raise in `_run_wkhtmltopdf()`)
- See that in the message board we got a message that the report has been committed,
which isn't the case, it failed to generate.
Reason for the problem:
Controllers are catching the exception when generating reports,
but never reset the state of the database.
Fix:
Raise an InternalServerError with an error code of 500 to trigger
a database rollback.
Affected versions:
- 14.0
- 15.0
- saas-15.2
- saas-15.3
- 16.0
- master
opw-3001950
closesodoo/odoo#106172
X-original-commit: ec185fcf7f32da05c83733af36bebe10ac22e2ad
Related: odoo/enterprise#34193
Signed-off-by: Julien Castiaux <juc@odoo.com>
Signed-off-by: Piryns Victor (pivi) <pivi@odoo.com>
Steps to reproduce:
- Switch to `?debug=assets`
- Change the user language to Arabic and back to English
-> The page is still displayed in rtl mode
Cause of the issue:
The css is retrieved like this
```py
>>> self.env['ir.attachment'].sudo().search([('url', '=like', '/web/assets/%/web.assets_common.css')])
ir.attachment(212, 189)
>>> self.env['ir.attachment'].sudo().search([('url', '=like', '/web/assets/%/web.assets_common.css')]).mapped('url')
['/web/assets/212-5d47380/rtl/web.assets_common.css', '/web/assets/189-5d47380/web.assets_common.css']
```
Only the second one should be matched.
Solution:
Check for the absence of an extra parameter in the url
opw-2892012
closesodoo/odoo#105127
X-original-commit: 539427fa2a099b29adf099c2b48d4f1d2fd4ebd2
Signed-off-by: Julien Castiaux <juc@odoo.com>
Signed-off-by: Hubert Van De Walle <huvw@odoo.com>
Start odoo on a specific database, e.g. 'db-example'. Drop it via JSON
or XML RPC. The database is successfully dropped but the RPC fails with
a traceback because it attempts to commit on a database that doesn't
exist anymore.
import requests
admin_passwd = ...
requests.post(
'http://127.0.0.1:8069/jsonrpc',
json={'params': {
'service': 'db',
'method': 'drop',
'args': [
admin_passwd, 'db-example'
]
}}
)
Closes odoo#104527
closesodoo/odoo#105710
X-original-commit: b6e195ccb3a6c37b0d980af159e546bdc67b1e42
Signed-off-by: Julien Castiaux <juc@odoo.com>
The new `borrow_request()` function has been introduced to properly
separate the HTTP layer from the RPC layer. We forgot to protect some
RPC endpoints, mainly inside of `odoo.addons.web.controllers.database`.
This commit moves `odoo.service.dispatch_rpc` to `odoo.http` as we only
permorm RPC from the controllers and that we don't want to import
`borrow_request` inside of `odoo.service` (circular import).
X-original-commit: d0ee8615d8820e02232989c50a6e6ffbc66a9266
Part-of: odoo/odoo#105710
Reading only 'id' with `search_read` is equivalent to use `search` but
complexify the result usage. Fix all these bad usages.
Part-of: odoo/odoo#104838
Co-authored-by: Julien Castiaux <juc@odoo.com>
If the decimal separator of the currently selected language is a comma,
exporting data in an xlsx would use a wrong float format
Steps to reproduce:
1. Install Invoicing
2. Go to Settings > Languages, add 'French / Français' language and
switch to it
3. Go to Facturation > Fournisseurs > Factures
4. Export the data (there should be at least one amount with a decimal
part)
5. The decimal part of the amounts is not displayed
Solution:
Always use the same decimal separator to print in the xlsx as we can
only use a dot as a decimal separator (the comma is used as the thousand
separator). The value will then be displayed to the user according to
his OS regional settings (see https://xlsxwriter.readthedocs.io/format.html#number-formats-in-different-locales)
Problem:
When using a comma for the float format, we actually specify the format
of the integral part of the number (the thousands) without displaying
the decimal part (which is represented with the dot)
opw-2965984
closesodoo/odoo#102255
X-original-commit: 21efa4f18266a5c5c57157035c2357ed3e147a69
Signed-off-by: Julien Castiaux <juc@odoo.com>
Signed-off-by: Guillaume Merlin (megu) <megu@odoo.com>