Skip to content

Commit

Permalink
[FIX] website_require_login: Login recursion
Browse files Browse the repository at this point in the history
If one of the parents of /web/login is requested for login, infinite redirection loop starts
  • Loading branch information
SirAionTech committed Jun 11, 2024
1 parent de2885e commit 28581b8
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
20 changes: 19 additions & 1 deletion website_require_login/models/ir_http.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ def _serve_fallback(cls):
return res
return super()._serve_fallback()

@classmethod
def _require_login_whitelist_paths(cls):
"""List of paths that must always be available to all users."""
return [
# backend is already protected by login,
# also /web/login, /web/assets, /web/image and others
# are needed to correctly render the login page
"/web",
"/website/translations",
]

@classmethod
def _require_login_get_matching_path(cls, path, search_paths):
"""Return which one of `search_paths` is a parent of `path`."""
Expand All @@ -42,6 +53,14 @@ def _check_require_auth(cls):
website = request.env["website"].sudo().get_current_website()
if not website:
return None

# Skip whitelisted paths
path = request.httprequest.path
whitelist_paths = cls._require_login_whitelist_paths()
whitelist_path = cls._require_login_get_matching_path(path, whitelist_paths)
if whitelist_path:
return None

if request.uid and (request.uid != website.user_id.id):
return None
auth_paths = (
Expand All @@ -54,7 +73,6 @@ def _check_require_auth(cls):
)
.mapped("path")
)
path = request.httprequest.path
auth_path = cls._require_login_get_matching_path(path, auth_paths)
if auth_path:
redirect_path = "/web/login?redirect=%s" % path
Expand Down
35 changes: 35 additions & 0 deletions website_require_login/tests/test_ir_http.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright 2024 Simone Rubino - Aion Tech
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0).

from odoo.tests import HttpCase


Expand Down Expand Up @@ -35,3 +38,35 @@ def test_dispatch_authorized(self):
200,
"Expected the response status code to be 200 which means no redirection",
)

def test_authorize_everything(self):
"""Requiring "/" for authorization always redirects to login page."""
# Arrange
self.env["website.auth.url"].unlink()
root_path = "/"
self.env["website.auth.url"].create(
{"website_id": self.website.id, "path": root_path}
)
self.env["ir.qweb"]._pregenerate_assets_bundles()
asset_attachment = self.env["ir.attachment"].search(
[
("url", "like", "/web/assets/%"),
],
limit=1,
)

redirection_path_map = {
"/": "/web/login?redirect=/",
"/contactus": "/web/login?redirect=/contactus",
asset_attachment.url: asset_attachment.url,
"/web/login": "/web/login",
}

# Assert
for requested_path, expected_redirected_path in redirection_path_map.items():
response = self.url_open(requested_path)
self.assertEqual(
response.status_code,
200,
)
self.assertTrue(response.url.endswith(expected_redirected_path))

0 comments on commit 28581b8

Please sign in to comment.