From d238a958ece638e6cc8d5ffc6625ed97e72c1731 Mon Sep 17 00:00:00 2001 From: John Knox Date: Fri, 17 May 2019 09:41:36 -0700 Subject: [PATCH] Extract execute and push to androidUtil Summary: This commit doesn't change anything, just moves the android command running stuff into its own utility. Reviewed By: passy Differential Revision: D15393476 fbshipit-source-id: de93bbd88fa62bddff8d9ea56cfbc33bfd854d53 --- src/utils/CertificateProvider.js | 75 ++++------------------------ src/utils/androidContainerUtility.js | 61 ++++++++++++++++++++++ 2 files changed, 72 insertions(+), 64 deletions(-) create mode 100644 src/utils/androidContainerUtility.js diff --git a/src/utils/CertificateProvider.js b/src/utils/CertificateProvider.js index fe8637ed5..04b48e444 100644 --- a/src/utils/CertificateProvider.js +++ b/src/utils/CertificateProvider.js @@ -19,7 +19,7 @@ const tmpDir = promisify(tmp.dir); import iosUtil from '../fb-stubs/iOSContainerUtility'; import {reportPlatformFailures} from './metrics'; import {getAdbClient} from './adbClient'; -const adb = require('adbkit-fb'); +import * as androidUtil from './androidContainerUtility'; // Desktop file paths const os = require('os'); @@ -38,9 +38,7 @@ const deviceClientCertFile = 'device.crt'; const caSubject = '/C=US/ST=CA/L=Menlo Park/O=Sonar/CN=SonarCA'; const serverSubject = '/C=US/ST=CA/L=Menlo Park/O=Sonar/CN=localhost'; const minCertExpiryWindowSeconds = 24 * 60 * 60; -const appNotDebuggableRegex = /debuggable/; const allowedAppNameRegex = /^[a-zA-Z0-9._\-]+$/; -const operationNotPermittedRegex = /not permitted/; const logTag = 'CertificateProvider'; /* * RFC2253 specifies the unamiguous x509 subject format. @@ -197,12 +195,7 @@ export default class CertificateProvider { ); return Promise.all([deviceIdPromise, appNamePromise]).then( ([deviceId, appName]) => - this.pushFileToAndroidDevice( - deviceId, - appName, - destination + filename, - contents, - ), + androidUtil.push(deviceId, appName, destination + filename, contents), ); } if (os === 'iOS' || os === 'windows') { @@ -337,13 +330,15 @@ export default class CertificateProvider { processName: string, csr: string, ): Promise { - return this.executeCommandOnAndroid( - deviceId, - processName, - `cat ${directory + csrFileName}`, - ).then(deviceCsr => { - return this.santitizeString(deviceCsr.toString()) === csr; - }); + return androidUtil + .executeCommandAsApp( + deviceId, + processName, + `cat ${directory + csrFileName}`, + ) + .then(deviceCsr => { + return this.santitizeString(deviceCsr.toString()) === csr; + }); } iOSDeviceHasMatchingCSR( @@ -383,54 +378,6 @@ export default class CertificateProvider { return csrString.replace(/\r/g, '').trim(); } - pushFileToAndroidDevice( - deviceId: string, - app: string, - filename: string, - contents: string, - ): Promise { - console.debug(`Deploying ${filename} to ${deviceId}:${app}`, logTag); - return this.executeCommandOnAndroid( - deviceId, - app, - `echo "${contents}" > ${filename} && chmod 600 ${filename}`, - ).then(output => undefined); - } - - executeCommandOnAndroid( - deviceId: string, - user: string, - command: string, - ): Promise { - if (!user.match(allowedAppNameRegex)) { - return Promise.reject(new Error(`Disallowed run-as user: ${user}`)); - } - if (command.match(/[']/)) { - return Promise.reject( - new Error(`Disallowed escaping command: ${command}`), - ); - } - return this.adb - .then(client => - client.shell(deviceId, `echo '${command}' | run-as '${user}'`), - ) - .then(adb.util.readAll) - .then(buffer => buffer.toString()) - .then(output => { - if (output.match(appNotDebuggableRegex)) { - throw new Error( - `Android app ${user} is not debuggable. To use it with Flipper, add android:debuggable="true" to the application section of AndroidManifest.xml`, - ); - } - if (output.toLowerCase().match(operationNotPermittedRegex)) { - throw new Error( - `Your android device (${deviceId}) does not support the adb shell run-as command. We're tracking this at https://github.com/facebook/flipper/issues/92`, - ); - } - return output; - }); - } - extractAppNameFromCSR(csr: string): Promise { return this.writeToTempFile(csr) .then(path => diff --git a/src/utils/androidContainerUtility.js b/src/utils/androidContainerUtility.js new file mode 100644 index 000000000..2577e89a9 --- /dev/null +++ b/src/utils/androidContainerUtility.js @@ -0,0 +1,61 @@ +/** + * Copyright 2018-present Facebook. + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * @format + */ +import {getAdbClient} from './adbClient'; +const adbkit = require('adbkit-fb'); + +const logTag = 'androidContainerUtility'; +const appNotDebuggableRegex = /debuggable/; +const allowedAppNameRegex = /^[a-zA-Z0-9._\-]+$/; +const operationNotPermittedRegex = /not permitted/; + +const adb = getAdbClient(); + +export function executeCommandAsApp( + deviceId: string, + app: string, + command: string, +): Promise { + if (!app.match(allowedAppNameRegex)) { + return Promise.reject(new Error(`Disallowed run-as user: ${app}`)); + } + if (command.match(/[']/)) { + return Promise.reject(new Error(`Disallowed escaping command: ${command}`)); + } + return adb + .then(client => + client.shell(deviceId, `echo '${command}' | run-as '${app}'`), + ) + .then(adbkit.util.readAll) + .then(buffer => buffer.toString()) + .then(output => { + if (output.match(appNotDebuggableRegex)) { + throw new Error( + `Android app ${app} is not debuggable. To use it with Flipper, add android:debuggable="true" to the application section of AndroidManifest.xml`, + ); + } + if (output.toLowerCase().match(operationNotPermittedRegex)) { + throw new Error( + `Your android device (${deviceId}) does not support the adb shell run-as command. We're tracking this at https://github.com/facebook/flipper/issues/92`, + ); + } + return output; + }); +} + +export function push( + deviceId: string, + app: string, + filename: string, + contents: string, +): Promise { + console.debug(`Deploying ${filename} to ${deviceId}:${app}`, logTag); + return executeCommandAsApp( + deviceId, + app, + `echo "${contents}" > ${filename} && chmod 600 ${filename}`, + ).then(output => undefined); +}