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

chore: deprecate getRequestMetadata #414

Merged
merged 3 commits into from
Jul 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions src/auth/googleauth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import {Compute} from './computeclient';
import {CredentialBody, JWTInput} from './credentials';
import {GCPEnv, getEnv} from './envDetect';
import {JWT, JWTOptions} from './jwtclient';
import {OAuth2Client, RefreshOptions} from './oauth2client';
import {Headers, OAuth2Client, RefreshOptions} from './oauth2client';
import {UserRefreshClient} from './refreshclient';

export interface ProjectIdCallback {
Expand Down Expand Up @@ -709,20 +709,20 @@ export class GoogleAuth {
*/
async getRequestHeaders(url?: string) {
const client = await this.getClient();
return (await client.getRequestMetadata(url)).headers;
return client.getRequestHeaders(url);
}

/**
* Obtain credentials for a request, then attach the appropriate headers to
* the request options.
* @param opts Axios or Request options on which to attach the headers
*/
async authorizeRequest(
opts: {url?: string, uri?: string, headers?: http.IncomingHttpHeaders}) {
async authorizeRequest(opts:
{url?: string, uri?: string, headers?: Headers}) {
opts = opts || {};
const url = opts.url || opts.uri;
const client = await this.getClient();
const {headers} = await client.getRequestMetadata(url);
const headers = await client.getRequestHeaders(url);
opts.headers = Object.assign(opts.headers || {}, headers);
return opts;
}
Expand Down
18 changes: 13 additions & 5 deletions src/auth/iam.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,25 @@ export class IAMAuth {

/**
* Pass the selector and token to the metadataFn callback.
*
* @deprecated
* @param unused_uri is required of the credentials interface
* @param metadataFn a callback invoked with object
* containing request metadata.
* @param metadataFn a callback invoked with object containing request
* metadata.
*/
getRequestMetadata(
unusedUri: string|null,
metadataFn: (err: Error|null, metadata?: RequestMetadata) => void) {
metadataFn(null, {
messages.warn(messages.IAM_GET_REQUEST_METADATA_DEPRECATED);
metadataFn(null, this.getRequestHeaders());
}

/**
* Acquire the HTTP headers required to make an authenticated request.
*/
getRequestHeaders() {
return {
'x-goog-iam-authority-selector': this.selector,
'x-goog-iam-authorization-token': this.token
});
};
}
}
63 changes: 39 additions & 24 deletions src/auth/jwtaccess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,18 @@ import * as stream from 'stream';
import * as messages from '../messages';

import {JWTInput} from './credentials';
import {RequestMetadataResponse} from './oauth2client';
import {Headers, RequestMetadataResponse} from './oauth2client';

export type Claims = {
[index: string]: string
};

export class JWTAccess {
email?: string|null;
key?: string|null;
projectId?: string;

private cache =
LRU<string, RequestMetadataResponse>({max: 500, maxAge: 60 * 60 * 1000});
private cache = LRU<string, Headers>({max: 500, maxAge: 60 * 60 * 1000});

/**
* JWTAccess service account credentials.
Expand Down Expand Up @@ -63,12 +66,25 @@ export class JWTAccess {
* @param authURI The URI being authorized.
* @param additionalClaims An object with a set of additional claims to
* include in the payload.
* @deprecated Please use `getRequestHeaders` instead.
* @returns An object that includes the authorization header.
*/
getRequestMetadata(
authURI: string,
additionalClaims?: {[index: string]: string}): RequestMetadataResponse {
const cachedToken = this.cache.get(authURI);
getRequestMetadata(url: string, additionalClaims?: Claims):
RequestMetadataResponse {
messages.warn(messages.JWT_ACCESS_GET_REQUEST_METADATA_DEPRECATED);
return {headers: this.getRequestHeaders(url, additionalClaims)};
}

/**
* Get a non-expired access token, after refreshing if necessary.
*
* @param url The URI being authorized.
* @param additionalClaims An object with a set of additional claims to
* include in the payload.
* @returns An object that includes the authorization header.
*/
getRequestHeaders(url: string, additionalClaims?: Claims): Headers {
const cachedToken = this.cache.get(url);
if (cachedToken) {
return cachedToken;
}
Expand All @@ -79,7 +95,7 @@ export class JWTAccess {
// iss == sub == <client email>
// aud == <the authorization uri>
const defaultClaims =
{iss: this.email, sub: this.email, aud: authURI, exp, iat};
{iss: this.email, sub: this.email, aud: url, exp, iat};

// if additionalClaims are provided, ensure they do not collide with
// other required claims.
Expand All @@ -97,9 +113,9 @@ export class JWTAccess {
// Sign the jwt and add it to the cache
const signedJWT =
jws.sign({header: {alg: 'RS256'}, payload, secret: this.key});
const res = {headers: {Authorization: `Bearer ${signedJWT}`}};
this.cache.set(authURI, res);
return res;
const headers = {Authorization: `Bearer ${signedJWT}`};
this.cache.set(url, headers);
return headers;
}

/**
Expand Down Expand Up @@ -149,19 +165,18 @@ export class JWTAccess {
'Must pass in a stream containing the service account auth settings.'));
}
let s = '';
inputStream.setEncoding('utf8');
inputStream.on('data', (chunk) => {
s += chunk;
});
inputStream.on('end', () => {
try {
const data = JSON.parse(s);
this.fromJSON(data);
resolve();
} catch (err) {
reject(err);
}
});
inputStream.setEncoding('utf8')
.on('data', (chunk) => s += chunk)
.on('error', reject)
.on('end', () => {
try {
const data = JSON.parse(s);
this.fromJSON(data);
resolve();
} catch (err) {
reject(err);
}
});
});
}
}
29 changes: 15 additions & 14 deletions src/auth/jwtclient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,9 @@ export class JWT extends OAuth2Client {
if (!this.access) {
this.access = new JWTAccess(this.email, this.key);
}
return this.access.getRequestMetadata(url, this.additionalClaims);
const headers =
await this.access.getRequestHeaders(url, this.additionalClaims);
return {headers};
}
} else {
return super.getRequestMetadataAsync(url);
Expand Down Expand Up @@ -258,19 +260,18 @@ export class JWT extends OAuth2Client {
'Must pass in a stream containing the service account auth settings.');
}
let s = '';
inputStream.setEncoding('utf8');
inputStream.on('data', (chunk) => {
s += chunk;
});
inputStream.on('end', () => {
try {
const data = JSON.parse(s);
this.fromJSON(data);
resolve();
} catch (e) {
reject(e);
}
});
inputStream.setEncoding('utf8')
.on('error', reject)
.on('data', (chunk) => s += chunk)
.on('end', () => {
try {
const data = JSON.parse(s);
this.fromJSON(data);
resolve();
} catch (e) {
reject(e);
}
});
});
}

Expand Down
39 changes: 25 additions & 14 deletions src/auth/oauth2client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ export type Certificates = {
[index: string]: string
};

export type Headers = {
[index: string]: string
};

export enum CodeChallengeMethod {
Plain = 'plain',
S256 = 'S256'
Expand Down Expand Up @@ -270,12 +274,12 @@ export interface RefreshAccessTokenResponse {
}

export interface RequestMetadataResponse {
headers: http.IncomingHttpHeaders;
headers: Headers;
res?: AxiosResponse<void>|null;
}

export interface RequestMetadataCallback {
(err: AxiosError|null, headers?: http.IncomingHttpHeaders,
(err: AxiosError|null, headers?: Headers,
res?: AxiosResponse<void>|null): void;
}

Expand Down Expand Up @@ -556,7 +560,7 @@ export class OAuth2Client extends AuthClient {
/**
* Retrieves the access token using refresh token
*
* @deprecated use getRequestMetadata instead.
* @deprecated use getRequestHeaders instead.
* @param callback callback
*/
refreshAccessToken(): Promise<RefreshAccessTokenResponse>;
Expand Down Expand Up @@ -619,32 +623,39 @@ export class OAuth2Client extends AuthClient {
}

/**
* getRequestMetadata obtains auth metadata to be used by requests.
*
* getRequestMetadata is the main authentication interface. It takes an
* optional uri which when present is the endpoint being accessed, and a
* callback func(err, metadata_obj, response) where metadata_obj contains
* authorization metadata fields and response is an optional response object.
*
* In OAuth2Client, metadata_obj has the form.
*
* {Authorization: 'Bearer <access_token_value>'}
* Obtain the set of headers required to authenticate a request.
*
* @deprecated Use getRequestHeaders instead.
* @param url the Uri being authorized
* @param callback the func described above
*/
getRequestMetadata(url?: string|null): Promise<RequestMetadataResponse>;
getRequestMetadata(url: string|null, callback: RequestMetadataCallback): void;
getRequestMetadata(url: string|null, callback?: RequestMetadataCallback):
Promise<RequestMetadataResponse>|void {
messages.warn(messages.OAUTH_GET_REQUEST_METADATA_DEPRECATED);
if (callback) {
this.getRequestMetadataAsync(url).then(
r => callback(null, r.headers, r.res), callback);
} else {
return this.getRequestMetadataAsync(url);
return this.getRequestMetadataAsync();
}
}

/**
* The main authentication interface. It takes an optional url which when
* present is the endpoint being accessed, and returns a Promise which
* resolves with authorization header fields.
*
* In OAuth2Client, the result has the form:
* { Authorization: 'Bearer <access_token_value>' }
* @param url The optional url being authorized
*/
async getRequestHeaders(url?: string): Promise<Headers> {
const res = await this.getRequestMetadataAsync(url);
return res.headers;
}

protected async getRequestMetadataAsync(url?: string|null):
Promise<RequestMetadataResponse> {
const thisCreds = this.credentials;
Expand Down
25 changes: 12 additions & 13 deletions src/auth/refreshclient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,19 +127,18 @@ export class UserRefreshClient extends OAuth2Client {
'Must pass in a stream containing the user refresh token.'));
}
let s = '';
inputStream.setEncoding('utf8');
inputStream.on('data', (chunk) => {
s += chunk;
});
inputStream.on('end', () => {
try {
const data = JSON.parse(s);
this.fromJSON(data);
return resolve();
} catch (err) {
return reject(err);
}
});
inputStream.setEncoding('utf8')
.on('error', reject)
.on('data', (chunk) => s += chunk)
.on('end', () => {
try {
const data = JSON.parse(s);
this.fromJSON(data);
return resolve();
} catch (err) {
return reject(err);
}
});
});
}
}
31 changes: 30 additions & 1 deletion src/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,36 @@ export const REFRESH_ACCESS_TOKEN_DEPRECATED = {
type: WarningTypes.DEPRECATION,
message: [
'The `refreshAccessToken` method has been deprecated, and will be removed',
'in the 3.0 release of google-auth-library. Please use the `getRequestMetadata`',
'in the 3.0 release of google-auth-library. Please use the `getRequestHeaders`',
'method instead.'
].join(' ')
};
export const OAUTH_GET_REQUEST_METADATA_DEPRECATED = {
code: 'google-auth-library:DEP004',
type: WarningTypes.DEPRECATION,
message: [
'The `getRequestMetadata` method on the `OAuth2` class has been deprecated,',
'and will be removed in the 3.0 release of google-auth-library. Please use',
'the `getRequestHeaders` method instead.'
].join(' ')
};

export const IAM_GET_REQUEST_METADATA_DEPRECATED = {
code: 'google-auth-library:DEP005',
type: WarningTypes.DEPRECATION,
message: [
'The `getRequestMetadata` method on the `IAM` class has been deprecated,',
'and will be removed in the 3.0 release of google-auth-library. Please use',
'the `getRequestHeaders` method instead.'
].join(' ')
};

export const JWT_ACCESS_GET_REQUEST_METADATA_DEPRECATED = {
code: 'google-auth-library:DEP006',
type: WarningTypes.DEPRECATION,
message: [
'The `getRequestMetadata` method on the `JWTAccess` class has been deprecated,',
'and will be removed in the 3.0 release of google-auth-library. Please use',
'the `getRequestHeaders` method instead.'
].join(' ')
};
Loading