fix(auth,restart): capture discarded ExecContext errors in token bumps + Restart #2042

Closed
core-be wants to merge 3 commits from fix/execcontext-error-audit into staging
4 changed files with 21 additions and 18 deletions
@@ -407,15 +407,6 @@ func validateCallerToken(ctx context.Context, c *gin.Context, callerID string) e
// matching (the wsauth errors are typed for the invalid case).
var errInvalidCallerToken = errors.New("missing caller auth token")
// canvasUserMessage holds the extracted user message extracted from an
// A2A canvas request body for broadcasting to other sessions.
type canvasUserMessage struct {
Message string `json:"message,omitempty"`
Parts []map[string]interface{} `json:"parts,omitempty"`
MessageID string `json:"messageId,omitempty"`
Attachments []map[string]interface{} `json:"attachments,omitempty"`
}
// extractCanvasUserMessage parses an A2A JSON-RPC request body and extracts
// the user-authored text and attachments from a canvas-initiated message/send.
// Returns nil when the body is not a canvas user message (empty, malformed,
@@ -150,7 +150,9 @@ func (h *WorkspaceHandler) Restart(c *gin.Context) {
if parsed != "" && parsed != containerRuntime {
log.Printf("Restart: runtime changed in config.yaml %q→%q for %s", containerRuntime, parsed, wsName)
containerRuntime = parsed
db.DB.ExecContext(ctx, `UPDATE workspaces SET runtime = $1 WHERE id = $2`, containerRuntime, id)
if _, err := db.DB.ExecContext(ctx, `UPDATE workspaces SET runtime = $1 WHERE id = $2`, containerRuntime, id); err != nil {
log.Printf("Restart: failed to persist runtime change for %s: %v", id, err)
}
}
break
}
@@ -159,8 +161,10 @@ func (h *WorkspaceHandler) Restart(c *gin.Context) {
}
// Reset to provisioning
db.DB.ExecContext(ctx,
`UPDATE workspaces SET status = $1, url = '', updated_at = now() WHERE id = $2`, models.StatusProvisioning, id)
if _, err := db.DB.ExecContext(ctx,
`UPDATE workspaces SET status = $1, url = '', updated_at = now() WHERE id = $2`, models.StatusProvisioning, id); err != nil {
log.Printf("Restart: failed to reset workspace %s to provisioning: %v", id, err)
}
h.broadcaster.RecordAndBroadcast(ctx, string(events.EventWorkspaceProvisioning), id, map[string]interface{}{
"name": wsName,
"tier": tier,
+5 -2
View File
@@ -24,6 +24,7 @@ import (
"encoding/base64"
"errors"
"fmt"
"log"
"time"
)
@@ -130,8 +131,10 @@ func Validate(ctx context.Context, db *sql.DB, plaintext string) (id, prefix, or
// Best-effort last_used_at bump. Failure here is acceptable — the
// request is already authenticated; we don't want a transient DB
// blip to flip a 200 into a 500.
_, _ = db.ExecContext(ctx,
`UPDATE org_api_tokens SET last_used_at = now() WHERE id = $1`, id)
if _, dbErr := db.ExecContext(ctx,
`UPDATE org_api_tokens SET last_used_at = now() WHERE id = $1`, id); dbErr != nil {
log.Printf("OrgToken: failed to bump last_used_at for %s: %v", id, dbErr)
}
return id, prefix, orgID, nil
}
+9 -4
View File
@@ -19,6 +19,7 @@ import (
"encoding/base64"
"errors"
"fmt"
"log"
"strings"
)
@@ -124,8 +125,10 @@ func ValidateToken(ctx context.Context, db *sql.DB, expectedWorkspaceID, plainte
// Best-effort last_used_at update. A failure here (DB hiccup, etc.)
// must not cause an otherwise-valid request to 401.
_, _ = db.ExecContext(ctx,
`UPDATE workspace_auth_tokens SET last_used_at = now() WHERE id = $1`, tokenID)
if _, dbErr := db.ExecContext(ctx,
`UPDATE workspace_auth_tokens SET last_used_at = now() WHERE id = $1`, tokenID); dbErr != nil {
log.Printf("WSAuth: failed to bump last_used_at for token %s: %v", tokenID, dbErr)
}
return nil
}
@@ -250,7 +253,9 @@ func ValidateAnyToken(ctx context.Context, db *sql.DB, plaintext string) error {
}
// Best-effort last_used_at update.
_, _ = db.ExecContext(ctx,
`UPDATE workspace_auth_tokens SET last_used_at = now() WHERE id = $1`, tokenID)
if _, dbErr := db.ExecContext(ctx,
`UPDATE workspace_auth_tokens SET last_used_at = now() WHERE id = $1`, tokenID); dbErr != nil {
log.Printf("WSAuth: failed to bump last_used_at for token %s: %v", tokenID, dbErr)
}
return nil
}