This repository has been archived on 2026-04-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
core/server/handlers/profile_permissions.go
Jeffrey Smith 64890bf12f
Some checks failed
CI/CD / detect-changes (pull_request) Successful in 4s
CI/CD / test-frontend (pull_request) Failing after 5s
CI/CD / test-go-pg (pull_request) Failing after 2m37s
CI/CD / test-sqlite (pull_request) Successful in 2m51s
CI/CD / build-and-deploy (pull_request) Has been skipped
Feat v0.2.6 admin settings audit (#10)
Roadmap reorder: Extension Lifecycle moved to v0.3.x, settings audit
milestones renumbered (v0.2.7→v0.2.6, v0.2.8→v0.2.7, v0.2.9→v0.2.8).
Added v0.2.9 for builtin extension retirement — 6 chat-centric
extensions (csv-table, diff-viewer, js-sandbox, katex, mermaid, regex)
are dormant until a chat surface ships; roadmap tracks converting them
to regular packages and removing the auto-seed mechanism.

Admin settings E2E verified — all 7 sections (default surface,
registration, banner, message bar, footer, vault, email) render and
save correctly. Packages surface verified (17/17 loaded).

Dead code removed:
- sectionCategory(): AI/routing/channel cases, default→system
- PublicSettings(): system_prompt, retention_ttl, paste_to_file,
  allow_user_personas
- PolicyDefaults: allow_raw_model_access, default_model
- Profile handlers: allow_raw_model_access, kb_direct_access lookups
- Test seeds: model_roles setting, allow_raw_model_access policy
- packages.js: 'chat' from CORE_IDS

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 15:03:10 +00:00

79 lines
1.9 KiB
Go

package handlers
import (
"net/http"
"sort"
"github.com/gin-gonic/gin"
"switchboard-core/auth"
"switchboard-core/store"
)
// ProfilePermissionsHandler exposes the current user's resolved permissions.
type ProfilePermissionsHandler struct {
stores store.Stores
}
func NewProfilePermissionsHandler(s store.Stores) *ProfilePermissionsHandler {
return &ProfilePermissionsHandler{stores: s}
}
// GetMyPermissions returns the current user's effective permission set.
// GET /api/v1/profile/permissions
func (h *ProfilePermissionsHandler) GetMyPermissions(c *gin.Context) {
userID := getUserID(c)
role, _ := c.Get("role")
ctx := c.Request.Context()
// Admin gets all permissions by definition.
var list []string
if role == "admin" {
list = make([]string, len(auth.AllPermissions))
copy(list, auth.AllPermissions)
} else {
perms, err := auth.ResolvePermissions(ctx, h.stores, userID)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed to resolve permissions"})
return
}
list = make([]string, 0, len(perms))
for p := range perms {
list = append(list, p)
}
}
sort.Strings(list)
// Contributing groups
groupIDs, _ := h.stores.Groups.GetUserGroupIDs(ctx, userID)
if groupIDs == nil {
groupIDs = []string{}
}
groupIDs = append(groupIDs, auth.EveryoneGroupID)
// Teams
teams, _ := h.stores.Teams.ListForUser(ctx, userID)
teamData := make([]gin.H, 0, len(teams))
for _, t := range teams {
teamData = append(teamData, gin.H{
"id": t.ID,
"name": t.Name,
"my_role": t.MyRole,
})
}
// Policies that affect UI gating
policies := make(map[string]bool)
if ps := h.stores.Policies; ps != nil {
policies["allow_user_byok"], _ = ps.GetBool(ctx, "allow_user_byok")
policies["allow_user_personas"], _ = ps.GetBool(ctx, "allow_user_personas")
}
c.JSON(http.StatusOK, gin.H{
"permissions": list,
"groups": groupIDs,
"teams": teamData,
"policies": policies,
})
}