From f0766dbc16f8b271bf5361ca836144a557ab624a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E9=A3=9E=E8=99=8E?= Date: Mon, 22 Sep 2025 11:24:14 +0800 Subject: [PATCH 1/5] [IMP] impersonate_login: Optimize database performance for partner deletion --- impersonate_login/models/mail_message.py | 1 + 1 file changed, 1 insertion(+) diff --git a/impersonate_login/models/mail_message.py b/impersonate_login/models/mail_message.py index e7bf2fd4dc..6227265ed9 100644 --- a/impersonate_login/models/mail_message.py +++ b/impersonate_login/models/mail_message.py @@ -14,6 +14,7 @@ class Message(models.Model): comodel_name="res.partner", compute="_compute_impersonated_author_id", store=True, + index=True, ) body = fields.Html( From e146e3e3beba6a0f9fe1e7ab6d6c43f10631a042 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Sun, 28 Dec 2025 11:51:03 +0000 Subject: [PATCH 2/5] [BOT] post-merge updates --- README.md | 2 +- impersonate_login/README.rst | 8 +++-- impersonate_login/__manifest__.py | 2 +- .../static/description/index.html | 30 +++++++++++-------- 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index e13933450a..b76c69014c 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ addon | version | maintainers | summary [auth_user_case_insensitive](auth_user_case_insensitive/) | 18.0.1.0.0 | | Makes the user login field case insensitive [base_user_empty_password](base_user_empty_password/) | 18.0.1.0.0 | grindtildeath | Allows to empty password of users [base_user_show_email](base_user_show_email/) | 18.0.1.0.0 | | Untangle user login and email -[impersonate_login](impersonate_login/) | 18.0.1.0.0 | Kev-Roche | tools +[impersonate_login](impersonate_login/) | 18.0.1.1.0 | Kev-Roche | tools [password_security](password_security/) | 18.0.1.0.0 | | Allow admin to set password security requirements. [user_log_view](user_log_view/) | 18.0.1.0.0 | trojikman | Allow to see user's actions log [users_ldap_mail](users_ldap_mail/) | 18.0.1.0.0 | joao-p-marques | LDAP mapping for user name and e-mail diff --git a/impersonate_login/README.rst b/impersonate_login/README.rst index 66afba1389..2b71b498b5 100644 --- a/impersonate_login/README.rst +++ b/impersonate_login/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ================= Impersonate Login ================= @@ -7,13 +11,13 @@ Impersonate Login !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:1c22b5e85d268d1f7b8b3d64d9d2d2acb8b05a9cb3170a33fd4dcdc64fbdbd61 + !! source digest: sha256:0f4564be316d51d716922597d0fbfc4ba6ee6b58b19243f17fc445dd6d9d3a4c !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--auth-lightgray.png?logo=github diff --git a/impersonate_login/__manifest__.py b/impersonate_login/__manifest__.py index e07a936e97..e7a9ef963f 100644 --- a/impersonate_login/__manifest__.py +++ b/impersonate_login/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Impersonate Login", "summary": "tools", - "version": "18.0.1.0.0", + "version": "18.0.1.1.0", "category": "Tools", "website": "https://github.com/OCA/server-auth", "author": "Akretion, Odoo Community Association (OCA)", diff --git a/impersonate_login/static/description/index.html b/impersonate_login/static/description/index.html index 3aa102e36d..1cf66496f8 100644 --- a/impersonate_login/static/description/index.html +++ b/impersonate_login/static/description/index.html @@ -3,7 +3,7 @@ -Impersonate Login +README.rst -
-

Impersonate Login

+
+ + +Odoo Community Association + +
+

Impersonate Login

-

Beta License: AGPL-3 OCA/server-auth Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/server-auth Translate me on Weblate Try me on Runboat

This module allows one user (for example, a member of the support team) to log in as another user. The impersonation session can be exited by clicking on the button “Back to Original User”.

@@ -400,11 +405,11 @@

Impersonate Login

-

Configuration

+

Configuration

The impersonating user must belong to group “Impersonate Users”.

-

Usage

+

Usage

  1. In the menu that is displayed when clicking on the user avatar on the top right corner, or in the res.users list, click “Switch Login” to @@ -414,7 +419,7 @@

    Usage

-

Bug Tracker

+

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed @@ -422,15 +427,15 @@

Bug Tracker

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • Akretion
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -455,5 +460,6 @@

Maintainers

+
From af0a4ec958da911781766c3dc22ccef813f4e46c Mon Sep 17 00:00:00 2001 From: chaule97 Date: Mon, 22 Dec 2025 11:29:44 +0700 Subject: [PATCH 3/5] [ADD] auth_autologin_via_jwt_cookie --- auth_autologin_via_jwt_cookie/README.rst | 72 +++ auth_autologin_via_jwt_cookie/__init__.py | 1 + auth_autologin_via_jwt_cookie/__manifest__.py | 21 + .../models/__init__.py | 5 + .../models/ir_http.py | 199 +++++++++ .../models/res_config_settings.py | 24 + .../readme/DESCRIPTION.rst | 2 + .../static/description/index.html | 417 ++++++++++++++++++ .../views/res_config_settings_view.xml | 58 +++ .../odoo/addons/auth_autologin_via_jwt_cookie | 1 + setup/auth_autologin_via_jwt_cookie/setup.py | 6 + 11 files changed, 806 insertions(+) create mode 100644 auth_autologin_via_jwt_cookie/README.rst create mode 100644 auth_autologin_via_jwt_cookie/__init__.py create mode 100644 auth_autologin_via_jwt_cookie/__manifest__.py create mode 100644 auth_autologin_via_jwt_cookie/models/__init__.py create mode 100644 auth_autologin_via_jwt_cookie/models/ir_http.py create mode 100644 auth_autologin_via_jwt_cookie/models/res_config_settings.py create mode 100644 auth_autologin_via_jwt_cookie/readme/DESCRIPTION.rst create mode 100644 auth_autologin_via_jwt_cookie/static/description/index.html create mode 100644 auth_autologin_via_jwt_cookie/views/res_config_settings_view.xml create mode 120000 setup/auth_autologin_via_jwt_cookie/odoo/addons/auth_autologin_via_jwt_cookie create mode 100644 setup/auth_autologin_via_jwt_cookie/setup.py diff --git a/auth_autologin_via_jwt_cookie/README.rst b/auth_autologin_via_jwt_cookie/README.rst new file mode 100644 index 0000000000..ac8b5dbb5f --- /dev/null +++ b/auth_autologin_via_jwt_cookie/README.rst @@ -0,0 +1,72 @@ +============================= +Auth Autologin via JWT Cookie +============================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:235b6c7853637cc201cf62eb0b9a6cfa257c77d6199a697f0a09c7be9c3afa8b + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--auth-lightgray.png?logo=github + :target: https://github.com/OCA/server-auth/tree/16.0/auth_autologin_via_jwt_cookie + :alt: OCA/server-auth +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/server-auth-16-0/server-auth-16-0-auth_autologin_via_jwt_cookie + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/server-auth&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module automatically authenticates Odoo users using a valid JWT found in a shared browser cookie. +If no Odoo session exists, the JWT is verified via a JWKS endpoint, user information is retrieved from a userinfo endpoint, and the matching user is logged in transparently based on email. + +**Table of contents** + +.. contents:: + :local: + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Kencove + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/server-auth `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/auth_autologin_via_jwt_cookie/__init__.py b/auth_autologin_via_jwt_cookie/__init__.py new file mode 100644 index 0000000000..0650744f6b --- /dev/null +++ b/auth_autologin_via_jwt_cookie/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/auth_autologin_via_jwt_cookie/__manifest__.py b/auth_autologin_via_jwt_cookie/__manifest__.py new file mode 100644 index 0000000000..6f0a4f368f --- /dev/null +++ b/auth_autologin_via_jwt_cookie/__manifest__.py @@ -0,0 +1,21 @@ +# Copyright 2025 Kencove (https://www.kencove.com/) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +{ + "name": "Auth Autologin via JWT Cookie", + "summary": "Auto-authenticate users using a shared JWT cookie", + "version": "16.0.1.0.0", + "category": "Authentication", + "author": "Kencove,Odoo Community Association (OCA)", + "website": "https://github.com/OCA/server-auth", + "license": "AGPL-3", + "depends": ["base_setup"], + "data": [ + "views/res_config_settings_view.xml", + ], + "installable": True, + "application": False, + "external_dependencies": { + "python": ["pyjwt"], + }, +} diff --git a/auth_autologin_via_jwt_cookie/models/__init__.py b/auth_autologin_via_jwt_cookie/models/__init__.py new file mode 100644 index 0000000000..8828c2e1e1 --- /dev/null +++ b/auth_autologin_via_jwt_cookie/models/__init__.py @@ -0,0 +1,5 @@ +# Copyright 2025 Kencove (https://www.kencove.com/) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from . import ir_http +from . import res_config_settings diff --git a/auth_autologin_via_jwt_cookie/models/ir_http.py b/auth_autologin_via_jwt_cookie/models/ir_http.py new file mode 100644 index 0000000000..b32de40abb --- /dev/null +++ b/auth_autologin_via_jwt_cookie/models/ir_http.py @@ -0,0 +1,199 @@ +# Copyright 2025 Kencove (https://www.kencove.com/) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +import logging +from functools import lru_cache + +import jwt +import requests +from jwt import PyJWKClient +from jwt.exceptions import InvalidTokenError, PyJWTError + +from odoo import models +from odoo.http import request +from odoo.service import security + +_logger = logging.getLogger(__name__) + + +@lru_cache(maxsize=16) +def _get_jwk_client(jwks_url: str) -> PyJWKClient: + """ + Cache a PyJWKClient per JWKS URL (per worker). + PyJWKClient itself caches fetched JWKS keys. + """ + return PyJWKClient(jwks_url) + + +class IrHttp(models.AbstractModel): + _inherit = "ir.http" + + @classmethod + def _authenticate(cls, endpoint): + # If already authenticated, keep default flow + if getattr(request, "session", None) and request.session.uid: + return super()._authenticate(endpoint) + + result = cls._try_autologin_from_jwt_cookie() + + if not result: + return super()._authenticate(endpoint) + + @classmethod + def _try_autologin_from_jwt_cookie(cls): + settings = cls._get_autologin_settings() + if not settings: + _logger.debug("JWT autologin disabled: missing config parameters") + return False + + token = cls._get_cookie_token(settings["cookie_name"]) + if not token: + _logger.debug( + "JWT autologin skipped: cookie '%s' not found", + settings["cookie_name"], + ) + return False + + claims = cls._verify_jwt_with_pyjwt(token, settings["jwks_url"]) + if not claims: + _logger.debug("JWT autologin failed: token verification returned no claims") + return False + + # Optional hardening: accept only access tokens when claim exists + token_use = claims.get("token_use") + if token_use and token_use != "access": + _logger.debug("Skipping autologin: token_use=%s", token_use) + return False + + email = cls._get_email_from_userinfo(settings["userinfo_url"], token) + if not email: + _logger.debug("JWT autologin failed: email not found in userinfo response") + return False + + user = cls._find_user_by_email(email) + if not user: + _logger.debug( + "JWT autologin failed: no active user found for email=%s", + email, + ) + return False + + cls._force_login(user) + + return True + + @classmethod + def _get_autologin_settings(cls): + icp = request.env["ir.config_parameter"].sudo() + cookie_name = ( + icp.get_param("auth_autologin_via_jwt_cookie.jwt_cookie_name") or "" + ).strip() + jwks_url = ( + icp.get_param("auth_autologin_via_jwt_cookie.jwks_url") or "" + ).strip() + userinfo_url = ( + icp.get_param("auth_autologin_via_jwt_cookie.userinfo_url") or "" + ).strip() + + if not (cookie_name and jwks_url and userinfo_url): + _logger.debug( + "JWT autologin config incomplete: cookie_name=%s, jwks_url=%s, userinfo_url=%s", + bool(cookie_name), + bool(jwks_url), + bool(userinfo_url), + ) + return None + return { + "cookie_name": cookie_name, + "jwks_url": jwks_url, + "userinfo_url": userinfo_url, + } + + @classmethod + def _get_cookie_token(cls, cookie_name: str): + return request.httprequest.cookies.get(cookie_name) + + @classmethod + def _verify_jwt_with_pyjwt(cls, token: str, jwks_url: str): + """ + Verify RS256 token using JWKS URL via PyJWKClient (cached). + Returns claims dict if valid, otherwise None. + """ + try: + header = jwt.get_unverified_header(token) + except PyJWTError as e: + _logger.info("Invalid JWT header: %s", e) + return None + + if header.get("alg") != "RS256": + _logger.info("Skipping autologin: unexpected alg=%s", header.get("alg")) + return None + + if not header.get("kid"): + _logger.info("Skipping autologin: missing kid") + return None + + try: + jwk_client = _get_jwk_client(jwks_url) + signing_key = jwk_client.get_signing_key_from_jwt(token).key + except (requests.RequestException, PyJWTError) as e: + _logger.warning("Unable to fetch/resolve JWKS signing key: %s", e) + return None + + try: + claims = jwt.decode( + token, + signing_key, + algorithms=["RS256"], + options={ + "verify_aud": False, + }, + ) + return claims + except InvalidTokenError as e: + _logger.info("JWT verification failed: %s", e) + return None + + @classmethod + def _get_email_from_userinfo(cls, userinfo_url: str, token: str): + try: + res = requests.get( + userinfo_url, + headers={"Authorization": f"Bearer {token}"}, + timeout=5, + ) + res.raise_for_status() + except requests.RequestException as e: + _logger.warning("Userinfo request failed: %s", e) + return None + + try: + data = res.json() + except ValueError: + _logger.info("Userinfo response is not JSON") + return None + + email = (data.get("email") or "").strip() + return email or None + + @classmethod + def _find_user_by_email(cls, email: str): + user = ( + request.env["res.users"] + .sudo() + .search( + ["|", ("login", "=ilike", email), ("email", "=ilike", email)], + limit=1, + ) + ) + return user if user and user.active else None + + @classmethod + def _force_login(cls, user): + request.update_env(user=user.id) + request.session.uid = user.id + request.session.session_token = security.compute_session_token( + request.session, request.env + ) + + _logger.info("Auto-authenticated user %s via JWT cookie", user.login) diff --git a/auth_autologin_via_jwt_cookie/models/res_config_settings.py b/auth_autologin_via_jwt_cookie/models/res_config_settings.py new file mode 100644 index 0000000000..86a8c86308 --- /dev/null +++ b/auth_autologin_via_jwt_cookie/models/res_config_settings.py @@ -0,0 +1,24 @@ +# Copyright 2025 Kencove (https://www.kencove.com/) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import fields, models + + +class ResConfigSettings(models.TransientModel): + _inherit = "res.config.settings" + + auth_autologin_jwt_cookie_name = fields.Char( + string="JWT Cookie Name", + config_parameter="auth_autologin_via_jwt_cookie.jwt_cookie_name", + help="Name of the shared cookie containing the JWT.", + ) + auth_autologin_jwks_url = fields.Char( + string="JWKS URL", + config_parameter="auth_autologin_via_jwt_cookie.jwks_url", + help="JWKS endpoint used to verify JWT signatures.", + ) + auth_autologin_userinfo_url = fields.Char( + string="Userinfo URL", + config_parameter="auth_autologin_via_jwt_cookie.userinfo_url", + help="Endpoint called with the JWT to retrieve the user email.", + ) diff --git a/auth_autologin_via_jwt_cookie/readme/DESCRIPTION.rst b/auth_autologin_via_jwt_cookie/readme/DESCRIPTION.rst new file mode 100644 index 0000000000..8e0f0cebba --- /dev/null +++ b/auth_autologin_via_jwt_cookie/readme/DESCRIPTION.rst @@ -0,0 +1,2 @@ +This module automatically authenticates Odoo users using a valid JWT found in a shared browser cookie. +If no Odoo session exists, the JWT is verified via a JWKS endpoint, user information is retrieved from a userinfo endpoint, and the matching user is logged in transparently based on email. diff --git a/auth_autologin_via_jwt_cookie/static/description/index.html b/auth_autologin_via_jwt_cookie/static/description/index.html new file mode 100644 index 0000000000..60bc690564 --- /dev/null +++ b/auth_autologin_via_jwt_cookie/static/description/index.html @@ -0,0 +1,417 @@ + + + + + +Auth Autologin via JWT Cookie + + + + + + diff --git a/auth_autologin_via_jwt_cookie/views/res_config_settings_view.xml b/auth_autologin_via_jwt_cookie/views/res_config_settings_view.xml new file mode 100644 index 0000000000..9fc4fbdd26 --- /dev/null +++ b/auth_autologin_via_jwt_cookie/views/res_config_settings_view.xml @@ -0,0 +1,58 @@ + + + + res.config.settings.view.form.auth.autologin.jwt.cookie + res.config.settings + + +
+

JWT Cookie Autologin

+ +
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+ + + diff --git a/setup/auth_autologin_via_jwt_cookie/odoo/addons/auth_autologin_via_jwt_cookie b/setup/auth_autologin_via_jwt_cookie/odoo/addons/auth_autologin_via_jwt_cookie new file mode 120000 index 0000000000..1c4f88a98f --- /dev/null +++ b/setup/auth_autologin_via_jwt_cookie/odoo/addons/auth_autologin_via_jwt_cookie @@ -0,0 +1 @@ +../../../../auth_autologin_via_jwt_cookie \ No newline at end of file diff --git a/setup/auth_autologin_via_jwt_cookie/setup.py b/setup/auth_autologin_via_jwt_cookie/setup.py new file mode 100644 index 0000000000..28c57bb640 --- /dev/null +++ b/setup/auth_autologin_via_jwt_cookie/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) From 690ab35692158444cea9eec9d1c979f329a5bc11 Mon Sep 17 00:00:00 2001 From: chaule97 Date: Tue, 30 Dec 2025 10:52:20 +0700 Subject: [PATCH 4/5] [IMP] auth_autologin_via_jwt_cookie: pre-commit auto fixes --- auth_autologin_via_jwt_cookie/README.rst | 21 +++++++++++-------- auth_autologin_via_jwt_cookie/pyproject.toml | 3 +++ .../readme/DESCRIPTION.md | 5 +++++ .../readme/DESCRIPTION.rst | 2 -- .../static/description/index.html | 13 +++++++----- .../views/res_config_settings_view.xml | 2 +- 6 files changed, 29 insertions(+), 17 deletions(-) create mode 100644 auth_autologin_via_jwt_cookie/pyproject.toml create mode 100644 auth_autologin_via_jwt_cookie/readme/DESCRIPTION.md delete mode 100644 auth_autologin_via_jwt_cookie/readme/DESCRIPTION.rst diff --git a/auth_autologin_via_jwt_cookie/README.rst b/auth_autologin_via_jwt_cookie/README.rst index ac8b5dbb5f..3d2141393b 100644 --- a/auth_autologin_via_jwt_cookie/README.rst +++ b/auth_autologin_via_jwt_cookie/README.rst @@ -17,19 +17,22 @@ Auth Autologin via JWT Cookie :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--auth-lightgray.png?logo=github - :target: https://github.com/OCA/server-auth/tree/16.0/auth_autologin_via_jwt_cookie + :target: https://github.com/OCA/server-auth/tree/18.0/auth_autologin_via_jwt_cookie :alt: OCA/server-auth .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/server-auth-16-0/server-auth-16-0-auth_autologin_via_jwt_cookie + :target: https://translation.odoo-community.org/projects/server-auth-18-0/server-auth-18-0-auth_autologin_via_jwt_cookie :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/server-auth&target_branch=16.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/server-auth&target_branch=18.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| -This module automatically authenticates Odoo users using a valid JWT found in a shared browser cookie. -If no Odoo session exists, the JWT is verified via a JWKS endpoint, user information is retrieved from a userinfo endpoint, and the matching user is logged in transparently based on email. +This module automatically authenticates Odoo users using a valid JWT +found in a shared browser cookie. If no Odoo session exists, the JWT is +verified via a JWKS endpoint, user information is retrieved from a +userinfo endpoint, and the matching user is logged in transparently +based on email. **Table of contents** @@ -42,7 +45,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -50,12 +53,12 @@ Credits ======= Authors -~~~~~~~ +------- * Kencove Maintainers -~~~~~~~~~~~ +----------- This module is maintained by the OCA. @@ -67,6 +70,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -This module is part of the `OCA/server-auth `_ project on GitHub. +This module is part of the `OCA/server-auth `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/auth_autologin_via_jwt_cookie/pyproject.toml b/auth_autologin_via_jwt_cookie/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/auth_autologin_via_jwt_cookie/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/auth_autologin_via_jwt_cookie/readme/DESCRIPTION.md b/auth_autologin_via_jwt_cookie/readme/DESCRIPTION.md new file mode 100644 index 0000000000..cbb8ea9dd5 --- /dev/null +++ b/auth_autologin_via_jwt_cookie/readme/DESCRIPTION.md @@ -0,0 +1,5 @@ +This module automatically authenticates Odoo users using a valid JWT +found in a shared browser cookie. If no Odoo session exists, the JWT is +verified via a JWKS endpoint, user information is retrieved from a +userinfo endpoint, and the matching user is logged in transparently +based on email. diff --git a/auth_autologin_via_jwt_cookie/readme/DESCRIPTION.rst b/auth_autologin_via_jwt_cookie/readme/DESCRIPTION.rst deleted file mode 100644 index 8e0f0cebba..0000000000 --- a/auth_autologin_via_jwt_cookie/readme/DESCRIPTION.rst +++ /dev/null @@ -1,2 +0,0 @@ -This module automatically authenticates Odoo users using a valid JWT found in a shared browser cookie. -If no Odoo session exists, the JWT is verified via a JWKS endpoint, user information is retrieved from a userinfo endpoint, and the matching user is logged in transparently based on email. diff --git a/auth_autologin_via_jwt_cookie/static/description/index.html b/auth_autologin_via_jwt_cookie/static/description/index.html index 60bc690564..cafa99ef38 100644 --- a/auth_autologin_via_jwt_cookie/static/description/index.html +++ b/auth_autologin_via_jwt_cookie/static/description/index.html @@ -369,9 +369,12 @@

Auth Autologin via JWT Cookie

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! source digest: sha256:235b6c7853637cc201cf62eb0b9a6cfa257c77d6199a697f0a09c7be9c3afa8b !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/server-auth Translate me on Weblate Try me on Runboat

-

This module automatically authenticates Odoo users using a valid JWT found in a shared browser cookie. -If no Odoo session exists, the JWT is verified via a JWKS endpoint, user information is retrieved from a userinfo endpoint, and the matching user is logged in transparently based on email.

+

Beta License: AGPL-3 OCA/server-auth Translate me on Weblate Try me on Runboat

+

This module automatically authenticates Odoo users using a valid JWT +found in a shared browser cookie. If no Odoo session exists, the JWT is +verified via a JWKS endpoint, user information is retrieved from a +userinfo endpoint, and the matching user is logged in transparently +based on email.

Table of contents

    @@ -388,7 +391,7 @@

    Bug Tracker

    Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -feedback.

    +feedback.

    Do not contact contributors directly about support or help with technical issues.

@@ -408,7 +411,7 @@

Maintainers

OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use.

-

This module is part of the OCA/server-auth project on GitHub.

+

This module is part of the OCA/server-auth project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

diff --git a/auth_autologin_via_jwt_cookie/views/res_config_settings_view.xml b/auth_autologin_via_jwt_cookie/views/res_config_settings_view.xml index 9fc4fbdd26..5617347397 100644 --- a/auth_autologin_via_jwt_cookie/views/res_config_settings_view.xml +++ b/auth_autologin_via_jwt_cookie/views/res_config_settings_view.xml @@ -46,7 +46,7 @@
From 493330583d7ba0b2e837b91124b0fe118cbc6b1e Mon Sep 17 00:00:00 2001 From: chaule97 Date: Tue, 30 Dec 2025 11:07:42 +0700 Subject: [PATCH 5/5] [MIG] auth_autologin_via_jwt_cookie: Migration to 18.0 --- auth_autologin_via_jwt_cookie/__manifest__.py | 2 +- .../models/ir_http.py | 3 +- .../views/res_config_settings_view.xml | 63 +++++++------------ 3 files changed, 25 insertions(+), 43 deletions(-) diff --git a/auth_autologin_via_jwt_cookie/__manifest__.py b/auth_autologin_via_jwt_cookie/__manifest__.py index 6f0a4f368f..1d5df36cd1 100644 --- a/auth_autologin_via_jwt_cookie/__manifest__.py +++ b/auth_autologin_via_jwt_cookie/__manifest__.py @@ -4,7 +4,7 @@ { "name": "Auth Autologin via JWT Cookie", "summary": "Auto-authenticate users using a shared JWT cookie", - "version": "16.0.1.0.0", + "version": "18.0.1.0.0", "category": "Authentication", "author": "Kencove,Odoo Community Association (OCA)", "website": "https://github.com/OCA/server-auth", diff --git a/auth_autologin_via_jwt_cookie/models/ir_http.py b/auth_autologin_via_jwt_cookie/models/ir_http.py index b32de40abb..8e9682b381 100644 --- a/auth_autologin_via_jwt_cookie/models/ir_http.py +++ b/auth_autologin_via_jwt_cookie/models/ir_http.py @@ -97,7 +97,8 @@ def _get_autologin_settings(cls): if not (cookie_name and jwks_url and userinfo_url): _logger.debug( - "JWT autologin config incomplete: cookie_name=%s, jwks_url=%s, userinfo_url=%s", + "JWT autologin config incomplete: cookie_name=%s, jwks_url=%s, " + "userinfo_url=%s", bool(cookie_name), bool(jwks_url), bool(userinfo_url), diff --git a/auth_autologin_via_jwt_cookie/views/res_config_settings_view.xml b/auth_autologin_via_jwt_cookie/views/res_config_settings_view.xml index 5617347397..99e0c0b875 100644 --- a/auth_autologin_via_jwt_cookie/views/res_config_settings_view.xml +++ b/auth_autologin_via_jwt_cookie/views/res_config_settings_view.xml @@ -10,49 +10,30 @@ res.config.settings -
-

JWT Cookie Autologin

+ + + + + -
-
-
-
-
-
+ + + -
-
-
-
-
- -
-
-
-
-
-
-
+ + + + +