Skip to content
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

Fix optional auth in the orchestrator #2808

Merged
merged 11 commits into from
Jun 26, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -250,11 +250,14 @@ mod test {
.await
.unwrap()
.with_provider_config($provider_config_builder)
.$func(|conf| async {
crate::default_provider::credentials::Builder::default()
.configure(conf)
.build()
.await
.$func(|conf| {
let conf = conf.clone();
async move {
crate::default_provider::credentials::Builder::default()
.configure(conf)
.build()
.await
}
})
.await
}
Expand Down
90 changes: 71 additions & 19 deletions aws/rust-runtime/aws-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,17 @@ mod loader {
use crate::profile::profile_file::ProfileFiles;
use crate::provider_config::ProviderConfig;

#[derive(Default, Debug)]
enum CredentialsProviderOption {
/// No provider was set by the user. We can set up the default credentials provider chain.
#[default]
NotSet,
/// The credentials provider was explicitly unset. Do not set up a default chain.
ExplicitlyUnset,
/// Use the given credentials provider.
Set(SharedCredentialsProvider),
}

/// Load a cross-service [`SdkConfig`](aws_types::SdkConfig) from the environment
///
/// This builder supports overriding individual components of the generated config. Overriding a component
Expand All @@ -181,7 +192,7 @@ mod loader {
pub struct ConfigLoader {
app_name: Option<AppName>,
credentials_cache: Option<CredentialsCache>,
credentials_provider: Option<SharedCredentialsProvider>,
credentials_provider: CredentialsProviderOption,
endpoint_url: Option<String>,
region: Option<Box<dyn ProvideRegion>>,
retry_config: Option<RetryConfig>,
Expand Down Expand Up @@ -348,7 +359,33 @@ mod loader {
mut self,
credentials_provider: impl ProvideCredentials + 'static,
) -> Self {
self.credentials_provider = Some(SharedCredentialsProvider::new(credentials_provider));
self.credentials_provider = CredentialsProviderOption::Set(
SharedCredentialsProvider::new(credentials_provider),
);
self
}

// TODO(enableNewSmithyRuntimeLaunch): Remove the doc hidden from this function
#[doc(hidden)]
/// Don't use credentials to sign requests.
///
/// Turning off signing with credentials is necessary in some cases, such as using
/// anonymous auth for S3, calling operations in STS that don't require a signature,
/// or using token-based auth.
///
/// # Examples
///
/// Turn off credentials in order to call a service without signing:
/// ```no_run
/// # async fn create_config() {
/// let config = aws_config::from_env()
/// .no_credentials()
/// .load()
/// .await;
/// # }
/// ```
pub fn no_credentials(mut self) -> Self {
self.credentials_provider = CredentialsProviderOption::ExplicitlyUnset;
self
}

Expand Down Expand Up @@ -570,13 +607,28 @@ mod loader {
.http_connector
.unwrap_or_else(|| HttpConnector::ConnectorFn(Arc::new(default_connector)));

let credentials_cache = self.credentials_cache.unwrap_or_else(|| {
let mut builder = CredentialsCache::lazy_builder().time_source(
aws_credential_types::time_source::TimeSource::shared(conf.time_source()),
);
builder.set_sleep(conf.sleep());
builder.into_credentials_cache()
});
let credentials_provider = match self.credentials_provider {
CredentialsProviderOption::Set(provider) => Some(provider),
CredentialsProviderOption::NotSet => {
let mut builder =
credentials::DefaultCredentialsChain::builder().configure(conf.clone());
builder.set_region(region.clone());
Some(SharedCredentialsProvider::new(builder.build().await))
}
CredentialsProviderOption::ExplicitlyUnset => None,
};

let credentials_cache = if credentials_provider.is_some() {
Some(self.credentials_cache.unwrap_or_else(|| {
let mut builder = CredentialsCache::lazy_builder().time_source(
aws_credential_types::time_source::TimeSource::shared(conf.time_source()),
);
builder.set_sleep(conf.sleep());
builder.into_credentials_cache()
}))
} else {
None
};

let use_fips = if let Some(use_fips) = self.use_fips {
Some(use_fips)
Expand All @@ -590,26 +642,18 @@ mod loader {
use_dual_stack_provider(&conf).await
};

let credentials_provider = if let Some(provider) = self.credentials_provider {
provider
} else {
let mut builder = credentials::DefaultCredentialsChain::builder().configure(conf);
builder.set_region(region.clone());
SharedCredentialsProvider::new(builder.build().await)
};

let ts = self.time_source.unwrap_or_default();

let mut builder = SdkConfig::builder()
.region(region)
.retry_config(retry_config)
.timeout_config(timeout_config)
.credentials_cache(credentials_cache)
.credentials_provider(credentials_provider)
.time_source(ts)
.http_connector(http_connector);

builder.set_app_name(app_name);
builder.set_credentials_cache(credentials_cache);
builder.set_credentials_provider(credentials_provider);
builder.set_sleep_impl(sleep_impl);
builder.set_endpoint_url(self.endpoint_url);
builder.set_use_fips(use_fips);
Expand Down Expand Up @@ -719,5 +763,13 @@ mod loader {
let conf = base_conf().app_name(app_name.clone()).load().await;
assert_eq!(Some(&app_name), conf.app_name());
}

#[cfg(aws_sdk_orchestrator_mode)]
#[tokio::test]
async fn disable_default_credentials() {
let config = from_env().no_credentials().load().await;
assert!(config.credentials_cache().is_none());
assert!(config.credentials_provider().is_none());
}
}
}
4 changes: 1 addition & 3 deletions aws/rust-runtime/aws-config/src/sts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ pub use assume_role::{AssumeRoleProvider, AssumeRoleProviderBuilder};
mod assume_role;

use crate::connector::expect_connector;
use aws_credential_types::cache::CredentialsCache;
use aws_sdk_sts::config::Builder as StsConfigBuilder;
use aws_smithy_types::retry::RetryConfig;

Expand All @@ -22,8 +21,7 @@ impl crate::provider_config::ProviderConfig {
.http_connector(expect_connector(self.connector(&Default::default())))
.retry_config(RetryConfig::standard())
.region(self.region())
.time_source(self.time_source())
.credentials_cache(CredentialsCache::no_caching());
.time_source(self.time_source());
builder.set_sleep_impl(self.sleep());
builder
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ use aws_sigv4::http_request::SignableBody;
use aws_smithy_http::body::SdkBody;
use aws_smithy_http::byte_stream;
use aws_smithy_runtime_api::box_error::BoxError;
use aws_smithy_runtime_api::client::config_bag_accessors::ConfigBagAccessors;
use aws_smithy_runtime_api::client::interceptors::context::{
BeforeSerializationInterceptorContextMut, BeforeTransmitInterceptorContextMut,
};
use aws_smithy_runtime_api::client::interceptors::Interceptor;
use aws_smithy_runtime_api::client::orchestrator::{ConfigBagAccessors, LoadedRequestBody};
use aws_smithy_runtime_api::client::orchestrator::LoadedRequestBody;
use aws_smithy_types::config_bag::ConfigBag;
use bytes::Bytes;
use http::header::{HeaderName, HeaderValue};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ use aws_sigv4::http_request::SignableBody;
use aws_smithy_async::time::{SharedTimeSource, StaticTimeSource};
use aws_smithy_runtime::client::retries::strategy::NeverRetryStrategy;
use aws_smithy_runtime_api::box_error::BoxError;
use aws_smithy_runtime_api::client::config_bag_accessors::ConfigBagAccessors;
use aws_smithy_runtime_api::client::interceptors::context::{
BeforeSerializationInterceptorContextMut, BeforeTransmitInterceptorContextMut,
};
use aws_smithy_runtime_api::client::interceptors::{
disable_interceptor, Interceptor, InterceptorRegistrar, SharedInterceptor,
};
use aws_smithy_runtime_api::client::orchestrator::ConfigBagAccessors;
use aws_smithy_runtime_api::client::retries::DynRetryStrategy;
use aws_smithy_runtime_api::client::runtime_plugin::RuntimePlugin;
use aws_smithy_types::config_bag::{ConfigBag, FrozenLayer, Layer};
Expand Down
13 changes: 8 additions & 5 deletions aws/rust-runtime/aws-runtime/src/auth/sigv4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,11 @@ use aws_smithy_runtime_api::box_error::BoxError;
use aws_smithy_runtime_api::client::auth::{
AuthSchemeEndpointConfig, AuthSchemeId, HttpAuthScheme, HttpRequestSigner,
};
use aws_smithy_runtime_api::client::identity::{Identity, IdentityResolver, IdentityResolvers};
use aws_smithy_runtime_api::client::orchestrator::{ConfigBagAccessors, HttpRequest};
use aws_smithy_runtime_api::client::config_bag_accessors::ConfigBagAccessors;
use aws_smithy_runtime_api::client::identity::{
Identity, IdentityResolvers, SharedIdentityResolver,
};
use aws_smithy_runtime_api::client::orchestrator::HttpRequest;
use aws_smithy_types::config_bag::{ConfigBag, Storable, StoreReplace};
use aws_smithy_types::Document;
use aws_types::region::{Region, SigningRegion};
Expand Down Expand Up @@ -94,10 +97,10 @@ impl HttpAuthScheme for SigV4HttpAuthScheme {
SCHEME_ID
}

fn identity_resolver<'a>(
fn identity_resolver(
&self,
identity_resolvers: &'a IdentityResolvers,
) -> Option<&'a dyn IdentityResolver> {
identity_resolvers: &IdentityResolvers,
) -> Option<SharedIdentityResolver> {
identity_resolvers.identity_resolver(self.scheme_id())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ class CustomizableOperationTestHelpers(runtimeConfig: RuntimeConfig) :
.resolve("user_agent::AwsUserAgent"),
"BeforeTransmitInterceptorContextMut" to RuntimeType.beforeTransmitInterceptorContextMut(runtimeConfig),
"ConfigBag" to RuntimeType.configBag(runtimeConfig),
"ConfigBagAccessors" to RuntimeType.smithyRuntimeApi(runtimeConfig)
.resolve("client::orchestrator::ConfigBagAccessors"),
"ConfigBagAccessors" to RuntimeType.configBagAccessors(runtimeConfig),
"http" to CargoDependency.Http.toType(),
"InterceptorContext" to RuntimeType.interceptorContext(runtimeConfig),
"SharedTimeSource" to CargoDependency.smithyAsync(runtimeConfig).withFeature("test-util").toType()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import software.amazon.smithy.model.traits.HttpQueryTrait
import software.amazon.smithy.model.traits.HttpTrait
import software.amazon.smithy.model.transform.ModelTransformer
import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.client.smithy.ClientRustSettings
import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegenDecorator
import software.amazon.smithy.rust.codegen.client.smithy.generators.OperationCustomization
import software.amazon.smithy.rust.codegen.client.smithy.generators.OperationSection
Expand Down Expand Up @@ -113,7 +114,7 @@ class AwsPresigningDecorator internal constructor(
/**
* Adds presignable trait to known presignable operations and creates synthetic presignable shapes for codegen
*/
override fun transformModel(service: ServiceShape, model: Model): Model {
override fun transformModel(service: ServiceShape, model: Model, settings: ClientRustSettings): Model {
val modelWithSynthetics = addSyntheticOperations(model)
val presignableTransforms = mutableListOf<PresignModelTransform>()
val intermediate = ModelTransformer.create().mapShapes(modelWithSynthetics) { shape ->
Expand Down Expand Up @@ -369,8 +370,7 @@ class AwsPresignedFluentBuilderMethod(
}
""",
"AlternateSerializer" to alternateSerializer(operationShape),
"ConfigBagAccessors" to RuntimeType.smithyRuntimeApi(codegenContext.runtimeConfig)
.resolve("client::orchestrator::ConfigBagAccessors"),
"ConfigBagAccessors" to RuntimeType.configBagAccessors(runtimeConfig),
"FrozenLayer" to smithyTypes.resolve("config_bag::FrozenLayer"),
"Layer" to smithyTypes.resolve("config_bag::Layer"),
"RuntimePlugin" to RuntimeType.runtimePlugin(codegenContext.runtimeConfig),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ class CredentialCacheConfig(codegenContext: ClientCodegenContext) : ConfigCustom
rustTemplate(
"""
/// Returns the credentials cache.
pub fn credentials_cache(&self) -> #{SharedCredentialsCache} {
self.inner.load::<#{SharedCredentialsCache}>().expect("credentials cache should be set").clone()
pub fn credentials_cache(&self) -> #{Option}<#{SharedCredentialsCache}> {
self.inner.load::<#{SharedCredentialsCache}>().cloned()
}
""",
*codegenScope,
Expand Down Expand Up @@ -145,9 +145,8 @@ class CredentialCacheConfig(codegenContext: ClientCodegenContext) : ConfigCustom
if (runtimeMode.defaultToOrchestrator) {
rustTemplate(
"""
layer.store_put(
layer.load::<#{CredentialsCache}>()
.cloned()
if let Some(credentials_provider) = layer.load::<#{SharedCredentialsProvider}>().cloned() {
let cache_config = layer.load::<#{CredentialsCache}>().cloned()
.unwrap_or_else({
let sleep = layer.load::<#{SharedAsyncSleep}>().cloned();
|| match sleep {
Expand All @@ -158,11 +157,10 @@ class CredentialCacheConfig(codegenContext: ClientCodegenContext) : ConfigCustom
}
None => #{CredentialsCache}::lazy(),
}
})
.create_cache(layer.load::<#{SharedCredentialsProvider}>().cloned().unwrap_or_else(|| {
#{SharedCredentialsProvider}::new(#{DefaultProvider})
}))
);
});
let shared_credentials_cache = cache_config.create_cache(credentials_provider);
layer.store_put(shared_credentials_cache);
}
""",
*codegenScope,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import software.amazon.smithy.rust.codegen.client.smithy.generators.config.Confi
import software.amazon.smithy.rust.codegen.client.smithy.generators.config.ServiceConfig
import software.amazon.smithy.rust.codegen.core.rustlang.Writable
import software.amazon.smithy.rust.codegen.core.rustlang.rust
import software.amazon.smithy.rust.codegen.core.rustlang.rustBlockTemplate
import software.amazon.smithy.rust.codegen.core.rustlang.rustTemplate
import software.amazon.smithy.rust.codegen.core.rustlang.writable
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
Expand Down Expand Up @@ -138,24 +139,24 @@ class CredentialsIdentityResolverRegistration(
override fun section(section: ServiceRuntimePluginSection): Writable = writable {
when (section) {
is ServiceRuntimePluginSection.AdditionalConfig -> {
rustTemplate(
"""
cfg.set_identity_resolvers(
#{IdentityResolvers}::builder()
.identity_resolver(
#{SIGV4_SCHEME_ID},
#{CredentialsIdentityResolver}::new(self.handle.conf.credentials_cache())
)
.build()
);
""",
"SIGV4_SCHEME_ID" to AwsRuntimeType.awsRuntime(runtimeConfig)
.resolve("auth::sigv4::SCHEME_ID"),
"CredentialsIdentityResolver" to AwsRuntimeType.awsRuntime(runtimeConfig)
.resolve("identity::credentials::CredentialsIdentityResolver"),
"IdentityResolvers" to RuntimeType.smithyRuntimeApi(runtimeConfig)
.resolve("client::identity::IdentityResolvers"),
)
rustBlockTemplate("if let Some(credentials_cache) = self.handle.conf.credentials_cache()") {
section.registerIdentityResolver(this, runtimeConfig) {
rustTemplate(
"""
#{SIGV4_SCHEME_ID},
#{SharedIdentityResolver}::new(
#{CredentialsIdentityResolver}::new(credentials_cache),
),
""",
"SIGV4_SCHEME_ID" to AwsRuntimeType.awsRuntime(runtimeConfig)
.resolve("auth::sigv4::SCHEME_ID"),
"CredentialsIdentityResolver" to AwsRuntimeType.awsRuntime(runtimeConfig)
.resolve("identity::credentials::CredentialsIdentityResolver"),
"SharedIdentityResolver" to RuntimeType.smithyRuntimeApi(runtimeConfig)
.resolve("client::identity::SharedIdentityResolver"),
)
}
}
}
else -> {}
}
Expand Down
Loading
Loading