Skip to content

Commit 0003bee

Browse files
authored
feat: PassThrough AuthClient (#1771)
* feat: `PassThrough` AuthClient * refactor: Expand Types
1 parent 6a6e496 commit 0003bee

File tree

5 files changed

+133
-27
lines changed

5 files changed

+133
-27
lines changed

src/auth/authclient.ts

+2-5
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {Gaxios, GaxiosOptions, GaxiosPromise, GaxiosResponse} from 'gaxios';
1717

1818
import {DefaultTransporter, Transporter} from '../transporters';
1919
import {Credentials} from './credentials';
20-
import {Headers} from './oauth2client';
20+
import {GetAccessTokenResponse, Headers} from './oauth2client';
2121
import {OriginalAndCamel, originalOrCamelOptions} from '../util';
2222

2323
/**
@@ -128,10 +128,7 @@ export interface CredentialsClient {
128128
* @return A promise that resolves with the current GCP access token
129129
* response. If the current credential is expired, a new one is retrieved.
130130
*/
131-
getAccessToken(): Promise<{
132-
token?: string | null;
133-
res?: GaxiosResponse | null;
134-
}>;
131+
getAccessToken(): Promise<GetAccessTokenResponse>;
135132

136133
/**
137134
* The main authentication interface. It takes an optional url which when

src/auth/passthrough.ts

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
import {GaxiosOptions} from 'gaxios';
16+
import {AuthClient} from './authclient';
17+
import {GetAccessTokenResponse, Headers} from './oauth2client';
18+
19+
/**
20+
* An AuthClient without any Authentication information. Useful for:
21+
* - Anonymous access
22+
* - Local Emulators
23+
* - Testing Environments
24+
*
25+
*/
26+
export class PassThroughClient extends AuthClient {
27+
/**
28+
* Creates a request without any authentication headers or checks.
29+
*
30+
* @remarks
31+
*
32+
* In testing environments it may be useful to change the provided
33+
* {@link AuthClient.transporter} for any desired request overrides/handling.
34+
*
35+
* @param opts
36+
* @returns The response of the request.
37+
*/
38+
async request<T>(opts: GaxiosOptions) {
39+
return this.transporter.request<T>(opts);
40+
}
41+
42+
/**
43+
* A required method of the base class.
44+
* Always will return an empty object.
45+
*
46+
* @returns {}
47+
*/
48+
async getAccessToken(): Promise<GetAccessTokenResponse> {
49+
return {};
50+
}
51+
52+
/**
53+
* A required method of the base class.
54+
* Always will return an empty object.
55+
*
56+
* @returns {}
57+
*/
58+
async getRequestHeaders(): Promise<Headers> {
59+
return {};
60+
}
61+
}
62+
63+
const a = new PassThroughClient();
64+
65+
a.getAccessToken();

src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ export {
6868
PluggableAuthClient,
6969
PluggableAuthClientOptions,
7070
} from './auth/pluggable-auth-client';
71+
export {PassThroughClient} from './auth/passthrough';
7172
export {DefaultTransporter} from './transporters';
7273

7374
const auth = new GoogleAuth();

test/test.authclient.ts

+3-22
Original file line numberDiff line numberDiff line change
@@ -14,29 +14,10 @@
1414

1515
import {strict as assert} from 'assert';
1616

17-
import {GaxiosOptions, GaxiosPromise, GaxiosResponse} from 'gaxios';
18-
import {AuthClient} from '../src';
19-
import {Headers} from '../src/auth/oauth2client';
17+
import {PassThroughClient} from '../src';
2018
import {snakeToCamel} from '../src/util';
2119

2220
describe('AuthClient', () => {
23-
class TestAuthClient extends AuthClient {
24-
request<T>(opts: GaxiosOptions): GaxiosPromise<T> {
25-
throw new Error('Method not implemented.');
26-
}
27-
28-
getRequestHeaders(url?: string | undefined): Promise<Headers> {
29-
throw new Error('Method not implemented.');
30-
}
31-
32-
getAccessToken(): Promise<{
33-
token?: string | null | undefined;
34-
res?: GaxiosResponse<any> | null | undefined;
35-
}> {
36-
throw new Error('Method not implemented.');
37-
}
38-
}
39-
4021
it('should accept and normalize snake case options to camel case', () => {
4122
const expected = {
4223
project_id: 'my-projectId',
@@ -49,11 +30,11 @@ describe('AuthClient', () => {
4930
const camelCased = snakeToCamel(key) as keyof typeof authClient;
5031

5132
// assert snake cased input
52-
let authClient = new TestAuthClient({[key]: value});
33+
let authClient = new PassThroughClient({[key]: value});
5334
assert.equal(authClient[camelCased], value);
5435

5536
// assert camel cased input
56-
authClient = new TestAuthClient({[camelCased]: value});
37+
authClient = new PassThroughClient({[camelCased]: value});
5738
assert.equal(authClient[camelCased], value);
5839
}
5940
});

test/test.passthroughclient.ts

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
import {strict as assert} from 'assert';
16+
17+
import * as nock from 'nock';
18+
19+
import {PassThroughClient} from '../src';
20+
21+
describe('AuthClient', () => {
22+
before(async () => {
23+
nock.disableNetConnect();
24+
});
25+
26+
afterEach(async () => {
27+
nock.cleanAll();
28+
});
29+
30+
describe('#getAccessToken', () => {
31+
it('should return an empty object', async () => {
32+
const client = new PassThroughClient();
33+
const token = await client.getAccessToken();
34+
35+
assert.deepEqual(token, {});
36+
});
37+
});
38+
39+
describe('#getRequestHeaders', () => {
40+
it('should return an empty object', async () => {
41+
const client = new PassThroughClient();
42+
const token = await client.getRequestHeaders();
43+
44+
assert.deepEqual(token, {});
45+
});
46+
});
47+
48+
describe('#request', () => {
49+
it('should return the expected response', async () => {
50+
const url = 'https://google.com';
51+
const example = {test: 'payload'};
52+
const scope = nock(url).get('/').reply(200, example);
53+
54+
const client = new PassThroughClient();
55+
const response = await client.request({url});
56+
57+
assert.deepEqual(response.data, example);
58+
59+
scope.done();
60+
});
61+
});
62+
});

0 commit comments

Comments
 (0)