mirror of
https://github.com/go-vikunja/vikunja.git
synced 2026-05-24 12:44:42 +00:00
The previous hasAccessToLabel implementation ran `Get(ll)` against a
label_tasks LEFT JOIN with no ORDER BY, which meant the database was
free to pick any matching row. When a label had multiple attachments,
or when access was granted via the creator branch while the label also
had label_tasks rows pointing at inaccessible tasks, the picked row
could belong to a task the caller could not actually read.
That led to two concrete problems reported on the follow-up review of
GHSA-hj5c-mhh2-g7jq:
1. maxPermission (exposed as the x-max-permission response header)
could be derived from a task the caller has no access to, ending
up as 0 or lower than the caller's real best permission on the
label.
2. Task.CanRead on a dangling/inaccessible task could return an
error and surface as a 500, even though the label itself was
perfectly readable via the creator branch.
Split the logic instead:
* Use `Exist` for the boolean access check, using the same carefully
grouped `And(Eq{labels.id}, Or(accessibleTask, creator))` cond.
* Compute maxPermission by selecting the label_tasks rows whose
task lives in a project the caller can access, then iterating
those tasks with `Task.CanRead` and taking the maximum.
* Fall back to PermissionRead when the access was granted via the
creator branch and no accessible task attachment exists.