Files
roi-theme/wp-content/plugins/google-site-kit/third-party/google/auth/src/Credentials/ExternalAccountCredentials.php
root a22573bf0b Commit inicial - WordPress Análisis de Precios Unitarios
- WordPress core y plugins
- Tema Twenty Twenty-Four configurado
- Plugin allow-unfiltered-html.php simplificado
- .gitignore configurado para excluir wp-config.php y uploads

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-03 21:04:30 -06:00

230 lines
12 KiB
PHP
Executable File

<?php
/*
* Copyright 2023 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace Google\Site_Kit_Dependencies\Google\Auth\Credentials;
use Google\Site_Kit_Dependencies\Google\Auth\CredentialSource\AwsNativeSource;
use Google\Site_Kit_Dependencies\Google\Auth\CredentialSource\FileSource;
use Google\Site_Kit_Dependencies\Google\Auth\CredentialSource\UrlSource;
use Google\Site_Kit_Dependencies\Google\Auth\ExternalAccountCredentialSourceInterface;
use Google\Site_Kit_Dependencies\Google\Auth\FetchAuthTokenInterface;
use Google\Site_Kit_Dependencies\Google\Auth\GetQuotaProjectInterface;
use Google\Site_Kit_Dependencies\Google\Auth\GetUniverseDomainInterface;
use Google\Site_Kit_Dependencies\Google\Auth\HttpHandler\HttpClientCache;
use Google\Site_Kit_Dependencies\Google\Auth\HttpHandler\HttpHandlerFactory;
use Google\Site_Kit_Dependencies\Google\Auth\OAuth2;
use Google\Site_Kit_Dependencies\Google\Auth\ProjectIdProviderInterface;
use Google\Site_Kit_Dependencies\Google\Auth\UpdateMetadataInterface;
use Google\Site_Kit_Dependencies\Google\Auth\UpdateMetadataTrait;
use Google\Site_Kit_Dependencies\GuzzleHttp\Psr7\Request;
use InvalidArgumentException;
class ExternalAccountCredentials implements \Google\Site_Kit_Dependencies\Google\Auth\FetchAuthTokenInterface, \Google\Site_Kit_Dependencies\Google\Auth\UpdateMetadataInterface, \Google\Site_Kit_Dependencies\Google\Auth\GetQuotaProjectInterface, \Google\Site_Kit_Dependencies\Google\Auth\GetUniverseDomainInterface, \Google\Site_Kit_Dependencies\Google\Auth\ProjectIdProviderInterface
{
use UpdateMetadataTrait;
private const EXTERNAL_ACCOUNT_TYPE = 'external_account';
private const CLOUD_RESOURCE_MANAGER_URL = 'https://cloudresourcemanager.UNIVERSE_DOMAIN/v1/projects/%s';
private \Google\Site_Kit_Dependencies\Google\Auth\OAuth2 $auth;
private ?string $quotaProject;
private ?string $serviceAccountImpersonationUrl;
private ?string $workforcePoolUserProject;
private ?string $projectId;
private string $universeDomain;
/**
* @param string|string[] $scope The scope of the access request, expressed either as an array
* or as a space-delimited string.
* @param array<mixed> $jsonKey JSON credentials as an associative array.
*/
public function __construct($scope, array $jsonKey)
{
if (!\array_key_exists('type', $jsonKey)) {
throw new \InvalidArgumentException('json key is missing the type field');
}
if ($jsonKey['type'] !== self::EXTERNAL_ACCOUNT_TYPE) {
throw new \InvalidArgumentException(\sprintf('expected "%s" type but received "%s"', self::EXTERNAL_ACCOUNT_TYPE, $jsonKey['type']));
}
if (!\array_key_exists('token_url', $jsonKey)) {
throw new \InvalidArgumentException('json key is missing the token_url field');
}
if (!\array_key_exists('audience', $jsonKey)) {
throw new \InvalidArgumentException('json key is missing the audience field');
}
if (!\array_key_exists('subject_token_type', $jsonKey)) {
throw new \InvalidArgumentException('json key is missing the subject_token_type field');
}
if (!\array_key_exists('credential_source', $jsonKey)) {
throw new \InvalidArgumentException('json key is missing the credential_source field');
}
if (\array_key_exists('service_account_impersonation_url', $jsonKey)) {
$this->serviceAccountImpersonationUrl = $jsonKey['service_account_impersonation_url'];
}
$this->quotaProject = $jsonKey['quota_project_id'] ?? null;
$this->workforcePoolUserProject = $jsonKey['workforce_pool_user_project'] ?? null;
$this->universeDomain = $jsonKey['universe_domain'] ?? \Google\Site_Kit_Dependencies\Google\Auth\GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN;
$this->auth = new \Google\Site_Kit_Dependencies\Google\Auth\OAuth2(['tokenCredentialUri' => $jsonKey['token_url'], 'audience' => $jsonKey['audience'], 'scope' => $scope, 'subjectTokenType' => $jsonKey['subject_token_type'], 'subjectTokenFetcher' => self::buildCredentialSource($jsonKey), 'additionalOptions' => $this->workforcePoolUserProject ? ['userProject' => $this->workforcePoolUserProject] : []]);
if (!$this->isWorkforcePool() && $this->workforcePoolUserProject) {
throw new \InvalidArgumentException('workforce_pool_user_project should not be set for non-workforce pool credentials.');
}
}
/**
* @param array<mixed> $jsonKey
*/
private static function buildCredentialSource(array $jsonKey) : \Google\Site_Kit_Dependencies\Google\Auth\ExternalAccountCredentialSourceInterface
{
$credentialSource = $jsonKey['credential_source'];
if (isset($credentialSource['file'])) {
return new \Google\Site_Kit_Dependencies\Google\Auth\CredentialSource\FileSource($credentialSource['file'], $credentialSource['format']['type'] ?? null, $credentialSource['format']['subject_token_field_name'] ?? null);
}
if (isset($credentialSource['environment_id']) && 1 === \preg_match('/^aws(\\d+)$/', $credentialSource['environment_id'], $matches)) {
if ($matches[1] !== '1') {
throw new \InvalidArgumentException("aws version \"{$matches[1]}\" is not supported in the current build.");
}
if (!\array_key_exists('regional_cred_verification_url', $credentialSource)) {
throw new \InvalidArgumentException('The regional_cred_verification_url field is required for aws1 credential source.');
}
if (!\array_key_exists('audience', $jsonKey)) {
throw new \InvalidArgumentException('aws1 credential source requires an audience to be set in the JSON file.');
}
return new \Google\Site_Kit_Dependencies\Google\Auth\CredentialSource\AwsNativeSource(
$jsonKey['audience'],
$credentialSource['regional_cred_verification_url'],
// $regionalCredVerificationUrl
$credentialSource['region_url'] ?? null,
// $regionUrl
$credentialSource['url'] ?? null,
// $securityCredentialsUrl
$credentialSource['imdsv2_session_token_url'] ?? null
);
}
if (isset($credentialSource['url'])) {
return new \Google\Site_Kit_Dependencies\Google\Auth\CredentialSource\UrlSource($credentialSource['url'], $credentialSource['format']['type'] ?? null, $credentialSource['format']['subject_token_field_name'] ?? null, $credentialSource['headers'] ?? null);
}
throw new \InvalidArgumentException('Unable to determine credential source from json key.');
}
/**
* @param string $stsToken
* @param callable $httpHandler
*
* @return array<mixed> {
* A set of auth related metadata, containing the following
*
* @type string $access_token
* @type int $expires_at
* }
*/
private function getImpersonatedAccessToken(string $stsToken, ?callable $httpHandler = null) : array
{
if (!isset($this->serviceAccountImpersonationUrl)) {
throw new \InvalidArgumentException('service_account_impersonation_url must be set in JSON credentials.');
}
$request = new \Google\Site_Kit_Dependencies\GuzzleHttp\Psr7\Request('POST', $this->serviceAccountImpersonationUrl, ['Content-Type' => 'application/json', 'Authorization' => 'Bearer ' . $stsToken], (string) \json_encode(['lifetime' => \sprintf('%ss', \Google\Site_Kit_Dependencies\Google\Auth\OAuth2::DEFAULT_EXPIRY_SECONDS), 'scope' => \explode(' ', $this->auth->getScope())]));
if (\is_null($httpHandler)) {
$httpHandler = \Google\Site_Kit_Dependencies\Google\Auth\HttpHandler\HttpHandlerFactory::build(\Google\Site_Kit_Dependencies\Google\Auth\HttpHandler\HttpClientCache::getHttpClient());
}
$response = $httpHandler($request);
$body = \json_decode((string) $response->getBody(), \true);
return ['access_token' => $body['accessToken'], 'expires_at' => \strtotime($body['expireTime'])];
}
/**
* @param callable $httpHandler
*
* @return array<mixed> {
* A set of auth related metadata, containing the following
*
* @type string $access_token
* @type int $expires_at (impersonated service accounts only)
* @type int $expires_in (identity pool only)
* @type string $issued_token_type (identity pool only)
* @type string $token_type (identity pool only)
* }
*/
public function fetchAuthToken(?callable $httpHandler = null)
{
$stsToken = $this->auth->fetchAuthToken($httpHandler);
if (isset($this->serviceAccountImpersonationUrl)) {
return $this->getImpersonatedAccessToken($stsToken['access_token'], $httpHandler);
}
return $stsToken;
}
public function getCacheKey()
{
return $this->auth->getCacheKey();
}
public function getLastReceivedToken()
{
return $this->auth->getLastReceivedToken();
}
/**
* Get the quota project used for this API request
*
* @return string|null
*/
public function getQuotaProject()
{
return $this->quotaProject;
}
/**
* Get the universe domain used for this API request
*
* @return string
*/
public function getUniverseDomain() : string
{
return $this->universeDomain;
}
/**
* Get the project ID.
*
* @param callable $httpHandler Callback which delivers psr7 request
* @param string $accessToken The access token to use to sign the blob. If
* provided, saves a call to the metadata server for a new access
* token. **Defaults to** `null`.
* @return string|null
*/
public function getProjectId(?callable $httpHandler = null, ?string $accessToken = null)
{
if (isset($this->projectId)) {
return $this->projectId;
}
$projectNumber = $this->getProjectNumber() ?: $this->workforcePoolUserProject;
if (!$projectNumber) {
return null;
}
if (\is_null($httpHandler)) {
$httpHandler = \Google\Site_Kit_Dependencies\Google\Auth\HttpHandler\HttpHandlerFactory::build(\Google\Site_Kit_Dependencies\Google\Auth\HttpHandler\HttpClientCache::getHttpClient());
}
$url = \str_replace('UNIVERSE_DOMAIN', $this->getUniverseDomain(), \sprintf(self::CLOUD_RESOURCE_MANAGER_URL, $projectNumber));
if (\is_null($accessToken)) {
$accessToken = $this->fetchAuthToken($httpHandler)['access_token'];
}
$request = new \Google\Site_Kit_Dependencies\GuzzleHttp\Psr7\Request('GET', $url, ['authorization' => 'Bearer ' . $accessToken]);
$response = $httpHandler($request);
$body = \json_decode((string) $response->getBody(), \true);
return $this->projectId = $body['projectId'];
}
private function getProjectNumber() : ?string
{
$parts = \explode('/', $this->auth->getAudience());
$i = \array_search('projects', $parts);
return $parts[$i + 1] ?? null;
}
private function isWorkforcePool() : bool
{
$regex = '#//iam\\.googleapis\\.com/locations/[^/]+/workforcePools/#';
return \preg_match($regex, $this->auth->getAudience()) === 1;
}
}