Commit Graph

6 Commits

Author SHA1 Message Date
kolaente fc216c38af fix(labels): derive label max permission from accessible tasks only
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.
2026-04-09 15:43:04 +00:00
kolaente e836555032 fix(labels): correct broken access-control query for label reads (GHSA-hj5c-mhh2-g7jq)
hasAccessToLabel built its WHERE clause by chaining xorm session .Where,
.Or, and .And calls. xorm flattened those to `WHERE A OR B OR C AND D`,
which under SQL precedence evaluates as
`A OR B OR (C AND D)` — so the `labels.id = ?` predicate only narrowed
the project-access branch. The standalone
`label_tasks.label_id IS NOT NULL` branch leaked every label with any
label_tasks row to any authenticated user, and the
`labels.created_by_id = ?` branch leaked any label the caller had ever
created regardless of the requested id.

Rewrite the query using explicit builder.And / builder.Or grouping so
the label-id scope wraps the entire disjunction, drop the bogus
label_tasks-is-not-null branch, and keep the creator branch only for
real user auths. Replace Exist(ll) with Get(ll) so the resulting
LabelTask row is populated and the follow-up Task.CanRead check that
computes maxPermission actually runs; fall back to PermissionRead when
the match came via the creator branch and no task row is joined.
2026-04-09 15:43:04 +00:00
kolaente 6673adf0b5
fix(filter): do not show tasks in filter results when they are filtered out by labels
This fixes a bug where tasks which were filtered out by their label would still be shown. That was caused by the way the filter query was translated to sql under the hood.

Resolves https://github.com/go-vikunja/vikunja/issues/394
2025-01-20 14:05:42 +01:00
kolaente 3b00a5c200
fix(test): fixtures 2023-05-24 15:52:32 +02:00
cernst a62b57ac62 feat(caldav): import caldav categories as Labels (#1413)
Resolves #1274

Co-authored-by: ce72 <christoph.ernst72@googlemail.com>
Reviewed-on: https://kolaente.dev/vikunja/api/pulls/1413
Reviewed-by: konrad <k@knt.li>
Co-authored-by: cernst <ce72@noreply.kolaente.de>
Co-committed-by: cernst <ce72@noreply.kolaente.de>
2023-03-02 15:25:26 +00:00
kolaente 73f2d4532d
Make sure all tables are properly pluralized 2021-03-28 20:17:35 +02:00
Renamed from pkg/db/fixtures/label_task.yml (Browse further)