{Ninja-Shell}
Home
Info
Upload
Command
View /etc/passwd
cPanel Reset Password
Filename: //var/www/arsu//vendor/aws/aws-sdk-php/src/Token/SsoTokenProvider.php
<?php namespace Aws\Token; use Aws\Exception\TokenException; use Aws\SSOOIDC\SSOOIDCClient; use GuzzleHttp\Promise; /** * Token that comes from the SSO provider */ class SsoTokenProvider implements RefreshableTokenProviderInterface { use ParsesIniTrait; const ENV_PROFILE = 'AWS_PROFILE'; const REFRESH_WINDOW_IN_SECS = 300; const REFRESH_ATTEMPT_WINDOW_IN_SECS = 30; /** @var string $profileName */ private $profileName; /** @var string $configFilePath */ private $configFilePath; /** @var SSOOIDCClient $ssoOidcClient */ private $ssoOidcClient; /** @var string $ssoSessionName */ private $ssoSessionName; /** * Constructs a new SsoTokenProvider object, which will fetch a token from an authenticated SSO profile * @param string $profileName The name of the profile that contains the sso_session key * @param string|null $configFilePath Name of the config file to sso profile from * @param SSOOIDCClient|null $ssoOidcClient The sso client for generating a new token */ public function __construct( $profileName, $configFilePath = null, SSOOIDCClient $ssoOidcClient = null ) { $this->profileName = $this->resolveProfileName($profileName); $this->configFilePath = $this->resolveConfigFile($configFilePath); $this->ssoOidcClient = $ssoOidcClient; } /** * This method resolves the profile name to be used. The * profile provided as instantiation argument takes precedence, * followed by AWS_PROFILE env variable, otherwise `default` is * used. * * @param string|null $argProfileName The profile provided as argument. * * @return string */ private function resolveProfileName($argProfileName): string { if (empty($argProfileName)) { return getenv(self::ENV_PROFILE) ?: 'default'; } else { return $argProfileName; } } /** * This method resolves the config file from where the profiles * are going to be loaded from. If $argFileName is not empty then, * it takes precedence over the default config file location. * * @param string|null $argConfigFilePath The config path provided as argument. * * @return string */ private function resolveConfigFile($argConfigFilePath): string { if (empty($argConfigFilePath)) { return self::getHomeDir() . '/.aws/config'; } else{ return $argConfigFilePath; } } /** * Loads cached sso credentials. * * @return Promise\PromiseInterface */ public function __invoke() { return Promise\Coroutine::of(function () { if (empty($this->configFilePath) || !is_readable($this->configFilePath)) { throw new TokenException("Cannot read profiles from {$this->configFilePath}"); } $profiles = self::loadProfiles($this->configFilePath); if (!isset($profiles[$this->profileName])) { throw new TokenException("Profile `{$this->profileName}` does not exist in {$this->configFilePath}."); } $profile = $profiles[$this->profileName]; if (empty($profile['sso_session'])) { throw new TokenException( "Profile `{$this->profileName}` in {$this->configFilePath} must contain an sso_session." ); } $ssoSessionName = $profile['sso_session']; $this->ssoSessionName = $ssoSessionName; $profileSsoSession = 'sso-session ' . $ssoSessionName; if (empty($profiles[$profileSsoSession])) { throw new TokenException( "Sso session `{$ssoSessionName}` does not exist in {$this->configFilePath}" ); } $sessionProfileData = $profiles[$profileSsoSession]; foreach (['sso_start_url', 'sso_region'] as $requiredProp) { if (empty($sessionProfileData[$requiredProp])) { throw new TokenException( "Sso session `{$ssoSessionName}` in {$this->configFilePath} is missing the required property `{$requiredProp}`" ); } } $tokenData = $this->refresh(); $tokenLocation = self::getTokenLocation($ssoSessionName); $this->validateTokenData($tokenLocation, $tokenData); $ssoToken = SsoToken::fromTokenData($tokenData); // To make sure the token is not expired if ($ssoToken->isExpired()) { throw new TokenException("Cached SSO token returned an expired token."); } yield $ssoToken; }); } /** * This method attempt to refresh when possible. * If a refresh is not possible then it just returns * the current token data as it is. * * @return array * @throws TokenException */ public function refresh(): array { $tokenLocation = self::getTokenLocation($this->ssoSessionName); $tokenData = $this->getTokenData($tokenLocation); if (!$this->shouldAttemptRefresh()) { return $tokenData; } if (null === $this->ssoOidcClient) { throw new TokenException( "Cannot refresh this token without an 'ssooidcClient' " ); } foreach (['clientId', 'clientSecret', 'refreshToken'] as $requiredProp) { if (empty($tokenData[$requiredProp])) { throw new TokenException( "Cannot refresh this token without `{$requiredProp}` being set" ); } } $response = $this->ssoOidcClient->createToken([ 'clientId' => $tokenData['clientId'], 'clientSecret' => $tokenData['clientSecret'], 'grantType' => 'refresh_token', // REQUIRED 'refreshToken' => $tokenData['refreshToken'], ]); if ($response['@metadata']['statusCode'] !== 200) { throw new TokenException('Unable to create a new sso token'); } $tokenData['accessToken'] = $response['accessToken']; $tokenData['expiresAt'] = time () + $response['expiresIn']; $tokenData['refreshToken'] = $response['refreshToken']; return $this->writeNewTokenDataToDisk($tokenData, $tokenLocation); } /** * This method checks for whether a token refresh should happen. * It will return true just if more than 30 seconds has happened * since last refresh, and if the expiration is within a 5-minutes * window from the current time. * * @return bool */ public function shouldAttemptRefresh(): bool { $tokenLocation = self::getTokenLocation($this->ssoSessionName); $tokenData = $this->getTokenData($tokenLocation); if (empty($tokenData['expiresAt'])) { throw new TokenException( "Token file at $tokenLocation must contain an expiration date" ); } $tokenExpiresAt = strtotime($tokenData['expiresAt']); $lastRefreshAt = filemtime($tokenLocation); $now = \time(); // If last refresh happened after 30 seconds // and if the token expiration is in the 5 minutes window return ($now - $lastRefreshAt) > self::REFRESH_ATTEMPT_WINDOW_IN_SECS && ($tokenExpiresAt - $now) < self::REFRESH_WINDOW_IN_SECS; } /** * @param $sso_session * @return string */ public static function getTokenLocation($sso_session): string { return self::getHomeDir() . '/.aws/sso/cache/' . mb_convert_encoding(sha1($sso_session), "UTF-8") . ".json"; } /** * @param $tokenLocation * @return array */ function getTokenData($tokenLocation): array { if (empty($tokenLocation) || !is_readable($tokenLocation)) { throw new TokenException("Unable to read token file at {$tokenLocation}"); } return json_decode(file_get_contents($tokenLocation), true); } /** * @param $tokenData * @param $tokenLocation * @return mixed */ private function validateTokenData($tokenLocation, $tokenData) { foreach (['accessToken', 'expiresAt'] as $requiredProp) { if (empty($tokenData[$requiredProp])) { throw new TokenException( "Token file at {$tokenLocation} must contain the required property `{$requiredProp}`" ); } } $expiration = strtotime($tokenData['expiresAt']); if ($expiration === false) { throw new TokenException("Cached SSO token returned an invalid expiration"); } elseif ($expiration < time()) { throw new TokenException("Cached SSO token returned an expired token"); } return $tokenData; } /** * @param array $tokenData * @param string $tokenLocation * * @return array */ private function writeNewTokenDataToDisk(array $tokenData, $tokenLocation): array { $tokenData['expiresAt'] = gmdate( 'Y-m-d\TH:i:s\Z', $tokenData['expiresAt'] ); file_put_contents($tokenLocation, json_encode(array_filter($tokenData))); return $tokenData; } }
./Ninja\.