Feat v0.7.7 API tokens + extension permissions (#61)
Personal access tokens (PATs) for programmatic API access with SHA-256 hashing, permission scoping (git model), and Settings/Admin UI. Extension-declared user permissions with dynamic registry, gate_permission manifest field, permissions Starlark module, and grouped admin UI. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"armature/auth"
|
||||
"armature/models"
|
||||
"armature/store"
|
||||
)
|
||||
@@ -167,6 +170,28 @@ func (h *ExtPermHandler) maybeSuspend(c *gin.Context, pkgID string) {
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterAllExtensionUserPermissions scans all active packages and registers
|
||||
// their user_permissions in the dynamic permission registry. Called at boot.
|
||||
func RegisterAllExtensionUserPermissions(stores store.Stores) {
|
||||
ctx := context.Background()
|
||||
pkgs, err := stores.Packages.List(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
count := 0
|
||||
for _, pkg := range pkgs {
|
||||
if pkg.Manifest != nil {
|
||||
SyncUserPermissions(pkg.Manifest, pkg.ID)
|
||||
if _, ok := pkg.Manifest["user_permissions"]; ok {
|
||||
count++
|
||||
}
|
||||
}
|
||||
}
|
||||
if count > 0 {
|
||||
log.Printf(" ✅ Registered user permissions from %d package(s)", count)
|
||||
}
|
||||
}
|
||||
|
||||
// ── Manifest Permission Parsing ──────────────
|
||||
|
||||
// SyncManifestPermissions extracts the "permissions" array from a
|
||||
@@ -208,5 +233,31 @@ func SyncManifestPermissions(c *gin.Context, stores store.Stores, pkgID string,
|
||||
// Package needs review before activation
|
||||
_ = stores.Packages.SetStatus(c.Request.Context(), pkgID, models.PackageStatusPendingReview)
|
||||
|
||||
// Register user-facing permissions in the dynamic permission registry
|
||||
SyncUserPermissions(manifest, pkgID)
|
||||
|
||||
return perms
|
||||
}
|
||||
|
||||
// SyncUserPermissions registers extension-declared user permissions in the
|
||||
// kernel's dynamic permission registry. Called on install and at boot.
|
||||
func SyncUserPermissions(manifest map[string]any, pkgID string) {
|
||||
raw, ok := manifest["user_permissions"]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
arr, ok := raw.([]any)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
var userPerms []string
|
||||
for _, v := range arr {
|
||||
if s, ok := v.(string); ok && s != "" {
|
||||
userPerms = append(userPerms, s)
|
||||
}
|
||||
}
|
||||
if len(userPerms) > 0 {
|
||||
auth.RegisterExtensionPermissions(pkgID, userPerms)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user