mirror of
https://github.com/sipeed/picoclaw.git
synced 2026-06-12 18:08:54 +00:00
23abbb67ea
* feat(auth): add Anthropic OAuth setup-token login flow Add support for Anthropic's OAuth-based setup tokens (sk-ant-oat01-*) as an alternative to API keys. This includes: - New `--setup-token` flag on `auth login` command - Interactive login menu for Anthropic (setup token vs API key) - Setup token validation and credential storage with oauth auth method - Usage endpoint integration to show 5h/7d utilization in `auth status` - Streaming support for OAuth tokens (required by Anthropic API) - Model ID normalization (dots to hyphens) for API compatibility - Remove .env.example (secrets should not be templated) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat(auth): update related functionality * refactor(auth): organize constants and improve header casing in requests fo CI * fix(auth): fix golint again * fix(auth): handle nil arguments in tool calls for buildParams function --------- Co-authored-by: Baller <sharonms3377@gmail.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
62 lines
1.6 KiB
Go
62 lines
1.6 KiB
Go
package auth
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestLoginSetupToken(t *testing.T) {
|
|
// A valid token: correct prefix + at least 80 chars
|
|
validToken := "sk-ant-oat01-" + strings.Repeat("a", 80)
|
|
|
|
tests := []struct {
|
|
name string
|
|
input string
|
|
wantErr string
|
|
}{
|
|
{"valid token", validToken, ""},
|
|
{"empty input", "", "expected prefix sk-ant-oat01-"},
|
|
{"wrong prefix", "sk-ant-api-" + strings.Repeat("a", 80), "expected prefix sk-ant-oat01-"},
|
|
{"too short", "sk-ant-oat01-short", "too short"},
|
|
{"whitespace only", " ", "expected prefix sk-ant-oat01-"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
r := strings.NewReader(tt.input + "\n")
|
|
cred, err := LoginSetupToken(r)
|
|
|
|
if tt.wantErr != "" {
|
|
if err == nil {
|
|
t.Fatalf("expected error containing %q, got nil", tt.wantErr)
|
|
}
|
|
if !strings.Contains(err.Error(), tt.wantErr) {
|
|
t.Fatalf("expected error containing %q, got %q", tt.wantErr, err.Error())
|
|
}
|
|
return
|
|
}
|
|
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
if cred.AccessToken != validToken {
|
|
t.Errorf("AccessToken = %q, want %q", cred.AccessToken, validToken)
|
|
}
|
|
if cred.Provider != "anthropic" {
|
|
t.Errorf("Provider = %q, want %q", cred.Provider, "anthropic")
|
|
}
|
|
if cred.AuthMethod != "oauth" {
|
|
t.Errorf("AuthMethod = %q, want %q", cred.AuthMethod, "oauth")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLoginSetupToken_EmptyReader(t *testing.T) {
|
|
r := strings.NewReader("")
|
|
_, err := LoginSetupToken(r)
|
|
if err == nil {
|
|
t.Fatal("expected error for empty reader, got nil")
|
|
}
|
|
}
|