Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor!: remove additionalOptions from AuthClients #1689

Merged
merged 10 commits into from
Feb 5, 2025
12 changes: 6 additions & 6 deletions .readme-partials.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,11 @@ body: |-
return new Promise((resolve, reject) => {
// create an oAuth client to authorize the API call. Secrets are kept in a `keys.json` file,
// which should be downloaded from the Google Developers Console.
const oAuth2Client = new OAuth2Client(
keys.web.client_id,
keys.web.client_secret,
keys.web.redirect_uris[0]
);
const oAuth2Client = new OAuth2Client({
clientId: keys.web.client_id,
clientSecret: keys.web.client_secret,
redirectUri: keys.web.redirect_uris[0]
});

// Generate the url that will be used for the consent dialog.
const authorizeUrl = oAuth2Client.generateAuthUrl({
Expand Down Expand Up @@ -1260,7 +1260,7 @@ body: |-
const client = await googleAuth.getClient();

// Use the client to create a DownscopedClient.
const cabClient = new DownscopedClient(client, cab);
const cabClient = new DownscopedClient({authClient: client, credentialAccessBoundary: cab});

// Refresh the tokens.
const refreshedAccessToken = await cabClient.getAccessToken();
Expand Down
7 changes: 5 additions & 2 deletions samples/downscopedclient.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ async function main() {
const objectName = process.env.OBJECT_NAME;
// Defines a credential access boundary that grants objectViewer access in
// the specified bucket.
const cab = {
const credentialAccessBoundary = {
accessBoundary: {
accessBoundaryRules: [
{
Expand All @@ -61,7 +61,10 @@ async function main() {
// Obtain an authenticated client via ADC.
const client = await googleAuth.getClient();
// Use the client to generate a DownscopedClient.
const cabClient = new DownscopedClient(client, cab);
const cabClient = new DownscopedClient({
authClient: client,
credentialAccessBoundary,
});

// OAuth 2.0 Client
const authClient = new OAuth2Client();
Expand Down
6 changes: 1 addition & 5 deletions samples/oauth2-codeVerifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,7 @@ async function getAuthenticatedClient() {
// create an oAuth client to authorize the API call. Secrets are kept in a
// `keys.json` file, which should be downloaded from the Google Developers
// Console.
const oAuth2Client = new OAuth2Client(
keys.web.client_id,
keys.web.client_secret,
keys.web.redirect_uris[0]
);
const oAuth2Client = new OAuth2Client(keys.web);

// Generate a code_verifier and code_challenge
const codes = await oAuth2Client.generateCodeVerifierAsync();
Expand Down
6 changes: 1 addition & 5 deletions samples/oauth2.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,7 @@ function getAuthenticatedClient() {
return new Promise((resolve, reject) => {
// create an oAuth client to authorize the API call. Secrets are kept in a `keys.json` file,
// which should be downloaded from the Google Developers Console.
const oAuth2Client = new OAuth2Client(
keys.web.client_id,
keys.web.client_secret,
keys.web.redirect_uris[0]
);
const oAuth2Client = new OAuth2Client(keys.web);

// Generate the url that will be used for the consent dialog.
const authorizeUrl = oAuth2Client.generateAuthUrl({
Expand Down
10 changes: 5 additions & 5 deletions samples/puppeteer/oauth2-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ function getAuthenticatedClient() {
return new Promise(resolve => {
// create an oAuth client to authorize the API call. Secrets are kept in a `keys.json` file,
// which should be downloaded from the Google Developers Console.
const oAuth2Client = new OAuth2Client(
keys.web.client_id,
keys.web.client_secret,
keys.web.redirect_uris[0]
);
const oAuth2Client = new OAuth2Client({
clientId: keys.web.client_id,
clientSecret: keys.web.client_secret,
redirectUri: keys.web.redirect_uris[0],
});

// Generate the url that will be used for the consent dialog.
const authorizeUrl = oAuth2Client.generateAuthUrl({
Expand Down
10 changes: 5 additions & 5 deletions samples/verifyIdToken.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ function getAuthenticatedClient() {
return new Promise((resolve, reject) => {
// create an oAuth client to authorize the API call. Secrets are kept in a `keys.json` file,
// which should be downloaded from the Google Developers Console.
const oAuth2Client = new OAuth2Client(
keys.web.client_id,
keys.web.client_secret,
keys.web.redirect_uris[0]
);
const oAuth2Client = new OAuth2Client({
clientId: keys.web.client_id,
clientSecret: keys.web.client_secret,
redirectUri: keys.web.redirect_uris[0],
});

// Generate the url that will be used for the consent dialog.
const authorizeUrl = oAuth2Client.generateAuthUrl({
Expand Down
10 changes: 2 additions & 8 deletions src/auth/awsclient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import {
ExternalAccountSupplierContext,
} from './baseexternalclient';

import {AuthClientOptions} from './authclient';
import {DefaultAwsSecurityCredentialsSupplier} from './defaultawssecuritycredentialssupplier';
import {originalOrCamelOptions, SnakeToCamelObject} from '../util';

Expand Down Expand Up @@ -131,16 +130,11 @@ export class AwsClient extends BaseExternalAccountClient {
* An error is thrown if the credential is not a valid AWS credential.
* @param options The external account options object typically loaded
* from the external account JSON credential file.
* @param additionalOptions **DEPRECATED, all options are available in the
* `options` parameter.** Optional additional behavior customization options.
* These currently customize expiration threshold time and whether to retry
* on 401/403 API request errors.
*/
constructor(
options: AwsClientOptions | SnakeToCamelObject<AwsClientOptions>,
additionalOptions?: AuthClientOptions
options: AwsClientOptions | SnakeToCamelObject<AwsClientOptions>
) {
super(options, additionalOptions);
super(options);
const opts = originalOrCamelOptions(options as AwsClientOptions);
const credentialSource = opts.get('credential_source');
const awsSecurityCredentialsSupplier = opts.get(
Expand Down
9 changes: 2 additions & 7 deletions src/auth/baseexternalclient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,18 +262,13 @@ export abstract class BaseExternalAccountClient extends AuthClient {
* @param options The external account options object typically loaded
* from the external account JSON credential file. The camelCased options
* are aliases for the snake_cased options.
* @param additionalOptions **DEPRECATED, all options are available in the
* `options` parameter.** Optional additional behavior customization options.
* These currently customize expiration threshold time and whether to retry
* on 401/403 API request errors.
*/
constructor(
options:
| BaseExternalAccountClientOptions
| SnakeToCamelObject<BaseExternalAccountClientOptions>,
additionalOptions?: AuthClientOptions
| SnakeToCamelObject<BaseExternalAccountClientOptions>
) {
super({...options, ...additionalOptions});
super(options);

const opts = originalOrCamelOptions(
options as BaseExternalAccountClientOptions
Expand Down
55 changes: 39 additions & 16 deletions src/auth/downscopedclient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,20 @@ interface AvailabilityCondition {
description?: string;
}

export interface DownscopedClientOptions extends AuthClientOptions {
/**
* The source AuthClient to be downscoped based on the provided Credential Access Boundary rules.
*/
authClient: AuthClient;
/**
* The Credential Access Boundary which contains a list of access boundary rules.
* Each rule contains information on the resource that the rule applies to, the upper bound of the
* permissions that are available on that resource and an optional
* condition to further restrict permissions.
*/
credentialAccessBoundary: CredentialAccessBoundary;
}

/**
* Defines a set of Google credentials that are downscoped from an existing set
* of Google OAuth2 credentials. This is useful to restrict the Identity and
Expand All @@ -107,6 +121,8 @@ interface AvailabilityCondition {
* resources.
*/
export class DownscopedClient extends AuthClient {
private readonly authClient: AuthClient;
private readonly credentialAccessBoundary: CredentialAccessBoundary;
private cachedDownscopedAccessToken: CredentialsWithResponse | null;
private readonly stsCredential: sts.StsCredentials;

Expand All @@ -118,25 +134,32 @@ export class DownscopedClient extends AuthClient {
* well as an upper bound on the permissions that are available on each
* resource, has to be defined. A downscoped client can then be instantiated
* using the source AuthClient and the Credential Access Boundary.
* @param authClient The source AuthClient to be downscoped based on the
* provided Credential Access Boundary rules.
* @param credentialAccessBoundary The Credential Access Boundary which
* contains a list of access boundary rules. Each rule contains information
* on the resource that the rule applies to, the upper bound of the
* permissions that are available on that resource and an optional
* condition to further restrict permissions.
* @param additionalOptions **DEPRECATED, set this in the provided `authClient`.**
* Optional additional behavior customization options.
* @param quotaProjectId **DEPRECATED, set this in the provided `authClient`.**
* Optional quota project id for setting up in the x-goog-user-project header.
* @param options the {@link DownscopedClientOptions `DownscopedClientOptions`} to use. Passing an `AuthClient` directly is **@DEPRECATED**.
* @param credentialAccessBoundary **@DEPRECATED**. Provide a {@link DownscopedClientOptions `DownscopedClientOptions`} object in the first parameter instead.
*/
constructor(
private readonly authClient: AuthClient,
private readonly credentialAccessBoundary: CredentialAccessBoundary,
additionalOptions?: AuthClientOptions,
quotaProjectId?: string
/**
* AuthClient is for backwards-compatibility.
*/
options: AuthClient | DownscopedClientOptions,
/**
* @deprecated - provide a {@link DownscopedClientOptions `DownscopedClientOptions`} object in the first parameter instead
*/
credentialAccessBoundary: CredentialAccessBoundary = {
accessBoundary: {
accessBoundaryRules: [],
},
}
) {
super({...additionalOptions, quotaProjectId});
super(options instanceof AuthClient ? {} : options);

if (options instanceof AuthClient) {
this.authClient = options;
this.credentialAccessBoundary = credentialAccessBoundary;
} else {
this.authClient = options.authClient;
this.credentialAccessBoundary = options.credentialAccessBoundary;
}

// Check 1-10 Access Boundary Rules are defined within Credential Access
// Boundary.
Expand Down
20 changes: 7 additions & 13 deletions src/auth/externalAccountAuthorizedUserClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import {AuthClient, AuthClientOptions, Headers} from './authclient';
import {AuthClient, Headers} from './authclient';
import {
ClientAuthentication,
getErrorFromOAuthErrorResponse,
Expand Down Expand Up @@ -162,16 +162,9 @@ export class ExternalAccountAuthorizedUserClient extends AuthClient {
* An error is throws if the credential is not valid.
* @param options The external account authorized user option object typically
* from the external accoutn authorized user JSON credential file.
* @param additionalOptions **DEPRECATED, all options are available in the
* `options` parameter.** Optional additional behavior customization options.
* These currently customize expiration threshold time and whether to retry
* on 401/403 API request errors.
*/
constructor(
options: ExternalAccountAuthorizedUserClientOptions,
additionalOptions?: AuthClientOptions
) {
super({...options, ...additionalOptions});
constructor(options: ExternalAccountAuthorizedUserClientOptions) {
super(options);
if (options.universe_domain) {
this.universeDomain = options.universe_domain;
}
Expand All @@ -195,13 +188,14 @@ export class ExternalAccountAuthorizedUserClient extends AuthClient {
// As threshold could be zero,
// eagerRefreshThresholdMillis || EXPIRATION_TIME_OFFSET will override the
// zero value.
if (typeof additionalOptions?.eagerRefreshThresholdMillis !== 'number') {
if (typeof options?.eagerRefreshThresholdMillis !== 'number') {
this.eagerRefreshThresholdMillis = EXPIRATION_TIME_OFFSET;
} else {
this.eagerRefreshThresholdMillis = additionalOptions!
this.eagerRefreshThresholdMillis = options!
.eagerRefreshThresholdMillis as number;
}
this.forceRefreshOnFailure = !!additionalOptions?.forceRefreshOnFailure;

this.forceRefreshOnFailure = !!options?.forceRefreshOnFailure;
}

async getAccessToken(): Promise<{
Expand Down
20 changes: 4 additions & 16 deletions src/auth/externalclient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ import {
PluggableAuthClient,
PluggableAuthClientOptions,
} from './pluggable-auth-client';
import {AuthClientOptions} from './authclient';

export type ExternalAccountClientOptions =
| IdentityPoolClientOptions
Expand Down Expand Up @@ -60,32 +59,21 @@ export class ExternalAccountClient {
* underlying credential source.
* @param options The external account options object typically loaded
* from the external account JSON credential file.
* @param additionalOptions **DEPRECATED, all options are available in the
* `options` parameter.** Optional additional behavior customization options.
* These currently customize expiration threshold time and whether to retry
* on 401/403 API request errors.
* @return A BaseExternalAccountClient instance or null if the options
* provided do not correspond to an external account credential.
*/
static fromJSON(
options: ExternalAccountClientOptions,
additionalOptions?: AuthClientOptions
options: ExternalAccountClientOptions
): BaseExternalAccountClient | null {
if (options && options.type === EXTERNAL_ACCOUNT_TYPE) {
if ((options as AwsClientOptions).credential_source?.environment_id) {
return new AwsClient(options as AwsClientOptions, additionalOptions);
return new AwsClient(options as AwsClientOptions);
} else if (
(options as PluggableAuthClientOptions).credential_source?.executable
) {
return new PluggableAuthClient(
options as PluggableAuthClientOptions,
additionalOptions
);
return new PluggableAuthClient(options as PluggableAuthClientOptions);
} else {
return new IdentityPoolClient(
options as IdentityPoolClientOptions,
additionalOptions
);
return new IdentityPoolClient(options as IdentityPoolClientOptions);
}
} else {
return null;
Expand Down
16 changes: 8 additions & 8 deletions src/auth/googleauth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -692,16 +692,16 @@ export class GoogleAuth<T extends AuthClient = JSONClient> {
} else if (json.type === IMPERSONATED_ACCOUNT_TYPE) {
client = this.fromImpersonatedJSON(json as ImpersonatedJWTInput);
} else if (json.type === EXTERNAL_ACCOUNT_TYPE) {
client = ExternalAccountClient.fromJSON(
json as ExternalAccountClientOptions,
options
)!;
client = ExternalAccountClient.fromJSON({
...json,
...options,
} as ExternalAccountClientOptions)!;
client.scopes = this.getAnyScopes();
} else if (json.type === EXTERNAL_ACCOUNT_AUTHORIZED_USER_TYPE) {
client = new ExternalAccountAuthorizedUserClient(
json as ExternalAccountAuthorizedUserClientOptions,
options
);
client = new ExternalAccountAuthorizedUserClient({
...json,
...options,
} as ExternalAccountAuthorizedUserClientOptions);
} else {
(options as JWTOptions).scopes = this.scopes;
client = new JWT(options);
Expand Down
10 changes: 2 additions & 8 deletions src/auth/identitypoolclient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {
BaseExternalAccountClientOptions,
ExternalAccountSupplierContext,
} from './baseexternalclient';
import {AuthClientOptions} from './authclient';
import {SnakeToCamelObject, originalOrCamelOptions} from '../util';
import {FileSubjectTokenSupplier} from './filesubjecttokensupplier';
import {UrlSubjectTokenSupplier} from './urlsubjecttokensupplier';
Expand Down Expand Up @@ -113,18 +112,13 @@ export class IdentityPoolClient extends BaseExternalAccountClient {
* @param options The external account options object typically loaded
* from the external account JSON credential file. The camelCased options
* are aliases for the snake_cased options.
* @param additionalOptions **DEPRECATED, all options are available in the
* `options` parameter.** Optional additional behavior customization options.
* These currently customize expiration threshold time and whether to retry
* on 401/403 API request errors.
*/
constructor(
options:
| IdentityPoolClientOptions
| SnakeToCamelObject<IdentityPoolClientOptions>,
additionalOptions?: AuthClientOptions
| SnakeToCamelObject<IdentityPoolClientOptions>
) {
super(options, additionalOptions);
super(options);

const opts = originalOrCamelOptions(options as IdentityPoolClientOptions);
const credentialSource = opts.get('credential_source');
Expand Down
Loading
Loading