2021-08-04 09:24:51 +05:30
|
|
|
import * as actions_http_client from '@actions/http-client'
|
2021-08-12 16:14:22 +05:30
|
|
|
import {IRequestOptions} from '@actions/http-client/interfaces'
|
2021-08-04 09:24:51 +05:30
|
|
|
import {HttpClient} from '@actions/http-client'
|
|
|
|
|
import {BearerCredentialHandler} from '@actions/http-client/auth'
|
2021-08-11 03:50:43 +05:30
|
|
|
import {debug, setSecret} from './core'
|
2021-08-04 09:24:51 +05:30
|
|
|
|
2021-08-16 12:46:17 +05:30
|
|
|
interface TokenRequest {
|
2021-08-23 10:49:53 +05:30
|
|
|
aud?: string
|
2021-08-16 12:46:17 +05:30
|
|
|
}
|
2021-08-09 06:36:02 +05:30
|
|
|
|
2021-08-16 12:46:17 +05:30
|
|
|
interface TokenResponse {
|
2021-08-23 10:49:53 +05:30
|
|
|
value?: string
|
2021-08-04 09:24:51 +05:30
|
|
|
}
|
|
|
|
|
|
2021-08-16 12:46:17 +05:30
|
|
|
export class OidcClient {
|
2021-08-09 06:36:02 +05:30
|
|
|
|
2021-08-16 12:46:17 +05:30
|
|
|
private static createHttpClient(allowRetry = true, maxRetry = 10) {
|
2021-08-18 07:22:04 +05:30
|
|
|
let requestOptions: IRequestOptions = {
|
2021-08-17 09:32:42 +05:30
|
|
|
allowRetries: allowRetry,
|
|
|
|
|
maxRetries: maxRetry
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-09 06:36:02 +05:30
|
|
|
return new HttpClient('actions/oidc-client', [
|
2021-08-16 12:46:17 +05:30
|
|
|
new BearerCredentialHandler(OidcClient.getRuntimeToken())],
|
2021-08-09 06:36:02 +05:30
|
|
|
requestOptions)
|
2021-08-04 09:24:51 +05:30
|
|
|
}
|
|
|
|
|
|
2021-08-16 12:46:17 +05:30
|
|
|
private static getApiVersion(): string {
|
2021-08-09 06:36:02 +05:30
|
|
|
return '2.0'
|
2021-08-04 09:24:51 +05:30
|
|
|
}
|
|
|
|
|
|
2021-08-16 12:46:17 +05:30
|
|
|
private static getRuntimeToken(){
|
2021-08-09 06:36:02 +05:30
|
|
|
const token = process.env['ACTIONS_RUNTIME_TOKEN']
|
|
|
|
|
if (!token) {
|
|
|
|
|
throw new Error('Unable to get ACTIONS_RUNTIME_TOKEN env variable')
|
|
|
|
|
}
|
|
|
|
|
return token
|
2021-08-04 09:24:51 +05:30
|
|
|
}
|
|
|
|
|
|
2021-08-16 12:46:17 +05:30
|
|
|
private static getIDTokenUrl(){
|
2021-08-09 06:36:02 +05:30
|
|
|
let runtimeUrl = process.env['ACTIONS_ID_TOKEN_REQUEST_URL']
|
|
|
|
|
if (!runtimeUrl) {
|
|
|
|
|
throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable')
|
|
|
|
|
}
|
2021-08-16 12:46:17 +05:30
|
|
|
return runtimeUrl + '?api-version=' + OidcClient.getApiVersion()
|
2021-08-09 06:36:02 +05:30
|
|
|
}
|
2021-08-04 09:24:51 +05:30
|
|
|
|
2021-08-23 10:49:53 +05:30
|
|
|
private static async postCall(id_token_url: string, data: TokenRequest): Promise<string> {
|
|
|
|
|
const httpclient = OidcClient.createHttpClient()
|
|
|
|
|
|
2021-08-16 14:29:58 +05:30
|
|
|
const res = await httpclient.postJson<TokenResponse>(id_token_url,data).catch((error) => {
|
2021-08-09 06:36:02 +05:30
|
|
|
throw new Error(
|
2021-08-11 03:50:43 +05:30
|
|
|
`Failed to get ID Token. \n
|
2021-08-12 10:07:18 +05:30
|
|
|
Error Code : ${error.statusCode}\n
|
2021-08-12 16:14:22 +05:30
|
|
|
Error Message: ${error.result.message}`
|
2021-08-09 06:36:02 +05:30
|
|
|
)
|
2021-08-12 10:07:18 +05:30
|
|
|
})
|
2021-08-04 09:24:51 +05:30
|
|
|
|
2021-08-16 12:46:17 +05:30
|
|
|
const id_token = res.result?.value
|
2021-08-23 10:49:53 +05:30
|
|
|
if (!id_token) {
|
2021-08-09 06:36:02 +05:30
|
|
|
throw new Error('Response json body do not have ID Token field')
|
|
|
|
|
}
|
|
|
|
|
return id_token
|
2021-08-12 10:07:18 +05:30
|
|
|
|
2021-08-09 06:36:02 +05:30
|
|
|
}
|
|
|
|
|
|
2021-08-18 14:38:04 +05:30
|
|
|
static async getIDToken(audience: string | undefined): Promise<string> {
|
2021-08-09 06:36:02 +05:30
|
|
|
try {
|
|
|
|
|
// New ID Token is requested from action service
|
2021-08-16 12:46:17 +05:30
|
|
|
const id_token_url: string = OidcClient.getIDTokenUrl()
|
2021-08-09 06:36:02 +05:30
|
|
|
|
|
|
|
|
debug(`ID token url is ${id_token_url}`)
|
2021-08-04 09:24:51 +05:30
|
|
|
|
2021-08-18 14:38:04 +05:30
|
|
|
const data: TokenRequest = { aud: audience }
|
|
|
|
|
|
|
|
|
|
debug(`audience is ${!!audience ? audience : 'not defined'}`)
|
|
|
|
|
|
2021-08-23 10:49:53 +05:30
|
|
|
const id_token = await OidcClient.postCall(id_token_url, data)
|
2021-08-12 10:07:18 +05:30
|
|
|
setSecret(id_token)
|
2021-08-09 06:36:02 +05:30
|
|
|
return id_token
|
|
|
|
|
} catch (error) {
|
|
|
|
|
throw new Error(`Error message: ${error.message}`)
|
|
|
|
|
}
|
2021-08-04 09:24:51 +05:30
|
|
|
}
|
|
|
|
|
}
|