Pulse/internal/api/api_token_owner_identity_integration_test.go
2026-03-18 16:06:30 +00:00

75 lines
2.2 KiB
Go

package api
import (
"context"
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"testing"
"github.com/rcourtman/pulse-go-rewrite/internal/config"
"github.com/rcourtman/pulse-go-rewrite/pkg/auth"
)
func TestOwnerBoundAPITokenInheritsBoundUserRBACPrincipal(t *testing.T) {
prevAuthorizer := auth.GetAuthorizer()
auth.SetAuthorizer(&mockAuthorizerFn{
fn: func(ctx context.Context, action string, resource string) (bool, error) {
return auth.GetUser(ctx) == "alice" && action == auth.ActionAdmin && resource == auth.ResourceUsers, nil
},
})
defer auth.SetAuthorizer(prevAuthorizer)
ownerBound := newTokenRecord(t, "owner-bound-token-123.12345678", []string{config.ScopeSettingsRead}, map[string]string{
apiTokenMetadataOwnerUserID: "alice",
})
detached := newTokenRecord(t, "detached-token-123.12345678", []string{config.ScopeSettingsRead}, nil)
cfg := newTestConfigWithTokens(t, ownerBound, detached)
router := NewRouter(cfg, nil, nil, nil, nil, "1.0.0")
server := httptest.NewServer(router.Handler())
t.Cleanup(server.Close)
requestList := func(rawToken string) (int, string) {
t.Helper()
req, err := http.NewRequest(http.MethodGet, server.URL+"/api/security/tokens", nil)
if err != nil {
t.Fatalf("new request: %v", err)
}
req.Header.Set("Authorization", "Bearer "+rawToken)
res, err := http.DefaultClient.Do(req)
if err != nil {
t.Fatalf("do request: %v", err)
}
defer res.Body.Close()
body, err := io.ReadAll(res.Body)
if err != nil {
t.Fatalf("read response: %v", err)
}
return res.StatusCode, string(body)
}
status, body := requestList("owner-bound-token-123.12345678")
if status != http.StatusOK {
t.Fatalf("expected owner-bound token to pass RBAC route, got %d: %s", status, body)
}
var payload struct {
Tokens []apiTokenDTO `json:"tokens"`
}
if err := json.Unmarshal([]byte(body), &payload); err != nil {
t.Fatalf("decode success payload: %v", err)
}
if len(payload.Tokens) != 2 {
t.Fatalf("expected 2 tokens in list response, got %d", len(payload.Tokens))
}
status, body = requestList("detached-token-123.12345678")
if status != http.StatusForbidden {
t.Fatalf("expected detached token to fail RBAC route, got %d: %s", status, body)
}
}