package handlers import ( "net/http" "sort" "github.com/gin-gonic/gin" "armature/auth" "armature/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) c.JSON(http.StatusOK, gin.H{ "permissions": list, "groups": groupIDs, "teams": teamData, "policies": policies, }) }