The 1.4.2 extension replaced the old signed/encrypted chat gateway with an
OpenAI-compatible aigateway. Align the proxy with the new flow:
- Use ecloud.10086.cn login/model base URLs, zhanlu_ide plugin headers and
v1.4.2 plugin version
- Provision the model API key via SM2-signed get-or-create after v1/login
profile fetch; store api_key/model_base_url/email in credentials
- Chat via Bearer apiKey against {modelBaseUrl}/chat/completions with plain
OpenAI SSE passthrough; fetch /v1/models from the gateway model-info endpoint
- Force HTTP/1.1 upstream (gateway drops HTTP/2 ALPN negotiation with EOF)
- Drop obsolete AES body encryption, model name mapping and vscode headers
79 lines
1.8 KiB
Go
79 lines
1.8 KiB
Go
package auth
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
type Credentials struct {
|
|
AccessKey string `json:"access_key"`
|
|
SecretKey string `json:"secret_key"`
|
|
Token string `json:"token"`
|
|
APIKey string `json:"api_key,omitempty"`
|
|
ModelBaseURL string `json:"model_base_url,omitempty"`
|
|
Email string `json:"email,omitempty"`
|
|
Organization string `json:"organization,omitempty"`
|
|
Team string `json:"team,omitempty"`
|
|
BaseURL string `json:"base_url,omitempty"`
|
|
SavedAt time.Time `json:"saved_at"`
|
|
}
|
|
|
|
type Profile struct {
|
|
Email string
|
|
Organization string
|
|
Team string
|
|
UserName string
|
|
Telephone string
|
|
}
|
|
|
|
func (c Credentials) Validate() error {
|
|
if strings.TrimSpace(c.APIKey) != "" && strings.TrimSpace(c.ModelBaseURL) != "" {
|
|
return nil
|
|
}
|
|
if strings.TrimSpace(c.AccessKey) == "" {
|
|
return errors.New("access_key is required")
|
|
}
|
|
if strings.TrimSpace(c.SecretKey) == "" {
|
|
return errors.New("secret_key is required")
|
|
}
|
|
if strings.TrimSpace(c.Token) == "" {
|
|
return errors.New("token is required")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c Credentials) HasAPIKey() bool {
|
|
return strings.TrimSpace(c.APIKey) != "" && strings.TrimSpace(c.ModelBaseURL) != ""
|
|
}
|
|
|
|
func LoadCredentials(path string) (Credentials, error) {
|
|
b, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return Credentials{}, err
|
|
}
|
|
var c Credentials
|
|
if err := json.Unmarshal(b, &c); err != nil {
|
|
return Credentials{}, err
|
|
}
|
|
return c, c.Validate()
|
|
}
|
|
|
|
func SaveCredentials(path string, c Credentials) error {
|
|
if err := c.Validate(); err != nil {
|
|
return err
|
|
}
|
|
c.SavedAt = time.Now()
|
|
b, err := json.MarshalIndent(c, "", " ")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := os.MkdirAll(filepath.Dir(path), 0o700); err != nil {
|
|
return err
|
|
}
|
|
return os.WriteFile(path, b, 0o600)
|
|
}
|