fix: stabilize quick win redirects and task ownership

This commit is contained in:
2026-04-26 12:35:19 +02:00
parent 67d362f1d9
commit b77efa880b
3 changed files with 33 additions and 11 deletions
+22 -5
View File
@@ -113,6 +113,23 @@ def _redirect_with_celebration(target_url: str, points: int | None = None):
return redirect(redirect_url)
def _safe_referrer_target(fallback: str) -> str:
referrer = request.referrer
if not referrer:
return fallback
parts = urlsplit(referrer)
if parts.netloc and parts.netloc != request.host:
return fallback
query = dict(parse_qsl(parts.query, keep_blank_values=True))
query.pop("celebrate_points", None)
target = urlunsplit(("", "", parts.path or fallback, urlencode(query), parts.fragment))
if not target.startswith("/") or len(target) > 1200:
return fallback
return target
@bp.route("/my-tasks")
@login_required
def my_tasks():
@@ -293,7 +310,7 @@ def quick_create():
flash(error, "error")
for error in extra_errors:
flash(error, "error")
return redirect(request.referrer or url_for("tasks.my_tasks"))
return redirect(_safe_referrer_target(url_for("tasks.my_tasks")))
task = create_quick_task(custom_title, form.effort.data, current_user, description="Quick-Win")
complete_task(task, current_user.id)
created_titles.append(task.title)
@@ -301,14 +318,14 @@ def quick_create():
if not created_titles:
flash("Bitte wähle mindestens einen Quick-Win aus.", "error")
return redirect(request.referrer or url_for("tasks.my_tasks"))
return redirect(_safe_referrer_target(url_for("tasks.my_tasks")))
if len(created_titles) == 1:
flash(f"Quick-Win „{created_titles[0]}“ wurde als erledigt gespeichert.", "success")
else:
flash(f"{len(created_titles)} Quick-Wins wurden als erledigt gespeichert.", "success")
return _redirect_with_celebration(
request.referrer or url_for("tasks.my_tasks"),
_safe_referrer_target(url_for("tasks.my_tasks")),
total_points,
)
@@ -360,7 +377,7 @@ def complete(task_id: int):
choice = request.form.get("completed_for", "me")
if task.is_completed:
flash("Diese Aufgabe ist bereits erledigt.", "info")
return redirect(request.referrer or url_for("tasks.my_tasks"))
return redirect(_safe_referrer_target(url_for("tasks.my_tasks")))
completed_by_id = current_user.id
allowed_ids = {current_user.id}
@@ -377,7 +394,7 @@ def complete(task_id: int):
complete_task(task, completed_by_id)
flash("Punkte verbucht. Gute Arbeit.", "success")
return _redirect_with_celebration(
request.referrer or url_for("tasks.my_tasks"),
_safe_referrer_target(url_for("tasks.my_tasks")),
awarded_points,
)
+3 -5
View File
@@ -66,8 +66,6 @@ def update_template_and_instance(task: TaskInstance, form) -> TaskInstance:
template.title = form.title.data.strip()
template.description = (form.description.data or "").strip()
template.default_points = form.default_points.data
template.default_assigned_user_id = form.assigned_user_id.data
template.default_assigned_user_secondary_id = form.assigned_user_secondary_id.data or None
template.recurrence_interval_unit = form.recurrence_interval_unit.data
template.recurrence_interval_value = (
form.recurrence_interval_value.data if form.recurrence_interval_unit.data != "none" else None
@@ -76,9 +74,9 @@ def update_template_and_instance(task: TaskInstance, form) -> TaskInstance:
task.title = template.title
task.description = template.description
task.assigned_user_id = template.default_assigned_user_id
task.assigned_user_secondary_id = template.default_assigned_user_secondary_id
task.points_awarded = effective_points(template.default_points, template.default_assigned_user_secondary_id)
task.assigned_user_id = form.assigned_user_id.data
task.assigned_user_secondary_id = form.assigned_user_secondary_id.data or None
task.points_awarded = effective_points(template.default_points, task.assigned_user_secondary_id)
task.due_date = form.due_date.data
refresh_task_status(task, form.due_date.data)
db.session.commit()
+8 -1
View File
@@ -30,8 +30,15 @@
</div>
<div class="field">
{{ form.assigned_user_id.label }}
{% if mode == 'edit' %}
<label for="{{ form.assigned_user_id.id }}">Zuständig für diese Aufgabe</label>
{% else %}
{{ form.assigned_user_id.label }}
{% endif %}
{{ form.assigned_user_id() }}
{% if mode == 'edit' %}
<small class="muted">Wiederholungen bleiben bei der ursprünglich vorgesehenen Person.</small>
{% endif %}
{% for error in form.assigned_user_id.errors %}<small class="error">{{ error }}</small>{% endfor %}
</div>