Commit Graph
100 Commits
Author SHA1 Message Date
Xavier Morel c7826675a8 [FIX] base: restore deletion of dependencies on field removal
odoo/odoo#111651 improved and optimised triggers but dropped the
in-place cleanup of field dependencies. As a consequence, during
module uninstallation if a stored computed field is removed (because
it's part of a module being uninstalled), and one of its dependencies
is subsequently altered (e.g. it's itself removed, or written to) the
second update will break as the query trying to find out which
dependent records to update will error, either because of trying to
select / filter on a missing column, or because of trying to fetch
in a missing table.

The simplest examples of this issue are computed fields with a
dependency on `ir.model`:

- In `calendar`, `calendar.event.res_model` is a related on
  `res_model_id.model`, this prevents the removal of *any* `ir.model`
  record if it gets uninstalled.

  As a result the `calendar.attendee` and `calendar.event` tables
  don't get removed (just emptied of all their non-automatic fields),
  their records remain as well, and when the non-automatic fields get
  re-added during installation re-instating the NOT NULL constraints
  fails, breaking the uninstall/reinstall test.

- In `payment`, `payment.provider.module_state` is a related on
  `module_id.state`, this breaks *during* uninstallation, as after
  `module_uninstall` first calls `_module_data_uninstall` which
  removes the field, then it *updates the modules being uninstalled*
  (sets their state), which tries to find out which
  `payment.provider`'s `module_state` is should update, which breaks
  because the `module_id` column has been removed.

  This second one was worked around in odoo/odoo#118900, by marking
  modules as uninstalled before actually gutting them, but as it turns
  out the "actual" fix is needed anyway. So revert the workaround, and
  actually fix the issue.

closes odoo/odoo#119130

X-original-commit: 48a420efcf7c7b46416bab006003553cc9d23846
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2023-04-20 09:33:48 +02:00
Xavier Morel 98b5505305 [FIX] base: mark modules as uninstalled before gutting them
Before this, uninstalling the `payment` module (or any of its
dependencies) is broken: as payment.provider has a dependency on
ir.module.module.state, marking the modules causes a lookup of the
payment provides to update, but the table was removed by
`_module_data_uninstall`, so the lookup blows up.

This is a consequence of odoo/odoo#111651 which improved and optimised
triggers but dropped the in-place cleanup of the triggers tree.

Thus while the columns & tables get removed from the database the
in-memory structures (registry, models, fields, ..., as well as the
trigger and dependency caches) are not so the python side will happily
try to look up stuff which has been nuked if accessed at the wrong
moment (which is any moment between the start of
`_module_data_uninstall` and the creation of a new registry, really).

As `_module_data_uninstall` is nothing but a giant pile of dodgy state
anyway, making modules as uninstalled before it executes doesn't seem
like a huge deal. It may cause unnecessary extra recomputation for the
few models which depend on modules, but that doesn't seem like a major
issue, at worst it makes uninstallation a touch slower but they're not
a huge performance concern at the moment (they're more of a
correctness one).

closes odoo/odoo#118959

X-original-commit: 460efeb623ec62c980d187710bd4e7614af0e7bd
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2023-04-19 12:13:32 +02:00
Xavier Morel 215ccd1194 [FIX] website_slides_survey: fix uninstall_hook
When #114353 forward port of #112425 which adds an uninstall_hook was
merged, it was not updated with the API change of #108254, which
replaced the `(cr, registry)` parameters by a sole `(env)` as most if
not all uninstall hooks immediately created an environment anyway.

So this hook has been breaking uninstall on anything on which
`website_slides_survey` depends since it was merged.

Fix the hook to match the new API.

closes odoo/odoo#118296

X-original-commit: 201a4b369cf1652a2da763181f6837cfb7f44f3e
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2023-04-13 04:08:35 +02:00
Xavier Morel c2848b9bb4 [IMP] point_of_sale: modernize get_price
- Remove dead code around now-unused categories
- lift `price` processing outside of `find` which complicates it
- use arrow functions, which obviates the need for aliasing `this`
- use slightly more expression-oriented code-style where applicable

Results in code which is noticeably shorter and (I hope) easier to follow.

closes odoo/odoo#117874

Signed-off-by: Joseph Caburnay (jcb) <jcb@odoo.com>
2023-04-13 00:06:00 +02:00
Xavier Morel e702e3a776 [IMP] point_of_sale: simplify can_be_merged_with code
Existing version uses a visually complicated chain of if/else and
double negations, this is much more readable as a simple chain of
AND-ed conditions checking for positive merge-ability factors.

Part-of: odoo/odoo#117874
2023-04-13 00:06:00 +02:00
Xavier Morel cedc968f22 [FIX] base: better filter drop table warnings
Along with improving the table_kind API, #117439 added a warning when
dropping non-tables.

This warning turns out to trigger on many models, in two major cases:

- the hook is called on abstract models, which don't have a table in
  the first place, it probably should not be called for those but can
  easily be skipped
- the hook is also called on `_auto = False` which don't have a table
  anymore, this is because we use `DROP TABLE $table CASCADE`, which
  implicitly drops any view (or table) depending on the table, it
  might be possible to avoid this by ensuring we drop models in
  reverse topological order *and* drop all of a module's views then
  tables at once (by passing multiple names to `DROP`, but for now
  just ignore the case where we're trying to drop an object which
  can't be found

closes odoo/odoo#118194

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2023-04-11 15:17:32 +02:00
Xavier Morel 8932d447aa [FIX] core: table_kind semantics (incorrect classification of toast as temp)
17c4f47b0a updated table_kind to return
`pg_class.relkind`, however the semantics are *not* the same, and that
was ignored: `relkind = t` is for *toast* tables, not *temporary*
tables. In `pg_class` the temporary-ness is instead signaled by
`relpersistence` (which applies to both tables and sequences), temp
(and unlogged) tables have `relkind = r`. `existing_tables` does that
correctly, possibly unwittingly.

While at it, upgrade `table_kind` to return an `enum` (whose value is
the old discriminant).

closes odoo/odoo#117444

Related: odoo/enterprise#39185
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2023-04-07 11:37:25 +02:00
Xavier Morel b799ef34ae [FIX] web: disable scripting & autoprint in PDF viewer
Support is limited and more of a hindrance than a help, as some
clients' suppliers create PDFs with broken scripting which trigger the
autoprinting any time they're loaded and can have other odd
misbehaviors, which is a hassle.

OPW-3208409
OPW-3222228

closes odoo/odoo#115659

X-original-commit: a7331d9709c8e097356f89bf144986f441c8f2cc
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2023-03-17 20:21:09 +01:00
Xavier Morel e37109c8c3 [REM] core: support for werkzeug interactive debugger
With the special support for postmortem debugging removed, the
likelihood of needing / wanting the werkzeug remote debugger seems
even more remote (as it works in strictly less situations, only for
frontend non-json requests).

So remove that as well.

closes odoo/odoo#115176

X-original-commit: a2022783b652299155c460294c00dbced9b619ac
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2023-03-14 13:30:19 +01:00
Xavier Morel 09023b6f87 [REM] core: remnants of debugger support
It's done nothing since #78857 and it doesn't seem like anyone has
cared (found no issues or tickets).

Rather than restore the feature, just remove the leftover bits.

X-original-commit: 4a7cfc8844eb9b754f16f9d013452d5bde8770b5
Part-of: odoo/odoo#115176
2023-03-14 13:30:19 +01:00
Xavier Morel 18ebbce51b [FIX] core: ability to run tours in Chrome 111
Chrome 111 enabled checking of websocket origin: if the WS connection
sends an Origin head which is not whitelisted with the new
`--remote-allow-origins` switch it is rejected.

Turns out websocket-client (amongst others) *does* send an `Origin`,
which trips the check, and means tours immediately break when trying
to run them as Odoo's test harness is unable to connect to (and
control) the devtools.

Suppress sending `Origin` to fix the issue.

To make the watch mode work, set `--remote-allow-origins`: since we
specifically only bind the devtools to the loopback
address (127.0.0.1) whatever issues this plugs are unlikely to affect
us. We might eventually want to change the behaviour of the watch
feature for UX reasons and remove this in the future though, either by
working through the non-ws remote inspection (`chrome://inspect`) or
by having the `watch` mode run in a normal browser directly instead of
having a browser connect to a headless browser.

Chrome 111 changeset: https://chromiumdash.appspot.com/commit/0154caeefc74530d5cb57ce71608beb1b77bca39

Chrome tracker issue: https://crbug.com/1422444

closes odoo/odoo#115067

X-original-commit: 47a02b3924c3e4d1690e336fdd764383393ee378
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2023-03-14 11:08:07 +01:00
Xavier Morel eb5515bee9 [ADD] core: support for binding IPv6 in worker mode
Because Werkzeug supports ipv6 natively (and has since ~2010
pallets/werkzeug@13a76262a4), running
Odoo in threaded mode allows binding to an ipv6 address.

However the prefork server is part of Odoo, and only creates
AF_INET (ipv4) sockets. Thus switching from threaded to worker mode
breaks the bind.

Add a family switch on the `http-interface`, so binding to ipv6
addresses also works in ipv6. Gevent already does that switching
internally, so the evented worker works out of the box, it was only
the prefork / workers which did not.

Looking at both the Werkzeug and Gevent implementations:

- https://github.com/pallets/werkzeug/blob/f9906fa6d83dd668f9214acef458419756bbc062/src/werkzeug/serving.py#L607-L614
- https://github.com/gevent/gevent/blob/1e412d35526183b26c1abf2eb658cbef661f5f70/src/gevent/baseserver.py#L415-L433

Both primarily check whether the host contains `:`. Werkzeug also
checks if `socket.AF_INET6` exists, however gevent doesn't bother with
that. Looking at the
source (https://github.com/python/cpython/blob/7d801f245e2021d19daff105ce722f22aa844391/Modules/socketmodule.c#L7419-L7421),
it is indeed possible for `AF_INET6` to be missing, however that
requires specifically compiling Python in an environment which doesn't
support IPv6.

Meanwhile it's also possible to disable ipv6 at runtime, in which case
I'd assume the `socket.AF_INET6` constant is present, and creating the
socket fails, which nobody guards against. Therefore just ignore the
entire thing, it doesn't seem worth the hassle (or the questioning) to
check whether the constant is present, especially since this is only a
concern when the user specifically requires an IPv6 address.

Fixes #35782

closes odoo/odoo#114666

Signed-off-by: Julien Castiaux (juc) <juc@odoo.com>
2023-03-08 13:49:05 +01:00
Xavier Morel 0d5b9d2030 [IMP] core: increase FileStorage buffer size
Closes odoo/odoo#83176

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2023-01-23 09:32:06 +01:00
Xavier Morel d1a0ac989f [FW][FIX] core: misleading handle_error docstring
`handle_error`'s docstring states that it returns a `Response`, but in most case `HttpDispatcher.handle_error` returns an `HTTPException`.

After discussion, the implementation is correct, `handle_error` should be documented to return a WSGI Application (a callable taking an `environ` and a `start_response` callable) instead.

closes odoo/odoo#112889

Forward-port-of: odoo/odoo#112690
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2023-02-16 16:58:49 +01:00
Xavier Morel 298567f64c [FIX] core: disable werkzeug log color when logging to file
Werkzeug 1.0 colorised some outputs on POSIX IFF `click` was
installed.

Since 2.0 (pallets/werkzeug#2012) werkzeug unconditionally colorises
the log on POSIX. This is annoying when using output redirection (let
alone logging to a non-stream), as werkzeug will dump ANSI color codes
to the non-term stdout and thus the logfile.

Werkzeug provides no official knob to control this behaviour, but it
does have a secret flag which is normally used to check if colorama is
available on windows (so the ANSI codes are not output if colorama
won't be interpreting and stripping them on the way out). Since
`werkzeug.serving` is available in pretty much all versions, we can
just (un)set this flag if not logging to a tty, and versions 2+ should
pick it up and disable colorisation.

closes odoo/odoo#112829

X-original-commit: 7c9f883dc508a7a8a45bf7bf7e900da0be9b34be
Signed-off-by: Christophe Monniez (moc) <moc@odoo.com>
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2023-02-16 09:01:10 +01:00
Xavier Morel a6d601dc4e [FIX] test_lint: deprecation warnings in pylint 3
Runbot currently doesn't use Pylint 3 in order to still have "style"
lints (since removed), however compatibility with pylint 3 is useful
to run tests / lints locally (and possibly eventually in future python
versions for which 2 might not be compatible).

Fix a few deprecation warnings:

- the `__implements__` magic thing has been deprecated
- `check_messages` has been renamed to
  `only_required_for_messages` (better explains the purpose)

Also remove second parameter of `is_message_enabled` call, if
specified it's supposed to be a `Confidence` value, not a
number. Recent pylints changed the way it's checked, so it now errors
even if not using the confidence system (or something like that).

closes odoo/odoo#107960

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2023-02-03 05:09:22 +01:00
Xavier Morel 6e700157d0 [REM] core: odoo.modules.module.loaded flag
Seems unnecessary, most of the information already lives in
`sys.modules`. We can just check that.

There are a few changes in behaviour, but they seem minor:

- if post_load fails, subsequent attempts to load the module will
  "succeed"
- since we didn't remove/reload the module, a failure because of an
  incorrect post_load wasn't fixable, however it was possible to
  update the manifest

Still seems like a wonky state to be in, and one we should ignore.

Also remove the logging of the error: since we're re-raising as-is,
the parent logs it with a traceback, so this is unnecessary and
redundant.

closes odoo/odoo#103933

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2023-02-03 05:08:40 +01:00
Xavier Morel 98dd7aba2f [FIX] *: used-before-assignment pylint warnings
Warnings show up when using a recent pylint. It's only a fraction of
what e.g. pycharm flags as "local variable might be referenced before
assignment" but seems a good idea to fix anyway in prevision of
possibly eventually updating the reference pylint.

closes odoo/odoo#107968

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2023-01-31 12:55:49 +01:00
Xavier Morel b951cb4422 [IMP] core: mark all responses as nosniff
Doesn't seem like it could hurt, and should only make CORB more
reliable by avoiding sniffing. Worst case scenario requires fixing a
few mimetypes, but aside from CORB it looks like modern (non-IE)
browsers only try to guess document mimetypes in very limited
contexts.

closes odoo/odoo#107957

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2023-01-31 12:55:46 +01:00
Xavier Morel d4f8f7ece6 [IMP] core: handling of the form tour checker
`DOM.querySelector` will generally return a `nodeId` of 0 when no node
is found, however there is a small window during which the document
can apparently get collected (?), which leads to an error

    Could not find node with given id

which can break otherwise successful builds (cf 20832402 / staging
60731).

Handle errors from the pipeline as if the node had not been found,
though the matter was not fully investigated so it's possible this
explanation is incomplete or incorrect.

The CDTP documentation does not document the failure modes for either
`DOM.getDocument` or `DOM.querySelector`.

closes odoo/odoo#105734

X-original-commit: 5ef975f75cf8044e7dcd67f403ca11058630c85a
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-11-15 11:38:43 +01:00
Xavier Morel 5d47883262 [REM] core: dead code for JSONRPC HTTP status
When `make_json_response` was added in
034d01b2f3 and `_response` was updated
to use it, the `http_status` extracted from the error object was
removed.

But it's still set by `handle_error` and a local is defined for
it. Drop that.

closes odoo/odoo#104507

X-original-commit: b0ea1cd6a2628a6acd1e2d79cc862976c63b1565
Signed-off-by: Julien Castiaux <juc@odoo.com>
2022-10-28 17:18:10 +02:00
xmo-odoo c9356b3582 [REM] core: SQL compiler helpers deprecated since 14.0
closes odoo/odoo#98138

Related: odoo/enterprise#33244
Related: odoo/documentation#2844
Signed-off-by: Raphael Collet <rco@odoo.com>
2022-10-26 19:03:48 +02:00
xmo-odoo 6a343a32ef [REM] core: deprecated TestCase classes
Part-of: odoo/odoo#98138
2022-10-26 19:03:47 +02:00
xmo-odoo 84e6be4150 [REM] core: deprecated osv-memory-age-limit option
Part-of: odoo/odoo#98138
2022-10-26 19:03:47 +02:00
xmo-odoo 110770b7c1 [REM] core: openerp.addons alias and legacy ad_path
Part-of: odoo/odoo#98138
2022-10-26 19:03:47 +02:00
xmo-odoo e98b44998f [REM] base: legacy autovacuum API (power_on method)
Part-of: odoo/odoo#98138
2022-10-26 19:03:47 +02:00
xmo-odoo d200dcfb2c [REM] core: exceptions bits deprecated since 14.0
And formally deprecate the contents of `odoo.osv.osv` so we can
eventually finally remove it.

Part-of: odoo/odoo#98138
2022-10-26 19:03:46 +02:00
xmo-odoo e806427d23 [REM] web: deprecated dataset methods
Part-of: odoo/odoo#98138
2022-10-26 19:03:46 +02:00
Xavier Morel 18446f23f1 [REM] core: support for the deprecated <report> and <act_window> tags
Part-of: odoo/odoo#98138
2022-10-26 19:03:46 +02:00
Xavier Morel 6c6ca16626 [REM] core: deprecated Environment methods
Part-of: odoo/odoo#98138
2022-10-26 19:03:46 +02:00
xmo-odoo 6dbe95c4ce [REM] base_setup: last reference to gengo
All other references were removed in 481d1393e7
but this was left over "to be removed in master" (the commit landed in 14.1).

The actual module was removed in 14.0 (b38b72e456a) so this is quite overdue.

closes odoo/odoo#100008

Related: odoo/upgrade#3884
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-10-26 14:05:26 +02:00
Xavier Morel 59442f0988 [IMP] web: open external links of PDFs in new tab
Reimplementation of 74fa91e0b3 on top of
new version of pdfjs. See previous commit for explanation.

Ideally we would set that behaviour from the outside using
e.g. `PDFViewerApplicationOptions.set` but there are multiple
locations from which we embed the viewer, which makes that a difficult
proposition. There should probably be a clean component which handles
loading the library, configuring it to our specifications (possibly on
a per-embed basis), and exposing both manipulations methods and events
which pdfjs triggers on its eventBus.

Part-of: odoo/odoo#100067
2022-10-26 09:07:34 +02:00
Xavier Morel 542cb1dc21 [FIX] website_slides: outdated pdfjs API use
Apparently a PDF Document used to *be* a promise (a "thenable") but
that's not the case anymore. The loading promise has to be deref'd
explicitely. This is also the case for `page.render`, which is not a
thenable anymore.

Furthermore, the API seems to have changed to favor parameter
objects (getViewport) and setting callbacks (onPassword) rather than
having lots of positional parameters.

Finally, remove apparently long dead `disableWorker` feature in
`PDFSlidesViewer`, although really the entire thing should be
rewritten in modern javascript.

Part-of: odoo/odoo#100067
2022-10-26 09:07:34 +02:00
Xavier Morel 55d9f318fb [IMP] web: update pdfjs to 2.16.105
Our current version is getting rather outdated. Replace by
the *legacy* bundle: pdfjs now provides a non-polyfilled version of
the library, which is probably faster though it doesn't save overly
much (for the entire bundle anyway). Use polyfilled version for
safety, though it's unclear whether non-chromium Edge is still
supported by Odoo. If not, we could just use the non-polyfilled
version.

The difference is quite large for pdf.js (+32.5%), however it is much
less consequential for the sandbox (+1%) or for the much larger
worker (+5.6%). The biggest difference is likely performances
but... who knows?

Notes:

- The main reason for this change is that automated vulnerability
  scanner have apparently started scanning for `postMessage(..., '*')`
  and the previous bundles includes a version of corejs polyfills
  without zloirock/core-js#542), therefore triggering those scans. As
  the PR notes this is almost certainly not a concern because of the
  innocuous payload, but there is no reason to waste time on those
  reports if we don't *have* to.
- The bundle now includes "standard fonts", those were removed as
  they're heavy and may not be necessary for our usage (?).
- All the bitmap images were dropped and replaced by svgs, which is
  nice.
- The local changes since the previous update were *not* impacted in
  this, the entire thing was just reset to upstream. This means
  changes which were backported (922c7c72, 6943714f) are superseded
  but more odoo-specific changes will have to be reapplied in further
  commits.

Part-of: odoo/odoo#100067
2022-10-26 09:07:34 +02:00
Xavier Morel e2b3463b5a [IMP] core: formally deprecate __openerp__.py manifests.
`__manifest__.py` was introduced in Odoo 10 and quickly migrated
to (c758e9043a fixed the last holdouts).

Deprecate old manifests. People who need the compatibility can just
add a symlink (or duplicate the file if they're working on FAT or an
old os where core.symlinks can't be set to `true`).

closes odoo/odoo#103952

Signed-off-by: Raphael Collet <rco@odoo.com>
2022-10-25 17:16:09 +02:00
Xavier Morel 75adabf11f [ADD] *: examples of Model.grouped
closes odoo/odoo#101522

Related: odoo/documentation#2783
Signed-off-by: Rémy Voet <ryv@odoo.com>
2022-10-21 13:06:09 +02:00
Xavier Morel d50db0587b [ADD] core: ORM-level internal grouping utility
When looking to fetch grouped data from the database, `read_group`
should work(-ish), especially with support for `array_agg`. This also
means this need should be more or less solved around RPC: client can
either `read_group` or group on the client side.

This leaves a glaring hole in the fabric: there's no convenient tools
to apply grouping to recordsets. `itertools.groupby` exists, but it
requires that the input be grouped by the key function, and it yields
an iterable of items which is not the most convenient for recordsets.

This here utility:

- is exclusive to recordsets
- returns a mapping of grouping keys to subsets of the input recordset
- keeps the prefetching of the source recordset
- allows grouping on a field, or an arbitrary (callable) key
- should work even on "new records" (aka should be suitable for
  onchanges / arbitrary compute functions)

While the method is RPC-compatible, it's not especially designed for
that, it is likely a much better idea for the client to `read` the
data they need then group that client side on whatever criteria they
are interested in, or `read_group` the aggregated information they
need directly if that's an option.

Part-of: odoo/odoo#101522
2022-10-21 13:06:09 +02:00
Xavier Morel 6d3c78fe30 [FIX] test_sale_product_configurators: re-enable test_01
closes odoo/odoo#103117

X-original-commit: c09b3c94ca6926669faf5df738a271e0e9789ce8
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-10-12 10:34:45 +02:00
202c377975 [FIX] web_tour: discard form helper
The helper's final trigger was hooked not on the list *view* but on
the list *widget/component*.

As a result, on a form containing an x2many field the trigger would
fire immediately, before the form view was actually discarded, leading
to a race condition in the Python-side check for unsaved forms, and
thus non-deterministic tour failures.

Update the check to look for the view specifically, this should be
exclusive with the form view.

X-original-commit: 28c569d7cb0ffeda4cd9abcb8332e96c551cf03a
Part-of: odoo/odoo#103117
Co-authored-by: Michaël Mattiello <mcm@odoo.com>
Co-authored-by: Aaron Bohy <aab@odoo.com>
2022-10-12 10:34:45 +02:00
Xavier Morel 9b891b6bb2 [IMP] core: error reporting on tour timeouts
When 2e8647bf16 converted the browser
runner to a more reactive / evented system, one bit was missed in
"wait_code_ok": concurrent.futures.Future raises exceptions on various
events, such as tour timeouts. Because those exceptions were not
caught (or just ignored) the code which takes screenshots was
bypassed, leading to a lack of screenshots on tour timeouts (and a few
other rarer errors), making debugging more complicated.

The error reporting was also not ideal as `wait_code_ok` would raise
an unexpected (by its caller) `TimeoutError` rather than
`ChromeBrowserException`.

Fix those two issues, should hopefully makes these occurrences clearer
and easier to diagnose.

closes odoo/odoo#102403

X-original-commit: 974217968ea970330946c5184bd3b3550ec3cde3
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-10-06 18:01:27 +02:00
Xavier Morel 482de91bfd [FIX] core: use proper break (hr) in PR template footer
A "thematic break"[1] is composed of 3 or more characters (-, _,
or *). The current separator using only 2 characters between the main
body of the PR and the footer / addendum makes it more difficult to
interpret the message.

Update to 3 so e.g. the mergebot can strip the footer.

[1]: https://spec.commonmark.org/0.30/#thematic-breaks

closes odoo/odoo#101148

X-original-commit: c7bf932c9eb2fc9bc34c653c51bce1552d6afb54
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-09-26 16:55:17 +02:00
Xavier Morel 9bcc30be8d [FIX] auth_password_policy: remove validation in meter
Not sure what I was thinking (there was no chance the validation would
be structural, probably didn't think about the validation itself).

Possibly thought of creating a proper `Recommendation` type then ended
up not doing it, but left the props types in.

closes odoo/odoo#100206

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-09-15 13:38:49 +02:00
Xavier Morel 598492ef4d [FIX] auth_password_policy_signup: port to modern js and fix
b3b85cae9b unwittingly broke
auth_password_policy_signup when it ported everything to owl.

- move the CSS file back to assets_common
- reintroduce the old password gauge, moved over to signup (as it's
  not used anymore by auth_password_policy), and converted to modern
  JS style
- convert signup_policy to more modern JS style (for consistency)

Manifest file doesn't need to be updated because it globs.

closes odoo/odoo#100169

Signed-off-by: Adrien Dieudonné (adr) <adr@odoo.com>
2022-09-15 13:38:46 +02:00
Xavier Morel b3b85cae9b [IMP] *: owlify password meter and convert change password to real wizard
The changes in `auth_password_policy` are largely the owlification of
the password meter widget:

- modernize the password policy module and convert it to an
  odoo-module (note: now exports a pseudo-abstract class which is
  really a policy, for the sake of somewhat sensibly typing
  `recommendations`)
- replace the implementation of the Meter and PasswordField widgets by
  owl versions

The changes to web and base stem from taking a look at converting the
ChangePassword wizard, and finding that it would be a pain in the ass
but also... unnecessary? It seems to have been done as a wizard
completely in javascript despite being backend-only for legacy
reasons: apparently one of the very old web clients (v5 or v6
probably) implemented it as a "native action" which was directly part
of the client's UI, and so it had to be implemented entirely in the
client.

Over time it was moved back into the regular UI (and moved around
quite a bit), hooked as a client action to maintain access to the
existing UI / dialog.

But since it's been an action opened via a button for years it can
just... be a normal wizard, with password fields, which
auth_password_policy can then set the widget of.

So did that:

- removed the old unnecessary JS, and its dedicated endpoint (which is
  *not* used by portal, portal has its own endpoint)
- used check_identity for the "old password check"
- split out `change_password` with an internal bit so we can have a
  safer (and logged) "set user password" without needing to provide
  the old password, which is now used for the bulk password change
  wizard as well
- added a small wizard which just takes a new password (and
  confirmation), for safety a given change password wizard is only
  accessible to their creator (also the wizard is restricted to
  employees though technically it would probably be fine for portal
  users as well)

Rather than extensive messy rewrite / monkeypatching (the original
wizard was 57 LOC, though also 22 LOC of template, the auth_policy
hooking / patching was 33, plus 8 lines of CSS),
`auth_password_policy` just sets the widget of the `new_password`
field in the new wizard, much as it did the bulk wizard.

Also improve the "hide meter if field is empty" feature by leveraging
`:placeholder-shown`. This requires setting a placeholder, and while
empty works fine in firefox, it doesn't work in chrome. So the
placeholder needs to be a single space. Still, seems better than
updating a fake attribute or manipulating a class for the sake of
trivial styling.

Notes on unlink + transient vacuum

Although the wizard object is only created when actually calling
`change_password`, and is deleted on success, it is possible for the
user to get an error and fail to continue (it should be unlikely
without overrides since the passwords are checked while creating /
saving but...).

While in that case the `new_password` in the database is not the
user's own, it could be their *future* password, or give evidence as
to their password-creation scheme, or some other signal useful to
attack that front of the user's life and behavior. As such, quickly
removing leftovers from the database (by setting a very low transient
lifetime) seems like a good idea.

This is compounded by the `check_identity` having a grace period of 10
minutes. 0.1 is 6 minutes, but because the cron runs every 10 the user
effectively has 6~10 minutes between the moment they create an
incorrect / incomplete version of the wizard and the moment where it
is destroyed if they just leave it.

closes odoo/odoo#99458

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-09-08 18:31:18 +02:00
Xavier Morel 5afcd06168 [REM] *: incorrect taggings which break tests when applied
Not entirely sure about TestAllocationRights. For TestEsEdiCommon
issue is quite obviously that it's inherited by tests which are
external, so when the `post_install_l10n` tag gets applied those tests
get run during "normal" l10n and they break.

closes odoo/odoo#98814

Related: odoo/enterprise#30825
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-09-05 08:33:13 +02:00
Xavier Morel d256bbac3e [FIX] test_lint: l10n linter
The linter would require flagging "Common" classes with
`post_install_l10n`, which is incorrect but innocuous before tag
inheritance, however it's incorrect and broken with tag inheritance.

Fix to only apply the lint to actual test containers.

Although eventually the analysis should probably run on the actual
classes, so that the "common" classes can be tagged and the children
don't need to be (since they inherit tagging from their parents).

Part-of: odoo/odoo#98814
2022-09-05 08:33:13 +02:00
Xavier Morel 8e469436da [IMP] core: allow inheriting test tags
The unconditional setting made a lot of sense before the new test
tags (95b4f2ab4b) when the test module
was a test tag: filtering the module out of the existing tags would be
difficult.

However since then the tags should only contain "actual" tags,
therefore inheriting tags (and tagging mixins or Common cases) should
not be an issue anymore.

Part-of: odoo/odoo#98814
2022-09-05 08:33:12 +02:00
Xavier Morel cf221d4ba7 [ADD] cli: db manager
Currently dbs can only be managed via the UI in order to take
filestores in account: while it's possible to load/copy/rename/drop
databases via `psql`, that will not manage the related filestores so
the result of the operation is incomplete DBs and leftover filestores
littering the disk.

Seems like a good idea to add a CLI to perform the same
tasks. Currently the CLI calls into the corresponding service, rather
than both calling into (possibly better designed) unified APIs, but
that seems fine for an initial version.

The top-level `db` command acts as a db manager, with git-style
sub-sub-commands for the various operations:

- `load` to load a dump file into a database (with a specified name or
  not)
- `dump` to dump a local db to a zip dump (pg_dump can be created via
  the corresponding command so not a concern)
- `duplicate` and `rename`
- `drop` in order to drop both the database itself and the
  corresponding filestore

Notably, `create` is currently left out because a database can
trivially be created by invoking odoo using a dbname which doesn't
exist, so doesn't seem useful.

`list` is also left out, because `psql -l` generally does the job.

closes odoo/odoo#97365

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-08-26 18:41:26 +02:00
Xavier Morel 9c0fa1efe3 [CHG] core: deprecate get_module_filetree
It's pretty much unused and fairly complicated.

Also deprecate `listdir` entirely since `get_module_filetree` is the
only extant user of the recursive listdir.

closes odoo/odoo#98034

Related: odoo/enterprise#30403
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-08-23 07:36:24 +02:00
Xavier Morel 4cd0119eff [CHG] core: move traverse_container out of utils
It's really not a general purpose utility, it's just a way of forcing
a lazy collection's evaluation.

Alternatively, add a helper for this to / alongside `lazy`? Note that
the lazy object(s) may not be the top-level.

closes odoo/odoo#98023

Related: odoo/upgrade#3776
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-08-22 16:48:28 +02:00
Xavier Morel 7f14631fe8 [CHG] core: deprecate all exec_pg_* functions
They're not used much and they don't seem much of an advantage
compared to just calling `subprocess` with the discovery utility
functions.

While at it, fix `dump_db` to not unnecessarily have an open stdin to
`pg_dump`.

Part-of: odoo/odoo#98023
2022-08-22 16:48:28 +02:00
Xavier Morel 719e7d46e4 [CHG] core: mark a bunch of utilities as deprecated
Remove UnquoteEvalContext directly because it's unused and super specialised.

Part-of: odoo/odoo#98023
2022-08-22 16:48:27 +02:00
Xavier Morel 48653bb11b [FIX] core: special casing of sequence in read_group
The sequence field is special-cased early on in read_group (_raw): if
the caller requests the aggregation of ``sequence`` that request is
ignored:

    if fspec == 'sequence':
        continue

This was added a long time ago, probably due to the special-ish status
of `sequence` (summing sequence number doesn't really make much
sense).

The issue is that it's also possible to request ordering by
`sequence`, which requires `sequence` to be one of the aggregated
fields. This is checked in `_read_group_prepare` and triggers a
warning.

This leads to an inconsistent behavior, where the user requests
aggregating & ordering by `sequence`, we remove it from the aggregated
fields, then warn that they didn't aggregate on the field.

Make the behavior consistent by also ignoring requests to order by
`sequence`.

closes odoo/odoo#97409

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-08-22 16:48:19 +02:00
Xavier Morel 97c0c42bff [FIX] base: remove ResLang.action_archive override
Override doesn't work with multiple records so breaks the built-in
bulk archive/unarchive action of the list view, and it's completely
unnecessary since `BaseModel` has a builtin `action_archive` which
works out of the box if the model has an `active` field (or
`x_active`, or a boolean field explicitely set as `_active_name`).

closes odoo/odoo#98515

X-original-commit: ad38943fb4e963d587ba9f292b7e277182f17a06
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-08-22 08:57:53 +02:00
Xavier Morel c6a4332cf2 [IMP] core: update tests loader to correctly report syntax errors
Currently e.g. syntax errors during the import are logged as
exceptions but they don't fail the loading / testing.

Update the loading using more modern loading APIs, in order to not
catch them at all (let them bubble up normally), and instead just
find *IF* a module has a tests submodule before trying to load
in (LBYL).

Fixes #80198

closes odoo/odoo#97957

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-08-22 08:57:44 +02:00
Xavier Morel 5c5876d74f [REM] osutil: deprecated code
We deprecated all those in 14.0, so 16.0 seems like a good time to
remove them.

`getppid` was not deprecated but it doesn't seem useful to keep

closes odoo/odoo#97987

Around: windows support was added to getppid in Python 3.2.
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-08-16 09:19:14 +02:00
Xavier Morel 5c02342704 [FIX] auth_totp: fix the incomplete fix
The previous pass in #97567 missed a small window of race condition
in *closing the fecking dialog*. Apparently that's still not
instantaneous enough and it's possible to have the check trigger in
the interval between clicking the button and the dialog being
completely torn down.

Add an explicit test for this to the existing `closeProfileDialog`
utility function.

closes odoo/odoo#97969

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-08-11 17:57:23 +02:00
Xavier Morel 4febee1998 [FIX] auto_totp: totp tours when hr is not installed
When #96517 was merged, it was missed that if hr is *not* installed,
then the user profile opens in a dialog in edition mode (always, can't
be readonly).

Since half the tours of `auth_totp` end in the profile screen (to
check that the totp state is what we expect) this means they work fine
in most test contexts where `hr` is installed, but they fail as soon
as `hr` is *not* installed.

Fix this by adding a helper function which checks whether the profile
screen uses a dialog or not, and closes the dialog if so (otherwise it
does nothing as the "form" profile screen is not in edition mode).

While at it, improve a bunch of steps:

- fold check steps which were really `extra_triggers` (something we
  wanted to check but not manipulate, in the same screen as something
  we do want to manipulate)
- convert a few promise-based functions to `async` (tours don't
  support promises but async functions work either way and lead to
  simpler code here)
- make better use of the tour action helpers (no need for explicit
  `_get_action_values` calls for the most part, and no need to
  call the internal versions either)
- clarify a pair of fixmes as I'd completely forgotten what they meant

closes odoo/odoo#97567

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-08-08 21:03:13 +02:00
Xavier Morel bb543d75a9 [FIX] web_editor: breaking _onBeforeUnload when canceling edition
After updating mass_mailing_snippets_menu_tabs to cancel the
template's edition at the end of the tour, the editor starts blowing
up during cleanup with:

```
Trying to set result to failed (UncaughtTypeError: Cannot read properties of null (reading 'anchorNode')
    at Sanitize._parse (/web/assets/363-d1667a2/web_editor.assets_wysiwyg.min.js:1453:105)
    at Sanitize.parse (/web/assets/363-d1667a2/web_editor.assets_wysiwyg.min.js:1450:6)
    at new Sanitize (/web/assets/363-d1667a2/web_editor.assets_wysiwyg.min.js:1448:6)
    at sanitize (/web/assets/363-d1667a2/web_editor.assets_wysiwyg.min.js:1460:53)
    at OdooEditor.cleanForSave (/web/assets/363-d1667a2/web_editor.assets_wysiwyg.min.js:1372:37)
    at Class.getValue (/web/assets/363-d1667a2/web_editor.assets_wysiwyg.min.js:2547:1121)
    at Class.isDirty (/web/assets/363-d1667a2/web_editor.assets_wysiwyg.min.js:2547:407)
    at
    _onBeforeUnload (/web/assets/363-d1667a2/web_editor.assets_wysiwyg.min.js:2509:560)
```

After consultation with the relevant team, there are edition contexts
where it's perfectly valid to have no "live" selection for one reason
or an other, so this should be fixed.

Ideally the field should also properly be discarded such that the
event listener is removed and the callback is never called at all,
however the legacy client has no such hook at the field level (the
controller seems to be the lowest).

closes odoo/odoo#96517

Related: odoo/documentation#2550
Related: odoo/enterprise#29824
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-08-04 09:14:11 +02:00
Xavier Morel bcb3e35754 [FIX] test_main_flows: properly terminate tours
- the community version would finish with a wizard opened in edition
  mode, add a "real" final step of waiting for the wizard to finish
  processing (the invoice to be marked as paid)
- the enterprise version would finish on the reconciliation widget,
  which is always an edition-mode form, check that the reconciliation
  succeeded and (as in the accounting tour) return to the accounting
  dashboard afterwards

Part-of: odoo/odoo#96517
2022-08-04 09:14:11 +02:00
Xavier Morel 67f36e8b2f [FIX] *: properly finish a bunch of form editions
Cancel or properly wait for save to finish, depending on tour.

Part-of: odoo/odoo#96517
2022-08-04 09:14:10 +02:00
Xavier Morel f552711074 [FIX] test_sale_product_configurators: correctly end a bunch of tours
Part-of: odoo/odoo#96517
2022-08-04 09:14:10 +02:00
Xavier Morel 992fb00b64 [FIX] test_new_api: properly conclude tours
- the x2many tour would finish on a click canceling the creation but
  not wait for that to resolve, leading to the driver catching it in
  the act (checking before the client had had the time to switch),
  just need to wait for the list view to be displayed
- the constraints tour would just drop in the middle of a creation
  with an error dialog open, so need to finish the entire thing and go
  back to the list view

Part-of: odoo/odoo#96517
2022-08-04 09:14:10 +02:00
Xavier Morel 9915953342 [FIX] account_tour: ensure the form is saved by the end of the tour
Since 54ea956490 the form view has an
"urgent save" fallback mechanism. Even if nothing has changed since
the last (?), it will save during unload, which leads to extra
requests during the browser teardown (deletion of cookies and storage,
navigation to about:blank, ...), which can lead to inconsistent
behaviors and non-deterministic errors.

- add check steps at the end of the tour to wait for relevant terminal
  states
- perform an explicit save during the tour (before confirmation)

Ideally we'd really only block on *dirty* forms, because logically the
urgent auto save thing should not trigger if the form is not
dirty. However I'm not sure there's any way to check for that
externally, so saved it is...

Part-of: odoo/odoo#96517
2022-08-04 09:14:10 +02:00
Xavier Morel a52789a8b5 [ADD] web_tour: utility steps to finish form edition
A tour finishing while a form is in edition mode is an issue, as it
then triggers an `urgentSave` which generates network traffic (and
promise handlers) during browser cleanup, at a time when the state of
the browser may not be entirely coherent.

Two methods seem to be the most common here:

- drop form during creation, aka the tour mostly wants to mess around
  with onchange & ui & error reporting, in those cases the tour just
  stops using the form, the "proper" way to handle this is to cancel
  the creation and wait until back to the list view (note: the utility
  step does not currently handle situation where the creation was
  triggered from an other form view, or canceling an edition)
- save form during creation or edition, aka the tour wanted to create
  an object, did trigger a save, but didn't wait for the save to
  complete, leading to the tour finishing mid-save (which in theory
  should allow the save to complete but may still trigger odd effects)

Part-of: odoo/odoo#96517
2022-08-04 09:14:09 +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
Xavier Morel b31bb2cf98 [FIX] core: add missing timeouts on end-of-tour waits
Not entirely sure why they come into play, but apparently they
sometimes do.

Part-of: odoo/odoo#96517
2022-08-04 09:14:09 +02:00
Xavier Morel 07ecd396b0 [ADD] core: error if a test finishes with a form being edited
Since 54ea956490 the form view has an
"urgentSave" fallback when the page is unloaded (tab closed, page
navigated away from, ...).

In tours, this translates to new network requests being performed
during the browser cleanup, possibly chaining further into more
network events.

Flag these tours as incorrect (by making them fail if we find a form
in edition mode after receiving `"test successful"`).

Adjust testing of http cases because I've added an empty line between
the signal and the actual message for better readability on complex
error messages.

Also provide opt-out, as for some tours it's difficult to impossible to
truly fix them: the `allow_end_on_form` class attribute can be set to
`True` in order to disable the new behaviour.

To implement this, update the browser runner receive the test class
directly (rather than just the test class' name) for more
introspection flexibility.

Part-of: odoo/odoo#96517
2022-08-04 09:14:09 +02:00
Xavier Morel 1a65d18ef7 [IMP] core: increase timeout in watch mode & tell client
Currently, when enabling watch mode on a tour the tour's timeout does
not change. This is usually an issue because:

- watch mode makes tours a bit slower, so they can timeout even
  without doing anything
- trying to diagnose what's wrong, it's common to add check steps with
  a long timeout or even a `debugger` statement, which trips the
  python-side timeout and kills the tour

To avoid needing to remember to update the timeouts (then revert them
afterwards), just bump the timeout to 1h by default, or 10x the
original time for very long tours (e.g. qweb test suite, which
currently has a 30mn timeout).

While at it, forward the watch mode status to the client via the QS,
so we can eventually make use of it for one reason or an other.

closes odoo/odoo#96994

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-08-01 07:32:39 +02:00
Xavier Morel e75f2989b4 [FIX] core, web: Pillow 9.1 deprecations
Pillow 9.1 deprecates most if not all toplevel Image constants:
https://pillow.readthedocs.io/en/stable/releasenotes/9.1.0.html#constants

These constants have been moved to thematic enum classes (e.g. all the
resampling constants in `PIL.Image.Resampling`).

This triggers warnings in Odoo, and the removal delay is quite short
(slated for Pillow 10, release planned mid 2023). Pillow 9.1 is also
already in Debian Bookworm (current testing).

Fix by shimming at the import level: if the enums are available import
them into the local namespace, otherwise alias `PIL.Image` itself as
to the enum.

closes odoo/odoo#96799

X-original-commit: 7be04d31bad078681ef0a2919234c11840a2e8e2
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-07-28 02:40:23 +02:00
Xavier Morel 8530d1233b [FIX] website_sale, website_sale_wishlist: fix and unify warnings box
The two modules both implemented the cart update warnings box
incorrectly, and differently (though in part because of later
changes):

- `aria-hidden` has meant `display: none` for a while, so the dismiss
  button would never show up
- the class is alert-dismiss*i*ble, not alert-dismiss*a*ble
- unnecessarily complicated dom manipulation on updating the warning
- wishlist would go and update the cart badge by hand, unnecessarily

Extracted the warnings stuff to its own helper, with a fixed DOM, and
a slightly modified structure so it's possible to update the message
without having to rewrite the entire box content.

Also modified wishlist to update the cart badge via the existing
helper, this way both modules just call

    updateCartNavBar(data);
    showWarning(data.warning);

the same way in the same order, and everything is clear.

Also updated `updateCartNavBar`:

- removed the iteration as jQuery should be able to work on the set
- added the warning message and an icon if the quantity is 0 (could
  not add to cart) as the separate warning may not be available on all
  pages e.g. "recently viewed" product widget can appear anywhere,
  previously was only set through wishlist
- keep reveal of cart quantity ancestor as on some pages it's not
  visible by default (see previous item for user-case)

closes odoo/odoo#96047

X-original-commit: 2ff55c5fd684ab701cf143d3b0d46979759a8e9f
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
Signed-off-by: William Braeckman (wbr) <wbr@odoo.com>
2022-07-14 21:44:55 +02:00
Xavier Morel ba37803064 [IMP] core: reintroduce test stats
Uses a dedicated logger (for easier filtering / silencing) for
results output, and provides rough (module-level) stats in INFO but
detailed (test-level) in DEBUG.

Also updates the global query counter (`odoo.sql_db.query_counter`) to
update after each query rather than on close: with test cursors the
actual underlying counter is only rarely flushed.

closes odoo/odoo#95420

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-07-11 09:04:51 +02:00
Xavier Morel 319f9bf5ea [IMP] mail: allow admins to remove channels they're not members of
The only mail.channel rule was that a user only had access to channels
they're members of, or can subscribe to (public, or group based).

This rule applied to admins as well, forcing them to switch to
super-admin mode in order to manage mail channels.

This is undesirable on lots of axis:

- superadmin mode is a bit of a last-ditch feature, as a result it's
  somewhat hidden
- there is a much higher risk of screwing up as superadmin mode
  basically lifts all the access rules, which can have correctness
  implications
- auditing completely breaks down when using superadmin mode, as the
  real identity of the user is lost

OPW-2857136

closes odoo/odoo#92299

X-original-commit: 1a77ab5726bbcc477d12f40f67433d474ea85316
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-05-30 09:28:49 +02:00
Xavier Morel ddb64e30f1 [FIX] bus: restore _daemonic workaround
In fixing leftover jammy warnings in #92078 I mistakenly updated the
setting of `_daemonic` to the public `daemon`, missing that it was a
dedicated and explicit workaround for Python's checks (cf
d03b4f8675).

closes odoo/odoo#92255

X-original-commit: e35a4d87578a588e33f604638289ca7e7ee02029
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-05-25 14:38:07 +02:00
Xavier Morel 2abc92afe5 [FIX] bus: deprecated threading attribute (and then some)
Python 3.10 formally deprecated the old threading API. This was missed
in #88803.

Also apply a few other fixes and improvements:

- `Thread._daemonic` is a non-public unchecked internal attribute, use
  the corresponding documented property
- remove unused assignment to unused local
- define `Event` attribute in `__init__` where it belongs
- cleanup spawning on thread to do everything in ctor (permissible
  since 3.3)
- fix import to not rely in implicit sub-module imports

closes odoo/odoo#92187

X-original-commit: 87d087ff7d53394dd991099cf7eac37d1ef68423
Signed-off-by: Vincent Schippefilt (vsc) <vsc@odoo.com>
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-05-25 07:33:49 +02:00
Xavier MorelandRaphael Collet 6c872f6c19 [FIX] core: _get_external_ids to behave better in onchange context
If `_get_external_ids` is called in an onchange context on a newid
wrapper, the result map uses NewId keys but the assigned data uses
real ids, which leads to a mis-setting, and usually the call blowing
up immediately as `data['res_id']` is not one of the preallocated dict
entries.

Update the code to better handle this possible difference.

closes odoo/odoo#91957

X-original-commit: 5797fd80a63309269f15bcbe4948d4429a53eec2
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
Co-authored-by: Raphael Collet <rco@odoo.com>
2022-05-23 08:30:11 +02:00
Xavier Morel 2041f55c85 [FIX] auth_oauth: restore fetching uid from user_id
In discussing 56fe16bd I was reminded to re-set the `user_id` from
`sub` in case an override / other client would be using it, but we
didn't think that an override might also be *setting* this work key,
which apparently is the case.

Therefore restore the old behavior of *getting* the user_id from the
response object, migration to using `sub` (and removal of compat with
`user_id` and `id`) will be done when the module is reworked and the
flow compatibility, nonce, etc... are all fixed.

closes odoo/odoo#91996

X-original-commit: a787a2f644e9e83dc6320eaf372e657718fd2e22
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-05-23 07:33:43 +02:00
Xavier Morel e0345512d9 [FIX] auth_oauth: google rejects nonce if response_type=token
I apparently missed this case in #88871: Google's legacy
flow (response_type=token) explicitly rejects a `nonce` parameter
being passed in the authentication request. The nonce parameter is
only accepted for an OIDC-conformant implicit flow request (aka
`response_type=token id_token`).

The specific endpoint doesn't seem to have any bearing on this, v1 and
v2 authentication endpoints result in the same behavior.

Drawback: Okta isn't supported anymore, as it requires the nonce, no
if, no but, even on "legacy" auth requests, possibly others. However
since these already weren't supported that's considered less of an
issue than possibly breaking compatibility with existing IDP.

Rejected alternative: adding `id_token` to the `response_type` to come
closer to OIDC-conformant request, however that was considered too
risky: Odoo clients could be using legacy IDP which also reject the
nonce parameter but don't have a magic "OIDC conformant" trigger.

closes odoo/odoo#91500

X-original-commit: 1fd738d9826f9bdfe8deddd5ef81dcb9757e8988
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
Signed-off-by: Olivier Dony <odo@odoo.com>
2022-05-16 20:18:24 +02:00
Xavier Morel c5964f84d9 [FIX] auth_oauth: improve implicit flow implementation / compat
The current implementation is rather non-standard and largely an
ad-hoc pre-RFC implementation, with a number of incompatibilities with
the standard & actual real-world identity providers (IDP).

Tested with the following IDP:

- google oauth v1
- google oauth v3
- auth0
- okta

Add support to bearer Authorization
===================================

Sending the access token via "Authorization: Bearer $TOK" is strongly
recommended by the RFC, and required for all IDP to support. The query
parameter method is a legacy compatibility method and should be
avoided.

Query parameter access tokens are supported by Google (both v1 and
v3), and auth0, but not okta. All three support bearer tokens. However
making this the default is complicated by compatibility issues with
current behavior.

Use standard `sub`ject for identity
===================================

The specification defines `sub` as the userinfo key providing the user
identifier at the IDP.

- auth0, okta, and google v3 use `sub`
- google v1 uses `id`
- google v1's `tokeninfo` (possibly v3 as well, not tested) uses
  `user_id`
- odoo replicates the google v1 tokeninfo behavior, using `user_id`

All the code is now standardised on `sub`, with `_auth_oauth_validate`
performing unification under that key.

Support non-json error bodies and WWW-Authenticate
==================================================

Per-spec, there is no requirement for error (userinfo) responses to
return any body, and all error information can be returned via
`WWW-Authenticate`.

Both auth0 and okta return empty bodies on error, though only okta
returns a useful www-authenticate, or relevant 40x statuses (auth0
seems to always return 400, okta has been observed to return both 400
and 401 depending on client error).

Error handling in `_auth_oauth_rpc` has been updated to only parse the
body as json on success (200), and fallback on a generic error payload
if `WWW-Authenticate` doesn't contain relevant information.

Nonce
=====

Okta requires a nonce to be provided.

Misc
====

A few improvements which are in no way required but should make things
simpler / clearer:

- update the default scope to match the standard for the implicit
  flow's values (intersected with our requirements)
- update the default google configuration to use the v3 endpoints and
  drop the tokeninfo request, remove the explicit scopes
- update the label of `validation_endpoint` to match the official
  terminology, same with `auth_endpoint`
- add a label to `body` in order to explain what it's for (as that's
  really confusing when the form just says `body` until you hover the
  field)

Expected future updates
=======================

These issues were left out and may lead to degraded security, but were
considered too large changes fora stable compatibility-oriented
update:

* store and validate the nonce
* request and properly validate the id token, as well as validate the
  access token (implicit guide sections 2.2.1, 2.2.2)
* implement "basic" flow[^basic], and / or "hybrid" flow, the implicit
  flow[^implicit] is intended for purely client-side applications
  (SPAs), the "authorization code" flow is intended as the primary
  flow for normal web applications involving a server component,
  the main advantage of the hybrid flow is that the id token *can*
  contain the claims selected by `scope`, avoiding the need for the
  userinfo request[^idtoken]
* remove support for query parameter requests
* remove support for Google's v1 oauth and subject identifiers other
  than `sub`, facebook has not been tested but looks to support that
  key as well in the OpenGraph API[^fb], this will require migrating
  existing google providers to v3 implicitly (but would allow
  simplifying their configuration)

References: RFC 6749, RFC 6750, Implicit Client Implementer's Guide
1.0 draft 23[^implicit]

Closes #88618, closes #64348, fixes #63963, closes #63970,
closes #69568

[^implicit]: https://openid.net/specs/openid-connect-implicit-1_0.html
[^basic]: https://openid.net/specs/openid-connect-basic-1_0.html also
          known as "authorization code" flow
[^fb]: https://www.facebook.com/.well-known/openid-configuration
[^idtoken]: during testing, only auth0 returned the additional claims
            as part of the id token, but this may be a configuration
            issue

closes odoo/odoo#91262

X-original-commit: fb3c4845b1549bc2e1378620a5f01e52aa4dbbdb
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-05-13 07:44:52 +02:00
Xavier Morel f0fe59dcf7 [FIX] web/lib: backport jquery bugfixes
opw-2793379

closes odoo/odoo#90463

X-original-commit: 684e3fc983e91168dfaef8536fcd1f71ce7f7fdc
2022-05-04 00:05:02 +02:00
Xavier Morel 9ac8050de8 [REV] web/lib: Revert: backport jquery bugfixes
This reverts commit 0dd7c78b06726543825008a48d3dc004d2af4557.

X-original-commit: b50cd480d3f40ab084689587e6cbed311c09fb2f
Part-of: odoo/odoo#90463
2022-05-04 00:05:01 +02:00
Xavier Morel 7bce4c19f3 [IMP] web_editor: cleanup channels regex
Model pattern was too permissive, separator is the literal `.`
character, not any random thing.

Also remove unnecessary bracket expression, it's unnecessary when
matching a single item.

OPW-2836106

closes odoo/odoo#90107

X-original-commit: 320cdb4e85cb86915fa25cfda8f17e0a372e765e
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
Signed-off-by: Raphael Collet <rco@odoo.com>
2022-05-03 13:31:03 +02:00
Xavier Morel 0569476adc [FIX] calendar: read([]) as a non-admin would not return all fields
Because private fields would automatically add a bunch of fields to
the user's request (in order to do their own post-treatment), unlike
normal behavior `read([])` would be completed to `read(['privacy',
'user_id'])` and would fail to trigger the "select all the fields"
behavior of `BaseModel.read`.

Move the privacy management to a `_read` override instead. Also update
the code to be more linear and straightforward, without a bunch of
intermediate helper function.

This is also a small performance optimisation, although apparently
much more minor for 14 (best case of about 5%) than on 15.0 (where it
seemed to reach 30). The gain is mostly for private events being read
for non-participants: because the non-public fields get neutered
before computation (rather than after), fields are computed on a
neutered basis and thus largely do nothing. This is especially salient
with computations relying on relations (in this case
`attendee_status`), as from an empty starting point they essentially
do not do anything.

This leads to the effort (and cost) of private events being read by
non-participants to be about the same as the cost of public events,
whereas before the change there is a visible overhead. The signal is
quite noisy though.

NOTE: backported the addition of `privacy` to the public fields from
      2f4a91c0ce as that is better
      behavior and makes the tests more logical (and easier to forward
      port probably)

OPW-2831113

closes odoo/odoo#89936

X-original-commit: b0c6f2969596fb715e0a6c62865b5c7dbc0bcc78
Related: odoo/enterprise#26699
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-04-28 09:59:49 +02:00
Xavier Morel 1e7051363d [REM] crm: ACL which hasn't been useful in a while
Only the group_salesman can see the opportunities statbuttons

Fix a few not-smart mass_mailing tests:

- running the mass mailing queue processes the messages as the user
  running the queue, and will try to send the demo messages, depending
  on demo data (when re-running the tests) the test user may not have
  the accesses required; sending just the one test email avoids that
  issue
- the leads kpi assumes the user has access to leads, that ain't
  necessarily the case

For the second issue, when sending statistics if the mailing has a
user `_prepare_statistics_email_values` should be called with that
user as "current" (cf `_action_send_statistics`), so we can just work
off of the current env, though it might be a good idea to eventually
check that.

closes odoo/odoo#89774

X-original-commit: 39af865800c6752b60171f16d6056ceb3c5a1636
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-04-27 10:04:37 +02:00
Xavier Morel 6c3bbdbef8 [FIX] core: fix "generator didn't yield" in assertRaises
Because the `savepoint` and `clear` calls are nested inside the
`assertRaises` context, if one of them happens to throw *the exception
we're looking for* the interpreter will jump back to the `with`, the
`assertRaises` will swallow the exception (and count it as a success)
and the function will end having not gone through a `yield`.

This is rather frustrating to debug as it's easy to forget that a
`with` is a control flow structure, leading to a seemingly impossible
error.

We can fix this by initializing and `__enter__`-ing the savepoint
first, but doing this by hand is a bit iffy and not really
future-proof as the addition of more fallible steps during the
initialization phase of `_assertRaises` could lead to the savepoint
not being properly disposed of. Furthermore once in the scope of the
"actual" assertRaises we want the savepoint to unwind first (otherwise
the savepoint won't be rolled back when the exception *we are
expecting* gets raised).

As it turns out `ExitStack` offers the solution to our woes though
it's a bit tricky at first glance: while modifying the cleanup queue
in-place is haram, `pop_all` allows moving cleanup callbacks from one
queue to the next.

This means we can first add the savepoint to one stack and get its
errors (if any) correctly reported, cover the rest of the
initialization, then move the savepoint from one stack to an other, in
order to correctly order the coverage of the `yield` (and the userland
code).

closes odoo/odoo#87733

X-original-commit: b1cd4e4e3c918b4b08d27b30b1017fc898d4b08a
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-04-01 13:37:21 +02:00
Xavier Morel 2cb4ec90aa [FIX] project: random cache flushing issue in test_task_portal_no_read
test_task_postal_no_read` calls `assertEqual`, which internally
creates a savepoint which flushes pending computations.

This is done by flushing the transaction (through the cursor), which
in turn goes and flushes the models.

The environment being used to flush the models is arbitrary, picked
from the set of all living environments associated with the
transaction favoring those with a user set. This means the environment
used to perform the pending computation can be a lot more restrictive
than the operation used to initiate said computation, which may lead
to the computation being flushed not being *possible to perform*.

The issue here is that the test specifically involves a restricted
user ("Portal user", created for the occasion). Logging the set, at
the start of the test function there are 11 active environments
associated with the superuser (uid1) and one (1) environment
associated with that user, let's call it 19 (because that's the uid it
gets when running only that job).

On the runbot the envset seems to shuffle really well and about 2/10
of the runs will have the env(uid=19) in leading position[0], thus try
to flush the *creation of the task* with the portal user, which
specifically does not have access to tasks.

This works around the issue by flushing the task creation in the
`setUp`, however the underlying issues remain.

[0]: This also seems to require some load on the runbots, if the
     runbots are pretty much unloaded (no pending builds)
     reproduction is never achieved. It is not clear why load
     would matter.

     Local reproduction was not successful, even using a dump from the
     runbot and inducing artificial load (via stress-ng).

closes odoo/odoo#87512

X-original-commit: fc08ff42ec8886f6258bde6586c4293b64c89456
Signed-off-by: Raphael Collet <rco@odoo.com>
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-03-30 08:15:49 +02:00
Xavier Morel 8045d656c8 [FW][FIX] web/lib: backport jquery bugfixes
opw-2793379

closes odoo/odoo#86416

X-original-commit: 0dd7c78b06726543825008a48d3dc004d2af4557
2022-03-15 07:56:28 +01:00
Xavier Morel 5463c1467c [FIX] payment_*: tests when running with a non-default port
For payment_buckaroo and payment_sips (at least) running with a
non-standard port is an issue to the `test_redirect_form_value` tests:
while the form and test will use respectively the base_url and the
configuration port, both check a response signature which is
predicated upon a base url of `http://127.0.0.1:8069`.

This means the test does not pass when run with a different port, and
may not pass if the database was installed with a different port
either (because this may have caused the `web.base_url` to be set to
the installation port).

The other payment modules don't seem to have such signature
verification and thus apparently don't mind running with non-default
port.

Update in 15.2: `test_webhook_notification_confirms_transaction` also
broke but differently, because the payment utils would fetch (and use)
the `web.base.url` they get confused if a db is installed using one
port then the tests are run using an other (or something along those
lines), despite `HttpCase` trying to set the `web.base.url` (could be
an ordering thing).

Anyway a working solution seems to be to *remove* the bespoke code
from `PaymentTestUtils` and fix `HttpCase.base_url()` so it uses the
right port (apparently that'd never been fixed). This does require
adapting the patch being forward-ported as `base_url` is now a
callable, not an attribute.

Also re-remove the attractive nuisance of the odoo.tests.common.PORT
constant which does not work: it is evaluated before the configuration
has been loaded and is thus always set to the default (8069).

closes odoo/odoo#86068

X-original-commit: c28c99f7399da91e1a6176d6f97d4fc947013cae
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-03-09 09:24:02 +00:00
Xavier Morel 49af835e20 [FIX] base: attachment copy ACL
Currently, `Attachment.copy` has an *explicit* check for write access
on the underlying record.

This doesn't necessarily make sense e.g. a user copying an attachment
from a template to an email may not have write access to the template,
but that should not be an issue. And indeed if the copy is performed
"by hand" (read then create) things work fine[^1].

Since both `read` and `create` are checked, the explicit `copy` check
doesn't seem necessary. Drop it, and try to add some tests around
`copy`. Move `test_06_linked_record_permission` to its own `TestCase`
and split it for readability.

A secondary issue is that the `check` in `create` was performed in the
context of the `self` being copied, leading to the same issue as
`copy` being repeated (that is, `a.copy()` would call `a.create()`
which would call `a.check('write')`, even though we're semantically
creating a record from scratch). The behavior is really intended for
`write` where we want to check if we have `write` access to both the
"source" and the "destination" records.

Explicitly opt-out of having any source data in the `create` before
performing the `check` calls, this way we correctly and only check for
the writability of the destination, and only check for the readability
of the source.

issue 2746483

[^1] well not entirely true, see 4th paragraph

X-original-commit: 60723fb311ed7cc1cf901fe90e8745835cf4d54d
Part-of: odoo/odoo#85271
2022-02-24 10:15:55 +00:00
Xavier Morel 722f0f9b65 [IMP] core: deduplicate @locked and @synchronized, use in Registry
It's not entirely clear whether `@synchronized` is even useful, but
keep it for now. `locked` is just the default instance of
`@synchronised`.

- rewrite `@synchronized` using `decorator`, don't fold everything
  into a single call as there's a potential for parametric conflict
- remove the independent `locked` in `sql_db.py`
- convert `lru` to `locked`
- move `Registry` over to `locked` where applicable

closes odoo/odoo#82718

Signed-off-by: Raphael Collet <rco@odoo.com>
2022-01-26 08:48:43 +00:00
Xavier Morel 62b731a3b8 [FIX] core: possibility of allocation error in native magic libraries
Both of the native `magic` libraries can trigger an allocation error
if the buffer being sniffed is large. This results in nothing useful
for the user and just triggers and exception when trying to create
large attachments (in the hundreds of MBs).

Fix by implementing the workaround suggested in
ahupp/python-magic#82, under the assumption that it should also work
fine for Debian's python-magic.

The pure-python trivial version of odoo should not have this issue, as
it does not normally copy the source buffer in full, it just seeks and
slices the buffer, and occasionally parses it as a zip (but does not
normally load everything in memory).

Task-2722110

closes odoo/odoo#83190

X-original-commit: 94fc66452f28a8c64b4077d6cc2dd17ea1f00aa6
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-01-21 15:58:59 +00:00
Xavier Morel 864d991c7e [FIX] mail, mass_mailing: fix attachment ownership (cont)
Followup to #82105: turns out we kind-of forgot that records could be
updated with new attachment and the exact same issue could occur.

So with the same reasoning as the previous PR, re-attach attachments
to the current object when updating it.

closes odoo/odoo#83083

X-original-commit: 398070ec1b6ed7d6a8e7c0ab75d45b8a9ad0e0d0
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-01-20 15:11:50 +00:00
xmo-odoo 44e7a693f0 [IMP] flake8 base config
The usage of `select=RST` apparently broke all local flake8 uses (which might
be implicit e.g. used for linting in the simpler editors). Always excluding
"addons" probably causes a similar problem.

Remove the exclusion of "addons", and use "extend-select" for the selection of
RST errors. This should play better with local configuration, or the lack of
configuration (thus flake8 defaults). This means the exclusion of addons and
the "blanking" of the default errors selection will have to be done in the CI 
configuration, but that probably makes sense.

closes odoo/odoo#82650

Signed-off-by: Raphael Collet <rco@odoo.com>
2022-01-14 15:44:52 +00:00
Xavier Morel b01a190a97 [FIX] base: incorrect UserError initialisation
Apparently a migration error in
0fd773a486, probably never noticed
because nobody ever tries to copy config objects since there's a
bespoke widget, and it's specifically forbidden.

Also fix the signature of the method itself to match the normal one.

closes odoo/odoo#82711

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2022-01-13 14:35:51 +00:00
Xavier Morel 74241b3766 [FIX] test_lint: support fstrings in sql injection checker
Those were not accounted for, leading to fstrings passing through
unflagged.

Also update the SQL checker to be stricter but smarter:

The previous version would "fail open", unknown nodes would be allowed
through hence f-strings not being flagged when they started appearing
in arg0 position, should now fail-closed, anything that's not allowed
is forbidden.

This flags a few more cases, all of which seem acceptable upon review.

However the previous version would also only resolve arg0 (in case it
had a `NAME`, to see if that resolved to an acceptable form of
query-building). The new version performs resolution during
`_check_concatenation` and should thus allow e.g. format strings to be
separate variables (though not e.g. module-level constants, yet
anyway).

In resolution, replace the ad-hoc process by astroid's built-in
`lookup` which seems to provide the same information. Slightly more in
fact, as it yields every assignment in case of e.g. conditionals, but
making use of that would require a lot more changes in the checker so
leaving the behaviour as-is for now.

It's important to *not* use `ilookup` here, because ilookup is not
"iterable" but "inferring", and we don't want values, we want
expression ASTs for analysis.

NOTE: previous improvements as well as fixes to existing code were
only implemented in 14.0, hence this being merged in 14.0 not 13.0
despite 13.0 still being supported.

closes odoo/odoo#81721

X-original-commit: 376ccf0944dae1bc53ae9c5385977c4e6b23e083
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
2021-12-27 09:36:42 +00:00
Xavier Morel 8d7a9162f9 [IMP] core: set CSP header on some non-HTML resources
Core client remains incompatible with CSP, however it can't hurt to
CSP the sub-resources.

Current scheme is simplistic, however if useful of necessary it could
be made more flexible e.g. there could be a map of mimetypes to CSP
configuration, that sort of things.
2021-12-13 14:46:14 +01:00
Xavier Morel a6c29c44f4 [IMP] l10n_fr_fec: fix report 2020-12-15 11:31:34 +01:00
Xavier Morel 209429f946 [IMP] base: increase password work factor
And make configurable via an ICP. Provide a reasonable default value,
and use it as a lower bound so user error can't lead to an insecure /
unsustainable amount of hashing.

Aside from being somewhat overdue on account of age (passlib's current
default were last updated 6 years ago), this is also made much more
feasible by API keys, meaning non-interactive use (RPC) is less
strained by the (interactive) password hashing.

Also modernize passlib usage:

* Remove global `DEFAULT_CRYPT_CONTEXT`, create inline (as overhead
  should not be too huge given what we're doing with it), and
  `ormcache()` for safety, the caches should be invalidated on any ICP
  addition, removal, or update, so user update to the rounds
  configuration should get reflected immediately.
* Switch on `deprecated=["auto"]`, feature was added in 1.6 and we now
  depend on 1.7.
* Remove mentions of `encrypt`, it is deprecated in 1.7.

closes odoo/odoo#81498

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2021-12-16 14:13:43 +00:00
Xavier Morel bdc9d9d369 [FIX] core; base: lots of docstrings
* add configuration for `flake8[flake8-rst-docstring]`
* enable docstring-related checks
* fix invalid docstrings in odoo's core & `base`
* fix a few more bits (mostly missing or incorrect `:param:` info
  fields) are out of scope for the lint but my editor catches

closes odoo/odoo#74604

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2021-12-09 14:36:58 +00:00
xmo-odoo 2789824fcc [FIX] core: dbname threadlocal in evented CDT
Since #77735 the chrome runner uses a receiver thread to better handle the
full-duplex nature of Chrome's websocket communication.

However that thread was missing the `dbname` threadlocal, leading to some of
the logging and reporting to be mis-configured, and thus the filtering on CI
(runbot) to exlude any logging message emitted from the receiver thread, such
as the screenshot notifications.

Fix by passing the current `dbname` to the receiver thread when spawning it,
and having said receiver start by setting up the threadlocal.

closes odoo/odoo#79808

Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
2021-11-16 11:34:37 +00:00