From b2ff9b3c8cfd8fa64d6cd8b14ab73f0d9a63cf23 Mon Sep 17 00:00:00 2001 From: Jack Dockerty Date: Mon, 5 Aug 2024 21:33:36 +0100 Subject: [PATCH 01/11] feat: add no_authentication fields --- core/src/services/gcs/backend.rs | 12 ++++++++++++ core/src/services/gcs/core.rs | 2 ++ 2 files changed, 14 insertions(+) diff --git a/core/src/services/gcs/backend.rs b/core/src/services/gcs/backend.rs index afeb38653d66..6b58bec20e38 100644 --- a/core/src/services/gcs/backend.rs +++ b/core/src/services/gcs/backend.rs @@ -66,6 +66,10 @@ pub struct GcsConfig { pub predefined_acl: Option, /// The default storage class used by gcs. pub default_storage_class: Option, + /// Explicitly disable authentication + /// + /// Used for testing purposes against storage emulators. + pub no_authentication: bool, } impl Debug for GcsConfig { @@ -234,6 +238,14 @@ impl GcsBuilder { }; self } + + /// Explicitly disable authentication. + /// + /// This is typically only done for testing purposes against storage emulators. + pub fn no_authentication(mut self) -> Self { + self.no_authentication = true; + self + } } impl Builder for GcsBuilder { diff --git a/core/src/services/gcs/core.rs b/core/src/services/gcs/core.rs index ae299abc634d..afd6ac4a4172 100644 --- a/core/src/services/gcs/core.rs +++ b/core/src/services/gcs/core.rs @@ -57,6 +57,8 @@ pub struct GcsCore { pub predefined_acl: Option, pub default_storage_class: Option, + + pub no_authentication: bool, } impl Debug for GcsCore { From ebd48762160689b4546787294ae22008f20126a1 Mon Sep 17 00:00:00 2001 From: Jack Dockerty Date: Mon, 5 Aug 2024 21:32:53 +0100 Subject: [PATCH 02/11] feat: add load_credentials skip from no_authentication --- core/src/services/gcs/backend.rs | 3 ++- core/src/services/gcs/core.rs | 20 +++++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/core/src/services/gcs/backend.rs b/core/src/services/gcs/backend.rs index 6b58bec20e38..dad7dcf0ad6f 100644 --- a/core/src/services/gcs/backend.rs +++ b/core/src/services/gcs/backend.rs @@ -243,7 +243,7 @@ impl GcsBuilder { /// /// This is typically only done for testing purposes against storage emulators. pub fn no_authentication(mut self) -> Self { - self.no_authentication = true; + self.config.no_authentication = true; self } } @@ -329,6 +329,7 @@ impl Builder for GcsBuilder { credential_loader: cred_loader, predefined_acl: self.config.predefined_acl.clone(), default_storage_class: self.config.default_storage_class.clone(), + no_authentication: self.config.no_authentication, }), }; diff --git a/core/src/services/gcs/core.rs b/core/src/services/gcs/core.rs index afd6ac4a4172..fe25c6e6d791 100644 --- a/core/src/services/gcs/core.rs +++ b/core/src/services/gcs/core.rs @@ -91,14 +91,18 @@ impl GcsCore { } } - fn load_credential(&self) -> Result { + fn load_credential(&self) -> Result> { + if self.no_authentication { + return Ok(None); + } + let cred = self .credential_loader .load() .map_err(new_request_credential_error)?; if let Some(cred) = cred { - Ok(cred) + Ok(Some(cred)) } else { Err(Error::new( ErrorKind::ConfigInvalid, @@ -126,11 +130,13 @@ impl GcsCore { } pub async fn sign_query(&self, req: &mut Request, duration: Duration) -> Result<()> { - let cred = self.load_credential()?; - - self.signer - .sign_query(req, duration, &cred) - .map_err(new_request_sign_error)?; + if let Some(cred) = self.load_credential()? { + self.signer + .sign_query(req, duration, &cred) + .map_err(new_request_sign_error)?; + } else { + return Ok(()); + } // Always remove host header, let users' client to set it based on HTTP // version. From 46d8626d88d6700817f9a045ea88b08c1d5395a7 Mon Sep 17 00:00:00 2001 From: Jack Dockerty Date: Mon, 5 Aug 2024 22:24:51 +0100 Subject: [PATCH 03/11] fix: skip signing with no auth --- core/src/services/gcs/core.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/src/services/gcs/core.rs b/core/src/services/gcs/core.rs index fe25c6e6d791..37a101316475 100644 --- a/core/src/services/gcs/core.rs +++ b/core/src/services/gcs/core.rs @@ -112,6 +112,9 @@ impl GcsCore { } pub async fn sign(&self, req: &mut Request) -> Result<()> { + if self.no_authentication { + return Ok(()); + } let cred = self.load_token().await?; self.signer From 555501ce5d7beb758237451376b3ed83f0c91593 Mon Sep 17 00:00:00 2001 From: Jack Dockerty Date: Tue, 6 Aug 2024 11:59:07 +0100 Subject: [PATCH 04/11] fix: use allow_anonymous similar to s3 --- core/src/services/gcs/backend.rs | 8 ++++---- core/src/services/gcs/core.rs | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core/src/services/gcs/backend.rs b/core/src/services/gcs/backend.rs index dad7dcf0ad6f..9b3ecd500ef0 100644 --- a/core/src/services/gcs/backend.rs +++ b/core/src/services/gcs/backend.rs @@ -69,7 +69,7 @@ pub struct GcsConfig { /// Explicitly disable authentication /// /// Used for testing purposes against storage emulators. - pub no_authentication: bool, + pub allow_anonymous: bool, } impl Debug for GcsConfig { @@ -242,8 +242,8 @@ impl GcsBuilder { /// Explicitly disable authentication. /// /// This is typically only done for testing purposes against storage emulators. - pub fn no_authentication(mut self) -> Self { - self.config.no_authentication = true; + pub fn allow_anonymous(mut self) -> Self { + self.config.allow_anonymous = true; self } } @@ -329,7 +329,7 @@ impl Builder for GcsBuilder { credential_loader: cred_loader, predefined_acl: self.config.predefined_acl.clone(), default_storage_class: self.config.default_storage_class.clone(), - no_authentication: self.config.no_authentication, + allow_anonymous: self.config.no_authentication, }), }; diff --git a/core/src/services/gcs/core.rs b/core/src/services/gcs/core.rs index 37a101316475..bd19a0dcf188 100644 --- a/core/src/services/gcs/core.rs +++ b/core/src/services/gcs/core.rs @@ -58,7 +58,7 @@ pub struct GcsCore { pub predefined_acl: Option, pub default_storage_class: Option, - pub no_authentication: bool, + pub allow_anonymous: bool, } impl Debug for GcsCore { @@ -92,7 +92,7 @@ impl GcsCore { } fn load_credential(&self) -> Result> { - if self.no_authentication { + if self.allow_anonymous { return Ok(None); } @@ -112,7 +112,7 @@ impl GcsCore { } pub async fn sign(&self, req: &mut Request) -> Result<()> { - if self.no_authentication { + if self.allow_anonymous { return Ok(()); } let cred = self.load_token().await?; From 407177920ec63ac42c631dceff2b1ad1dd36a0fa Mon Sep 17 00:00:00 2001 From: Jack Dockerty Date: Tue, 6 Aug 2024 11:59:24 +0100 Subject: [PATCH 05/11] docs: clarify allow_anonymous --- core/src/services/gcs/backend.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/core/src/services/gcs/backend.rs b/core/src/services/gcs/backend.rs index 9b3ecd500ef0..77db543dafab 100644 --- a/core/src/services/gcs/backend.rs +++ b/core/src/services/gcs/backend.rs @@ -66,9 +66,8 @@ pub struct GcsConfig { pub predefined_acl: Option, /// The default storage class used by gcs. pub default_storage_class: Option, - /// Explicitly disable authentication - /// - /// Used for testing purposes against storage emulators. + /// Explicitly allow anonymous access, such as for publicly available buckets + /// which do not require authentication. pub allow_anonymous: bool, } @@ -329,7 +328,7 @@ impl Builder for GcsBuilder { credential_loader: cred_loader, predefined_acl: self.config.predefined_acl.clone(), default_storage_class: self.config.default_storage_class.clone(), - allow_anonymous: self.config.no_authentication, + allow_anonymous: self.config.allow_anonymous, }), }; From 8acce4494d15fd082e2ba46d3c72d976aeedfaea Mon Sep 17 00:00:00 2001 From: Jack Dockerty Date: Tue, 6 Aug 2024 12:21:02 +0100 Subject: [PATCH 06/11] feat: add disable vm/config values --- core/src/services/gcs/backend.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/core/src/services/gcs/backend.rs b/core/src/services/gcs/backend.rs index 77db543dafab..dd75b829f29d 100644 --- a/core/src/services/gcs/backend.rs +++ b/core/src/services/gcs/backend.rs @@ -69,6 +69,11 @@ pub struct GcsConfig { /// Explicitly allow anonymous access, such as for publicly available buckets /// which do not require authentication. pub allow_anonymous: bool, + /// Disable attempting to load credentials from the GCE metadata server when + /// running within Google Cloud. + pub disable_vm_metadata: bool, + /// Disable loading configuration from the environment. + pub disable_config_load: bool, } impl Debug for GcsConfig { @@ -208,6 +213,18 @@ impl GcsBuilder { self } + /// Disable attempting to load credentials from the GCE metadata server. + pub fn disable_vm_metadata(mut self) -> Self { + self.config.disable_vm_metadata = true; + self + } + + /// Disable loading configuration from the environment. + pub fn disable_config_load(mut self) -> Self { + self.config.disable_config_load = true; + self + } + /// Set the predefined acl for GCS. /// /// Available values are: From d3d3288553e7c09bf812ee44ad7c4a9711031115 Mon Sep 17 00:00:00 2001 From: Jack Dockerty Date: Tue, 6 Aug 2024 12:47:32 +0100 Subject: [PATCH 07/11] feat: wire up credential/token skip --- core/src/services/gcs/backend.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/core/src/services/gcs/backend.rs b/core/src/services/gcs/backend.rs index dd75b829f29d..ac67a89b97a4 100644 --- a/core/src/services/gcs/backend.rs +++ b/core/src/services/gcs/backend.rs @@ -315,6 +315,10 @@ impl Builder for GcsBuilder { cred_loader = cred_loader.with_disable_well_known_location(); } + if self.config.disable_config_load { + cred_loader = cred_loader.with_disable_env(); + } + let scope = if let Some(scope) = &self.config.scope { scope } else { @@ -332,6 +336,10 @@ impl Builder for GcsBuilder { token_loader = token_loader.with_customized_token_loader(loader) } + if self.config.disable_vm_metadata { + token_loader = token_loader.with_disable_vm_metadata(true); + } + let signer = GoogleSigner::new("storage"); let backend = GcsBackend { From 61719e8b461b93c3be03691c4221bbb729bc0f6a Mon Sep 17 00:00:00 2001 From: Jack Dockerty Date: Wed, 7 Aug 2024 14:45:28 +0100 Subject: [PATCH 08/11] docs: allow_anonymous fn comment --- core/src/services/gcs/backend.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/core/src/services/gcs/backend.rs b/core/src/services/gcs/backend.rs index ac67a89b97a4..fa18331f0dcb 100644 --- a/core/src/services/gcs/backend.rs +++ b/core/src/services/gcs/backend.rs @@ -255,9 +255,10 @@ impl GcsBuilder { self } - /// Explicitly disable authentication. + /// Allow anonymous requests. /// - /// This is typically only done for testing purposes against storage emulators. + /// This is typically used for buckets which are open to the public or GCS + /// storage emulators. pub fn allow_anonymous(mut self) -> Self { self.config.allow_anonymous = true; self From ce0b2d40e6b18f615ad8a57d0aa2adb90746f27b Mon Sep 17 00:00:00 2001 From: Jack Dockerty Date: Wed, 7 Aug 2024 14:47:15 +0100 Subject: [PATCH 09/11] feat: disable well known locations for disable_config_load --- core/src/services/gcs/backend.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/src/services/gcs/backend.rs b/core/src/services/gcs/backend.rs index fa18331f0dcb..74cc46d370c1 100644 --- a/core/src/services/gcs/backend.rs +++ b/core/src/services/gcs/backend.rs @@ -317,7 +317,9 @@ impl Builder for GcsBuilder { } if self.config.disable_config_load { - cred_loader = cred_loader.with_disable_env(); + cred_loader = cred_loader + .with_disable_env() + .with_disable_well_known_location(); } let scope = if let Some(scope) = &self.config.scope { From 4d2cf1901050998fcab42124d20538a2db79224c Mon Sep 17 00:00:00 2001 From: Jack Dockerty Date: Wed, 7 Aug 2024 14:55:02 +0100 Subject: [PATCH 10/11] fix: move allow_anonymous to after cred load --- core/src/services/gcs/core.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/core/src/services/gcs/core.rs b/core/src/services/gcs/core.rs index bd19a0dcf188..0b9e8ae84c94 100644 --- a/core/src/services/gcs/core.rs +++ b/core/src/services/gcs/core.rs @@ -92,23 +92,23 @@ impl GcsCore { } fn load_credential(&self) -> Result> { - if self.allow_anonymous { - return Ok(None); - } - let cred = self .credential_loader .load() .map_err(new_request_credential_error)?; if let Some(cred) = cred { - Ok(Some(cred)) - } else { - Err(Error::new( - ErrorKind::ConfigInvalid, - "no valid credential found", - )) + return Ok(Some(cred)); } + + if self.allow_anonymous { + return Ok(None); + } + + Err(Error::new( + ErrorKind::ConfigInvalid, + "no valid credential found", + )) } pub async fn sign(&self, req: &mut Request) -> Result<()> { From 04ecbbfe66dfb74ca4586009c09c2e0aaeec6e25 Mon Sep 17 00:00:00 2001 From: Jack Dockerty Date: Wed, 7 Aug 2024 14:56:57 +0100 Subject: [PATCH 11/11] doc: clarify allow_anonymous I've taken the similar description to the s3 backend here --- core/src/services/gcs/backend.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/services/gcs/backend.rs b/core/src/services/gcs/backend.rs index 74cc46d370c1..acda28e91def 100644 --- a/core/src/services/gcs/backend.rs +++ b/core/src/services/gcs/backend.rs @@ -66,8 +66,8 @@ pub struct GcsConfig { pub predefined_acl: Option, /// The default storage class used by gcs. pub default_storage_class: Option, - /// Explicitly allow anonymous access, such as for publicly available buckets - /// which do not require authentication. + /// Allow opendal to send requests without signing when credentials are not + /// loaded. pub allow_anonymous: bool, /// Disable attempting to load credentials from the GCE metadata server when /// running within Google Cloud.