Skip to content

Commit

Permalink
Support setting ssl client certificate information and ssl root certi…
Browse files Browse the repository at this point in the history
…ficate independently (#578)

### What

We want to be able to set the ssl root certificate without setting the
ssl client certificate information. We want to be able to set the two
independently.

### How

- Split the SslClientInfo to two Optionals and rename to SslInfo. Now
they can be set independently.

---------

Co-authored-by: Samir Talwar <[email protected]>
  • Loading branch information
Gil Mizrahi and SamirTalwar authored Aug 20, 2024
1 parent 2c9a74c commit edce403
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 29 deletions.
3 changes: 3 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

### Changed

- Support setting ssl client certificate information and ssl root certificate independently.
[#578](https://github.com/hasura/ndc-postgres/pull/578)

### Fixed

## [v1.1.0] - 2024-08-16
Expand Down
12 changes: 6 additions & 6 deletions crates/cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,18 +106,18 @@ async fn initialize(with_metadata: bool, context: Context<impl Environment>) ->
},
metadata::EnvironmentVariableDefinition {
name: "CLIENT_CERT".to_string(),
description: "The SSL client certificate".to_string(),
default_value: None,
description: "The SSL client certificate (Optional)".to_string(),
default_value: Some(String::new()),
},
metadata::EnvironmentVariableDefinition {
name: "CLIENT_KEY".to_string(),
description: "The SSL client key".to_string(),
default_value: None,
description: "The SSL client key (Optional)".to_string(),
default_value: Some(String::new()),
},
metadata::EnvironmentVariableDefinition {
name: "ROOT_CERT".to_string(),
description: "The SSL root certificate".to_string(),
default_value: None,
description: "The SSL root certificate (Optional)".to_string(),
default_value: Some(String::new()),
},
],
commands: metadata::Commands {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ supportedEnvironmentVariables:
description: The PostgreSQL connection URI
defaultValue: postgresql://read_only_user:[email protected]:5432/v3-docs-sample-app
- name: CLIENT_CERT
description: The SSL client certificate
description: The SSL client certificate (Optional)
defaultValue: ''
- name: CLIENT_KEY
description: The SSL client key
description: The SSL client key (Optional)
defaultValue: ''
- name: ROOT_CERT
description: The SSL root certificate
description: The SSL root certificate (Optional)
defaultValue: ''
commands:
update: hasura-ndc-postgres update
cliPlugin:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ supportedEnvironmentVariables:
description: The PostgreSQL connection URI
defaultValue: postgresql://read_only_user:[email protected]:5432/v3-docs-sample-app
- name: CLIENT_CERT
description: The SSL client certificate
description: The SSL client certificate (Optional)
defaultValue: ''
- name: CLIENT_KEY
description: The SSL client key
description: The SSL client key (Optional)
defaultValue: ''
- name: ROOT_CERT
description: The SSL root certificate
description: The SSL root certificate (Optional)
defaultValue: ''
commands:
update: hasura-ndc-postgres update
cliPlugin:
Expand Down
54 changes: 37 additions & 17 deletions crates/configuration/src/connect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,33 @@ pub fn get_connect_options(

let ssl = read_ssl_info(environment);

// Add ssl info if present.
Ok(match ssl {
// Add ssl client info if present.
let connect_options = match ssl.client {
None => connect_options,
Some(secret) => connect_options
.ssl_client_cert_from_pem(secret.certificate)
.ssl_client_key_from_pem(secret.key)
.ssl_root_cert_from_pem(secret.root_certificate),
Some(client) => connect_options
.ssl_client_cert_from_pem(client.certificate)
.ssl_client_key_from_pem(client.key),
};
// Add ssl root certificate if present.
Ok(match ssl.root_certificate {
None => connect_options,
Some(root_certificate) => connect_options.ssl_root_cert_from_pem(root_certificate),
})
}

/// SSL certificate information.
struct SslInfo {
client: Option<SslClientInfo>,
root_certificate: Option<Vec<u8>>,
}
/// SSL client certificate information.
struct SslClientInfo {
certificate: String,
key: String,
root_certificate: Vec<u8>,
}

/// Read ssl certificate and key from the environment.
fn read_ssl_info(environment: impl Environment) -> Option<SslClientInfo> {
fn read_ssl_info(environment: impl Environment) -> SslInfo {
// read ssl info
let certificate = environment.read(&Variable::from("CLIENT_CERT")).ok();
let key = environment.read(&Variable::from("CLIENT_KEY")).ok();
Expand All @@ -51,16 +59,28 @@ fn read_ssl_info(environment: impl Environment) -> Option<SslClientInfo> {
.ok()
.map(|text| text.as_bytes().to_vec());

match (certificate, key, root_certificate) {
(Some(certificate), Some(key), Some(root_certificate))
if !certificate.is_empty() && !key.is_empty() && !root_certificate.is_empty() =>
{
Some(SslClientInfo {
certificate,
key,
root_certificate,
})
let client = match (certificate, key) {
(Some(certificate), Some(key)) if !certificate.is_empty() && !key.is_empty() => {
Some(SslClientInfo { certificate, key })
}
(Some(certificate), None) if !certificate.is_empty() => {
tracing::warn!("SSL client certificate set without key. Ignoring.");
None
}
(_, Some(key)) if !key.is_empty() => {
tracing::warn!("SSL client key set without certificate. Ignoring.");
None
}
_ => None,
};

let root_certificate = match root_certificate {
Some(root_certificate) if !root_certificate.is_empty() => Some(root_certificate),
_ => None,
};

SslInfo {
client,
root_certificate,
}
}

0 comments on commit edce403

Please sign in to comment.