Skip to content

Commit 69e8a01

Browse files
committed
[FIX] website_require_login: Login recursion
If one of the parents of /web/login is requested for login, infinite redirection loop starts
1 parent de2885e commit 69e8a01

File tree

2 files changed

+53
-1
lines changed

2 files changed

+53
-1
lines changed

website_require_login/models/ir_http.py

+18-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@ def _serve_fallback(cls):
2424
return res
2525
return super()._serve_fallback()
2626

27+
@classmethod
28+
def _require_login_whitelist_paths(cls):
29+
"""List of paths that must always be available to all users."""
30+
return [
31+
# backend is already protected by login,
32+
# also /web/login, /web/assets, /web/image and others
33+
# are needed to correctly render the login page
34+
"/web",
35+
]
36+
2737
@classmethod
2838
def _require_login_get_matching_path(cls, path, search_paths):
2939
"""Return which one of `search_paths` is a parent of `path`."""
@@ -42,6 +52,14 @@ def _check_require_auth(cls):
4252
website = request.env["website"].sudo().get_current_website()
4353
if not website:
4454
return None
55+
56+
# Skip whitelisted paths
57+
path = request.httprequest.path
58+
whitelist_paths = cls._require_login_whitelist_paths()
59+
whitelist_path = cls._require_login_get_matching_path(path, whitelist_paths)
60+
if whitelist_path:
61+
return None
62+
4563
if request.uid and (request.uid != website.user_id.id):
4664
return None
4765
auth_paths = (
@@ -54,7 +72,6 @@ def _check_require_auth(cls):
5472
)
5573
.mapped("path")
5674
)
57-
path = request.httprequest.path
5875
auth_path = cls._require_login_get_matching_path(path, auth_paths)
5976
if auth_path:
6077
redirect_path = "/web/login?redirect=%s" % path

website_require_login/tests/test_ir_http.py

+35
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Copyright 2024 Simone Rubino - Aion Tech
2+
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0).
3+
14
from odoo.tests import HttpCase
25

36

@@ -35,3 +38,35 @@ def test_dispatch_authorized(self):
3538
200,
3639
"Expected the response status code to be 200 which means no redirection",
3740
)
41+
42+
def test_authorize_everything(self):
43+
"""Requiring "/" for authorization always redirects to login page."""
44+
# Arrange
45+
self.env["website.auth.url"].unlink()
46+
root_path = "/"
47+
self.env["website.auth.url"].create(
48+
{"website_id": self.website.id, "path": root_path}
49+
)
50+
self.env["ir.qweb"]._pregenerate_assets_bundles()
51+
asset_attachment = self.env["ir.attachment"].search(
52+
[
53+
("url", "like", "/web/assets/%"),
54+
],
55+
limit=1,
56+
)
57+
58+
redirection_path_map = {
59+
"/": "/web/login?redirect=/",
60+
"/contactus": "/web/login?redirect=/contactus",
61+
asset_attachment.url: asset_attachment.url,
62+
"/web/login": "/web/login",
63+
}
64+
65+
# Assert
66+
for requested_path, expected_redirected_path in redirection_path_map.items():
67+
response = self.url_open(requested_path)
68+
self.assertEqual(
69+
response.status_code,
70+
200,
71+
)
72+
self.assertTrue(response.url.endswith(expected_redirected_path))

0 commit comments

Comments
 (0)