Unverified Commit e07aa766 authored by John DiSanti's avatar John DiSanti Committed by GitHub
Browse files

Add HTTP basic and bearer auth support to the orchestrator (#2622)



## Motivation and Context
This PR adds support for Smithy's `@httpBasicAuth` and `@httpBearerAuth`
auth schemes, and ports the `@httpApiKeyAuth` scheme to the
orchestrator. This is prerequisite work for supporting Amazon
CodeCatalyst since that requires bearer auth.

This PR also fixes a bug in auth orchestrator that caused an error if no
identity is present for a scheme even when an identity for a lower
priority scheme is available.

----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._

---------

Co-authored-by: default avatarZelda Hessler <zhessler@amazon.com>
parent 2ebbfad4
Loading
Loading
Loading
Loading
+2 −3
Original line number Diff line number Diff line
@@ -12,10 +12,9 @@ pub mod sigv4 {
        UriPathNormalizationMode,
    };
    use aws_smithy_http::property_bag::PropertyBag;
    use aws_smithy_runtime_api::client::identity::Identity;
    use aws_smithy_runtime_api::client::identity::{Identity, IdentityResolver, IdentityResolvers};
    use aws_smithy_runtime_api::client::orchestrator::{
        BoxError, HttpAuthScheme, HttpRequest, HttpRequestSigner, IdentityResolver,
        IdentityResolvers,
        BoxError, HttpAuthScheme, HttpRequest, HttpRequestSigner,
    };
    use aws_types::region::SigningRegion;
    use aws_types::SigningService;
+5 −7
Original line number Diff line number Diff line
@@ -7,10 +7,8 @@
pub mod credentials {
    use aws_credential_types::cache::SharedCredentialsCache;
    use aws_smithy_http::property_bag::PropertyBag;
    use aws_smithy_runtime_api::client::identity::Identity;
    use aws_smithy_runtime_api::client::orchestrator::{
        BoxError, BoxFallibleFut, IdentityResolver,
    };
    use aws_smithy_runtime_api::client::identity::{Identity, IdentityResolver};
    use aws_smithy_runtime_api::client::orchestrator::{BoxError, Future};

    /// Smithy identity resolver for AWS credentials.
    #[derive(Debug)]
@@ -26,13 +24,13 @@ pub mod credentials {
    }

    impl IdentityResolver for CredentialsIdentityResolver {
        fn resolve_identity(&self, _identity_properties: &PropertyBag) -> BoxFallibleFut<Identity> {
        fn resolve_identity(&self, _identity_properties: &PropertyBag) -> Future<Identity> {
            let cache = self.credentials_cache.clone();
            Box::pin(async move {
            Future::new(Box::pin(async move {
                let credentials = cache.as_ref().provide_cached_credentials().await?;
                let expiration = credentials.expiry();
                Result::<_, BoxError>::Ok(Identity::new(credentials, expiration))
            })
            }))
        }
    }
}
+2 −33
Original line number Diff line number Diff line
@@ -5,7 +5,6 @@

package software.amazon.smithy.rustsdk

import software.amazon.smithy.codegen.core.Symbol
import software.amazon.smithy.rust.codegen.client.smithy.ClientCodegenContext
import software.amazon.smithy.rust.codegen.client.smithy.ClientRustModule
import software.amazon.smithy.rust.codegen.client.smithy.customize.ClientCodegenDecorator
@@ -14,6 +13,7 @@ import software.amazon.smithy.rust.codegen.client.smithy.generators.client.Fluen
import software.amazon.smithy.rust.codegen.client.smithy.generators.client.FluentClientGenerator
import software.amazon.smithy.rust.codegen.client.smithy.generators.client.FluentClientGenerics
import software.amazon.smithy.rust.codegen.client.smithy.generators.client.FluentClientSection
import software.amazon.smithy.rust.codegen.client.smithy.generators.client.NoClientGenerics
import software.amazon.smithy.rust.codegen.core.rustlang.Attribute
import software.amazon.smithy.rust.codegen.core.rustlang.Feature
import software.amazon.smithy.rust.codegen.core.rustlang.GenericTypeArg
@@ -50,37 +50,6 @@ private class Types(runtimeConfig: RuntimeConfig) {
    val timeoutConfig = smithyTypes.resolve("timeout::TimeoutConfig")
}

private class AwsClientGenerics(private val types: Types) : FluentClientGenerics {
    /** Declaration with defaults set */
    override val decl = writable { }

    /** Instantiation of the Smithy client generics */
    override val smithyInst = writable {
        rustTemplate(
            "<#{DynConnector}, #{DynMiddleware}<#{DynConnector}>>",
            "DynConnector" to types.dynConnector,
            "DynMiddleware" to types.dynMiddleware,
        )
    }

    /** Instantiation */
    override val inst = ""

    /** Trait bounds */
    override val bounds = writable { }

    /** Bounds for generated `send()` functions */
    override fun sendBounds(
        operation: Symbol,
        operationOutput: Symbol,
        operationError: Symbol,
        retryClassifier: RuntimeType,
    ): Writable =
        writable { }

    override fun toRustGenerics() = RustGenerics()
}

class AwsFluentClientDecorator : ClientCodegenDecorator {
    override val name: String = "FluentClient"

@@ -90,7 +59,7 @@ class AwsFluentClientDecorator : ClientCodegenDecorator {
    override fun extras(codegenContext: ClientCodegenContext, rustCrate: RustCrate) {
        val runtimeConfig = codegenContext.runtimeConfig
        val types = Types(runtimeConfig)
        val generics = AwsClientGenerics(types)
        val generics = NoClientGenerics(runtimeConfig)
        FluentClientGenerator(
            codegenContext,
            reexportSmithyClientBuilder = false,
+11 −5
Original line number Diff line number Diff line
@@ -112,18 +112,24 @@ class CredentialsIdentityResolverRegistration(

    override fun section(section: ServiceRuntimePluginSection): Writable = writable {
        when (section) {
            is ServiceRuntimePluginSection.IdentityResolver -> {
            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"),
                )
            }
            else -> {}
+6 −3
Original line number Diff line number Diff line
@@ -15,7 +15,9 @@ 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.CodegenContext
import software.amazon.smithy.rust.codegen.core.smithy.RuntimeType
import software.amazon.smithy.rust.codegen.core.util.letIf

// TODO(enableNewSmithyRuntime): Delete this decorator since it's now in `codegen-client`
class HttpConnectorDecorator : ClientCodegenDecorator {
    override val name: String = "HttpConnectorDecorator"
    override val order: Byte = 0
@@ -23,8 +25,9 @@ class HttpConnectorDecorator : ClientCodegenDecorator {
    override fun configCustomizations(
        codegenContext: ClientCodegenContext,
        baseCustomizations: List<ConfigCustomization>,
    ): List<ConfigCustomization> {
        return baseCustomizations + HttpConnectorConfigCustomization(codegenContext)
    ): List<ConfigCustomization> =
        baseCustomizations.letIf(!codegenContext.settings.codegenConfig.enableNewSmithyRuntime) {
            it + HttpConnectorConfigCustomization(codegenContext)
        }
}

Loading