Skip to content

Commit

Permalink
fix: Universe Domain Resolution (#1745)
Browse files Browse the repository at this point in the history
* fix: Universe Domain Resolution

* fix: `source_credentials` from JSON

* test: Add ADC universe domain test
  • Loading branch information
danielbankhead authored Feb 1, 2024
1 parent 7282af8 commit a4f9f9c
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 23 deletions.
47 changes: 26 additions & 21 deletions src/auth/googleauth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,13 +185,6 @@ export class GoogleAuth<T extends AuthClient = JSONClient> {
private scopes?: string | string[];
private clientOptions: AuthClientOptions = {};

/**
* The cached universe domain.
*
* @see {@link GoogleAuth.getUniverseDomain}
*/
#universeDomain?: string = undefined;

/**
* Export DefaultTransporter as a static property of the class.
*/
Expand Down Expand Up @@ -220,7 +213,6 @@ export class GoogleAuth<T extends AuthClient = JSONClient> {

if (opts.universeDomain) {
this.clientOptions.universeDomain = opts.universeDomain;
this.#universeDomain = opts.universeDomain;
}
}

Expand Down Expand Up @@ -315,9 +307,13 @@ export class GoogleAuth<T extends AuthClient = JSONClient> {
return this._findProjectIdPromise;
}

async #getUniverseFromMetadataServer() {
if (!(await this._checkIsGCE())) return;

/**
* Retrieves a universe domain from the metadata server via
* {@link gcpMetadata.universe}.
*
* @returns a universe domain
*/
async getUniverseDomainFromMetadataServer(): Promise<string> {
let universeDomain: string;

try {
Expand All @@ -338,17 +334,18 @@ export class GoogleAuth<T extends AuthClient = JSONClient> {
* Retrieves, caches, and returns the universe domain in the following order
* of precedence:
* - The universe domain in {@link GoogleAuth.clientOptions}
* - {@link gcpMetadata.universe}
* - An existing or ADC {@link AuthClient}'s universe domain
* - {@link gcpMetadata.universe}, if {@link Compute} client
*
* @returns The universe domain
*/
async getUniverseDomain(): Promise<string> {
this.#universeDomain ??= originalOrCamelOptions(this.clientOptions).get(
let universeDomain = originalOrCamelOptions(this.clientOptions).get(
'universe_domain'
);
this.#universeDomain ??= await this.#getUniverseFromMetadataServer();
universeDomain ??= (await this.getClient()).universeDomain;

return this.#universeDomain || DEFAULT_UNIVERSE;
return universeDomain;
}

/**
Expand Down Expand Up @@ -438,7 +435,8 @@ export class GoogleAuth<T extends AuthClient = JSONClient> {
if (await this._checkIsGCE()) {
// set universe domain for Compute client
if (!originalOrCamelOptions(options).get('universe_domain')) {
options.universeDomain = await this.getUniverseDomain();
options.universeDomain =
await this.getUniverseDomainFromMetadataServer();
}

(options as ComputeOptions).scopes = this.getAnyScopes();
Expand Down Expand Up @@ -622,11 +620,8 @@ export class GoogleAuth<T extends AuthClient = JSONClient> {
}

// Create source client for impersonation
const sourceClient = new UserRefreshClient(
json.source_credentials.client_id,
json.source_credentials.client_secret,
json.source_credentials.refresh_token
);
const sourceClient = new UserRefreshClient();
sourceClient.fromJSON(json.source_credentials);

if (json.service_account_impersonation_url?.length > 256) {
/**
Expand All @@ -652,6 +647,7 @@ export class GoogleAuth<T extends AuthClient = JSONClient> {
const targetScopes = this.getAnyScopes() ?? [];

const client = new Impersonated({
...json,
delegates: json.delegates ?? [],
sourceClient: sourceClient,
targetPrincipal: targetPrincipal,
Expand All @@ -672,6 +668,10 @@ export class GoogleAuth<T extends AuthClient = JSONClient> {
): JSONClient {
let client: JSONClient;

// user's preferred universe domain
const preferredUniverseDomain =
originalOrCamelOptions(options).get('universe_domain');

if (json.type === USER_REFRESH_ACCOUNT_TYPE) {
client = new UserRefreshClient(options);
client.fromJSON(json);
Expand All @@ -694,6 +694,11 @@ export class GoogleAuth<T extends AuthClient = JSONClient> {
this.setGapicJWTValues(client);
client.fromJSON(json);
}

if (preferredUniverseDomain) {
client.universeDomain = preferredUniverseDomain;
}

return client;
}

Expand Down
1 change: 1 addition & 0 deletions src/auth/jwtclient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ export class JWT extends OAuth2Client implements IdTokenProvider {
this.keyId = json.private_key_id;
this.projectId = json.project_id;
this.quotaProjectId = json.quota_project_id;
this.universeDomain = json.universe_domain || this.universeDomain;
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/auth/refreshclient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export class UserRefreshClient extends OAuth2Client {
this._refreshToken = json.refresh_token;
this.credentials.refresh_token = json.refresh_token;
this.quotaProjectId = json.quota_project_id;
this.universeDomain = json.universe_domain || this.universeDomain;
}

/**
Expand Down
5 changes: 3 additions & 2 deletions test/fixtures/private2.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
"client_email": "goodbye@youarecool.com",
"client_id": "client456",
"type": "service_account",
"project_id": "my-awesome-project"
}
"project_id": "my-awesome-project",
"universe_domain": "my-universe"
}
14 changes: 14 additions & 0 deletions test/test.googleauth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1568,6 +1568,20 @@ describe('googleauth', () => {
assert.equal(await auth.getUniverseDomain(), universeDomain);
});

it('should get the universe from ADC', async () => {
mockEnvVar(
'GOOGLE_APPLICATION_CREDENTIALS',
'./test/fixtures/private2.json'
);
const {universe_domain} = JSON.parse(
fs.readFileSync('./test/fixtures/private2.json', 'utf-8')
);

assert(universe_domain);
assert.notEqual(universe_domain, DEFAULT_UNIVERSE);
assert.equal(await auth.getUniverseDomain(), universe_domain);
});

it('should use the metadata service if on GCP', async () => {
const universeDomain = 'my.universe.com';
const scope = nockIsGCE({universeDomain});
Expand Down

0 comments on commit a4f9f9c

Please sign in to comment.