dwsmith1983 commented on code in PR #6059:
URL: https://github.com/apache/datafusion-comet/pull/6059#discussion_r4206409707


##########
native/core/src/parquet/objectstore/azure.rs:
##########
@@ -118,12 +190,426 @@ pub fn create_store(
             .map(|(k, _)| k.as_ref())
             .collect::<Vec<_>>()
     );
+
+    let env: Vec<(String, String)> = env.collect();
+    validate_translated(
+        configs,
+        &translated,
+        account.as_deref(),
+        container.as_deref(),
+        env_token_file(&env).is_some(),
+    )?;
+    let store = build_builder(
+        url,
+        configs,
+        account.as_deref(),
+        container.as_deref(),
+        &translated,
+        env.into_iter(),
+    )
+    .build()?;
+    Ok((Box::new(store), path))
+}
+
+fn config_error(message: String) -> object_store::Error {
+    object_store::Error::Generic {
+        store: "MicrosoftAzure",
+        source: message.into(),
+    }
+}
+
+/// Reject a Hadoop configuration that `object_store` would silently build a 
different
+/// identity from: a blank credential, an auth type or mechanism the native 
scan cannot
+/// build, a named principal with no token file in Hadoop or the environment, 
or a client
+/// secret or token file without the client id and tenant that complete it.
+/// `has_env_token_file` says whether `AZURE_FEDERATED_TOKEN_FILE` is set.
+fn validate_translated(
+    configs: &HashMap<String, String>,
+    translated: &[(AzureConfigKey, String)],
+    account: Option<&str>,
+    container: Option<&str>,
+    has_env_token_file: bool,
+) -> Result<(), object_store::Error> {
+    let account_name = account.unwrap_or("<unknown>");
+    let fail = |reason: String| {
+        Err(config_error(format!(
+            "Hadoop configuration for account {account_name}: {reason}"
+        )))
+    };
+    if let Some(reason) = hadoop_problem(configs, account, container, 
translated) {
+        return fail(reason);
+    }
+    let has = |wanted: AzureConfigKey| translated.iter().any(|(key, _)| *key 
== wanted);
+    let borrows_env_token_file = env_policy(configs, account, container, 
translated)
+        == EnvPolicy::TokenFileOnly
+        && !has(AzureConfigKey::FederatedTokenFile);
+    if borrows_env_token_file && !has_env_token_file {
+        return fail(format!(
+            "the principal named by the Hadoop keys needs a token file from \
+             `{HADOOP_WI_TOKEN_FILE}` or `{ENV_FEDERATED_TOKEN_FILE}`"
+        ));
+    }
+    let mechanism = if has(AzureConfigKey::ClientSecret) {
+        HADOOP_OAUTH_CLIENT_SECRET
+    } else if has(AzureConfigKey::FederatedTokenFile) {
+        HADOOP_WI_TOKEN_FILE

Review Comment:
   The resolver brought this back through the check that decides whether the 
account is configured at all: it read every auth key, so the cyclic 
`${unused.secret}` threw before the mechanism was chosen. Fixed in 092ed362e. A 
key whose read throws inside Hadoop now counts as configured without failing, 
and only the selected mechanism reads its own keys, so SharedKey with that 
unused OAuth secret resolves to SharedKey as Hadoop does. A broken key the 
mechanism does need still fails in Hadoop's words. `AbfsAuthResolverSuite` 
covers the cyclic client secret, the cyclic provider type, and a cyclic key on 
its own.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to