mirror of
https://github.com/neondatabase/neon.git
synced 2026-01-13 16:32:56 +00:00
95 lines
3.0 KiB
Rust
95 lines
3.0 KiB
Rust
//! Payload for ad hoc authentication method for clients that don't support SNI.
|
|
//! See the `impl` for [`super::backend::BackendType<ClientCredentials>`].
|
|
//! Read more: <https://github.com/neondatabase/cloud/issues/1620#issuecomment-1165332290>.
|
|
//! UPDATE (Mon Aug 8 13:20:34 UTC 2022): the payload format has been simplified.
|
|
|
|
use bstr::ByteSlice;
|
|
|
|
pub struct PasswordHackPayload {
|
|
pub endpoint: String,
|
|
pub password: Vec<u8>,
|
|
}
|
|
|
|
impl PasswordHackPayload {
|
|
pub fn parse(bytes: &[u8]) -> Option<Self> {
|
|
// The format is `project=<utf-8>;<password-bytes>`.
|
|
let mut iter = bytes.splitn_str(2, ";");
|
|
let endpoint = iter.next()?.to_str().ok()?;
|
|
let endpoint = parse_endpoint_param(endpoint)?.to_owned();
|
|
let password = iter.next()?.to_owned();
|
|
|
|
Some(Self { endpoint, password })
|
|
}
|
|
}
|
|
|
|
pub fn parse_endpoint_param(bytes: &str) -> Option<&str> {
|
|
bytes
|
|
.strip_prefix("project=")
|
|
.or_else(|| bytes.strip_prefix("endpoint="))
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn parse_endpoint_param_fn() {
|
|
let input = "";
|
|
assert!(parse_endpoint_param(input).is_none());
|
|
|
|
let input = "project=";
|
|
assert_eq!(parse_endpoint_param(input), Some(""));
|
|
|
|
let input = "project=foobar";
|
|
assert_eq!(parse_endpoint_param(input), Some("foobar"));
|
|
|
|
let input = "endpoint=";
|
|
assert_eq!(parse_endpoint_param(input), Some(""));
|
|
|
|
let input = "endpoint=foobar";
|
|
assert_eq!(parse_endpoint_param(input), Some("foobar"));
|
|
|
|
let input = "other_option=foobar";
|
|
assert!(parse_endpoint_param(input).is_none());
|
|
}
|
|
|
|
#[test]
|
|
fn parse_password_hack_payload_project() {
|
|
let bytes = b"";
|
|
assert!(PasswordHackPayload::parse(bytes).is_none());
|
|
|
|
let bytes = b"project=";
|
|
assert!(PasswordHackPayload::parse(bytes).is_none());
|
|
|
|
let bytes = b"project=;";
|
|
let payload: PasswordHackPayload =
|
|
PasswordHackPayload::parse(bytes).expect("parsing failed");
|
|
assert_eq!(payload.endpoint, "");
|
|
assert_eq!(payload.password, b"");
|
|
|
|
let bytes = b"project=foobar;pass;word";
|
|
let payload = PasswordHackPayload::parse(bytes).expect("parsing failed");
|
|
assert_eq!(payload.endpoint, "foobar");
|
|
assert_eq!(payload.password, b"pass;word");
|
|
}
|
|
|
|
#[test]
|
|
fn parse_password_hack_payload_endpoint() {
|
|
let bytes = b"";
|
|
assert!(PasswordHackPayload::parse(bytes).is_none());
|
|
|
|
let bytes = b"endpoint=";
|
|
assert!(PasswordHackPayload::parse(bytes).is_none());
|
|
|
|
let bytes = b"endpoint=;";
|
|
let payload = PasswordHackPayload::parse(bytes).expect("parsing failed");
|
|
assert_eq!(payload.endpoint, "");
|
|
assert_eq!(payload.password, b"");
|
|
|
|
let bytes = b"endpoint=foobar;pass;word";
|
|
let payload = PasswordHackPayload::parse(bytes).expect("parsing failed");
|
|
assert_eq!(payload.endpoint, "foobar");
|
|
assert_eq!(payload.password, b"pass;word");
|
|
}
|
|
}
|