Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 29 additions & 14 deletions internal/api/handlers/management/auth_files.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/router-for-me/CLIProxyAPI/v6/internal/misc"
"github.com/router-for-me/CLIProxyAPI/v6/internal/registry"
"github.com/router-for-me/CLIProxyAPI/v6/internal/util"
"github.com/router-for-me/CLIProxyAPI/v6/internal/watcher/synthesizer"
sdkAuth "github.com/router-for-me/CLIProxyAPI/v6/sdk/auth"
coreauth "github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy/auth"
log "github.com/sirupsen/logrus"
Expand Down Expand Up @@ -1007,21 +1008,35 @@ func (h *Handler) buildAuthFromFileData(path string, data []byte) (*coreauth.Aut
if authID == "" {
authID = path
}
attr := map[string]string{
"path": path,
"source": path,
}
auth := &coreauth.Auth{
ID: authID,
Provider: provider,
FileName: filepath.Base(path),
Label: label,
Status: coreauth.StatusActive,
Attributes: attr,
Metadata: metadata,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
auth := (*coreauth.Auth)(nil)
if h != nil && h.cfg != nil {
sctx := &synthesizer.SynthesisContext{
Config: h.cfg,
AuthDir: h.cfg.AuthDir,
Now: time.Now(),
IDGenerator: synthesizer.NewStableIDGenerator(),
}
if generated := synthesizer.SynthesizeAuthFile(sctx, path, data); len(generated) > 0 && generated[0] != nil {
auth = generated[0].Clone()
}
}
if auth == nil {
auth = &coreauth.Auth{
ID: authID,
Provider: provider,
Label: label,
Status: coreauth.StatusActive,
Attributes: map[string]string{
"path": path,
"source": path,
},
Metadata: metadata,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
}
auth.ID = authID
auth.FileName = filepath.Base(path)
if hasLastRefresh {
auth.LastRefreshedAt = lastRefresh
}
Expand Down
69 changes: 69 additions & 0 deletions internal/api/handlers/management/auth_files_upload_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package management

import (
"bytes"
"encoding/json"
"mime/multipart"
"net/http"
"net/http/httptest"
"testing"

"github.com/gin-gonic/gin"
"github.com/router-for-me/CLIProxyAPI/v6/internal/config"
coreauth "github.com/router-for-me/CLIProxyAPI/v6/sdk/cliproxy/auth"
)

func TestUploadAuthFile_PreservesPriorityAttributes(t *testing.T) {
t.Setenv("MANAGEMENT_PASSWORD", "")
gin.SetMode(gin.TestMode)

authDir := t.TempDir()
manager := coreauth.NewManager(nil, nil, nil)
h := NewHandlerWithoutConfigFilePath(&config.Config{AuthDir: authDir}, manager)

content := `{"type":"codex","email":"midai0530@gmail.com","priority":98}`

var body bytes.Buffer
writer := multipart.NewWriter(&body)
part, err := writer.CreateFormFile("file", "codex-midai0530@gmail.com-plus.json")
if err != nil {
t.Fatalf("failed to create multipart file: %v", err)
}
if _, err = part.Write([]byte(content)); err != nil {
t.Fatalf("failed to write multipart content: %v", err)
}
if err = writer.Close(); err != nil {
t.Fatalf("failed to close multipart writer: %v", err)
}

rec := httptest.NewRecorder()
ctx, _ := gin.CreateTestContext(rec)
req := httptest.NewRequest(http.MethodPost, "/v0/management/auth-files", &body)
req.Header.Set("Content-Type", writer.FormDataContentType())
ctx.Request = req

h.UploadAuthFile(ctx)

if rec.Code != http.StatusOK {
t.Fatalf("expected upload status %d, got %d with body %s", http.StatusOK, rec.Code, rec.Body.String())
}

var payload map[string]any
if err = json.Unmarshal(rec.Body.Bytes(), &payload); err != nil {
t.Fatalf("failed to decode response: %v", err)
}
if status, _ := payload["status"].(string); status != "ok" {
t.Fatalf("expected status ok, got %#v", payload["status"])
}

auth, ok := manager.GetByID("codex-midai0530@gmail.com-plus.json")
if !ok || auth == nil {
t.Fatalf("expected uploaded auth record to exist")
}
if got := auth.Attributes["priority"]; got != "98" {
t.Fatalf("priority attribute = %q, want %q", got, "98")
}
if got := auth.Metadata["priority"]; got != float64(98) {
t.Fatalf("priority metadata = %#v, want 98", got)
}
}
Loading