fix(ssf): 允许同一配对恢复未完成连接
首次创建 SSF Stream 失败后,恢复管理器会因缺少尚未生成的 Audience 而将同一 Revision 误判为凭据交接冲突。现在仅对同一 owner、Transmitter、机器客户端且尚未绑定 Stream 的可恢复状态放行重试,跨 Revision 与不完整绑定配置仍保持安全拒绝。\n\n验证:gofmt、go vet ./...、env -u AI_GATEWAY_TEST_DATABASE_URL go test ./... -count=1。
This commit is contained in:
@@ -183,6 +183,9 @@ func NewConnectionManager(ctx context.Context, repository ConnectionRepository,
|
||||
}
|
||||
} else if hasRevisionBindingExpectation(config) {
|
||||
if err := manager.validateConnectionBinding(connection); err != nil {
|
||||
if manager.recoverableIncompleteConnectionBinding(connection) {
|
||||
return manager, nil
|
||||
}
|
||||
// A recovery manager may inspect a foreign singleton connection, but
|
||||
// it must not activate it: activate() would combine the old persisted
|
||||
// Secret with the new Revision's token endpoint.
|
||||
@@ -257,6 +260,22 @@ func (m *ConnectionManager) validateConnectionBinding(connection store.SecurityE
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *ConnectionManager) recoverableIncompleteConnectionBinding(connection store.SecurityEventConnection) bool {
|
||||
expectedIssuer := strings.TrimRight(strings.TrimSpace(m.config.ExpectedTransmitterIssuer), "/")
|
||||
expectedAudience := strings.TrimSpace(m.config.ExpectedAudience)
|
||||
expectedClientID := strings.TrimSpace(m.config.ManagementClientID)
|
||||
expectedOwner := strings.TrimSpace(m.config.ExpectedOwnerKey)
|
||||
if expectedIssuer == "" || expectedAudience == "" || expectedClientID == "" || expectedOwner == "" {
|
||||
return false
|
||||
}
|
||||
return connection.StreamID == nil &&
|
||||
connection.Audience == nil &&
|
||||
resumableConnectionLifecycle(connection.LifecycleStatus) &&
|
||||
strings.TrimRight(strings.TrimSpace(connection.TransmitterIssuer), "/") == expectedIssuer &&
|
||||
strings.TrimSpace(connection.ManagementClientID) == expectedClientID &&
|
||||
strings.TrimSpace(connection.IdempotencyKey) == expectedOwner
|
||||
}
|
||||
|
||||
func (m *ConnectionManager) Get(ctx context.Context) (ConnectionView, error) {
|
||||
connection, err := m.repository.SecurityEventConnection(ctx)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user