Resolve named access lists in the access checker (#125) #137
No reviewers
Labels
No labels
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
qwc-open/asiakirjat!137
Loading…
Reference in a new issue
No description provided.
Delete branch "feature/access-list-resolution"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Second of the #125 series. Stacked on #136 — the base branch is
feature/named-access-lists, so this diff shows only the resolution work. Merge #136 first and this retargets tomaincleanly.How a list admits someone
Two routes in, mirroring the split
global_accessalready uses:userldap_group/oauth2_groupaccess_list_grants, written at loginThe stronger of the two wins if someone is admitted both ways. Migration 013 adds
access_list_grants(unique per list + user + source), which the login sync will populate in the next PR.I checked whether group membership could be resolved at check time instead, which would avoid the table entirely — it can't:
usersstores no group columns, andmemberOfis computed during LDAP bind and discarded. So the grant table is the same compromise #135 landed on, not a new mechanism.Fail-closed cases
visibility = 'list'with no list pointer admits nobody (admins excepted, as everywhere). The list is the only thing that could let anyone in, so a missing pointer is not a reason to fall back to something broader.TestListProjectWithoutListFailsClosedpins it.privatebehaves — naming someone on the project itself is more specific than the list, never less.Drift protection
CanView,CanUploadandFilterAccessibleall resolve through the sameRolesForUserlookup.TestFilterAccessibleIncludesListProjectsasserts the list view and the per-project check agree on the same two projects — that drift is the bug this package was extracted to prevent, so it seemed worth a test rather than a convention.FilterAccessibledoes one lookup for all of a user's lists, not one per project, so long project lists don't get slower.Visibility validation
Moved into
projects.ValidateVisibility(visibility, accessListID, creator)so the HTTP layer can apply the same rule in the next PR instead of re-deriving it —admin.go:236currently has its own copy of the three-literal check.listvisibility requires a list id; public stays admin-only; unknown values are still rejected.Tests
internal/access/access_list_test.gocovers the issue's shape directly — a list holding an LDAP group plus two named users with different roles — plus grant-based admission and revocation when the grant is dropped, the fail-closed orphan, and the filter/check agreement.internal/projects/service_test.gocovers the validation rule.Full suite green.
Still to come
Step 3 — LDAP/OAuth2 login sync writes and revokes list grants, so the group half of a list actually fills in.
Step 4 — admin UI for managing lists and members, the visibility picker, and docs.
Until step 4,
visibility = 'list'still can't be set through the UI, so merging this changes no behaviour on its own.Assisted by Claude Opus 5.