grpc-node/src/channel-credentials.ts

120 lines
3.8 KiB
TypeScript

import { CallCredentials } from './call-credentials';
import { createSecureContext, SecureContext } from 'tls';
/**
* A class that contains credentials for communicating over a channel, as well
* as a set of per-call credentials, which are applied to every method call made
* over a channel initialized with an instance of this class.
*/
export interface ChannelCredentials {
/**
* Returns a copy of this object with the included set of per-call credentials
* expanded to include callCredentials.
* @param callCredentials A CallCredentials object to associate with this
* instance.
*/
compose(callCredentials: CallCredentials) : ChannelCredentials;
/**
* Gets the set of per-call credentials associated with this instance.
*/
getCallCredentials() : CallCredentials | null;
/**
* Gets a SecureContext object generated from input parameters if this
* instance was created with createSsl, or null if this instance was created
* with createInsecure.
*/
getSecureContext() : SecureContext | null;
}
export namespace ChannelCredentials {
/**
* Return a new ChannelCredentials instance with a given set of credentials.
* The resulting instance can be used to construct a Channel that communicates
* over TLS.
* @param rootCerts The root certificate data.
* @param privateKey The client certificate private key, if available.
* @param certChain The client certificate key chain, if available.
*/
export function createSsl(rootCerts?: Buffer | null, privateKey?: Buffer | null, certChain?: Buffer | null) : ChannelCredentials {
if (privateKey && !certChain) {
throw new Error('Private key must be given with accompanying certificate chain');
}
if (!privateKey && certChain) {
throw new Error('Certificate chain must be given with accompanying private key');
}
const secureContext = createSecureContext({
ca: rootCerts || undefined,
key: privateKey || undefined,
cert: certChain || undefined
});
return new SecureChannelCredentialsImpl(secureContext);
}
/**
* Return a new ChannelCredentials instance with no credentials.
*/
export function createInsecure() : ChannelCredentials {
return new InsecureChannelCredentialsImpl();
}
}
abstract class ChannelCredentialsImpl implements ChannelCredentials {
protected callCredentials: CallCredentials | null;
protected constructor(callCredentials?: CallCredentials) {
this.callCredentials = callCredentials || null;
}
abstract compose(callCredentials: CallCredentials) : ChannelCredentialsImpl;
getCallCredentials() : CallCredentials | null {
return this.callCredentials;
}
abstract getSecureContext() : SecureContext | null;
}
class InsecureChannelCredentialsImpl extends ChannelCredentialsImpl {
constructor(callCredentials?: CallCredentials) {
super(callCredentials);
}
compose(callCredentials: CallCredentials) : ChannelCredentialsImpl {
const combinedCallCredentials = this.callCredentials ?
this.callCredentials.compose(callCredentials) :
callCredentials;
return new InsecureChannelCredentialsImpl(combinedCallCredentials);
}
getSecureContext() : SecureContext | null {
return null;
}
}
class SecureChannelCredentialsImpl extends ChannelCredentialsImpl {
secureContext: SecureContext;
constructor(
secureContext: SecureContext,
callCredentials?: CallCredentials
) {
super(callCredentials);
this.secureContext = secureContext;
}
compose(callCredentials: CallCredentials) : ChannelCredentialsImpl {
const combinedCallCredentials = this.callCredentials ?
this.callCredentials.compose(callCredentials) :
callCredentials;
return new SecureChannelCredentialsImpl(this.secureContext,
combinedCallCredentials);
}
getSecureContext() : SecureContext | null {
return this.secureContext;
}
}