11import execa = require( 'execa' ) ;
2+ import https = require( 'https' ) ;
3+ import request = require( 'request' ) ;
24
35import { Authenticator } from './auth' ;
46import { User } from './config_types' ;
57
8+ export interface CredentialStatus {
9+ readonly token : string ;
10+ readonly clientCertificateData : string ;
11+ readonly clientKeyData : string ;
12+ readonly expirationTimestamp : string ;
13+ }
14+
15+ export interface Credential {
16+ readonly status : CredentialStatus ;
17+ }
18+
619export class ExecAuth implements Authenticator {
7- private readonly tokenCache : { [ key : string ] : any } = { } ;
20+ private readonly tokenCache : { [ key : string ] : Credential | null } = { } ;
821 private execFn : ( cmd : string , args : string [ ] , opts : execa . SyncOptions ) => execa . ExecaSyncReturnValue =
922 execa . sync ;
1023
@@ -24,15 +37,36 @@ export class ExecAuth implements Authenticator {
2437 }
2538
2639 public getToken ( user : User ) : string | null {
27- // TODO: Handle client cert auth here, requires auth refactor.
28- // See https://kubernetes.io/docs/reference/access-authn-authz/authentication/#input-and-output-formats
29- // for details on this protocol.
40+ const credential = this . getCredential ( user ) ;
41+ if ( ! credential ) {
42+ return null ;
43+ }
44+ if ( credential . status . token ) {
45+ return `Bearer ${ credential . status . token } ` ;
46+ }
47+ return null ;
48+ }
49+
50+ public async applyAuthentication ( user : User , opts : request . Options | https . RequestOptions ) {
51+ const credential = this . getCredential ( user ) ;
52+ if ( ! credential ) {
53+ return ;
54+ }
55+ if ( credential . status . clientCertificateData ) {
56+ opts . cert = credential . status . clientCertificateData ;
57+ }
58+ if ( credential . status . clientKeyData ) {
59+ opts . key = credential . status . clientKeyData ;
60+ }
61+ }
62+
63+ private getCredential ( user : User ) : Credential | null {
3064 // TODO: Add a unit test for token caching.
3165 const cachedToken = this . tokenCache [ user . name ] ;
3266 if ( cachedToken ) {
3367 const date = Date . parse ( cachedToken . status . expirationTimestamp ) ;
3468 if ( date > Date . now ( ) ) {
35- return `Bearer ${ cachedToken . status . token } ` ;
69+ return cachedToken ;
3670 }
3771 this . tokenCache [ user . name ] = null ;
3872 }
@@ -57,9 +91,9 @@ export class ExecAuth implements Authenticator {
5791 }
5892 const result = this . execFn ( exec . command , exec . args , opts ) ;
5993 if ( result . code === 0 ) {
60- const obj = JSON . parse ( result . stdout ) ;
94+ const obj = JSON . parse ( result . stdout ) as Credential ;
6195 this . tokenCache [ user . name ] = obj ;
62- return `Bearer ${ obj . status . token } ` ;
96+ return obj ;
6397 }
6498 throw new Error ( result . stderr ) ;
6599 }
0 commit comments