From 3cdd925c410dfbe2df74774caa5a1d57cac1f996 Mon Sep 17 00:00:00 2001 From: Juan Cruz Viotti Date: Sat, 8 Apr 2017 20:15:17 -0400 Subject: [PATCH] refactor: get rid of `is-elevated` (#1262) This commit implements our own version of the `is-elevated` module. The reason behind this is that `is-elevated` relies on lots of unnecessary modules, that eventually require `spawn-sync` and `try-thread-sleep`, which conditionally require dependencies that are not even declared in their `package.json`, causing issues when concatenating the Etcher CLI. See: https://github.com/resin-io/etcher/pull/1235 See: https://github.com/resin-io/etcher/pull/1228 Signed-off-by: Juan Cruz Viotti --- lib/child-writer/writer-proxy.js | 4 +- lib/cli/etcher.js | 4 +- lib/shared/permissions.js | 69 ++++++++++++++++++++++++++ npm-shrinkwrap.json | 85 +++++--------------------------- package.json | 1 - 5 files changed, 85 insertions(+), 78 deletions(-) create mode 100644 lib/shared/permissions.js diff --git a/lib/child-writer/writer-proxy.js b/lib/child-writer/writer-proxy.js index be3c9d26..ca764557 100644 --- a/lib/child-writer/writer-proxy.js +++ b/lib/child-writer/writer-proxy.js @@ -19,7 +19,6 @@ const Bluebird = require('bluebird'); const childProcess = require('child_process'); const commandJoin = require('command-join'); -const isElevated = require('is-elevated'); const ipc = require('node-ipc'); const _ = require('lodash'); const os = require('os'); @@ -29,6 +28,7 @@ const utils = require('./utils'); const EXIT_CODES = require('../shared/exit-codes'); const errors = require('../shared/errors'); const robot = require('../shared/robot'); +const permissions = require('../shared/permissions'); const packageJSON = require('../../package.json'); // This script is in charge of spawning the writer process and @@ -67,7 +67,7 @@ const OPTIONS_INDEX_START = 2; */ const etcherArguments = process.argv.slice(OPTIONS_INDEX_START); -return isElevated().then((elevated) => { +return permissions.isElevated().then((elevated) => { if (!elevated) { console.log('Attempting to elevate'); diff --git a/lib/cli/etcher.js b/lib/cli/etcher.js index 05703704..0923ffa8 100644 --- a/lib/cli/etcher.js +++ b/lib/cli/etcher.js @@ -18,7 +18,6 @@ const _ = require('lodash'); const Bluebird = require('bluebird'); -const isElevated = require('is-elevated'); const visuals = require('resin-cli-visuals'); const form = require('resin-cli-form'); const drivelist = Bluebird.promisifyAll(require('drivelist')); @@ -29,11 +28,12 @@ const robot = require('../shared/robot'); const messages = require('../shared/messages'); const EXIT_CODES = require('../shared/exit-codes'); const errors = require('../shared/errors'); +const permissions = require('../shared/permissions'); const ARGV_IMAGE_PATH_INDEX = 0; const imagePath = options._[ARGV_IMAGE_PATH_INDEX]; -isElevated().then((elevated) => { +permissions.isElevated().then((elevated) => { if (!elevated) { throw errors.createUserError( messages.error.elevationRequired(), diff --git a/lib/shared/permissions.js b/lib/shared/permissions.js new file mode 100644 index 00000000..668dbc0b --- /dev/null +++ b/lib/shared/permissions.js @@ -0,0 +1,69 @@ +/* + * Copyright 2016 resin.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +'use strict'; + +const os = require('os'); +const Bluebird = require('bluebird'); +const childProcess = Bluebird.promisifyAll(require('child_process')); +const _ = require('lodash'); + +/** + * @summary The user id of the UNIX "superuser" + * @constant + * @type {Number} + */ +const UNIX_SUPERUSER_USER_ID = 0; + +/** + * @summary Check if the current process is running with elevated permissions + * @function + * @public + * + * @description + * This function has been adapted from https://github.com/sindresorhus/is-elevated, + * which was originally licensed under MIT. + * + * We're not using such module directly given that is + * contains dependencies with dynamic undeclared dependencies, + * causing a mess when trying to concatenate the code. + * + * @fulfil {Boolean} - whether the current process has elevated permissions + * @returns {Promise} + * + * @example + * permissions.isElevated().then((isElevated) => { + * if (isElevated) { + * console.log('This process has elevated permissions'); + * } + * }); + */ +exports.isElevated = () => { + if (process.platform === 'win32') { + + // `fltmc` is available on WinPE, XP, Vista, 7, 8, and 10 + // Works even when the "Server" service is disabled + // See http://stackoverflow.com/a/28268802 + return childProcess.execAsync('fltmc') + .then(_.constant(true)) + .catch({ + code: os.constants.errno.EPERM + }, _.constant(false)); + + } + + return Bluebird.resolve(process.geteuid() === UNIX_SUPERUSER_USER_ID); +}; diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index d064970e..c40d8e96 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -2726,11 +2726,6 @@ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", "dev": true }, - "get-stream": { - "version": "3.0.0", - "from": "get-stream@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz" - }, "get-uri": { "version": "0.1.4", "from": "get-uri@>=0.1.0 <0.2.0", @@ -3309,33 +3304,6 @@ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", "dev": true }, - "is-admin": { - "version": "2.1.0", - "from": "is-admin@>=2.1.0 <3.0.0", - "resolved": "https://registry.npmjs.org/is-admin/-/is-admin-2.1.0.tgz", - "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "from": "cross-spawn@>=5.0.1 <6.0.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz" - }, - "execa": { - "version": "0.6.2", - "from": "execa@>=0.6.1 <0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.6.2.tgz" - }, - "npm-run-path": { - "version": "2.0.2", - "from": "npm-run-path@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz" - }, - "path-key": { - "version": "2.0.1", - "from": "path-key@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz" - } - } - }, "is-arrayish": { "version": "0.2.1", "from": "is-arrayish@>=0.2.1 <0.3.0", @@ -3383,11 +3351,6 @@ "resolved": "https://registry.npmjs.org/is-electron-renderer/-/is-electron-renderer-2.0.1.tgz", "dev": true }, - "is-elevated": { - "version": "2.0.1", - "from": "is-elevated@2.0.1", - "resolved": "https://registry.npmjs.org/is-elevated/-/is-elevated-2.0.1.tgz" - }, "is-equal-shallow": { "version": "0.1.3", "from": "is-equal-shallow@>=0.1.3 <0.2.0", @@ -3519,16 +3482,6 @@ "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", "dev": true }, - "is-root": { - "version": "1.0.0", - "from": "is-root@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/is-root/-/is-root-1.0.0.tgz" - }, - "is-stream": { - "version": "1.1.0", - "from": "is-stream@>=1.1.0 <2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz" - }, "is-typedarray": { "version": "1.0.0", "from": "is-typedarray@>=1.0.0 <1.1.0", @@ -3566,7 +3519,8 @@ "isexe": { "version": "1.1.2", "from": "isexe@>=1.1.1 <2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-1.1.2.tgz" + "resolved": "https://registry.npmjs.org/isexe/-/isexe-1.1.2.tgz", + "dev": true }, "isobject": { "version": "0.2.0", @@ -3967,7 +3921,8 @@ "lru-cache": { "version": "4.0.1", "from": "lru-cache@>=4.0.0 <5.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.1.tgz" + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.1.tgz", + "dev": true }, "lzma-native": { "version": "1.5.2", @@ -5192,11 +5147,6 @@ "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz", "dev": true }, - "p-finally": { - "version": "1.0.0", - "from": "p-finally@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz" - }, "pac-proxy-agent": { "version": "0.2.0", "from": "pac-proxy-agent@>=0.0.0 <1.0.0", @@ -5491,7 +5441,8 @@ "pseudomap": { "version": "1.0.2", "from": "pseudomap@>=1.0.1 <2.0.0", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz" + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "dev": true }, "public-encrypt": { "version": "4.0.0", @@ -6050,16 +6001,6 @@ "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", "dev": true }, - "shebang-command": { - "version": "1.2.0", - "from": "shebang-command@>=1.2.0 <2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz" - }, - "shebang-regex": { - "version": "1.0.0", - "from": "shebang-regex@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz" - }, "shell-quote": { "version": "1.6.1", "from": "shell-quote@>=1.6.1 <2.0.0", @@ -6081,7 +6022,8 @@ "signal-exit": { "version": "3.0.2", "from": "signal-exit@>=3.0.0 <4.0.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz" + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "dev": true }, "signcode-tf": { "version": "0.7.5", @@ -6390,11 +6332,6 @@ "from": "strip-bom@>=2.0.0 <3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz" }, - "strip-eof": { - "version": "1.0.0", - "from": "strip-eof@>=1.0.0 <2.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz" - }, "strip-indent": { "version": "1.0.1", "from": "strip-indent@>=1.0.1 <2.0.0", @@ -7021,7 +6958,8 @@ "which": { "version": "1.2.10", "from": "which@>=1.2.8 <2.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.2.10.tgz" + "resolved": "https://registry.npmjs.org/which/-/which-1.2.10.tgz", + "dev": true }, "which-module": { "version": "1.0.0", @@ -7128,7 +7066,8 @@ "yallist": { "version": "2.0.0", "from": "yallist@>=2.0.0 <3.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.0.0.tgz" + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.0.0.tgz", + "dev": true }, "yargs": { "version": "4.7.1", diff --git a/package.json b/package.json index cd827d61..9275047c 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,6 @@ "flat": "^2.0.1", "flexboxgrid": "^6.3.0", "immutable": "^3.8.1", - "is-elevated": "^2.0.1", "lodash": "^4.5.1", "lodash-deep": "^2.0.0", "lzma-native": "^1.5.2",