diff --git a/addons/http_routing/models/ir_http.py b/addons/http_routing/models/ir_http.py index 9ebec6dca62..ebe37919fee 100644 --- a/addons/http_routing/models/ir_http.py +++ b/addons/http_routing/models/ir_http.py @@ -626,7 +626,12 @@ class IrHttp(models.AbstractModel): code, values = cls._get_exception_code_values(exception) request.cr.rollback() - if code == 500: + if code == 403: + response = cls._serve_fallback() + if response: + cls._post_dispatch(response) + return response + elif code == 500: values = cls._get_values_500_error(request.env, values, exception) try: code, html = cls._get_error_html(request.env, code, values) diff --git a/addons/test_website/tests/test_redirect.py b/addons/test_website/tests/test_redirect.py index 1080530ba0a..39840f9184d 100644 --- a/addons/test_website/tests/test_redirect.py +++ b/addons/test_website/tests/test_redirect.py @@ -172,3 +172,40 @@ class TestRedirect(HttpCase): 'href="/empty_controller_test_redirected?a=a"', r.text, "Redirection should have been applied, and query string should not have been duplicated.", ) + + @mute_logger('odoo.http') # mute 403 warning + def test_04_redirect_301_route_unpublished_record(self): + # 1. Accessing published record: Normal case, expecting 200 + rec1 = self.env['test.model'].create({ + 'name': '301 test record', + 'is_published': True, + }) + url_rec1 = '/test_website/200/' + slug(rec1) + r = self.url_open(url_rec1) + self.assertEqual(r.status_code, 200) + + # 2. Accessing unpublished record: expecting 403 by default + rec1.is_published = False + r = self.url_open(url_rec1) + self.assertEqual(r.status_code, 403) + + # 3. Accessing unpublished record with redirect to a 404: expecting 404 + redirect = self.env['website.rewrite'].create({ + 'name': 'Test 301 Redirect route unpublished record', + 'redirect_type': '301', + 'url_from': url_rec1, + 'url_to': '/404', + }) + r = self.url_open(url_rec1) + self.assertEqual(r.status_code, 404) + + # 4. Accessing unpublished record with redirect to another published + # record: expecting redirect to that record + rec2 = rec1.copy({'is_published': True}) + url_rec2 = '/test_website/200/' + slug(rec2) + redirect.url_to = url_rec2 + r = self.url_open(url_rec1) + self.assertEqual(r.status_code, 200) + self.assertTrue( + r.url.endswith(url_rec2), + "Unpublished record should redirect to published record set in redirect")