patx/gitman
fix star/unstar redirect
Commit 003ab59 · patx · 2026-05-10T21:17:26Z
Comments
No comments yet.
Diff
diff --git a/app.py b/app.py
index 50c1e77..01bcaa2 100644
--- a/app.py
+++ b/app.py
@@ -904,6 +904,8 @@ def render(template_name, **context):
context.setdefault("render_repo_description", render_repo_description)
context.setdefault("format_ref_label", format_ref_label)
context.setdefault("url_with_ref", url_with_ref)
+ context.setdefault("login_url", login_url)
+ context.setdefault("current_url", current_url)
context.setdefault("current_url_with_ref", current_url_with_ref)
context.setdefault("current_url_with_page", current_url_with_page)
context.setdefault("current_url_with_params", current_url_with_params)
@@ -935,10 +937,18 @@ def require_login():
redirect("/login?next=" + quote(next_url, safe="/?=&"))
-def safe_next_url(value):
+def safe_next_url(value, default="/"):
if value and value.startswith("/") and not value.startswith("//"):
return value
- return "/"
+ return default
+
+
+def current_url():
+ return request.path + (f"?{request.query_string}" if request.query_string else "")
+
+
+def login_url(next_url=None):
+ return "/login?" + urlencode({"next": safe_next_url(next_url or current_url())})
def parse_bounded_int(value, default, minimum=1, maximum=None):
@@ -4758,7 +4768,7 @@ def repo_star(owner, repo_name):
unstar_repo(user, repo)
else:
star_repo(user, repo)
- redirect(f"/{owner}/{repo_name}")
+ redirect(safe_next_url(request.forms.get("next"), f"/{owner}/{repo_name}"))
@app.route("/<owner>/<repo_name>/fork", method=["GET", "POST"])
diff --git a/templates/repo_nav.tpl b/templates/repo_nav.tpl
index b4946fd..640cf05 100644
--- a/templates/repo_nav.tpl
+++ b/templates/repo_nav.tpl
@@ -9,6 +9,7 @@
% if user:
<form class="inline-form" method="post" action="/{{repo['owner_username']}}/{{repo['name']}}/star">
{{!csrf_field()}}
+ <input type="hidden" name="next" value="{{current_url()}}">
% if is_starred:
<input type="hidden" name="action" value="unstar">
<button class="button-link" type="submit">Unstar ({{star_count}})</button>
@@ -18,7 +19,7 @@
% end
</form>
% else:
- <a class="button-link" href="/login?next=/{{repo['owner_username']}}/{{repo['name']}}">Star ({{star_count}})</a>
+ <a class="button-link" href="{{login_url(current_url())}}">Star ({{star_count}})</a>
% end
% if user and not is_owner and not has_fork:
<form class="inline-form" method="post" action="/{{repo['owner_username']}}/{{repo['name']}}/fork">
diff --git a/tests/test_app.py b/tests/test_app.py
index e8864d1..982fbfa 100644
--- a/tests/test_app.py
+++ b/tests/test_app.py
@@ -2161,11 +2161,27 @@ def test_bottle_profile_star_fork_and_repo_settings_flows(isolated_app):
create_repo_with_refs(owner)
bob_client = WsgiClient(isolated_app.app)
+ source_url = "/alice/demo/src?ref_type=branch&ref=feature"
+ guest_source_response = bob_client.get(source_url)
+ assert guest_source_response.status_code == 200
+ expected_login_href = (
+ 'href="/login?next=%2Falice%2Fdemo%2Fsrc%3Fref_type%3Dbranch%26ref%3Dfeature"'
+ )
+ assert expected_login_href in guest_source_response.text
+
response = login_client(bob_client, "bob")
assert response.status_code == 303
- response = bob_client.post("/alice/demo/star", {"action": "star"})
+ source_response = bob_client.get(source_url)
+ assert source_response.status_code == 200
+ assert 'name="next" value="/alice/demo/src?ref_type=branch&ref=feature"' in source_response.text
+
+ response = bob_client.post(
+ "/alice/demo/star",
+ {"action": "star", "next": "/alice/demo/src?ref_type=branch&ref=feature"},
+ )
assert response.status_code == 303
+ assert response.location_path == "/alice/demo/src?ref_type=branch&ref=feature"
assert isolated_app.repo_star_count(isolated_app.get_repo("alice", "demo")["id"]) == 1
response = bob_client.post("/alice/demo/fork", {"name": "demo", "description": "Forked"})