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

Handle the case when endpoints rules can return more than one AuthScheme #2736

Merged
merged 1 commit into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -44,29 +59,36 @@ 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<Utils::Json::JsonView> signingRegionArray = mapItemProperty.second.AsArray();
if (signingRegionArray.GetLength() != 1) {
AWS_LOG_WARN(ENDPOINT_AUTH_SCHEME_TAG,
"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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,12 @@ public String getAsCppSourceString(boolean isEndpointProperty, int indent) throw
for (Map.Entry<String, EndpointTestParameter> 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, " "));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

something to explore for later: doing all those indent calculations is so messy. can we generate badly formatted code and just run it through formatter?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

frankly speaking I though about just dumping a json and then parsing it in runtime.
But for now just diving deeper into a rabbit hole.

else
separator = ",\n" + String.join("", Collections.nCopies(indent + 1, " "));
} else {
separator = ", ";
}
Expand Down Expand Up @@ -156,11 +159,17 @@ public String getAsCppSourceString(int indent) throws Exception {
String separator = "";
for (Map.Entry<String, List<EndpointTestParams>> 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 + " ";
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Aws::String, Aws::Vector<EpProp>>;
using ExpEpProps = Aws::UnorderedMap<Aws::String, Aws::Vector<Aws::Vector<EpProp>>>;
using ExpEpHeaders = Aws::UnorderedMap<Aws::String, Aws::Vector<Aws::String>>;

class ${metadata.classNamePrefix}EndpointProviderTests : public ::testing::TestWithParam<size_t> {};
Expand Down Expand Up @@ -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<Aws::String> 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<EpProp>& 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());
Expand Down
Loading