Add Anthropic access-review driver and resolver
The driver lists organization members through the Anthropic Admin API (GET /v1/organizations/users) with cursor pagination, mapping the role and the RFC 3339 added_at timestamp. The name resolver reads the organization name from /v1/organizations/me; a non-2xx response (for example a revoked key) yields no name rather than making the source-name worker retry forever. Both send the required anthropic-version header. Add a VCR test helper that injects the key via x-api-key so the cassette stays recordable, and strip x-api-key on save. The cassette holds synthetic members covering the user, developer, and admin roles. Signed-off-by: Aurélien Sibiril <81782+aureliensibiril@users.noreply.github.com>
This commit is contained in:
@@ -50,6 +50,11 @@ func newRecorder(t *testing.T, cassettePath string, envVar string) *recorder.Rec
|
||||
)),
|
||||
recorder.WithHook(func(i *cassette.Interaction) error {
|
||||
i.Request.Headers.Del("Authorization")
|
||||
// Providers like Anthropic authenticate via x-api-key rather
|
||||
// than Authorization; strip it too so a re-record never
|
||||
// persists a raw key.
|
||||
i.Request.Headers.Del("X-Api-Key")
|
||||
|
||||
return nil
|
||||
}, recorder.BeforeSaveHook),
|
||||
)
|
||||
@@ -110,3 +115,37 @@ func newVCRClient(rec *recorder.Recorder, authValue string) *http.Client {
|
||||
|
||||
return &http.Client{Transport: transport}
|
||||
}
|
||||
|
||||
// headerRoundTripper injects a value into an arbitrary request header.
|
||||
// Used for providers (e.g. Anthropic) that authenticate with a custom
|
||||
// header instead of Authorization.
|
||||
type headerRoundTripper struct {
|
||||
header string
|
||||
value string
|
||||
transport http.RoundTripper
|
||||
}
|
||||
|
||||
func (rt *headerRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
if rt.value != "" {
|
||||
req.Header.Set(rt.header, rt.value)
|
||||
}
|
||||
|
||||
return rt.transport.RoundTrip(req)
|
||||
}
|
||||
|
||||
// newVCRClientWithHeader is like newVCRClient but injects the auth value
|
||||
// into a named header (e.g. "x-api-key") instead of Authorization, for
|
||||
// providers that do not use Bearer auth. The header is stripped from the
|
||||
// cassette by newRecorder's BeforeSave hook.
|
||||
func newVCRClientWithHeader(rec *recorder.Recorder, header, value string) *http.Client {
|
||||
transport := rec.GetDefaultClient().Transport
|
||||
if value != "" {
|
||||
transport = &headerRoundTripper{
|
||||
header: header,
|
||||
value: value,
|
||||
transport: transport,
|
||||
}
|
||||
}
|
||||
|
||||
return &http.Client{Transport: transport}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user