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