Support non-ASCII chars in postgres credentials

The `url` crate returns username and password portions of a URL as
percent encoded ASCII strings. In order to use them for the Postgres
connection, we need to decode them.
This commit is contained in:
Jan Kuehle 2020-08-13 15:50:07 +01:00
parent 9ed6428c8e
commit 106a6a8395
No known key found for this signature in database
GPG Key ID: D0ADAE2F2F134C0A

View File

@ -1,5 +1,6 @@
use crate::error::Error;
use crate::postgres::PgConnectOptions;
use percent_encoding::percent_decode_str;
use std::str::FromStr;
use url::Url;
@ -21,11 +22,19 @@ impl FromStr for PgConnectOptions {
let username = url.username();
if !username.is_empty() {
options = options.username(username);
options = options.username(
&*percent_decode_str(username)
.decode_utf8()
.map_err(Error::config)?,
);
}
if let Some(password) = url.password() {
options = options.password(password);
options = options.password(
&*percent_decode_str(password)
.decode_utf8()
.map_err(Error::config)?,
);
}
let path = url.path().trim_start_matches('/');
@ -80,3 +89,19 @@ fn it_parses_host_correctly_from_parameter() {
assert_eq!(None, opts.socket);
assert_eq!("google.database.com", &opts.host);
}
#[test]
fn it_parses_username_with_at_sign_correctly() {
let uri = "postgres://user@hostname:password@hostname:5432/database";
let opts = PgConnectOptions::from_str(uri).unwrap();
assert_eq!("user@hostname", &opts.username);
}
#[test]
fn it_parses_password_with_non_ascii_chars_correctly() {
let uri = "postgres://username:p@ssw0rd@hostname:5432/database";
let opts = PgConnectOptions::from_str(uri).unwrap();
assert_eq!(Some("p@ssw0rd".into()), opts.password);
}