From c3b5381c4c2084cd072d40e2f5079aaeaee27a3c Mon Sep 17 00:00:00 2001 From: James Date: Sat, 7 Feb 2026 18:24:27 -0500 Subject: [PATCH] fix: add backward compatibility for old dossier_access table RBAC editor was failing with 403 Forbidden when trying to edit permissions for users who have access via the old dossier_access table but not the new access grants table. Added fallback logic to CanManageDossier and CanAccessDossier: 1. Check new RBAC system (access table) first 2. If no grant found, check old dossier_access table 3. For manage: check can_edit = 1 4. For access: check status = 1 This allows existing access relationships to work with the new RBAC editor while we migrate data from old to new system. Fixes: "Forbidden" error when editing permissions for legacy access grants Co-Authored-By: Claude Sonnet 4.5 --- lib/access.go | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/lib/access.go b/lib/access.go index 77b4a85..66ff8b5 100644 --- a/lib/access.go +++ b/lib/access.go @@ -329,13 +329,43 @@ func EnsureCategoryEntry(dossierID string, category int) (string, error) { } // CanAccessDossier returns true if accessor can read dossier (for quick checks) +// Falls back to old dossier_access for backward compatibility func CanAccessDossier(accessorID, dossierID string) bool { - return CheckAccess(accessorID, dossierID, "", 'r') == nil + // Check new RBAC system first + if CheckAccess(accessorID, dossierID, "", 'r') == nil { + return true + } + + // Fallback: check old dossier_access table + var result []struct { + Status int `db:"status"` + } + err := Query( + "SELECT status FROM dossier_access WHERE accessor_dossier_id = ? AND target_dossier_id = ? AND status = 1", + []any{accessorID, dossierID}, + &result, + ) + return err == nil && len(result) > 0 && result[0].Status == 1 } // CanManageDossier returns true if accessor can manage permissions for dossier +// Falls back to old dossier_access.can_edit for backward compatibility func CanManageDossier(accessorID, dossierID string) bool { - return CheckAccess(accessorID, dossierID, "", 'm') == nil + // Check new RBAC system first + if CheckAccess(accessorID, dossierID, "", 'm') == nil { + return true + } + + // Fallback: check old dossier_access table + var result []struct { + CanEdit int `db:"can_edit"` + } + err := Query( + "SELECT can_edit FROM dossier_access WHERE accessor_dossier_id = ? AND target_dossier_id = ? AND status = 1", + []any{accessorID, dossierID}, + &result, + ) + return err == nil && len(result) > 0 && result[0].CanEdit == 1 } // GrantAccess creates an access grant