diff --git a/DjangoPlugin/tracdjangoplugin/plugins.py b/DjangoPlugin/tracdjangoplugin/plugins.py index 17bdab4..94992f2 100644 --- a/DjangoPlugin/tracdjangoplugin/plugins.py +++ b/DjangoPlugin/tracdjangoplugin/plugins.py @@ -121,9 +121,14 @@ def process_request(self, req): raise RequestDone def do_get(self, req): + # Not 100% sure why, but for some links (RSS especially) Trac likes + # to generate URLs pointing to `/login?referer=` when + # the user is already authenticated. + if req.is_authenticated: + req.redirect(self._get_safe_redirect_url(req)) return "plainlogin.html", { "form": AuthenticationForm(), - "next": req.args.get("next", ""), + "referer": req.args.get("referer", ""), } def do_post(self, req): @@ -132,11 +137,11 @@ def do_post(self, req): req.environ["REMOTE_USER"] = form.get_user().username LoginModule(self.compmgr)._do_login(req) req.redirect(self._get_safe_redirect_url(req)) - return "plainlogin.html", {"form": form, "next": req.args.get("next", "")} + return "plainlogin.html", {"form": form, "referer": req.args.get("referer", "")} def _get_safe_redirect_url(self, req): host = urlparse(req.base_url).hostname - redirect_url = iri_to_uri(req.args.get("next", "")) + redirect_url = iri_to_uri(req.args.get("referer", "")) if not redirect_url: redirect_url = settings.LOGIN_REDIRECT_URL diff --git a/DjangoPlugin/tracdjangoplugin/tests.py b/DjangoPlugin/tracdjangoplugin/tests.py index 7b7eb43..e10cec3 100644 --- a/DjangoPlugin/tracdjangoplugin/tests.py +++ b/DjangoPlugin/tracdjangoplugin/tests.py @@ -73,7 +73,7 @@ def test_login_valid_with_custom_redirection(self): username="test", password="test", check_redirect="/test", - extra_data={"next": "/test"}, + extra_data={"referer": "/test"}, ) def test_login_valid_with_custom_redirection_with_hostname(self): @@ -83,7 +83,7 @@ def test_login_valid_with_custom_redirection_with_hostname(self): username="test", password="test", check_redirect="http://localhost/test", - extra_data={"next": "http://localhost/test"}, + extra_data={"referer": "http://localhost/test"}, ) def test_login_valid_with_malicious_redirection(self): @@ -108,7 +108,7 @@ def test_login_valid_with_malicious_redirection(self): username="test", password="test", check_redirect="http://localhost/test", - extra_data={"next": redirect_url}, + extra_data={"referer": redirect_url}, ) def assertLoginFails(self, username, password, error_message=None): @@ -149,6 +149,20 @@ def test_login_invalid_inactive_user(self): User.objects.create_user(username="test", password="test", is_active=False) self.assertLoginFails(username="test", password="test") + def test_login_page_redirects_if_already_logged_in(self): + self.env.config.set("trac", "base_url", "") + request = self.request_factory( + method="GET", + path_info="/login", + args={"referer": "/test"}, + authname="admin", + ) + + with self.assertRaises(RequestDone): + self.component.process_request(request) + + self.assertEqual(request.headers_sent["Location"], "/test") + class DjangoDBManagementMiddlewareTestCase(SimpleTestCase): @classmethod diff --git a/trac-env/templates/django_theme.html b/trac-env/templates/django_theme.html index 8aeb8af..31c5a16 100644 --- a/trac-env/templates/django_theme.html +++ b/trac-env/templates/django_theme.html @@ -28,7 +28,7 @@ # else -
  • Login
  • +
  • Login
  • # endif
  • Preferences
  • diff --git a/trac-env/templates/plainlogin.html b/trac-env/templates/plainlogin.html index c3c84c7..e629be7 100644 --- a/trac-env/templates/plainlogin.html +++ b/trac-env/templates/plainlogin.html @@ -25,7 +25,7 @@

    Log in with your DjangoProject account

    {# Trac's CSRF protection #} - +