mirror of
https://github.com/t8y2/dbx.git
synced 2026-10-23 00:27:16 +00:00
Merge pull request #116 from SuLea-IT/codex/issue-110-mongodb-legacy
feat: add MongoDB form URL parameters
This commit is contained in:
@@ -123,7 +123,8 @@ impl ConnectionConfig {
|
||||
if let Some(cs) = self.connection_string.as_deref().filter(|s| !s.is_empty()) {
|
||||
return cs.to_string();
|
||||
}
|
||||
format!("mongodb://{host}:{port}{db_part}")
|
||||
let suffix = if params.is_empty() { String::new() } else { format!("?{params}") };
|
||||
format!("mongodb://{host}:{port}{db_part}{suffix}")
|
||||
}
|
||||
DatabaseType::Oracle => format!("oracle://{host}:{port}{db_part}"),
|
||||
DatabaseType::Elasticsearch => format!("http://{host}:{port}"),
|
||||
@@ -174,10 +175,11 @@ impl ConnectionConfig {
|
||||
if let Some(cs) = self.connection_string.as_deref().filter(|s| !s.is_empty()) {
|
||||
return cs.to_string();
|
||||
}
|
||||
let suffix = if params.is_empty() { String::new() } else { format!("?{params}") };
|
||||
if self.username.is_empty() {
|
||||
format!("mongodb://{host}:{port}{db_part}")
|
||||
format!("mongodb://{host}:{port}{db_part}{suffix}")
|
||||
} else {
|
||||
format!("mongodb://{username}:{password}@{host}:{port}{db_part}")
|
||||
format!("mongodb://{username}:{password}@{host}:{port}{db_part}{suffix}")
|
||||
}
|
||||
}
|
||||
DatabaseType::Oracle => {
|
||||
@@ -234,7 +236,9 @@ impl ConnectionConfig {
|
||||
format!("ssl-mode=disabled&{}", filtered.join("&"))
|
||||
}
|
||||
}
|
||||
DatabaseType::Postgres | DatabaseType::Redshift => value.trim_start_matches('?').to_string(),
|
||||
DatabaseType::Postgres | DatabaseType::Redshift | DatabaseType::MongoDb => {
|
||||
value.trim_start_matches('?').to_string()
|
||||
}
|
||||
_ => value.trim_start_matches('?').to_string(),
|
||||
}
|
||||
}
|
||||
@@ -284,6 +288,13 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
fn mongodb_config(username: &str, password: &str, database: Option<&str>) -> ConnectionConfig {
|
||||
let mut config = mysql_config(username, password, database);
|
||||
config.db_type = DatabaseType::MongoDb;
|
||||
config.port = 17000;
|
||||
config
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mysql_url_encodes_oceanbase_username() {
|
||||
let config = mysql_config("user@tenant#cluster", "secret", None);
|
||||
@@ -324,6 +335,24 @@ mod tests {
|
||||
assert_eq!(config.connection_url(), "postgres://postgres:secret@10.1.2.3:2883/test?sslmode=disable");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mongodb_form_url_without_params_does_not_force_topology_or_auth() {
|
||||
let config = mongodb_config("root", "secret", Some("admin"));
|
||||
|
||||
assert_eq!(config.connection_url(), "mongodb://root:secret@10.1.2.3:17000/admin");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn mongodb_form_url_appends_custom_params() {
|
||||
let mut config = mongodb_config("root", "secret", Some("app"));
|
||||
config.url_params = Some("?authSource=admin&authMechanism=SCRAM-SHA-1&directConnection=true".to_string());
|
||||
|
||||
assert_eq!(
|
||||
config.connection_url(),
|
||||
"mongodb://root:secret@10.1.2.3:17000/app?authSource=admin&authMechanism=SCRAM-SHA-1&directConnection=true"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn redacted_mysql_url_omits_credentials() {
|
||||
let config = mysql_config("user@tenant#cluster", "p@ss:word#1", Some("db/name"));
|
||||
@@ -360,4 +389,16 @@ mod tests {
|
||||
assert!(!url.contains("default"));
|
||||
assert!(!url.contains("redis-secret"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn redacted_mongodb_url_keeps_custom_params_without_credentials() {
|
||||
let mut config = mongodb_config("root", "secret", Some("admin"));
|
||||
config.url_params = Some("authSource=admin&authMechanism=SCRAM-SHA-1".to_string());
|
||||
|
||||
let url = config.redacted_connection_url();
|
||||
|
||||
assert_eq!(url, "mongodb://10.1.2.3:17000/admin?authSource=admin&authMechanism=SCRAM-SHA-1");
|
||||
assert!(!url.contains("root"));
|
||||
assert!(!url.contains("secret"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -401,7 +401,7 @@ async function testConnection() {
|
||||
isTesting.value = true;
|
||||
testResult.value = null;
|
||||
try {
|
||||
const config: ConnectionConfig = { ...form.value, id: editingId.value || uuid() };
|
||||
const config = connectionConfigForSubmit(editingId.value || uuid());
|
||||
const msg = await api.testConnection(config);
|
||||
if (runId !== testRunId) return;
|
||||
testResult.value = { ok: true, message: msg };
|
||||
@@ -415,6 +415,14 @@ async function testConnection() {
|
||||
}
|
||||
}
|
||||
|
||||
function connectionConfigForSubmit(id: string): ConnectionConfig {
|
||||
const config: ConnectionConfig = { ...form.value, id };
|
||||
if (config.db_type === "mongodb" && !mongoUseUrl.value) {
|
||||
config.connection_string = undefined;
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
function resetTestState() {
|
||||
testRunId += 1;
|
||||
isTesting.value = false;
|
||||
@@ -462,11 +470,11 @@ async function save() {
|
||||
resetTestState();
|
||||
try {
|
||||
if (editingId.value) {
|
||||
const updated: ConnectionConfig = { ...form.value, id: editingId.value };
|
||||
const updated = connectionConfigForSubmit(editingId.value);
|
||||
await store.updateConnection(updated);
|
||||
store.stopEditing();
|
||||
} else {
|
||||
const config: ConnectionConfig = { ...form.value, id: uuid() };
|
||||
const config = connectionConfigForSubmit(uuid());
|
||||
await store.addConnection(config);
|
||||
open.value = false;
|
||||
await nextTick();
|
||||
@@ -757,6 +765,20 @@ async function browseSshKeyPath() {
|
||||
:placeholder="t('connection.databasePlaceholder')"
|
||||
/>
|
||||
</div>
|
||||
<div class="grid grid-cols-4 items-center gap-4">
|
||||
<Label class="text-right">{{ t("connection.urlParams") }}</Label>
|
||||
<Input
|
||||
v-model="form.url_params"
|
||||
class="col-span-3"
|
||||
placeholder="authSource=admin&authMechanism=SCRAM-SHA-1"
|
||||
/>
|
||||
</div>
|
||||
<div class="grid grid-cols-4 items-start gap-4">
|
||||
<span />
|
||||
<p class="col-span-3 text-xs text-muted-foreground">
|
||||
{{ t("connection.mongoLegacyHint") }}
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -112,6 +112,8 @@ export default {
|
||||
sshKeyPathBrowse: "Browse",
|
||||
sshExposeLan: "Expose tunnel to LAN",
|
||||
dmCompatHint: "Requires DM PG compatibility mode (set COMPATIBLE_MODE=7 in dm.ini and restart)",
|
||||
mongoLegacyHint:
|
||||
"For older MongoDB servers, enter authSource=admin&authMechanism=SCRAM-SHA-1 here; add directConnection=true only when needed for direct standalone connections.",
|
||||
compatible: "Compatible",
|
||||
mainstream: "Popular",
|
||||
color: "Color",
|
||||
|
||||
@@ -111,6 +111,8 @@ export default {
|
||||
sshKeyPathBrowse: "浏览",
|
||||
sshExposeLan: "允许局域网访问隧道",
|
||||
dmCompatHint: "需要开启达梦 PG 兼容模式(dm.ini 中设置 COMPATIBLE_MODE=7 并重启服务)",
|
||||
mongoLegacyHint:
|
||||
"连接旧版 MongoDB 时,可在此填写 authSource=admin&authMechanism=SCRAM-SHA-1;直连单节点时可按需追加 directConnection=true。",
|
||||
compatible: "兼容",
|
||||
mainstream: "主流",
|
||||
color: "颜色",
|
||||
|
||||
Reference in New Issue
Block a user