Commit Graph
13 Commits
Author SHA1 Message Date
Julien Castiaux 3d1f486bcc [IMP] *: update modules to use the new geoip API
request.geoip is no more a dictionnary cached in the session. It is now
a full blown object with lazy and smart geolocalisation capabilities.

Among other things, the previous dictionnary API is now deprecated. The
changes are:

* `request.geoip['country_name']` -> `request.geoip.country_name`
* `request.geoip['country_code']` -> `request.geoip.country_code`
* `request.geoip['city']` -> `request.geoip.city.name`
* `request.geoip['latitude']` -> `request.geoip.location.latitude`
* `request.geoip['longitude']` -> `request.geoip.location.longitude`
* `request.geoip['region']` -> `(request.geoip.subdivisions[0].iso_code if request.geoip.subdivisions else None)`
* `request.geoip['time_zone']` -> `request.geoip.location.time_zone`

It is safe to access all the attributes. Doing `request.geoip.city.name`
when the geolocalization failed (missing db, invalid address, ...)
evaluates to None. It does not raise an AttributeError.

Task: 2848206
Part-of: odoo/odoo#91337
2023-01-03 13:16:02 +01:00
Olivier Dony 038cdc66b9 [IMP] auth_totp: add trusted device method to validate user
Adds a variant `_check_credentials_for_uid()` for auth_totp.device's
`_check_credentials()`. The new method will directly verify the device
key matches the given uid.

This spares the redundant uid comparison on the caller side, and
allows extension modules to customise the user/device matching logic.

closes odoo/odoo#94365

X-original-commit: 0e266eb3c73409950d1eb160c41eb6668d439856
Signed-off-by: Olivier Dony <odo@odoo.com>
2022-06-23 02:05:42 +02:00
Nicolas Martinelli 0edcd1ac41 [IMP] base, auth_totp: log user in case of failed login
When a login attempt is ignored, we add the user info for a better
understanding on the attack (brute force, credentials stuffing...).

closes odoo/odoo#91588

X-original-commit: 0f69448202244e808e1122a618be701806d606cf
Signed-off-by: Nicolas Martinelli (nim) <nim@odoo.com>
2022-05-18 07:14:00 +02:00
Julien Castiaux 04e972660b [IMP] core: don't save visitor default session
Every request comes with a session, a dictionary that is persisted on
the filesystem and that saves various information such as the user
cart on the ecommerce.

When a user simply visits the website, a default session is created and
saved on disk, this bloats the filestore with many sessions. Creating
the session on-the-fly is cheaper than loading it from the filesystem.
With this work the default session is not saved on disk anymore unless
explicitly asked via `session.touch()`.

An exception to the statement "creating the session on-the-fly is
cheaper" is geoip, the ip geolocalization is not cheap. In this work,
geoip have been moved from http_routing/request.session.geoip to a
lazy property core/request.geoip. When requested the info is persisted
on the session. Like other keys from the default session, geoip will not
be persisted unless there is non-default stuff in the session.

Because the CSRF-TOKEN is based on the session-id, it is important the
session-id stays the same across multiples requests even when the
session is not persisted on disk. Even when a session is not persisted
on disk, the session-id cookie is still set so that the next session
created on-the-fly uses the same session-id.

Technical note regarding the session, it has been decided to drop the
session-snapshot protocol and to reintroduce a "modified" flag. It has
been decided not to use werkzeug's session (which natively comes with a
"modified" flag) and to keep our own session object. We decided to
extend MutableMapping instead of dict; using MutableMapping we only
have to override __setitem__ and __detitem__; using dict we would had to
override update()/pop()/... too.

Task: 2789035
Part-of: odoo/odoo#86015
2022-04-05 14:13:54 +02:00
Jeremy Kersten d2b4214409 [FIX] auth_totp: don't redirect to url prefixed with lang
This commit removes the multilang feature on the /web/login/totp controller,
it doesn't really add value since it triggers a redirect and that the page is
all the same translated.

It is a good practice by default for SEO, but in this case it brings
some bug with the IOS apps that doesn't follow the redirect, while we don't
need to optimize this page for Search Engine.

The bug into the IOS apps, create a loop when we request the totp screen.
    Device request /web/login/totp
    Server ask a redirect to /fr_FR/web/login/totp
    Device redirect to /web/login/totp
    Server ask a redirect to /fr_FR/web/login/totp
    ...

closes odoo/odoo#87810

X-original-commit: 4dea1b9b7cf0855095f9cfa37ff6a9a6db7cf55e
Signed-off-by: Adrien Dieudonné (adr) <adr@odoo.com>
Signed-off-by: Jérémy Kersten <jke@odoo.com>
2022-04-02 21:10:54 +02:00
Julien Castiaux 1dd3865208 [IMP] *: odoo.addons.web.controllers.main splitted
The odoo.addons.web.controllers.main python module have been splitted
over multiple files on the basis 1 controller = 1 file. In this work we
adapt all modules to use the new imports.

A non-exhaustive list of where stuff have been moved:

* main.Home		--> home.Home
* main.Session		--> session.Session
* main.WebClient	--> webclient.WebClient
* main.clean_action	--> action.clean_action
* main.ensure_db	--> home.ensure_db

The complete list is accessible in odoo.addons.web.controllers.main.

closes odoo/odoo#87571

Related: odoo/enterprise#25746
Signed-off-by: Raphael Collet <rco@odoo.com>
2022-03-31 02:10:53 +02:00
Pierre Paridans 7df7ecae9b [FIX] auth_totp,web: TOTP login from mobile apps
Since PR odoo/odoo#78857 , the TOTP authentication support is broken
when used inside either Android or iOS mobile apps.

Due to our inability to update the iOS app (following review from
Apple), this commit aims at restoring the bare minimum requirements to
make the current mobile apps (specially iOS but also Android)
authentication workflow works.

As extended explanation:
- Set-Cookie header is expected to be sent even when session_id hasn't
  changed (iOS specific).
- Successful credentials check on `/web/session/authenticate` expect a
  successful response with a result containing `uid` set to `null` to
  mark the need of an additional totp handshake (both platforms).

closes odoo/odoo#85463

Signed-off-by: Julien Castiaux <juc@odoo.com>
2022-02-26 13:41:23 +00:00
Julien Castiaux f04b90b6e8 [REF] core: HTTPocalypse (12) web ir.http & login
This commit is the 12th commit of a comprehensive refactor of our HTTP
framework. See odoo/odoo#78857 for complete historic, discussions and
rationnals.

The web module is twofold, on one side there are many controllers: /,
/web, /web/login, /web/database/selector, /web/dataset/call_kw, etc, on
the other side there is `session_info`: the method responsible to create
the web client's environ.

This module is kinda an exception as it is (with base) a server wide
module. In the case of the HTTP framework, it means that the controllers
of web are always accessible, i.e. going to / or /web/login will never
return a 404 Not Found even if the user is not connected to a database.

This is both a blessing and a curse. It is a blessing because the
controllers are always accessible it means that a new users can freely
access those routes. It is a curse because *any* user can access them,
even user who don't have a session yet thus who are not connected to a
database yet. From a developer standpoint, we have to put extra care to
correct serve users with and without a database. An example is the
/web/login route, the login/password pair is stored in a database,
without database it is impossible to validate a user login but users can
still access this route without db.

To solve this problem, there is the `ensure_db` function. This function
attempts to find a database using various sources (?db= query-string,
session db, mono db) and to save it on the user session. In case no db
is found, the user is redirected to the database selector. In a way,
this function grants a database to the user in a seamingly experience.
In a way, this function brings a welcome differentiation between
`auth='none'` with a database and `auth='none'` without a database. Such
differentiation only matters for the server wide modules as "regular"
module controllers are only accessible via the ir.http routing map, i.e.
it is not possible to declare a nodb controller outside of server wide
modules.

An important changement is the `session.authenticate` method, before it
was possible to call the method when the cursor was not yet initialized,
authenticate would open a cursor against the given database, setup a
registry and an environment and ultimately save everything on the
current request. Because the cursor is now greedily created, it is no
more possible to update the request environment when authenticating on
another database.

PR: odoo#78857
Task: 2571224
2022-02-24 13:30:50 +00:00
Denis Ledoux a08a0b6454 [ADD] auth_totp_mail: 2FA using code sent by email
Add the possibility to force the two-factor authentication for all users,
using a two-factor authentication by email
when the 2FA using an Authenticator app is not configured for the user.

Two possibilities:
 - Force the 2FA only for employee users using the system parameter `auth_totp.policy=employee_required`
 - Force the 2FA for all users, employees and portals, using the system parameter `auth_totp.policy=all_required`

closes odoo/odoo#83750

Signed-off-by: Denis Ledoux (dle) <dle@odoo.com>
2022-02-01 17:15:30 +00:00
Arnaud GonyandMartin Trigaux 2dee29a7dc [IMP] auth_totp: 2FA Trusted Devices
+ Added the 'Trusted Devices' feature
+ Added 'Remember this Device' checkbox on /web/login/totp
+ Added trusted device's OS / browser on Profile > Account Security

Added '2FA Trusted Devices' feature to allow users to remember their
device to bypass the 2FA for the next connections. The trusted devices
are displayed in a 'Trusted Devices' One2Many under the 'Developer API
Keys'. It is possible to revoke all the trusted devices at once with a
special button. It is also possible to revoke one at a time on the
desired one.

Task-id 2523092

closes odoo/odoo#75535

Related: odoo/upgrade#2800
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
Co-authored-by: Martin Trigaux <mat@odoo.com>
2021-09-06 13:17:48 +00:00
Jeremy Kersten 478068c829 [IMP] *: always use Odoo Response
This branch adds request.redirect on all requests.
In case of a front end request, we do an url_for to the location.

We removed redirect_with_hash that was only for retro compatibility

local_redirect has been renamed to redirect_query, and param keep_hash has been
removed and moved.

Default code for redirect is 303 now instead of 302.

Now redirect and redirect_query make local redirect by default, you need to
pass local=False to make external redirect.

All werkeug.utils.redirect has been replaced by request.redirect.

Http.redirect now use an http.Response type, and it become easy to add an
override like 'set_cookies' e.g.

Dispatch of a website.page return an http.response too, so we first need to
check if it is a cached version before to check if it is an Odoo Response.

Migrate your code:

http.redirect -> request.redirect(location, code, local)
http.local_redirect -> request.redirect_query(location, query, code, local)
http.redirect_with_hash -> request.redirect

Courtesy of odony for help and review ;)

closes odoo/odoo#72599

Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
2021-07-08 07:00:06 +00:00
Xavier Morel 70b6ac5009 [IMP] auth_totp: allow spaces in totp code input
TOTP programs generally group the code into two groups of 3 digits,
but we'd only allow a single group of 6 digits.

Allow spaces in the value for a bit of flexibility, and fix
placeholders to look like codes (also turns out @placeholder on a
field doesn't do anything, not sure where I got this idea).

Also improve the label slightly in the login flow:

* add information to the label itself
* properly link the label & input via an `id`
2020-09-10 12:47:15 +00:00
Xavier MorelandOlivier Dony a9a6509713 [ADD] auth_totp
New module for supporting two-factor authentication via time-base
one-time-password (TOTP).

Users (including portal users) can choose to enable two-factor auth in
their user account settings, by scanning a QR code and adding it to an
authenticator app, such as Google Auth, 1Password, etc.

When two-factor is enabled, password-based non-interactive RPC is only
possible by using API keys.

Co-authored-by: Olivier Dony <odo@odoo.com>
2020-08-14 23:06:24 +00:00