Revoke the access grant that was actually clicked (fixes #126) #132
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!132
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/revoke-nonmanual-access"
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?
Fixes #126 — "User access cannot be revoked, click on the button does not do anything".
Root cause
The markup and the handler both looked fine, which is why this was hard to spot. The mismatch is between what the page lists and what the store deletes:
ProjectAccessStore.ListByProjectreturns everyproject_accessrow for the project, whatever itssource, and the edit page renders all of them.user_id, andProjectAccessStore.RevokedeletesWHERE project_id = ? AND user_id = ? AND source = 'manual'.So revoking a user whose access came from an LDAP or OAuth2 group mapping deleted zero rows. The POST succeeded, the handler redirected 303, the page reloaded with the row still in the table — indistinguishable from a dead button.
The fix
sourcein a hidden field;handleAdminRevokeAccessrevokes that exact grant via the existingRevokeBySource. A missing field still meansmanual, so nothing that predates the field changes behaviour.database.ValidAccessSource), so the field can't widen into a free-form delete filter.internal/docs/builtin/docs/reference/roles-permissions.mddocuments the grant sources and that revoke/re-sync interaction.Tests
internal/handler/revoke_access_test.godrives the real form POST end to end.TestRevokeRemovesAccessRegardlessOfSourcefails onmainfor theldapandoauth2subtests (still have 1 row(s)) and passes formanual— the reported symptom, reproduced. Also covers source-scoped deletion and rejection of an unknown source. Full suite green.Follow-up found while testing (not in this PR)
On SQLite only, migration
002_auth_groupsnever dropped the originalUNIQUE(project_id, user_id)table constraint —DROP INDEX IF EXISTS idx_project_access_uniqueis a no-op against SQLite'ssqlite_autoindex_project_access_1, which cannot be dropped that way. Postgres and MySQL drop theirs correctly. A separate issue follows; it needs a table-rebuild migration and deserves its own review.Assisted by Claude Opus 5.