Skip to content

Commit 6399ce3

Browse files
percent encode password in constructed url string (#173)
* percent encode password in constructed url string * comments
1 parent 037a7eb commit 6399ce3

File tree

3 files changed

+40
-9
lines changed

3 files changed

+40
-9
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ rpassword = "7.3.1"
9090
async-trait = "0.1.83"
9191
dotenvy = "0.15.7"
9292
csv = "1.3.1"
93+
percent-encoding = "2.3.1"
9394

9495
[target.'cfg(any(target_os = "macos", target_os = "ios", target_os = "android"))'.dependencies]
9596
keyring = { version = "3.6.2", features = [

src/config.rs

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,44 @@ use std::{collections::HashMap, path::PathBuf};
33
use color_eyre::eyre::{self, Result};
44
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
55
use derive_deref::{Deref, DerefMut};
6+
use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS};
67
use ratatui::style::{Color, Modifier, Style};
78
use serde::{de::Deserializer, Deserialize};
89

910
use crate::{action::Action, cli::Driver, focus::Focus, keyring::Password};
1011

12+
// percent encoding for passwords in connection strings
13+
const FRAGMENT: &AsciiSet = &CONTROLS
14+
.add(b' ')
15+
.add(b'"')
16+
.add(b'<')
17+
.add(b'>')
18+
.add(b'`')
19+
.add(b'#')
20+
.add(b'{')
21+
.add(b'}')
22+
.add(b'|')
23+
.add(b'^')
24+
.add(b'\\')
25+
.add(b'[')
26+
.add(b']')
27+
.add(b'$')
28+
.add(b'&')
29+
.add(b'(')
30+
.add(b')')
31+
.add(b':')
32+
.add(b';')
33+
.add(b'=')
34+
.add(b'?')
35+
.add(b'@')
36+
.add(b'!')
37+
.add(b'~')
38+
.add(b'\'')
39+
.add(b'*')
40+
.add(b'+')
41+
.add(b',')
42+
.add(b'/');
43+
1144
const CONFIG: &str = include_str!("../.config/rainfrog_config.toml");
1245

1346
#[derive(Clone, Debug, Deserialize, Default)]
@@ -65,17 +98,13 @@ pub struct Config {
6598

6699
impl StructuredConnection {
67100
pub fn connection_string(&self, driver: Driver, password: Password) -> Result<String> {
101+
let encoded_password = utf8_percent_encode(password.as_ref(), FRAGMENT);
68102
match driver {
69-
Driver::Postgres => Ok(format!(
70-
"postgresql://{}:{}@{}:{}/{}",
71-
self.username,
72-
password.as_ref(),
73-
self.host,
74-
self.port,
75-
self.database
76-
)),
103+
Driver::Postgres => {
104+
Ok(format!("postgresql://{}:{}@{}:{}/{}", self.username, encoded_password, self.host, self.port, self.database))
105+
},
77106
Driver::MySql => {
78-
Ok(format!("mysql://{}:{}@{}:{}/{}", self.username, password.as_ref(), self.host, self.port, self.database))
107+
Ok(format!("mysql://{}:{}@{}:{}/{}", self.username, encoded_password, self.host, self.port, self.database))
79108
},
80109
Driver::Sqlite => Err(eyre::Report::msg("Sqlite only supports raw connection strings")),
81110
}

0 commit comments

Comments
 (0)