mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-05-07 08:57:12 +00:00
75 lines
2.2 KiB
Go
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)
|
|
}
|
|
}
|