Feat v0.9.9 surface access via roles

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-03 19:52:47 +00:00
parent b0e9dd7f80
commit 75dfdb3dcd
9 changed files with 359 additions and 6 deletions

View File

@@ -522,7 +522,7 @@ func (e *Engine) RenderExtensionSurface() gin.HandlerFunc {
}
// ── Access check ─────────────────────────────────────────
if !evaluateAccess(c, surfaceAccess) {
if !e.evaluateAccess(c, surfaceAccess) {
// Redirect unauthenticated users to login; deny others with 403
if c.GetString("user_id") == "" {
c.Redirect(http.StatusTemporaryRedirect, e.cfg.BasePath+"/login")
@@ -651,7 +651,7 @@ func aggregateAccess(surfaces []any) string {
}
// evaluateAccess checks whether the current request meets an access requirement.
func evaluateAccess(c *gin.Context, access string) bool {
func (e *Engine) evaluateAccess(c *gin.Context, access string) bool {
switch {
case access == "public":
return true
@@ -672,6 +672,20 @@ func evaluateAccess(c *gin.Context, access string) bool {
}
}
return false
case strings.HasPrefix(access, "role:"):
role := strings.TrimPrefix(access, "role:")
userID := c.GetString("user_id")
if userID == "" {
return false
}
if c.GetBool("is_admin") {
return true
}
if e.stores.Teams == nil {
return false
}
has, err := e.stores.Teams.HasRoleInAnyTeam(c.Request.Context(), userID, role)
return err == nil && has
default:
return false
}