-
Notifications
You must be signed in to change notification settings - Fork 2k
fix: Make conversion from FileDecryptionProperties to ConfigFileDecryptionProperties fallible #21603
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
fix: Make conversion from FileDecryptionProperties to ConfigFileDecryptionProperties fallible #21603
Changes from all commits
1eae1f4
6d380a1
704d0f1
e20c6bb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3024,8 +3024,18 @@ impl From<ConfigFileDecryptionProperties> for FileDecryptionProperties { | |
| } | ||
|
|
||
| #[cfg(feature = "parquet_encryption")] | ||
| impl From<&Arc<FileDecryptionProperties>> for ConfigFileDecryptionProperties { | ||
| fn from(f: &Arc<FileDecryptionProperties>) -> Self { | ||
| impl TryFrom<&Arc<FileDecryptionProperties>> for ConfigFileDecryptionProperties { | ||
| type Error = DataFusionError; | ||
|
|
||
| fn try_from(f: &Arc<FileDecryptionProperties>) -> Result<Self> { | ||
| let footer_key = f.footer_key(None).map_err(|e| { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This still depends on
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that's not currently possible with the public API of
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sure, Please open a follow-up issue and link it here so that it is tracked. Also handle the upgrade note.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've opened a follow-up Datafusion issue at #21634 and an arrow-rs issue at apache/arrow-rs#9721, and will implement the arrow-rs change soon. |
||
| DataFusionError::Configuration(format!( | ||
| "Could not retrieve footer key from FileDecryptionProperties. \ | ||
| Note that conversion to ConfigFileDecryptionProperties is not supported \ | ||
| when using a key retriever: {e}" | ||
| )) | ||
| })?; | ||
|
|
||
| let (column_names_vec, column_keys_vec) = f.column_keys(); | ||
| let mut column_decryption_properties: HashMap< | ||
| String, | ||
|
|
@@ -3039,14 +3049,12 @@ impl From<&Arc<FileDecryptionProperties>> for ConfigFileDecryptionProperties { | |
| } | ||
|
|
||
| let aad_prefix = f.aad_prefix().cloned().unwrap_or_default(); | ||
| ConfigFileDecryptionProperties { | ||
| footer_key_as_hex: hex::encode( | ||
| f.footer_key(None).unwrap_or_default().as_ref(), | ||
| ), | ||
| Ok(ConfigFileDecryptionProperties { | ||
| footer_key_as_hex: hex::encode(footer_key.as_ref()), | ||
| column_decryption_properties, | ||
| aad_prefix_as_hex: hex::encode(aad_prefix), | ||
| footer_signature_verification: f.check_plaintext_footer_integrity(), | ||
| } | ||
| }) | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -3519,7 +3527,8 @@ mod tests { | |
| Arc::new(FileEncryptionProperties::from(config_encrypt.clone())); | ||
| assert_eq!(file_encryption_properties, encryption_properties_built); | ||
|
|
||
| let config_decrypt = ConfigFileDecryptionProperties::from(&decryption_properties); | ||
| let config_decrypt = | ||
| ConfigFileDecryptionProperties::try_from(&decryption_properties).unwrap(); | ||
| let decryption_properties_built = | ||
| Arc::new(FileDecryptionProperties::from(config_decrypt.clone())); | ||
| assert_eq!(decryption_properties, decryption_properties_built); | ||
|
|
@@ -3637,6 +3646,42 @@ mod tests { | |
| assert_eq!(factory_options.get("key2"), Some(&"value 2".to_string())); | ||
| } | ||
|
|
||
| #[cfg(feature = "parquet_encryption")] | ||
| struct ParquetEncryptionKeyRetriever {} | ||
|
|
||
| #[cfg(feature = "parquet_encryption")] | ||
| impl parquet::encryption::decrypt::KeyRetriever for ParquetEncryptionKeyRetriever { | ||
| fn retrieve_key(&self, key_metadata: &[u8]) -> parquet::errors::Result<Vec<u8>> { | ||
| if !key_metadata.is_empty() { | ||
| Ok(b"1234567890123450".to_vec()) | ||
| } else { | ||
| Err(parquet::errors::ParquetError::General( | ||
| "Key metadata not provided".to_string(), | ||
| )) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| #[cfg(feature = "parquet_encryption")] | ||
| #[test] | ||
| fn conversion_from_key_retriever_to_config_file_decryption_properties() { | ||
| use crate::Result; | ||
| use crate::config::ConfigFileDecryptionProperties; | ||
| use crate::encryption::FileDecryptionProperties; | ||
|
|
||
| let retriever = std::sync::Arc::new(ParquetEncryptionKeyRetriever {}); | ||
| let decryption_properties = | ||
| FileDecryptionProperties::with_key_retriever(retriever) | ||
| .build() | ||
| .unwrap(); | ||
| let config_file_decryption_properties: Result<ConfigFileDecryptionProperties> = | ||
| (&decryption_properties).try_into(); | ||
| assert!(config_file_decryption_properties.is_err()); | ||
| let err = config_file_decryption_properties.unwrap_err().to_string(); | ||
| assert!(err.contains("key retriever")); | ||
| assert!(err.contains("Key metadata not provided")); | ||
| } | ||
|
|
||
| #[cfg(feature = "parquet")] | ||
| #[test] | ||
| fn parquet_table_options_config_entry() { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -450,3 +450,22 @@ clusters (e.g., ZWJ emoji sequences). For ASCII and most common Unicode text, | |
| behavior is unchanged. | ||
|
|
||
| [#17861]: https://github.com/apache/datafusion/pull/17861 | ||
|
|
||
| ### Conversion from `FileDecryptionProperties` to `ConfigFileDecryptionProperties` is now fallible | ||
|
|
||
| Previously, `datafusion_common::config::ConfigFileDecryptionProperties` | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think |
||
| implemented `From<&Arc<parquet::encryption::decrypt::FileDecryptionProperties>>`. | ||
| If an error was encountered when retrieving the footer key without providing key metadata, | ||
| the error would be ignored and an empty footer key set in the result. | ||
| This could lead to obscure errors later. | ||
|
|
||
| `ConfigFileDecryptionProperties` now instead implements `TryFrom<&Arc<FileDecryptionProperties>>`, | ||
| and errors retrieving the footer key will be propagated up. | ||
|
|
||
| Code that uses `ConfigFileDecryptionProperties::from(&Arc<FileDecryptionProperties>)` | ||
| should be updated to use `try_from`, | ||
| and calls to `FileDecryptionProperties::into` should be changed to `try_into`, | ||
| with appropriate error handling added. | ||
|
|
||
| See [#21602](https://github.com/apache/datafusion/issues/21602) and | ||
| [PR #21603](https://github.com/apache/datafusion/pull/21603) for details. | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This changes a public API from
FromtoTryFrom, so downstream code using(&decrypt).into()orConfigFileDecryptionProperties::from(&decrypt)will stop compiling. Can we add an upgrade note for this change.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, I've added a note to the 54.0.0 upgrade guide now.