fix: stabilize quick win redirects and task ownership
This commit is contained in:
+22
-5
@@ -113,6 +113,23 @@ def _redirect_with_celebration(target_url: str, points: int | None = None):
|
|||||||
return redirect(redirect_url)
|
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")
|
@bp.route("/my-tasks")
|
||||||
@login_required
|
@login_required
|
||||||
def my_tasks():
|
def my_tasks():
|
||||||
@@ -293,7 +310,7 @@ def quick_create():
|
|||||||
flash(error, "error")
|
flash(error, "error")
|
||||||
for error in extra_errors:
|
for error in extra_errors:
|
||||||
flash(error, "error")
|
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")
|
task = create_quick_task(custom_title, form.effort.data, current_user, description="Quick-Win")
|
||||||
complete_task(task, current_user.id)
|
complete_task(task, current_user.id)
|
||||||
created_titles.append(task.title)
|
created_titles.append(task.title)
|
||||||
@@ -301,14 +318,14 @@ def quick_create():
|
|||||||
|
|
||||||
if not created_titles:
|
if not created_titles:
|
||||||
flash("Bitte wähle mindestens einen Quick-Win aus.", "error")
|
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:
|
if len(created_titles) == 1:
|
||||||
flash(f"Quick-Win „{created_titles[0]}“ wurde als erledigt gespeichert.", "success")
|
flash(f"Quick-Win „{created_titles[0]}“ wurde als erledigt gespeichert.", "success")
|
||||||
else:
|
else:
|
||||||
flash(f"{len(created_titles)} Quick-Wins wurden als erledigt gespeichert.", "success")
|
flash(f"{len(created_titles)} Quick-Wins wurden als erledigt gespeichert.", "success")
|
||||||
return _redirect_with_celebration(
|
return _redirect_with_celebration(
|
||||||
request.referrer or url_for("tasks.my_tasks"),
|
_safe_referrer_target(url_for("tasks.my_tasks")),
|
||||||
total_points,
|
total_points,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -360,7 +377,7 @@ def complete(task_id: int):
|
|||||||
choice = request.form.get("completed_for", "me")
|
choice = request.form.get("completed_for", "me")
|
||||||
if task.is_completed:
|
if task.is_completed:
|
||||||
flash("Diese Aufgabe ist bereits erledigt.", "info")
|
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
|
completed_by_id = current_user.id
|
||||||
allowed_ids = {current_user.id}
|
allowed_ids = {current_user.id}
|
||||||
@@ -377,7 +394,7 @@ def complete(task_id: int):
|
|||||||
complete_task(task, completed_by_id)
|
complete_task(task, completed_by_id)
|
||||||
flash("Punkte verbucht. Gute Arbeit.", "success")
|
flash("Punkte verbucht. Gute Arbeit.", "success")
|
||||||
return _redirect_with_celebration(
|
return _redirect_with_celebration(
|
||||||
request.referrer or url_for("tasks.my_tasks"),
|
_safe_referrer_target(url_for("tasks.my_tasks")),
|
||||||
awarded_points,
|
awarded_points,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -66,8 +66,6 @@ def update_template_and_instance(task: TaskInstance, form) -> TaskInstance:
|
|||||||
template.title = form.title.data.strip()
|
template.title = form.title.data.strip()
|
||||||
template.description = (form.description.data or "").strip()
|
template.description = (form.description.data or "").strip()
|
||||||
template.default_points = form.default_points.data
|
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_unit = form.recurrence_interval_unit.data
|
||||||
template.recurrence_interval_value = (
|
template.recurrence_interval_value = (
|
||||||
form.recurrence_interval_value.data if form.recurrence_interval_unit.data != "none" else None
|
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.title = template.title
|
||||||
task.description = template.description
|
task.description = template.description
|
||||||
task.assigned_user_id = template.default_assigned_user_id
|
task.assigned_user_id = form.assigned_user_id.data
|
||||||
task.assigned_user_secondary_id = template.default_assigned_user_secondary_id
|
task.assigned_user_secondary_id = form.assigned_user_secondary_id.data or None
|
||||||
task.points_awarded = effective_points(template.default_points, template.default_assigned_user_secondary_id)
|
task.points_awarded = effective_points(template.default_points, task.assigned_user_secondary_id)
|
||||||
task.due_date = form.due_date.data
|
task.due_date = form.due_date.data
|
||||||
refresh_task_status(task, form.due_date.data)
|
refresh_task_status(task, form.due_date.data)
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|||||||
@@ -30,8 +30,15 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field">
|
||||||
|
{% if mode == 'edit' %}
|
||||||
|
<label for="{{ form.assigned_user_id.id }}">Zuständig für diese Aufgabe</label>
|
||||||
|
{% else %}
|
||||||
{{ form.assigned_user_id.label }}
|
{{ form.assigned_user_id.label }}
|
||||||
|
{% endif %}
|
||||||
{{ form.assigned_user_id() }}
|
{{ 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 %}
|
{% for error in form.assigned_user_id.errors %}<small class="error">{{ error }}</small>{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user