diff --git a/action.yml b/action.yml index 64b40c06..8212ec95 100644 --- a/action.yml +++ b/action.yml @@ -9,10 +9,21 @@ inputs: Early access versions can be specified in the form of e.g. 14-ea, 14.0.0-ea, or 14.0.0-ea.28' required: true - maven-creds: - description: 'Maven credential needed to setup MTLS. Credentails In the format - of base64 encoded yaml containing following fields also containing - base64 blobs ( CA_CERT, CERT, KEY, SETTINGS, SECURITY_SETTINGS)' + maven-ca-cert-b64: + description: 'CA cert in the format of a base64 blob used to connect to private + maven repo protected by MTLS' + maven-keystore-p12-b64: + description: 'Keystore p12 in the format of a base64 blob used to connect to private + maven repo protected by MTLS' + maven-keystore-password: + description: 'Password to perform extractions from the keystore used to connect to private + maven repo protected by MTLS' + maven-settings-b64: + description: 'Settings xml in the format of base64 blob used to connect to private + maven repo protected by MTLS' + maven-security-settings-b64: + description: 'Security ettings xml in the format of base64 blob used to connect to private + maven repo protected by MTLS' java-package: description: 'The package type (jre, jdk, jdk+fx)' required: false diff --git a/src/auth.ts b/src/auth.ts index 4e82a708..39d966a1 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -5,7 +5,7 @@ import * as core from '@actions/core'; import * as io from '@actions/io'; import {create as xmlCreate} from 'xmlbuilder2'; import * as constants from './constants'; -import * as yamlCreds from '@tradeshift/actions-credentials-yaml'; +import {setupMaven, MavenOpts} from './maven'; export const M2_DIR = '.m2'; export const SETTINGS_FILE = 'settings.xml'; @@ -15,7 +15,7 @@ export async function configAuthentication( username: string, password: string, gpgPassphrase: string | undefined = undefined, - mvnCredsBlob: string | undefined = undefined + mvnOpts: MavenOpts | undefined = undefined ) { console.log( `creating ${SETTINGS_FILE} with server-id: ${id};`, @@ -37,8 +37,8 @@ export async function configAuthentication( generate(id, username, password, gpgPassphrase) ); - if (mvnCredsBlob) { - await setupMvnMTLSCfg(mvnCredsBlob, settingsDirectory); + if (mvnOpts) { + await setupMaven(mvnOpts); } } @@ -91,56 +91,3 @@ async function write(directory: string, settings: string) { flag: 'w' }); } - -async function setupMvnMTLSCfg(credBlob: string, settingsDir: string) { - // this is what we need to set - // ~/.m2/settings.xml - // ~/.m2/settings-security.xml - // mkdir -p ~/certs - // ~/certs/certificate.p12 - // ~/rootca.crt - // export MAVEN_OPTS="-Djavax.net.ssl.keyStore=~/certs/certificate.p12 -Djavax.net.ssl.keyStoreType=pkcs12 -Djavax.net.ssl.keyStorePassword=${MAVEN_P12_PASSWORD}" - - const creds = await yamlCreds.parseCredsToObject( - credBlob - ); - const certDir = path.join(os.homedir(), 'certs'); - - fs.writeFileSync( - path.join(settingsDir, 'settings.xml'), - btoa(creds.MVN_SETTINGS), - { - encoding: 'utf-8', - flag: 'w' - } - ); - - fs.writeFileSync( - path.join(settingsDir, 'settings-security.xml'), - btoa(creds.MVN_SECURITY_SETTINGS), - { - encoding: 'utf-8', - flag: 'w' - } - ); - - await io.mkdirP(certDir); - fs.writeFileSync(path.join(certDir, 'rootca.crt'), btoa(creds.MTLS_CA_CERT), { - encoding: 'utf-8', - flag: 'w' - }); - - const p12Path = path.join(certDir, 'certificate.p12'); - fs.writeFileSync(p12Path, btoa(creds.MVN_P12), { - encoding: 'utf-8', - flag: 'w' - }); - - const password = btoa(creds.MVN_P12_PASSWORD); - core.exportVariable( - 'MAVEN_OPTS', - `-Djavax.net.ssl.keyStore=${p12Path} -Djavax.net.ssl.keyStoreType=pkcs12 -Djavax.net.ssl.keyStorePassword=${password}` - ); - - core.debug(`added maven opts for MTLS access`); -} diff --git a/src/constants.ts b/src/constants.ts index eea43912..a8dcfb44 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -9,7 +9,11 @@ export const INPUT_SERVER_PASSWORD = 'server-password'; export const INPUT_SETTINGS_PATH = 'settings-path'; export const INPUT_GPG_PRIVATE_KEY = 'gpg-private-key'; export const INPUT_GPG_PASSPHRASE = 'gpg-passphrase'; -export const INPUT_MAVEN_CREDS = 'maven-creds'; +export const INPUT_MAVEN_CA_CERT_B64 = 'maven-ca-cert-b64'; +export const INPUT_MAVEN_KEYSTORE_P12_B64 = 'maven-keystore-p12-b64'; +export const INPUT_MAVEN_KEYSTORE_PASSWORD = 'maven-keystore-password'; +export const INPUT_MAVEN_SETTINGS_B64 = 'maven-settings-b64'; +export const INPUT_MAVEN_SECURITY_SETTINGS_B64 = 'maven-security-settings-b64'; export const INPUT_DEFAULT_GPG_PRIVATE_KEY = undefined; export const INPUT_DEFAULT_GPG_PASSPHRASE = 'GPG_PASSPHRASE'; diff --git a/src/maven.ts b/src/maven.ts new file mode 100644 index 00000000..e2d38e0b --- /dev/null +++ b/src/maven.ts @@ -0,0 +1,74 @@ +import * as core from '@actions/core'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as constants from './constants'; +import * as os from 'os'; +import * as io from '@actions/io'; + +export interface MavenOpts { + caCert: string; + keystore: string; + password: string; + settings: string; + securitySettings: string; +} + +export function validateOptions(opts: MavenOpts): boolean { + if ( + (opts.caCert === '' || + opts.keystore === '' || + opts.password === '' || + opts.securitySettings === '', + opts.settings === '') + ) { + core.debug('maven options set is not valid: some field is empty'); + return false; + } + return true; +} + +export async function setupMaven(opts: MavenOpts): Promise { + const settingsDir = path.join( + core.getInput(constants.INPUT_SETTINGS_PATH) || os.homedir(), + core.getInput(constants.INPUT_SETTINGS_PATH) ? '' : '.m2' + ); + const certDir = path.join(os.homedir(), 'certs'); + + fs.writeFileSync( + path.join(settingsDir, 'settings.xml'), + btoa(opts.settings), + { + encoding: 'utf-8', + flag: 'w' + } + ); + + fs.writeFileSync( + path.join(settingsDir, 'settings-security.xml'), + btoa(opts.securitySettings), + { + encoding: 'utf-8', + flag: 'w' + } + ); + + await io.mkdirP(certDir); + fs.writeFileSync(path.join(certDir, 'rootca.crt'), btoa(opts.caCert), { + encoding: 'utf-8', + flag: 'w' + }); + + const p12Path = path.join(certDir, 'certificate.p12'); + fs.writeFileSync(p12Path, btoa(opts.keystore), { + encoding: 'utf-8', + flag: 'w' + }); + + const password = btoa(opts.password); + core.exportVariable( + 'MAVEN_OPTS', + `-Djavax.net.ssl.keyStore=${p12Path} -Djavax.net.ssl.keyStoreType=pkcs12 -Djavax.net.ssl.keyStorePassword=${password}` + ); + + core.debug(`added maven opts for MTLS access`); +} diff --git a/src/setup-java.ts b/src/setup-java.ts index 61b00881..f9ffd982 100644 --- a/src/setup-java.ts +++ b/src/setup-java.ts @@ -4,6 +4,7 @@ import * as auth from './auth'; import * as gpg from './gpg'; import * as constants from './constants'; import * as path from 'path'; +import {MavenOpts, validateOptions} from './maven'; async function run() { try { @@ -12,7 +13,28 @@ async function run() { version = core.getInput(constants.INPUT_JAVA_VERSION, {required: true}); } - const mavenCredsBlob = core.getInput(constants.INPUT_MAVEN_CREDS); + const mvnOpts: MavenOpts = { + caCert: core.getInput(constants.INPUT_MAVEN_CA_CERT_B64), + keystore: core.getInput(constants.INPUT_MAVEN_KEYSTORE_P12_B64), + password: core.getInput(constants.INPUT_MAVEN_KEYSTORE_PASSWORD), + settings: core.getInput(constants.INPUT_MAVEN_SETTINGS_B64), + securitySettings: core.getInput( + constants.INPUT_MAVEN_SECURITY_SETTINGS_B64 + ) + }; + + if ( + (mvnOpts.caCert !== '' || + mvnOpts.keystore !== '' || + mvnOpts.password !== '' || + mvnOpts.securitySettings !== '', + mvnOpts.settings !== '') && + !validateOptions(mvnOpts) + ) { + throw new Error( + 'Some of the Maven options is empty: please check maven-* parameters' + ); + } const arch = core.getInput(constants.INPUT_ARCHITECTURE, {required: true}); if (!['x86', 'x64'].includes(arch)) { @@ -52,7 +74,7 @@ async function run() { username, password, gpgPassphrase, - mavenCredsBlob + mvnOpts ); if (gpgPrivateKey) {