-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathApplicationDefaultCredentials.php
157 lines (124 loc) · 5.26 KB
/
ApplicationDefaultCredentials.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
<?php declare(strict_types=1);
namespace ericnorris\GCPAuthContrib\Credentials;
use ericnorris\GCPAuthContrib\Contracts\Credentials;
use ericnorris\GCPAuthContrib\Contracts\CredentialsWithProjectID;
use ericnorris\GCPAuthContrib\CredentialsFactory;
use ericnorris\GCPAuthContrib\Response\FetchAccessTokenResponse;
use ericnorris\GCPAuthContrib\Response\FetchIdentityTokenResponse;
use ericnorris\GCPAuthContrib\Response\GenerateSignatureResponse;
/**
* The ApplicationDefaultCredentials class follows the
* {@link https://cloud.google.com/docs/authentication/production#automatically ApplicationDefaultCredentials} pattern.
*
* It defers credential loading until first use, in order to avoid causing spurious IO.
*/
class ApplicationDefaultCredentials implements Credentials {
const WELL_KNOWN_ENV_VAR = "GOOGLE_APPLICATION_CREDENTIALS";
const WELL_KNOWN_FILE_PATH = ".config/gcloud/application_default_credentials.json";
/** @var CredentialsFactory */
private $credentialsFactory;
/** @var ?Credentials */
private $lazyCredentials;
public function __construct(CredentialsFactory $factory) {
$this->credentialsFactory = $factory;
$this->lazyCredentials = null;
}
/**
* @return class-string|null
*/
public function getCredentialsClass(): ?string {
return $this->lazyCredentials ? \get_class($this->lazyCredentials) : null;
}
/**
* Fetches an access token using the {@link https://cloud.google.com/docs/authentication/production#automatically
* ApplicationDefaultCredentials} pattern.
*
* @param string[] $scopes An array of scopes to request from default credentials.
*
* @return FetchAccessTokenResponse
*/
public function fetchAccessToken(array $scopes = []): FetchAccessTokenResponse {
return $this->getLazyCredentials()->fetchAccessToken($scopes);
}
/**
* Fetches an ID token using the {@link https://cloud.google.com/docs/authentication/production#automatically
* ApplicationDefaultCredentials} pattern.
*
* @param string $audience The desired 'aud' claim in the Google-signed ID token.
*
* @return FetchIdentityTokenResponse
*/
public function fetchIdentityToken(string $audience): FetchIdentityTokenResponse {
return $this->getLazyCredentials()->fetchIdentityToken($audience);
}
/**
* Fetches the project ID from the default credentials.
*
* @return string
*/
public function fetchProjectID(): string {
return $this->getLazyCredentials()->fetchProjectID();
}
/**
* Fetches the service account email from the default credentials.
*
* @return string
*/
public function fetchServiceAccountEmail(): string {
return $this->getLazyCredentials()->fetchServiceAccountEmail();
}
/**
* Generates a signature using the default credentials.
*
* @param string $toSign The bytes to sign.
*
* @return GenerateSignatureResponse
*/
public function generateSignature(string $toSign): GenerateSignatureResponse {
return $this->getLazyCredentials()->generateSignature($toSign);
}
/**
* Returns true if the default credentials supports the given capability.
*/
public function supportsCapability(string $capability): bool {
return $this->getLazyCredentials()->supportsCapability($capability);
}
private function getLazyCredentials(): Credentials {
if ($this->lazyCredentials !== null) {
return $this->lazyCredentials;
}
$envVarCredentials = $this->readEnvironmentVariableFile();
if (ServiceAccountKey::isServiceAccountKey($envVarCredentials)) {
return $this->lazyCredentials = $this->credentialsFactory->makeServiceAccountKey($envVarCredentials);
}
if (AuthorizedUserCredentials::isAuthorizedUserCredentials($envVarCredentials)) {
return $this->lazyCredentials = $this->credentialsFactory->makeAuthorizedUserCredentials(
$envVarCredentials
);
}
$wellKnownFileCredentials = $this->readWellKnownFile();
if (ServiceAccountKey::isServiceAccountKey($wellKnownFileCredentials)) {
return $this->lazyCredentials = $this->credentialsFactory->makeServiceAccountKey($wellKnownFileCredentials);
}
if (AuthorizedUserCredentials::isAuthorizedUserCredentials($wellKnownFileCredentials)) {
return $this->lazyCredentials = $this->credentialsFactory->makeAuthorizedUserCredentials(
$wellKnownFileCredentials
);
}
return $this->lazyCredentials = $this->credentialsFactory->makeMetadataServerCredentials();
}
private function readEnvironmentVariableFile(): array {
$path = (string)getenv(self::WELL_KNOWN_ENV_VAR);
if (empty($path)) {
return [];
}
$jsonString = @\file_get_contents($path) ?: "";
return (array)json_decode($jsonString, true);
}
private function readWellKnownFile(): array {
$parentDir = (string)getenv("HOME");
$path = $parentDir . DIRECTORY_SEPARATOR . self::WELL_KNOWN_FILE_PATH;
$jsonString = @\file_get_contents($path) ?: "";
return (array)json_decode($jsonString, true);
}
}