mirror of https://github.com/grpc/grpc-node.git
Merge pull request #1400 from murgatroid99/grpc-js_internal_google_creds
grpc-js: Add internal "Google default" channel credentials
This commit is contained in:
commit
4db637e543
|
@ -55,6 +55,7 @@
|
||||||
"posttest": "npm run check"
|
"posttest": "npm run check"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"google-auth-library": "^6.0.0",
|
||||||
"semver": "^6.2.0"
|
"semver": "^6.2.0"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
|
|
|
@ -26,6 +26,35 @@ export type CallMetadataGenerator = (
|
||||||
cb: (err: Error | null, metadata?: Metadata) => void
|
cb: (err: Error | null, metadata?: Metadata) => void
|
||||||
) => void;
|
) => void;
|
||||||
|
|
||||||
|
// google-auth-library pre-v2.0.0 does not have getRequestHeaders
|
||||||
|
// but has getRequestMetadata, which is deprecated in v2.0.0
|
||||||
|
export interface OldOAuth2Client {
|
||||||
|
getRequestMetadata: (
|
||||||
|
url: string,
|
||||||
|
callback: (
|
||||||
|
err: Error | null,
|
||||||
|
headers?: {
|
||||||
|
[index: string]: string;
|
||||||
|
}
|
||||||
|
) => void
|
||||||
|
) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CurrentOAuth2Client {
|
||||||
|
getRequestHeaders: (url?: string) => Promise<{ [index: string]: string }>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type OAuth2Client = OldOAuth2Client | CurrentOAuth2Client;
|
||||||
|
|
||||||
|
function isCurrentOauth2Client(
|
||||||
|
client: OAuth2Client
|
||||||
|
): client is CurrentOAuth2Client {
|
||||||
|
return (
|
||||||
|
'getRequestHeaders' in client &&
|
||||||
|
typeof client.getRequestHeaders === 'function'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class that represents a generic method of adding authentication-related
|
* A class that represents a generic method of adding authentication-related
|
||||||
* metadata on a per-request basis.
|
* metadata on a per-request basis.
|
||||||
|
@ -65,6 +94,47 @@ export abstract class CallCredentials {
|
||||||
return new SingleCallCredentials(metadataGenerator);
|
return new SingleCallCredentials(metadataGenerator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a gRPC credential from a Google credential object.
|
||||||
|
* @param googleCredentials The authentication client to use.
|
||||||
|
* @return The resulting CallCredentials object.
|
||||||
|
*/
|
||||||
|
static createFromGoogleCredential(
|
||||||
|
googleCredentials: OAuth2Client
|
||||||
|
): CallCredentials {
|
||||||
|
return CallCredentials.createFromMetadataGenerator((options, callback) => {
|
||||||
|
let getHeaders: Promise<{ [index: string]: string }>;
|
||||||
|
if (isCurrentOauth2Client(googleCredentials)) {
|
||||||
|
getHeaders = googleCredentials.getRequestHeaders(options.service_url);
|
||||||
|
} else {
|
||||||
|
getHeaders = new Promise((resolve, reject) => {
|
||||||
|
googleCredentials.getRequestMetadata(
|
||||||
|
options.service_url,
|
||||||
|
(err, headers) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resolve(headers);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
getHeaders.then(
|
||||||
|
(headers) => {
|
||||||
|
const metadata = new Metadata();
|
||||||
|
for (const key of Object.keys(headers)) {
|
||||||
|
metadata.add(key, headers[key]);
|
||||||
|
}
|
||||||
|
callback(null, metadata);
|
||||||
|
},
|
||||||
|
(err) => {
|
||||||
|
callback(err);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static createEmpty(): CallCredentials {
|
static createEmpty(): CallCredentials {
|
||||||
return new EmptyCallCredentials();
|
return new EmptyCallCredentials();
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import { ConnectionOptions, createSecureContext, PeerCertificate } from 'tls';
|
||||||
|
|
||||||
import { CallCredentials } from './call-credentials';
|
import { CallCredentials } from './call-credentials';
|
||||||
import { CIPHER_SUITES, getDefaultRootsData } from './tls-helpers';
|
import { CIPHER_SUITES, getDefaultRootsData } from './tls-helpers';
|
||||||
|
import { GoogleAuth as GoogleAuthType } from 'google-auth-library';
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
function verifyIsBufferOrNull(obj: any, friendlyName: string): void {
|
function verifyIsBufferOrNull(obj: any, friendlyName: string): void {
|
||||||
|
@ -278,3 +279,13 @@ class ComposedChannelCredentialsImpl extends ChannelCredentials {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function createGoogleDefaultCredentials(): ChannelCredentials {
|
||||||
|
const GoogleAuth = require('google-auth-library')
|
||||||
|
.GoogleAuth as typeof GoogleAuthType;
|
||||||
|
const sslCreds = ChannelCredentials.createSsl();
|
||||||
|
const googleAuthCreds = CallCredentials.createFromGoogleCredential(
|
||||||
|
new GoogleAuth()
|
||||||
|
);
|
||||||
|
return sslCreds.compose(googleAuthCreds);
|
||||||
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ import {
|
||||||
ClientWritableStream,
|
ClientWritableStream,
|
||||||
ServiceError,
|
ServiceError,
|
||||||
} from './call';
|
} from './call';
|
||||||
import { CallCredentials } from './call-credentials';
|
import { CallCredentials, OAuth2Client } from './call-credentials';
|
||||||
import { Deadline, StatusObject } from './call-stream';
|
import { Deadline, StatusObject } from './call-stream';
|
||||||
import { Channel, ConnectivityState, ChannelImplementation } from './channel';
|
import { Channel, ConnectivityState, ChannelImplementation } from './channel';
|
||||||
import { ChannelCredentials } from './channel-credentials';
|
import { ChannelCredentials } from './channel-credentials';
|
||||||
|
@ -33,7 +33,7 @@ import {
|
||||||
Client,
|
Client,
|
||||||
CallInvocationTransformer,
|
CallInvocationTransformer,
|
||||||
CallProperties,
|
CallProperties,
|
||||||
UnaryCallback
|
UnaryCallback,
|
||||||
} from './client';
|
} from './client';
|
||||||
import { LogVerbosity, Status } from './constants';
|
import { LogVerbosity, Status } from './constants';
|
||||||
import * as logging from './logging';
|
import * as logging from './logging';
|
||||||
|
@ -87,71 +87,13 @@ function mixin(...sources: IndexedObject[]) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OAuth2Client {
|
export { OAuth2Client };
|
||||||
getRequestMetadata: (
|
|
||||||
url: string,
|
|
||||||
callback: (
|
|
||||||
err: Error | null,
|
|
||||||
headers?: {
|
|
||||||
[index: string]: string;
|
|
||||||
}
|
|
||||||
) => void
|
|
||||||
) => void;
|
|
||||||
getRequestHeaders: (url?: string) => Promise<{ [index: string]: string }>;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**** Client Credentials ****/
|
/**** Client Credentials ****/
|
||||||
|
|
||||||
// Using assign only copies enumerable properties, which is what we want
|
// Using assign only copies enumerable properties, which is what we want
|
||||||
export const credentials = mixin(
|
export const credentials = mixin(
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Create a gRPC credential from a Google credential object.
|
|
||||||
* @param googleCredentials The authentication client to use.
|
|
||||||
* @return The resulting CallCredentials object.
|
|
||||||
*/
|
|
||||||
createFromGoogleCredential: (
|
|
||||||
googleCredentials: OAuth2Client
|
|
||||||
): CallCredentials => {
|
|
||||||
return CallCredentials.createFromMetadataGenerator(
|
|
||||||
(options, callback) => {
|
|
||||||
// google-auth-library pre-v2.0.0 does not have getRequestHeaders
|
|
||||||
// but has getRequestMetadata, which is deprecated in v2.0.0
|
|
||||||
let getHeaders: Promise<{ [index: string]: string }>;
|
|
||||||
if (typeof googleCredentials.getRequestHeaders === 'function') {
|
|
||||||
getHeaders = googleCredentials.getRequestHeaders(
|
|
||||||
options.service_url
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
getHeaders = new Promise((resolve, reject) => {
|
|
||||||
googleCredentials.getRequestMetadata(
|
|
||||||
options.service_url,
|
|
||||||
(err, headers) => {
|
|
||||||
if (err) {
|
|
||||||
reject(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
resolve(headers);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
getHeaders.then(
|
|
||||||
(headers) => {
|
|
||||||
const metadata = new Metadata();
|
|
||||||
for (const key of Object.keys(headers)) {
|
|
||||||
metadata.add(key, headers[key]);
|
|
||||||
}
|
|
||||||
callback(null, metadata);
|
|
||||||
},
|
|
||||||
(err) => {
|
|
||||||
callback(err);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Combine a ChannelCredentials with any number of CallCredentials into a
|
* Combine a ChannelCredentials with any number of CallCredentials into a
|
||||||
* single ChannelCredentials object.
|
* single ChannelCredentials object.
|
||||||
|
@ -211,7 +153,7 @@ export {
|
||||||
CallInvocationTransformer,
|
CallInvocationTransformer,
|
||||||
ChannelImplementation as Channel,
|
ChannelImplementation as Channel,
|
||||||
Channel as ChannelInterface,
|
Channel as ChannelInterface,
|
||||||
UnaryCallback as requestCallback
|
UnaryCallback as requestCallback,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue