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:
2026-04-02 18:20:16 +00:00
parent e02b13dc12
commit f32eefab14
34 changed files with 1769 additions and 58 deletions

View File

@@ -30,10 +30,26 @@ func RequirePermission(perm string, stores store.Stores) gin.HandlerFunc {
}
// resolveAndCachePerms loads the user's effective permissions once per request.
// For PAT-authenticated requests, uses the token's stored permissions directly
// (git model: token retains permissions even if user later loses them).
func resolveAndCachePerms(c *gin.Context, stores store.Stores, userID string) (map[string]bool, error) {
if cached, exists := c.Get(permCacheKey); exists {
return cached.(map[string]bool), nil
}
// PAT path: use token's stored permissions directly
if c.GetString("auth_method") == "pat" {
if patPerms, exists := c.Get("pat_permissions"); exists {
perms := make(map[string]bool)
for _, p := range patPerms.([]string) {
perms[p] = true
}
c.Set(permCacheKey, perms)
return perms, nil
}
}
// JWT path: resolve from groups
perms, err := auth.ResolvePermissions(c.Request.Context(), stores, userID)
if err != nil {
return nil, err