mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-05-15 20:37:52 +08:00
🐛 fix(dameng): 修复特殊字符密码导致连接认证失败
- 调整达梦 DSN 生成逻辑,密码按驱动解析规则原样传入 - 移除默认 escapeProcess 参数示例,避免误导配置 - 补充特殊字符密码与问号密码的回归测试 Refs #446
This commit is contained in:
@@ -1853,7 +1853,7 @@ const ConnectionModal: React.FC<{
|
||||
case "mongodb":
|
||||
return "retryWrites=true&readPreference=secondaryPreferred";
|
||||
case "dameng":
|
||||
return "schema=SYSDBA&escapeProcess=true";
|
||||
return "schema=SYSDBA";
|
||||
case "tdengine":
|
||||
return "timezone=Asia%2FShanghai";
|
||||
default:
|
||||
|
||||
@@ -31,7 +31,6 @@ func (d *DamengDB) getDSN(config connection.ConnectionConfig) string {
|
||||
// or dm://user:password@host:port
|
||||
|
||||
address := net.JoinHostPort(config.Host, strconv.Itoa(config.Port))
|
||||
escapedPassword := url.PathEscape(config.Password)
|
||||
q := url.Values{}
|
||||
if config.Database != "" {
|
||||
q.Set("schema", config.Database)
|
||||
@@ -44,15 +43,16 @@ func (d *DamengDB) getDSN(config connection.ConnectionConfig) string {
|
||||
q.Set("SSL_KEY_PATH", keyPath)
|
||||
}
|
||||
}
|
||||
if escapedPassword != config.Password {
|
||||
// 达梦驱动要求:密码包含特殊字符时,password 需 PathEscape,并添加 escapeProcess=true 让驱动解码。
|
||||
q.Set("escapeProcess", "true")
|
||||
}
|
||||
mergeConnectionParamsFromConfig(q, config, "dm", "dameng")
|
||||
|
||||
dsn := fmt.Sprintf("dm://%s:%s@%s", config.User, escapedPassword, address)
|
||||
// 当前达梦 Go 驱动使用字符串切分解析 DSN,认证信息不会做 URL 反解码。
|
||||
// 密码保持原样传入,避免 p%40ss 这类转义文本被当作真实密码登录。
|
||||
dsn := fmt.Sprintf("dm://%s:%s@%s", config.User, config.Password, address)
|
||||
encoded := q.Encode()
|
||||
if encoded == "" {
|
||||
if strings.Contains(config.User, "?") || strings.Contains(config.Password, "?") {
|
||||
return dsn + "?"
|
||||
}
|
||||
return dsn
|
||||
}
|
||||
return dsn + "?" + encoded
|
||||
|
||||
@@ -126,7 +126,7 @@ func TestOracleDSN_EscapesUserAndPassword(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestDamengDSN_EscapesPasswordAndEnablesEscapeProcess(t *testing.T) {
|
||||
func TestDamengDSN_KeepsRawPasswordForDriverParser(t *testing.T) {
|
||||
d := &DamengDB{}
|
||||
cfg := connection.ConnectionConfig{
|
||||
Type: "dameng",
|
||||
@@ -138,20 +138,36 @@ func TestDamengDSN_EscapesPasswordAndEnablesEscapeProcess(t *testing.T) {
|
||||
}
|
||||
|
||||
dsn := d.getDSN(cfg)
|
||||
if strings.Contains(dsn, cfg.Password) {
|
||||
t.Fatalf("dsn 包含原始密码:%s", dsn)
|
||||
if !strings.Contains(dsn, "SYSDBA:p@ss:wo/rd@127.0.0.1:5236") {
|
||||
t.Fatalf("dsn 未保留达梦驱动可识别的原始认证信息:%s", dsn)
|
||||
}
|
||||
if strings.Contains(dsn, "wo/rd") || !strings.Contains(dsn, "wo%2Frd") {
|
||||
t.Fatalf("dsn 未按达梦驱动要求转义密码(至少应转义 '/'):%s", dsn)
|
||||
if strings.Contains(dsn, "p%40ss") || strings.Contains(dsn, "wo%2Frd") {
|
||||
t.Fatalf("dsn 不应转义达梦密码,驱动不会反解码认证信息:%s", dsn)
|
||||
}
|
||||
if !strings.Contains(dsn, "escapeProcess=true") {
|
||||
t.Fatalf("dsn 缺少 escapeProcess=true:%s", dsn)
|
||||
if strings.Contains(dsn, "escapeProcess=true") {
|
||||
t.Fatalf("dsn 不应自动添加 escapeProcess=true:%s", dsn)
|
||||
}
|
||||
if !strings.Contains(dsn, "schema=DBName") {
|
||||
t.Fatalf("dsn 缺少 schema 参数:%s", dsn)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDamengDSN_AppendsQuerySentinelForQuestionMarkInPassword(t *testing.T) {
|
||||
d := &DamengDB{}
|
||||
cfg := connection.ConnectionConfig{
|
||||
Type: "dameng",
|
||||
Host: "127.0.0.1",
|
||||
Port: 5236,
|
||||
User: "SYSDBA",
|
||||
Password: "p?ss",
|
||||
}
|
||||
|
||||
dsn := d.getDSN(cfg)
|
||||
if dsn != "dm://SYSDBA:p?ss@127.0.0.1:5236?" {
|
||||
t.Fatalf("dsn = %q, want raw password with trailing query sentinel", dsn)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDamengDSN_AppendsSSLCertAndKeyParams(t *testing.T) {
|
||||
d := &DamengDB{}
|
||||
cfg := connection.ConnectionConfig{
|
||||
|
||||
Reference in New Issue
Block a user