in src/odbc/rsodbc/iam/RsIamHelper.cpp [296:504]
void RsIamHelper::SetIamSettings(
bool isIAMAuth,
RS_IAM_CONN_PROPS_INFO *pIamProps,
RS_PROXY_CONN_PROPS_INFO *pHttpsProps,
RsSettings& settings)
{
RS_LOG_DEBUG("IAMHLP", "RsIamHelper::SetIamSettings");
rs_string temp;
settings.m_iamAuth = isIAMAuth;
SetCommonFederatedAuthSettings(pIamProps, settings);
if(settings.m_iamAuth == true) {
settings.m_username = pIamProps->szUser;
settings.m_password = pIamProps->szPassword;
std::vector<rs_string> hostnameTokens = IAMUtils::TokenizeSetting(settings.m_host, ".");
rs_string workGroup;
rs_string acctId;
rs_string requiredClusterId;
if (hostnameTokens.size() >= 6 && (hostnameTokens[3].find("serverless") != rs_string::npos))
{
/*Serverless_cluster's host examples:
e.g., default.518627716765.us-east-1.redshift-serverless.amazonaws.com
*/
workGroup = hostnameTokens[0];
acctId = hostnameTokens[1];
settings.m_isServerless = true;
if (settings.m_awsRegion.empty()) {
settings.m_awsRegion = hostnameTokens[2];
}
}
else if (hostnameTokens.size() >= 6)
{
/*provisioned_cluster_host examples:
e.g., redshiftj-iam-test.c2mf5zd3u3sv.us-west-2.redshift.amazonaws.com
e.g., redshiftj-iam-test.c2mf5zd3u3sv.us-west-2.redshift.amazonaws.com.cn
*/
requiredClusterId = hostnameTokens[0];
if (settings.m_awsRegion.empty()) {
settings.m_awsRegion = hostnameTokens[2];
}
}
settings.m_isServerless = pIamProps->isServerless;
settings.m_workGroup = pIamProps->szWorkGroup;
std::smatch mProvisioned;
std::smatch mServerless;
std::smatch mNlb;
bool provisionedMatches = std::regex_match(settings.m_host, mProvisioned, hostPattern);
bool serverlessMatches = std::regex_match(settings.m_host, mServerless, serverlessWorkgroupHostPattern);
bool nlbMatches = std::regex_match(settings.m_host, mNlb, nlbHostPattern);
rs_string clusterId;
// replace host value if user has provided a managed VPC URL.
settings.m_managedVpcUrl = pIamProps->szManagedVpcUrl;
if (!settings.m_managedVpcUrl.empty()) {
if (!workGroup.empty()) {
settings.m_workGroup = workGroup;
}
settings.m_host = settings.m_managedVpcUrl;
}
if(provisionedMatches){
RS_LOG_DEBUG("IAMHLP", "Code flow for regular provisioned cluster");
if (strlen(pIamProps->szClusterId) > 0) {
clusterId = pIamProps->szClusterId;
} else {
clusterId = requiredClusterId;
}
}
else if(serverlessMatches){
// serverless vanilla
// do nothing, regular serverless logic flow
RS_LOG_DEBUG("IAMHLP", "Code flow for regular serverless cluster");
settings.m_isServerless=true;
}
else if (nlbMatches && !settings.m_isServerless) {
// Workflow for connection with NLB for provisioned clusters
RS_LOG_DEBUG("IAMHLP", "Code flow for nlb provisioned cluster");
if (strlen(pIamProps->szClusterId) > 0) {
clusterId = pIamProps->szClusterId;
}
}
else if(settings.m_isServerless){
// hostname doesn't match serverless regex but serverless set to true explicitly by user
// when ready for implementation, remove setting of the isServerless property automatically in parseUrl(),
// set it here instead
if(!(settings.m_workGroup.empty())){
// workgroup specified by user - serverless nlb call
// check for serverlessAcctId to enter serverless NLB logic flow, for when we implement this for serverless after server side is ready
// currently do nothing as regular code flow is sufficient
RS_LOG_DEBUG("IAMHLP", "Code flow for nlb serverless cluster");
}
else if (strlen(pIamProps->szClusterId) > 0) {
// Workflow for using GetClusterCredentials API with serverless cluster
RS_LOG_DEBUG("IAMHLP", "Code flow for using GetClusterCredentials with serverless cluster");
clusterId = pIamProps->szClusterId;
settings.m_isServerless = false;
}
else{
// attempt serverless cname call
// currently sets isCname to true which will be asserted on later
RS_LOG_DEBUG("IAMHLP", "Code flow for cname serverless cluster");
settings.m_isCname = true;
}
}
else {
// Workflow for using CNAME with provisioned cluster
RS_LOG_DEBUG("IAMHLP", "Code flow for cname provisioned cluster");
clusterId = pIamProps->szClusterId;
// attempt provisioned cname call
// cluster id will be fetched upon describing custom domain name
settings.m_isCname = true;
}
settings.m_accessKeyID = pIamProps->szAccessKeyID;
settings.m_secretAccessKey = pIamProps->szSecretAccessKey;
settings.m_sessionToken = pIamProps->szSessionToken;
settings.m_accessDuration = pIamProps->lIAMDuration;
if (settings.m_accessDuration > 3600)
settings.m_accessDuration = 3600;
else
if (settings.m_accessDuration < 900)
settings.m_accessDuration = 900;
settings.m_clusterIdentifer = clusterId;
RS_LOG_DEBUG("IAMHLP", "Cluster Identifier:%s",
settings.m_clusterIdentifer.c_str());
//settings.m_clusterIdentifer = pIamProps->szClusterId;
if(!settings.m_isServerless && !settings.m_isCname && (settings.m_clusterIdentifer.empty())){
RS_LOG_DEBUG("IAMHLP", "Invalid connection property setting. cluster_identifier must be provided when IAM is enabled");
}
settings.m_dbUser = pIamProps->szDbUser;
temp = pIamProps->szDbGroups;
settings.m_dbGroups = IAMUtils::convertStringToWstring(temp);
settings.m_awsProfile = pIamProps->szProfile;
temp = pIamProps->szStsEndpointUrl;
settings.m_stsEndpointUrl = IAMUtils::convertStringToWstring(temp);
settings.m_oktaAppName = pIamProps->szAppName;
settings.m_partnerSpid = pIamProps->szPartnerSpid;
settings.m_loginToRp = pIamProps->szLoginToRp;
temp = pIamProps->szIdpHost;
settings.m_idpHost = IAMUtils::convertStringToWstring(temp);
settings.m_idpPort = pIamProps->iIdpPort;
settings.m_idpTenant = pIamProps->szIdpTenant;
settings.m_clientSecret = pIamProps->szClientSecret;
settings.m_clientId = pIamProps->szClientId;
settings.m_scope = pIamProps->szScope;
settings.m_idp_response_timeout = pIamProps->lIdpResponseTimeout;
settings.m_login_url = pIamProps->szLoginUrl;
settings.m_role_arn = pIamProps->szRoleArn;
//Added the autoCreate keyword from the user input connection string
settings.m_userAutoCreate = pIamProps->isAutoCreate;
settings.m_duration = pIamProps->lDuration;
settings.m_role_session_name = pIamProps->szRoleSessionName;
settings.m_dbGroupsFilter = pIamProps->szDbGroupsFilter;
settings.m_listen_port = pIamProps->lListenPort;
temp = pIamProps->szAppId;
settings.m_appId = IAMUtils::convertStringToWstring(temp);
temp = pIamProps->szPreferredRole;
settings.m_preferredRole = IAMUtils::convertStringToWstring(temp);
settings.m_useInstanceProfile = pIamProps->isInstanceProfile;
settings.m_authProfile = pIamProps->szAuthProfile;
settings.m_disableCache = pIamProps->isDisableCache;
settings.m_stsConnectionTimeout = pIamProps->iStsConnectionTimeout;
if(pHttpsProps) {
settings.m_httpsProxyHost = pHttpsProps->szHttpsHost;
settings.m_httpsProxyPort = pHttpsProps->iHttpsPort;
settings.m_httpsProxyUsername = pHttpsProps->szHttpsUser;
settings.m_httpsProxyPassword = pHttpsProps->szHttpsPassword;
settings.m_useProxyForIdpAuth = pHttpsProps->isUseProxyForIdp;
}
settings.m_groupFederation = pIamProps->isGroupFederation;
} else {
// Only IdC based programmatic and browser based plugins follow this flow.
settings.m_managedVpcUrl = pIamProps->szManagedVpcUrl;
if (!settings.m_managedVpcUrl.empty()) {
settings.m_host = settings.m_managedVpcUrl;
}
settings.m_clusterIdentifer = pIamProps->szClusterId;
settings.m_idpAuthToken = pIamProps->szBasicAuthToken;
settings.m_idpAuthTokenType = pIamProps->szTokenType;
settings.m_issuerUrl = pIamProps->szIssuerUrl;
settings.m_idcRegion = pIamProps->szIdcRegion;
settings.m_listen_port = pIamProps->lListenPort;
settings.m_idp_response_timeout = pIamProps->lIdpResponseTimeout;
settings.m_idcClientDisplayName = pIamProps->szIdcClientDisplayName;
if (pIamProps->szPluginName[0] != '\0' && (_stricmp(pIamProps->szPluginName, PLUGIN_IDP_TOKEN_AUTH) == 0)) {
// Explicitly disable caching for idc programmatic plugin. This is set false by default in RsSettings.h
settings.m_disableCache = true;
}
}
settings.m_caPath = pIamProps->szCaPath;
settings.m_caFile = pIamProps->szCaFile;
}