门禁兼容修复

This commit is contained in:
andy committed 2026-09-05 17:36:23 +08:00
1 parent f60b416949
commit 801c0af692
18 files changed
+257 -87

No files matched your search

+10 -9
View File
@@ -32,11 +32,12 @@ type ChatUseCase interface {
// ChatOptions contains the independently authenticated user-facing transport settings.
type ChatOptions struct {
AuthToken string
AllowedOrigins []string
MaxBodyBytes int64
RunTimeout time.Duration
Logger *log.Logger
AuthToken string
AllowLegacyShortToken bool
AllowedOrigins []string
MaxBodyBytes int64
RunTimeout time.Duration
Logger *log.Logger
}
// ChatHandler exposes a bounded SSE chat API without exposing provider credentials or sessions.
@@ -54,8 +55,8 @@ func NewChatHandler(chat ChatUseCase, options ChatOptions) (*ChatHandler, error)
if chat == nil {
return nil, errors.New("chat service is required")
}
if !validChatToken(options.AuthToken) {
return nil, errors.New("chat auth token must contain at least 32 printable ASCII characters")
if !validChatToken(options.AuthToken, options.AllowLegacyShortToken) {
return nil, errors.New("chat auth token is outside the configured printable ASCII length policy")
}
if options.MaxBodyBytes <= 0 || options.MaxBodyBytes > maximumChatBodyBytes {
return nil, errors.New("chat max body bytes is outside the supported range")
@@ -389,8 +390,8 @@ func publicChatError(err error) (int, string, string) {
}
}
func validChatToken(value string) bool {
if len(value) < 32 || len(value) > 4096 {
func validChatToken(value string, allowLegacyShortToken bool) bool {
if value == "" || len(value) > 4096 || (!allowLegacyShortToken && len(value) < 32) {
return false
}
for _, character := range value {
+16
View File
@@ -19,6 +19,10 @@ const testChatToken = "abcdef0123456789abcdef0123456789"
func TestNewChatHandlerRejectsUnsafeOptions(t *testing.T) {
tests := []ChatOptions{
{AuthToken: "short", MaxBodyBytes: 1, RunTimeout: time.Second},
{AuthToken: "", AllowLegacyShortToken: true, MaxBodyBytes: 1, RunTimeout: time.Second},
{AuthToken: "delivered\tkey", AllowLegacyShortToken: true, MaxBodyBytes: 1, RunTimeout: time.Second},
{AuthToken: "delivered密钥", AllowLegacyShortToken: true, MaxBodyBytes: 1, RunTimeout: time.Second},
{AuthToken: strings.Repeat("a", 4097), AllowLegacyShortToken: true, MaxBodyBytes: 1, RunTimeout: time.Second},
{AuthToken: testChatToken, MaxBodyBytes: maximumChatBodyBytes + 1, RunTimeout: time.Second},
{AuthToken: testChatToken, MaxBodyBytes: 1, RunTimeout: maximumChatRunTime + time.Second},
{AuthToken: testChatToken, AllowedOrigins: []string{"*"}, MaxBodyBytes: 1, RunTimeout: time.Second},
@@ -31,6 +35,18 @@ func TestNewChatHandlerRejectsUnsafeOptions(t *testing.T) {
}
}
func TestNewChatHandlerAllowsExplicitLegacyShortToken(t *testing.T) {
_, err := NewChatHandler(&fakeChatUseCase{}, ChatOptions{
AuthToken: "delivered-key",
AllowLegacyShortToken: true,
MaxBodyBytes: 1,
RunTimeout: time.Second,
})
if err != nil {
t.Fatalf("NewChatHandler() error = %v", err)
}
}
func TestChatTransportGuardsRunBeforeService(t *testing.T) {
tests := []struct {
name string
+9 -8
View File
@@ -20,12 +20,13 @@ import (
// transport. Its token authenticates callers of this service and is never a
// provider credential.
type DashScopeChatOptions struct {
AppID string
AuthToken string
AllowedOrigins []string
MaxBodyBytes int64
RunTimeout time.Duration
Logger *log.Logger
AppID string
AuthToken string
AllowLegacyShortToken bool
AllowedOrigins []string
MaxBodyBytes int64
RunTimeout time.Duration
Logger *log.Logger
}
// DashScopeChatHandler adapts the provider-neutral ChatUseCase to the narrow
@@ -48,8 +49,8 @@ func NewDashScopeChatHandler(chat ChatUseCase, options DashScopeChatOptions) (*D
if !validDashScopeAppID(options.AppID) {
return nil, errors.New("DashScope-compatible app ID is invalid")
}
if !validChatToken(options.AuthToken) {
return nil, errors.New("DashScope-compatible auth token must contain at least 32 printable ASCII characters")
if !validChatToken(options.AuthToken, options.AllowLegacyShortToken) {
return nil, errors.New("DashScope-compatible auth token is outside the configured printable ASCII length policy")
}
if options.MaxBodyBytes <= 0 || options.MaxBodyBytes > maximumChatBodyBytes {
return nil, errors.New("DashScope-compatible max body bytes is outside the supported range")
+17
View File
@@ -22,6 +22,10 @@ func TestNewDashScopeChatHandlerRejectsUnsafeOptions(t *testing.T) {
{AppID: "app/other", AuthToken: testChatToken, MaxBodyBytes: 1, RunTimeout: time.Second},
{AppID: "app.other", AuthToken: testChatToken, MaxBodyBytes: 1, RunTimeout: time.Second},
{AppID: testDashScopeAppID, AuthToken: "short", MaxBodyBytes: 1, RunTimeout: time.Second},
{AppID: testDashScopeAppID, AuthToken: "", AllowLegacyShortToken: true, MaxBodyBytes: 1, RunTimeout: time.Second},
{AppID: testDashScopeAppID, AuthToken: "delivered\tkey", AllowLegacyShortToken: true, MaxBodyBytes: 1, RunTimeout: time.Second},
{AppID: testDashScopeAppID, AuthToken: "delivered密钥", AllowLegacyShortToken: true, MaxBodyBytes: 1, RunTimeout: time.Second},
{AppID: testDashScopeAppID, AuthToken: strings.Repeat("a", 4097), AllowLegacyShortToken: true, MaxBodyBytes: 1, RunTimeout: time.Second},
{AppID: testDashScopeAppID, AuthToken: testChatToken, MaxBodyBytes: maximumChatBodyBytes + 1, RunTimeout: time.Second},
{AppID: testDashScopeAppID, AuthToken: testChatToken, MaxBodyBytes: 1, RunTimeout: maximumChatRunTime + time.Second},
{AppID: testDashScopeAppID, AuthToken: testChatToken, AllowedOrigins: []string{"*"}, MaxBodyBytes: 1, RunTimeout: time.Second},
@@ -38,6 +42,19 @@ func TestNewDashScopeChatHandlerRejectsUnsafeOptions(t *testing.T) {
}
}
func TestNewDashScopeChatHandlerAllowsExplicitLegacyShortToken(t *testing.T) {
_, err := NewDashScopeChatHandler(&fakeChatUseCase{}, DashScopeChatOptions{
AppID: testDashScopeAppID,
AuthToken: "delivered-key",
AllowLegacyShortToken: true,
MaxBodyBytes: 1,
RunTimeout: time.Second,
})
if err != nil {
t.Fatalf("NewDashScopeChatHandler() error = %v", err)
}
}
func TestDashScopeChatStreamsCompatibleResultAfterStrictSuccess(t *testing.T) {
turn := &fakeChatTurn{
conversationID: "conv_0123456789abcdef01234567",