Remove generics from credentials

This commit is contained in:
Kelvin Jin 2018-03-14 12:31:14 -07:00
parent e92224ba7b
commit 42ddabe398
3 changed files with 58 additions and 58 deletions

View File

@ -2,33 +2,35 @@ import {map, reduce} from 'lodash';
import {Metadata} from './metadata';
export type CallMetadataGenerator<T extends {} = {}> =
(options: T, cb: (err: Error|null, metadata?: Metadata) => void) =>
export type CallMetadataOptions = { service_url?: string; };
export type CallMetadataGenerator =
(options: CallMetadataOptions, cb: (err: Error|null, metadata?: Metadata) => void) =>
void;
/**
* A class that represents a generic method of adding authentication-related
* metadata on a per-request basis.
*/
export interface CallCredentials<T extends {} = {}> {
export interface CallCredentials {
/**
* Asynchronously generates a new Metadata object.
* @param options Options used in generating the Metadata object.
*/
generateMetadata(options: T): Promise<Metadata>;
generateMetadata(options: CallMetadataOptions): Promise<Metadata>;
/**
* Creates a new CallCredentials object from properties of both this and
* another CallCredentials object. This object's metadata generator will be
* called first.
* @param callCredentials The other CallCredentials object.
*/
compose<S>(callCredentials: CallCredentials<S>): CallCredentials<S&T>;
compose(callCredentials: CallCredentials): CallCredentials;
}
class ComposedCallCredentials<T> implements CallCredentials<T> {
constructor(private creds: CallCredentials<T>[]) {}
class ComposedCallCredentials implements CallCredentials {
constructor(private creds: CallCredentials[]) {}
async generateMetadata(options: T): Promise<Metadata> {
async generateMetadata(options: CallMetadataOptions): Promise<Metadata> {
let base: Metadata = new Metadata();
let generated: Metadata[] = await Promise.all(
map(this.creds, (cred) => cred.generateMetadata(options)));
@ -38,15 +40,15 @@ class ComposedCallCredentials<T> implements CallCredentials<T> {
return base;
}
compose<S>(other: CallCredentials<S>): CallCredentials<S&T> {
return new ComposedCallCredentials<S&T>([...this.creds, other]);
compose(other: CallCredentials): CallCredentials {
return new ComposedCallCredentials(this.creds.concat([other]));
}
}
class SingleCallCredentials<T> implements CallCredentials<T> {
constructor(private metadataGenerator: CallMetadataGenerator<T>) {}
class SingleCallCredentials implements CallCredentials {
constructor(private metadataGenerator: CallMetadataGenerator) {}
generateMetadata(options: T): Promise<Metadata> {
generateMetadata(options: CallMetadataOptions): Promise<Metadata> {
return new Promise<Metadata>((resolve, reject) => {
this.metadataGenerator(options, (err, metadata) => {
if (metadata !== undefined) {
@ -58,17 +60,17 @@ class SingleCallCredentials<T> implements CallCredentials<T> {
});
}
compose<S>(other: CallCredentials<S>): CallCredentials<S&T> {
return new ComposedCallCredentials<S&T>([this, other]);
compose(other: CallCredentials): CallCredentials {
return new ComposedCallCredentials([this, other]);
}
}
class EmptyCallCredentials implements CallCredentials<{}> {
generateMetadata(options: {}): Promise<Metadata> {
class EmptyCallCredentials implements CallCredentials {
generateMetadata(options: CallMetadataOptions): Promise<Metadata> {
return Promise.resolve(new Metadata());
}
compose<S>(other: CallCredentials<S>): CallCredentials<S> {
compose(other: CallCredentials): CallCredentials {
return other;
}
}
@ -81,12 +83,12 @@ export namespace CallCredentials {
* generates a Metadata object based on these options, which is passed back
* to the caller via a supplied (err, metadata) callback.
*/
export function createFromMetadataGenerator<T>(
metadataGenerator: CallMetadataGenerator<T>): CallCredentials<T> {
export function createFromMetadataGenerator(
metadataGenerator: CallMetadataGenerator): CallCredentials {
return new SingleCallCredentials(metadataGenerator);
}
export function createEmpty(): CallCredentials<{}> {
export function createEmpty(): CallCredentials {
return new EmptyCallCredentials();
}
}

View File

@ -7,19 +7,19 @@ import {CallCredentials} from './call-credentials';
* 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<T extends {} = {}> {
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<S>(callCredentials: CallCredentials<S>): ChannelCredentials<S&T>;
compose(callCredentials: CallCredentials): ChannelCredentials;
/**
* Gets the set of per-call credentials associated with this instance.
*/
getCallCredentials(): CallCredentials<T>;
getCallCredentials(): CallCredentials;
/**
* Gets a SecureContext object generated from input parameters if this
@ -29,28 +29,28 @@ export interface ChannelCredentials<T extends {} = {}> {
getSecureContext(): SecureContext|null;
}
abstract class ChannelCredentialsImpl<T> implements ChannelCredentials<T> {
protected callCredentials: CallCredentials<T>;
abstract class ChannelCredentialsImpl implements ChannelCredentials {
protected callCredentials: CallCredentials;
protected constructor(callCredentials?: CallCredentials<T>) {
protected constructor(callCredentials?: CallCredentials) {
this.callCredentials = callCredentials || CallCredentials.createEmpty();
}
abstract compose<S>(callCredentials: CallCredentials<S>): ChannelCredentialsImpl<S&T>;
abstract compose(callCredentials: CallCredentials): ChannelCredentialsImpl;
getCallCredentials(): CallCredentials<T> {
getCallCredentials(): CallCredentials {
return this.callCredentials;
}
abstract getSecureContext(): SecureContext|null;
}
class InsecureChannelCredentialsImpl<T> extends ChannelCredentialsImpl<T> {
constructor(callCredentials?: CallCredentials<T>) {
class InsecureChannelCredentialsImpl extends ChannelCredentialsImpl {
constructor(callCredentials?: CallCredentials) {
super(callCredentials);
}
compose<S>(callCredentials: CallCredentials<S>): ChannelCredentialsImpl<S&T> {
compose(callCredentials: CallCredentials): ChannelCredentialsImpl {
throw new Error('Cannot compose insecure credentials');
}
@ -59,15 +59,15 @@ class InsecureChannelCredentialsImpl<T> extends ChannelCredentialsImpl<T> {
}
}
class SecureChannelCredentialsImpl<T> extends ChannelCredentialsImpl<T> {
class SecureChannelCredentialsImpl extends ChannelCredentialsImpl {
secureContext: SecureContext;
constructor(secureContext: SecureContext, callCredentials?: CallCredentials<T>) {
constructor(secureContext: SecureContext, callCredentials?: CallCredentials) {
super(callCredentials);
this.secureContext = secureContext;
}
compose<S>(callCredentials: CallCredentials<S>): ChannelCredentialsImpl<S&T> {
compose(callCredentials: CallCredentials): ChannelCredentialsImpl {
const combinedCallCredentials =
this.callCredentials.compose(callCredentials);
return new SecureChannelCredentialsImpl(
@ -86,6 +86,7 @@ function verifyIsBufferOrNull(obj: any, friendlyName: string): void {
}
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
@ -96,7 +97,7 @@ export namespace ChannelCredentials {
*/
export function createSsl(
rootCerts?: Buffer|null, privateKey?: Buffer|null,
certChain?: Buffer|null): ChannelCredentials<{}> {
certChain?: Buffer|null): ChannelCredentials {
verifyIsBufferOrNull(rootCerts, 'Root certificate');
verifyIsBufferOrNull(privateKey, 'Private key');
verifyIsBufferOrNull(certChain, 'Certificate chain');
@ -119,7 +120,7 @@ export namespace ChannelCredentials {
/**
* Return a new ChannelCredentials instance with no credentials.
*/
export function createInsecure(): ChannelCredentials<{}> {
export function createInsecure(): ChannelCredentials {
return new InsecureChannelCredentialsImpl();
}
}

View File

@ -8,11 +8,9 @@ import { Metadata } from './metadata';
import { IncomingHttpHeaders } from 'http';
export interface OAuth2Client {
getRequestMetadata: (url: string) => Promise<{ Authorization: string }>;
getRequestMetadata: (url: string, callback: (err: Error|null, headers?: { Authorization: string }) => void) => void;
}
export type GoogleCallCredentials = CallCredentials<{ service_url: string }>;
/**** Client Credentials ****/
// Using assign only copies enumerable properties, which is what we want
@ -22,18 +20,17 @@ export const credentials = Object.assign({
* @param googleCredentials The authentication client to use.
* @return The resulting CallCredentials object.
*/
createFromGoogleCredential: (googleCredentials: OAuth2Client): GoogleCallCredentials => {
return CallCredentials.createFromMetadataGenerator(async (options, callback) => {
let header;
try {
header = await googleCredentials.getRequestMetadata(options.service_url);
} catch (err) {
callback(err);
return;
}
const metadata = new Metadata();
metadata.add('authorization', header.Authorization);
callback(null, metadata);
createFromGoogleCredential: (googleCredentials: OAuth2Client): CallCredentials => {
return CallCredentials.createFromMetadataGenerator((options, callback) => {
googleCredentials.getRequestMetadata(options.service_url!, (err, headers) => {
if (err) {
callback(err);
return;
}
const metadata = new Metadata();
metadata.add('authorization', headers!.Authorization);
callback(null, metadata);
});
});
},
@ -44,9 +41,9 @@ export const credentials = Object.assign({
* @param callCredentials Any number of CallCredentials objects.
* @return The resulting ChannelCredentials object.
*/
combineChannelCredentials: <S, T>(
channelCredentials: ChannelCredentials<S>,
...callCredentials: CallCredentials<T>[]): ChannelCredentials<S&T> => {
combineChannelCredentials: (
channelCredentials: ChannelCredentials,
...callCredentials: CallCredentials[]): ChannelCredentials => {
return callCredentials.reduce((acc, other) => acc.compose(other), channelCredentials);
},
@ -56,9 +53,9 @@ export const credentials = Object.assign({
* @param additional Any number of additional CallCredentials objects.
* @return The resulting CallCredentials object.
*/
combineCallCredentials: <S, T>(
first: CallCredentials<S>,
...additional: CallCredentials<T>[]): CallCredentials<S&T> => {
combineCallCredentials: (
first: CallCredentials,
...additional: CallCredentials[]): CallCredentials => {
return additional.reduce((acc, other) => acc.compose(other), first);
}
}, ChannelCredentials, CallCredentials);