refactor: enforce RBAC only in lib layer

- Remove API-level access checks (requireDossierAccess)
- Pass user context to lib functions instead of system context
- Single enforcement point: lib.EntryList/EntryGet/etc check access
- Fixes EnsureCategoryEntry to use EntryWrite (correct function name)

All access control now happens at the lowest level in lib.
API and MCP layers just pass context through.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
James 2026-02-07 17:05:05 -05:00
parent 8ccab9581d
commit d5be120058
2 changed files with 9 additions and 15 deletions

View File

@ -40,13 +40,7 @@ func handleGenomeQuery(w http.ResponseWriter, r *http.Request) {
return
}
// RBAC: TEMPORARILY DISABLED FOR DEBUGGING
// if !requireDossierAccess(w, ctx, dossierID) {
// return
// }
// Use system context for genome queries (dossier access already checked)
sysCtx := &lib.AccessContext{IsSystem: true}
// RBAC enforced in lib layer - no checks here
category := r.URL.Query().Get("category")
search := r.URL.Query().Get("search")
@ -87,28 +81,28 @@ func handleGenomeQuery(w http.ResponseWriter, r *http.Request) {
}
}
// Find extraction entry
extraction, err := lib.GenomeGetExtraction(sysCtx, dossierID)
// Find extraction entry (RBAC enforced in lib)
extraction, err := lib.GenomeGetExtraction(ctx, dossierID)
if err != nil {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]string{"error": "no genome data for this dossier"})
return
}
// Get tiers to query
// Get tiers to query (RBAC enforced in lib)
var tiers []lib.GenomeTier
tierCategories := make(map[string]string) // tierID -> category name
if category != "" {
// Specific category requested
tier, err := lib.GenomeGetTierByCategory(sysCtx, dossierID, extraction.EntryID, category)
tier, err := lib.GenomeGetTierByCategory(ctx, dossierID, extraction.EntryID, category)
if err == nil {
tiers = append(tiers, *tier)
tierCategories[tier.TierID] = tier.Category
}
} else {
// All tiers
tiers, _ = lib.GenomeGetTiers(sysCtx, dossierID, extraction.EntryID)
tiers, _ = lib.GenomeGetTiers(ctx, dossierID, extraction.EntryID)
for _, t := range tiers {
tierCategories[t.TierID] = t.Category
}
@ -126,8 +120,8 @@ func handleGenomeQuery(w http.ResponseWriter, r *http.Request) {
tierIDs[i] = t.TierID
}
// Query variants
variants, err := lib.GenomeGetVariants(sysCtx, dossierID, tierIDs)
// Query variants (RBAC enforced in lib)
variants, err := lib.GenomeGetVariants(ctx, dossierID, tierIDs)
if err != nil {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(GenomeResponse{Matches: []GenomeMatch{}, Returned: 0, Total: 0})

View File

@ -333,7 +333,7 @@ func EnsureCategoryEntry(dossierID string, category int) (string, error) {
Value: CategoryName(category),
ParentID: "", // Categories are root-level
}
if err := EntrySave(SystemContext, entry); err != nil {
if err := EntryWrite(SystemContext, entry); err != nil {
return "", err
}
return entry.EntryID, nil