diff --git a/base_debug_restricted/README.rst b/base_debug_restricted/README.rst new file mode 100644 index 000000000..a3977e3df --- /dev/null +++ b/base_debug_restricted/README.rst @@ -0,0 +1,93 @@ +================ +Restricted Debug +================ + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:d51921203310af24e1b7eed7ad5f9d46e918d7f844254488a93dc99fb9b5dd1a + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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-LGPL--3-blue.png + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--backend-lightgray.png?logo=github + :target: https://github.com/OCA/server-backend/tree/18.0/base_debug_restricted + :alt: OCA/server-backend +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/server-backend-18-0/server-backend-18-0-base_debug_restricted + :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-backend&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module restricts the usage of Debug Mode to selected users. + +By default, Debug Mode is even available to public users on the web +part. When enabled and an error is raised, the public user will see a +detailed error page with the traceback and file paths. It discloses +information about the server, which may be avoided. + +After installing this module, only connected users with the "Debug Mode" +role will be able to enable the Debug Mode and see detailed error pages. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +Add the "Debug Mode" group to the users who should have access to Debug +Mode. + +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 +------- + +* QoQa + +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. + +.. |maintainer-guewen| image:: https://github.com/guewen.png?size=40px + :target: https://github.com/guewen + :alt: guewen + +Current `maintainer `__: + +|maintainer-guewen| + +This module is part of the `OCA/server-backend `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/base_debug_restricted/__init__.py b/base_debug_restricted/__init__.py new file mode 100644 index 000000000..0650744f6 --- /dev/null +++ b/base_debug_restricted/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/base_debug_restricted/__manifest__.py b/base_debug_restricted/__manifest__.py new file mode 100644 index 000000000..45130b92d --- /dev/null +++ b/base_debug_restricted/__manifest__.py @@ -0,0 +1,17 @@ +# Copyright 2026 QoQa +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +{ + "name": "Restricted Debug", + "version": "18.0.1.0.0", + "category": "Tools", + "author": "QoQa, Odoo Community Association (OCA)", + "license": "LGPL-3", + "maintainers": ["guewen"], + "website": "https://github.com/OCA/server-backend", + "depends": ["web"], + "data": [ + "data/res_groups.xml", + ], + "installable": True, +} diff --git a/base_debug_restricted/data/res_groups.xml b/base_debug_restricted/data/res_groups.xml new file mode 100644 index 000000000..98170c75e --- /dev/null +++ b/base_debug_restricted/data/res_groups.xml @@ -0,0 +1,11 @@ + + + + Debug Mode + + + + diff --git a/base_debug_restricted/models/__init__.py b/base_debug_restricted/models/__init__.py new file mode 100644 index 000000000..9a5eb7187 --- /dev/null +++ b/base_debug_restricted/models/__init__.py @@ -0,0 +1 @@ +from . import ir_http diff --git a/base_debug_restricted/models/ir_http.py b/base_debug_restricted/models/ir_http.py new file mode 100644 index 000000000..37ba32623 --- /dev/null +++ b/base_debug_restricted/models/ir_http.py @@ -0,0 +1,28 @@ +# Copyright 2026 QoQa +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +from odoo import models +from odoo.http import request + + +class Http(models.AbstractModel): + _inherit = "ir.http" + + @classmethod + def _handle_debug(cls): + if request.httprequest.args.get("debug") is None: + return + + if not cls._debug_mode_allowed_users(): + request.session.debug = "" + return + + return super()._handle_debug() + + @classmethod + def _debug_mode_allowed_users(cls): + if not request.session.uid: + # always disallowed in public + return False + user = request.env["res.users"].browse(request.session.uid) + return user.sudo().has_group("base_debug_restricted.group_debug_mode") diff --git a/base_debug_restricted/pyproject.toml b/base_debug_restricted/pyproject.toml new file mode 100644 index 000000000..4231d0ccc --- /dev/null +++ b/base_debug_restricted/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/base_debug_restricted/readme/DESCRIPTION.md b/base_debug_restricted/readme/DESCRIPTION.md new file mode 100644 index 000000000..b74ea6f27 --- /dev/null +++ b/base_debug_restricted/readme/DESCRIPTION.md @@ -0,0 +1,9 @@ +This module restricts the usage of Debug Mode to selected users. + +By default, Debug Mode is even available to public users on the web part. When +enabled and an error is raised, the public user will see a detailed error page with +the traceback and file paths. It discloses information about the server, which +may be avoided. + +After installing this module, only connected users with the "Debug Mode" role +will be able to enable the Debug Mode and see detailed error pages. diff --git a/base_debug_restricted/readme/USAGE.md b/base_debug_restricted/readme/USAGE.md new file mode 100644 index 000000000..4f3624799 --- /dev/null +++ b/base_debug_restricted/readme/USAGE.md @@ -0,0 +1 @@ +Add the "Debug Mode" group to the users who should have access to Debug Mode. diff --git a/base_debug_restricted/static/description/index.html b/base_debug_restricted/static/description/index.html new file mode 100644 index 000000000..14ced13bd --- /dev/null +++ b/base_debug_restricted/static/description/index.html @@ -0,0 +1,430 @@ + + + + + +Restricted Debug + + + +
+

Restricted Debug

+ + +

Beta License: LGPL-3 OCA/server-backend Translate me on Weblate Try me on Runboat

+

This module restricts the usage of Debug Mode to selected users.

+

By default, Debug Mode is even available to public users on the web +part. When enabled and an error is raised, the public user will see a +detailed error page with the traceback and file paths. It discloses +information about the server, which may be avoided.

+

After installing this module, only connected users with the “Debug Mode” +role will be able to enable the Debug Mode and see detailed error pages.

+

Table of contents

+ +
+

Usage

+

Add the “Debug Mode” group to the users who should have access to Debug +Mode.

+
+
+

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

+
    +
  • QoQa
  • +
+
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

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.

+

Current maintainer:

+

guewen

+

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

+

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

+
+
+
+ + diff --git a/base_debug_restricted/tests/__init__.py b/base_debug_restricted/tests/__init__.py new file mode 100644 index 000000000..2c1a297e0 --- /dev/null +++ b/base_debug_restricted/tests/__init__.py @@ -0,0 +1 @@ +from . import test_ir_http_restricted_debug diff --git a/base_debug_restricted/tests/test_ir_http_restricted_debug.py b/base_debug_restricted/tests/test_ir_http_restricted_debug.py new file mode 100644 index 000000000..d6079140a --- /dev/null +++ b/base_debug_restricted/tests/test_ir_http_restricted_debug.py @@ -0,0 +1,99 @@ +# Copyright 2026 QoQa +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +from odoo import Command +from odoo.tests import tagged +from odoo.tools import mute_logger + +from odoo.addons.web.tests.test_login import TestWebLoginCommon + + +@tagged("-at_install", "post_install") +class TestIrHttpRestrictedDebug(TestWebLoginCommon): + @mute_logger("odoo.http") + def test_debug_mode_restricted_public(self): + """Test that debug mode is forbidden for public users""" + response = self.url_open( + "/web/reset_password?debug=1&self=test", + ) + self.assertEqual(response.status_code, 500) + # details of the traceback should not be shown to public users + self.assertNotIn( + "Traceback (most recent call last)", + response.text, + "Debug mode should be forbidden for public users", + ) + + @mute_logger("odoo.http") + def test_debug_mode_restricted_user(self): + """Test that debug mode is forbidden for users without the group""" + self.login("internal_user", "internal_user") + + response = self.url_open( + "/web/reset_password?debug=1&self=test", + ) + self.assertEqual(response.status_code, 500) + # details of the traceback should not be shown to unallowed users + self.assertNotIn( + "Traceback (most recent call last)", + response.text, + "Debug mode should be forbidden for users without the group", + ) + + @mute_logger("odoo.http") + def test_debug_mode_allowed(self): + """Test that debug mode is allowed for users with the group""" + internal_user = self.env["res.users"].search( + [("login", "=", "internal_user")], limit=1 + ) + internal_user.groups_id = [ + Command.link(self.env.ref("base_debug_restricted.group_debug_mode").id) + ] + + self.login("internal_user", "internal_user") + + response = self.url_open( + "/web/reset_password?debug=1&self=test", + ) + self.assertEqual(response.status_code, 500) + # details of the traceback should be shown to allowed users + self.assertIn( + "Traceback (most recent call last)", + response.text, + "Debug mode should be allowed for users with the group", + ) + + def test_debug_mode_backend_allowed(self): + """Test that debug mode is allowed for users with the group in backend""" + internal_user = self.env["res.users"].search( + [("login", "=", "internal_user")], limit=1 + ) + internal_user.groups_id = [ + Command.link(self.env.ref("base_debug_restricted.group_debug_mode").id) + ] + + self.login("internal_user", "internal_user") + + response = self.url_open( + "/odoo?debug=1", + ) + self.assertEqual(response.status_code, 200) + self.assertIn( + '"debug": "1"', + response.text, + "Debug mode should be allowed for users with the group in backend", + ) + + def test_debug_mode_backend_restricted(self): + """Test that debug mode is forbidden for users without the group in backend""" + self.login("internal_user", "internal_user") + + response = self.url_open( + "/odoo?debug=1", + ) + self.assertEqual(response.status_code, 200) + self.assertNotIn( + '"debug": "1"', + response.text, + "Debug mode should be forbidden for users without the group in backend", + )