From a2d12d368fd17d68b53dcac5168d3be46f75a465 Mon Sep 17 00:00:00 2001 From: SergeyRyabinin Date: Tue, 7 Nov 2023 21:38:18 +0000 Subject: [PATCH] Handle the case when endpoints rules can return more than one Auth Scheme by selecting the first/highest priority one --- .../internal/AWSEndpointAttribute.cpp | 32 ++++++++++++++++--- .../domainmodels/endpoints/EndpointTests.java | 17 +++++++--- .../ServiceEndpointRulesTests.vm | 18 +++++++++-- 3 files changed, 56 insertions(+), 11 deletions(-) diff --git a/src/aws-cpp-sdk-core/source/endpoint/internal/AWSEndpointAttribute.cpp b/src/aws-cpp-sdk-core/source/endpoint/internal/AWSEndpointAttribute.cpp index 5c295bb1325..4a70e2ca663 100644 --- a/src/aws-cpp-sdk-core/source/endpoint/internal/AWSEndpointAttribute.cpp +++ b/src/aws-cpp-sdk-core/source/endpoint/internal/AWSEndpointAttribute.cpp @@ -26,6 +26,21 @@ Aws::String CrtToSdkSignerName(const Aws::String& crtSignerName) return sdkSigner; } +size_t GetAuthSchemePriority(const Aws::String& authSchemeName) +{ + if(authSchemeName == "NullSigner" || authSchemeName.empty()) + return 0; + if(authSchemeName == "SignatureV4") + return 1; + if(authSchemeName == "AsymmetricSignatureV4") + return 2; + if(authSchemeName == "Bearer") + return 2; + + return 0; // unknown thus unsupported +} + + Aws::Internal::Endpoint::EndpointAttributes Aws::Internal::Endpoint::EndpointAttributes::BuildEndpointAttributesFromJson(const Aws::String& iJsonStr) { @@ -44,14 +59,15 @@ Aws::Internal::Endpoint::EndpointAttributes::BuildEndpointAttributesFromJson(con for (size_t arrayIdx = 0; arrayIdx < jsonAuthSchemeArray.GetLength(); ++arrayIdx) { const Utils::Json::JsonView& property = jsonAuthSchemeArray.GetItem(arrayIdx); + Aws::Internal::Endpoint::EndpointAuthScheme currentAuthScheme; for (const auto& mapItemProperty : property.GetAllObjects()) { if (mapItemProperty.first == "name") { - authScheme.SetName(CrtToSdkSignerName(mapItemProperty.second.AsString())); + currentAuthScheme.SetName(CrtToSdkSignerName(mapItemProperty.second.AsString())); } else if (mapItemProperty.first == "signingName") { - authScheme.SetSigningName(mapItemProperty.second.AsString()); + currentAuthScheme.SetSigningName(mapItemProperty.second.AsString()); } else if (mapItemProperty.first == "signingRegion") { - authScheme.SetSigningRegion(mapItemProperty.second.AsString()); + currentAuthScheme.SetSigningRegion(mapItemProperty.second.AsString()); } else if (mapItemProperty.first == "signingRegionSet") { Aws::Utils::Array signingRegionArray = mapItemProperty.second.AsArray(); if (signingRegionArray.GetLength() != 1) { @@ -59,14 +75,20 @@ Aws::Internal::Endpoint::EndpointAttributes::BuildEndpointAttributesFromJson(con "Signing region set size is not equal to 1"); } if (signingRegionArray.GetLength() > 0) { - authScheme.SetSigningRegionSet(signingRegionArray.GetItem(0).AsString()); + currentAuthScheme.SetSigningRegionSet(signingRegionArray.GetItem(0).AsString()); } } else if (mapItemProperty.first == "disableDoubleEncoding") { - authScheme.SetDisableDoubleEncoding(mapItemProperty.second.AsBool()); + currentAuthScheme.SetDisableDoubleEncoding(mapItemProperty.second.AsBool()); } else { AWS_LOG_WARN(ENDPOINT_AUTH_SCHEME_TAG, Aws::String("Unknown Endpoint authSchemes attribute property: " + mapItemProperty.first).c_str()); } } + /* Can't decide if both (i.e. SigV4 and Bearer is present, fail in debug and use first resolved by rules */ + assert(GetAuthSchemePriority(currentAuthScheme.GetName()) != GetAuthSchemePriority(authScheme.GetName())); + if (GetAuthSchemePriority(currentAuthScheme.GetName()) > GetAuthSchemePriority(authScheme.GetName())) + { + authScheme = std::move(currentAuthScheme); + } } } else { AWS_LOG_WARN(ENDPOINT_AUTH_SCHEME_TAG, Aws::String("Unknown Endpoint Attribute: " + mapItemAttribute.first).c_str()); diff --git a/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/domainmodels/endpoints/EndpointTests.java b/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/domainmodels/endpoints/EndpointTests.java index 77d4412b86e..ad5363c3574 100644 --- a/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/domainmodels/endpoints/EndpointTests.java +++ b/tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/domainmodels/endpoints/EndpointTests.java @@ -67,9 +67,12 @@ public String getAsCppSourceString(boolean isEndpointProperty, int indent) throw for (Map.Entry paramEntry : this.entrySet()) { builder.append(separator); builder.append(paramEntry.getValue().getAsCppSourceString(isEndpointProperty)); - if (builder.length() > onPreviousLinesLength + 100) { + if (builder.length() > onPreviousLinesLength + 150) { onPreviousLinesLength = builder.length(); - separator = ",\n" + String.join("", Collections.nCopies(indent + 1, " "));; + if (isEndpointProperty) + separator = ",\n" + String.join("", Collections.nCopies(indent + 3, " ")); + else + separator = ",\n" + String.join("", Collections.nCopies(indent + 1, " ")); } else { separator = ", "; } @@ -156,11 +159,17 @@ public String getAsCppSourceString(int indent) throws Exception { String separator = ""; for (Map.Entry> propEntry : properties.entrySet()) { builder.append(separator); - builder.append("{\"").append(propEntry.getKey()).append("\", "); + builder.append("{\"").append(propEntry.getKey()).append("\", {"); + boolean atLeastOneEpParamWritten = false; for (EndpointTestParams epParam : propEntry.getValue()) { + if (atLeastOneEpParamWritten){ + builder.append(",\n"); + builder.append(String.join("", Collections.nCopies(indent + 24 + propEntry.getKey().length(), " "))); + } builder.append(epParam.getAsCppSourceString(true, indent + 22 + propEntry.getKey().length())); + atLeastOneEpParamWritten = true; } - builder.append("}"); + builder.append("}}"); separator = "," + indentStr + " "; } } diff --git a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/generatedtests/ServiceEndpointRulesTests.vm b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/generatedtests/ServiceEndpointRulesTests.vm index 4ad574de717..38b0698eb9c 100644 --- a/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/generatedtests/ServiceEndpointRulesTests.vm +++ b/tools/code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity/cpp/generatedtests/ServiceEndpointRulesTests.vm @@ -18,7 +18,7 @@ using ResolveEndpointOutcome = Aws::Endpoint::ResolveEndpointOutcome; using EpParam = Aws::Endpoint::EndpointParameter; using EpProp = Aws::Endpoint::EndpointParameter; // just a container to store test expectations -using ExpEpProps = Aws::UnorderedMap>; +using ExpEpProps = Aws::UnorderedMap>>; using ExpEpHeaders = Aws::UnorderedMap>; class ${metadata.classNamePrefix}EndpointProviderTests : public ::testing::TestWithParam {}; @@ -100,9 +100,23 @@ void ValidateOutcome(const ResolveEndpointOutcome& outcome, const ${metadata.cla const auto expAuthSchemesIt = expect.endpoint.properties.find("authSchemes"); if (expAuthSchemesIt != expect.endpoint.properties.end()) { + // in the list of AuthSchemes, select the one with a highest priority + const Aws::Vector priotityList = {"sigv4a", "sigv4", "bearer", "none", ""}; + const auto expectedAuthSchemePropsIt = std::find_first_of(expAuthSchemesIt->second.begin(), expAuthSchemesIt->second.end(), + priotityList.begin(), priotityList.end(), [](const Aws::Vector& props, const Aws::String& expName) + { + const auto& propNameIt = std::find_if(props.begin(), props.end(), [](const EpProp& prop) + { + return prop.GetName() == "name"; + }); + assert(propNameIt != props.end()); + return propNameIt->GetStrValueNoCheck() == expName; + }); + assert(expectedAuthSchemePropsIt != expAuthSchemesIt->second.end()); + const auto& endpointResultAttrs = outcome.GetResult().GetAttributes(); ASSERT_TRUE(endpointResultAttrs) << "Expected non-empty EndpointAttributes (authSchemes)"; - for (const auto& expProperty : expAuthSchemesIt->second) + for (const auto& expProperty : *expectedAuthSchemePropsIt) { if (expProperty.GetName() == "name") { ASSERT_TRUE(!endpointResultAttrs->authScheme.GetName().empty());