|
7 | 7 | use AsyncAws\Core\Configuration;
|
8 | 8 | use AsyncAws\Core\Exception\RuntimeException;
|
9 | 9 | use AsyncAws\Core\Sts\StsClient;
|
| 10 | +use AsyncAws\Sso\SsoClient; |
10 | 11 | use Psr\Log\LoggerInterface;
|
11 | 12 | use Psr\Log\NullLogger;
|
12 | 13 | use Symfony\Contracts\HttpClient\HttpClientInterface;
|
@@ -92,6 +93,16 @@ private function getCredentialsFromProfile(array $profilesData, string $profile,
|
92 | 93 | return $this->getCredentialsFromRole($profilesData, $profileData, $profile, $circularCollector);
|
93 | 94 | }
|
94 | 95 |
|
| 96 | + if (isset($profileData[IniFileLoader::KEY_SSO_START_URL])) { |
| 97 | + if (class_exists(SsoClient::class)) { |
| 98 | + return $this->getCredentialsFromLegacySso($profileData, $profile); |
| 99 | + } |
| 100 | + |
| 101 | + $this->logger->warning('The profile "{profile}" contains SSO (legacy) config but the "async-aws/sso" package is not installed. Try running "composer require async-aws/sso".', ['profile' => $profile]); |
| 102 | + |
| 103 | + return null; |
| 104 | + } |
| 105 | + |
95 | 106 | $this->logger->info('No credentials found for profile "{profile}".', ['profile' => $profile]);
|
96 | 107 |
|
97 | 108 | return null;
|
@@ -146,4 +157,68 @@ private function getCredentialsFromRole(array $profilesData, array $profileData,
|
146 | 157 | Credentials::adjustExpireDate($credentials->getExpiration(), $this->getDateFromResult($result))
|
147 | 158 | );
|
148 | 159 | }
|
| 160 | + |
| 161 | + /** |
| 162 | + * @param array<string, string> $profileData |
| 163 | + */ |
| 164 | + private function getCredentialsFromLegacySso(array $profileData, string $profile): ?Credentials |
| 165 | + { |
| 166 | + if (!isset( |
| 167 | + $profileData[IniFileLoader::KEY_SSO_START_URL], |
| 168 | + $profileData[IniFileLoader::KEY_SSO_REGION], |
| 169 | + $profileData[IniFileLoader::KEY_SSO_ACCOUNT_ID], |
| 170 | + $profileData[IniFileLoader::KEY_SSO_ROLE_NAME] |
| 171 | + )) { |
| 172 | + $this->logger->warning('Profile "{profile}" does not contains required legacy SSO config.', ['profile' => $profile]); |
| 173 | + |
| 174 | + return null; |
| 175 | + } |
| 176 | + |
| 177 | + $ssoCacheFileLoader = new SsoCacheFileLoader($this->logger); |
| 178 | + $tokenData = $ssoCacheFileLoader->loadSsoCacheFile($profileData[IniFileLoader::KEY_SSO_START_URL]); |
| 179 | + |
| 180 | + if ([] === $tokenData) { |
| 181 | + return null; |
| 182 | + } |
| 183 | + |
| 184 | + $ssoClient = new SsoClient( |
| 185 | + ['region' => $profileData[IniFileLoader::KEY_SSO_REGION]], |
| 186 | + new NullProvider(), // no credentials required as we provide an access token via the role credentials request |
| 187 | + $this->httpClient |
| 188 | + ); |
| 189 | + $result = $ssoClient->getRoleCredentials([ |
| 190 | + 'accessToken' => $tokenData[SsoCacheFileLoader::KEY_ACCESS_TOKEN], |
| 191 | + 'accountId' => $profileData[IniFileLoader::KEY_SSO_ACCOUNT_ID], |
| 192 | + 'roleName' => $profileData[IniFileLoader::KEY_SSO_ROLE_NAME], |
| 193 | + ]); |
| 194 | + |
| 195 | + try { |
| 196 | + if (null === $credentials = $result->getRoleCredentials()) { |
| 197 | + throw new RuntimeException('The RoleCredentials response does not contains credentials'); |
| 198 | + } |
| 199 | + if (null === $accessKeyId = $credentials->getAccessKeyId()) { |
| 200 | + throw new RuntimeException('The RoleCredentials response does not contain an accessKeyId'); |
| 201 | + } |
| 202 | + if (null === $secretAccessKey = $credentials->getSecretAccessKey()) { |
| 203 | + throw new RuntimeException('The RoleCredentials response does not contain a secretAccessKey'); |
| 204 | + } |
| 205 | + if (null === $sessionToken = $credentials->getSessionToken()) { |
| 206 | + throw new RuntimeException('The RoleCredentials response does not contain a sessionToken'); |
| 207 | + } |
| 208 | + if (null === $expiration = $credentials->getExpiration()) { |
| 209 | + throw new RuntimeException('The RoleCredentials response does not contain an expiration'); |
| 210 | + } |
| 211 | + } catch (\Exception $e) { |
| 212 | + $this->logger->warning('Failed to get credentials from role credentials in profile "{profile}: {exception}".', ['profile' => $profile, 'exception' => $e]); |
| 213 | + |
| 214 | + return null; |
| 215 | + } |
| 216 | + |
| 217 | + return new Credentials( |
| 218 | + $accessKeyId, |
| 219 | + $secretAccessKey, |
| 220 | + $sessionToken, |
| 221 | + (new \DateTimeImmutable())->setTimestamp($expiration) |
| 222 | + ); |
| 223 | + } |
149 | 224 | }
|
0 commit comments