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"
|
||||
},
|
||||
"dependencies": {
|
||||
"google-auth-library": "^6.0.0",
|
||||
"semver": "^6.2.0"
|
||||
},
|
||||
"files": [
|
||||
|
|
|
@ -26,6 +26,35 @@ export type CallMetadataGenerator = (
|
|||
cb: (err: Error | null, metadata?: Metadata) => 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
|
||||
* metadata on a per-request basis.
|
||||
|
@ -65,6 +94,47 @@ export abstract class CallCredentials {
|
|||
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 {
|
||||
return new EmptyCallCredentials();
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ import { ConnectionOptions, createSecureContext, PeerCertificate } from 'tls';
|
|||
|
||||
import { CallCredentials } from './call-credentials';
|
||||
import { CIPHER_SUITES, getDefaultRootsData } from './tls-helpers';
|
||||
import { GoogleAuth as GoogleAuthType } from 'google-auth-library';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
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,
|
||||
ServiceError,
|
||||
} from './call';
|
||||
import { CallCredentials } from './call-credentials';
|
||||
import { CallCredentials, OAuth2Client } from './call-credentials';
|
||||
import { Deadline, StatusObject } from './call-stream';
|
||||
import { Channel, ConnectivityState, ChannelImplementation } from './channel';
|
||||
import { ChannelCredentials } from './channel-credentials';
|
||||
|
@ -33,7 +33,7 @@ import {
|
|||
Client,
|
||||
CallInvocationTransformer,
|
||||
CallProperties,
|
||||
UnaryCallback
|
||||
UnaryCallback,
|
||||
} from './client';
|
||||
import { LogVerbosity, Status } from './constants';
|
||||
import * as logging from './logging';
|
||||
|
@ -87,71 +87,13 @@ function mixin(...sources: IndexedObject[]) {
|
|||
return result;
|
||||
}
|
||||
|
||||
export interface OAuth2Client {
|
||||
getRequestMetadata: (
|
||||
url: string,
|
||||
callback: (
|
||||
err: Error | null,
|
||||
headers?: {
|
||||
[index: string]: string;
|
||||
}
|
||||
) => void
|
||||
) => void;
|
||||
getRequestHeaders: (url?: string) => Promise<{ [index: string]: string }>;
|
||||
}
|
||||
export { OAuth2Client };
|
||||
|
||||
/**** Client Credentials ****/
|
||||
|
||||
// Using assign only copies enumerable properties, which is what we want
|
||||
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
|
||||
* single ChannelCredentials object.
|
||||
|
@ -211,7 +153,7 @@ export {
|
|||
CallInvocationTransformer,
|
||||
ChannelImplementation as Channel,
|
||||
Channel as ChannelInterface,
|
||||
UnaryCallback as requestCallback
|
||||
UnaryCallback as requestCallback,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue