import * as proc from 'child_process' ; import https = require ( 'https' ) ; import * as jsonpath from 'jsonpath-plus' ; import request = require ( 'request' ) ; import { Authenticator } from './auth' ; import { User } from './config_types' ; interface Config { expiry : string ; [ 'cmd-args' ] ? : string ; [ 'cmd-path' ] ? : string ; [ 'token-key' ] : string ; [ 'expiry-key' ] : string ; [ 'access-token' ] ? : string ; } export class GoogleCloudPlatformAuth implements Authenticator { public isAuthProvider ( user ) { if ( ! user || ! user . authProvider ) { return false ; } return user . authProvider . name === 'gcp' ; } public async applyAuthentication ( user , opts ) { const token = this . getToken ( user ) ; if ( token ) { opts . headers ! . Authorization = `Bearer ${ token }` ; } } private getToken ( user ) { const config = user . authProvider . config ; if ( this . isExpired ( config ) ) { this . updateAccessToken ( config ) ; } return config [ 'access-token' ] ; } private isExpired ( config ) { const token = config [ 'access-token' ] ; const expiry = config . expiry ; if ( ! token ) { return true ; } if ( ! expiry ) { return false ; } const expiration = Date . parse ( expiry ) ; if ( expiration < Date . now ( ) ) { return true ; } return false ; } private updateAccessToken ( config ) { let cmd = config [ 'cmd-path' ] ; if ( ! cmd ) { throw new Error ( 'Token is expired!' ) ; } cmd = `"${ cmd }"` ; const args = config [ 'cmd-args' ] ; if ( args ) { cmd = cmd + ' ' + args ; } let output ; try { output = proc . execSync ( cmd ) ; } catch ( err ) { throw new Error ( 'Failed to refresh token: ' + err . message ) ; } const resultObj = JSON . parse ( output ) ; const tokenPathKeyInConfig = config [ 'token-key' ] ; const expiryPathKeyInConfig = config [ 'expiry-key' ] ; const tokenPathKey = '$' + tokenPathKeyInConfig . slice ( 1 , - 1 ) ; const expiryPathKey = '$' + expiryPathKeyInConfig . slice ( 1 , - 1 ) ; config [ 'access-token' ] = jsonpath . JSONPath ( tokenPathKey , resultObj ) ; config . expiry = jsonpath . JSONPath ( expiryPathKey , resultObj ) ; } }