azure-cli
Version:
Microsoft Azure Cross Platform Command Line tool
158 lines (137 loc) • 4.27 kB
JavaScript
/**
* Copyright (c) Microsoft. All rights reserved.
*
* 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.
*/
;
//
// Wrapper module around Windows credential store.
// Uses the creds.exe program.
//
var _ = require('underscore');
var childProcess = require('child_process');
var es = require('event-stream');
var path = require('path');
var parser = require('./win-credstore-parser');
var credExePath = path.join(__dirname, '../../../bin/windows/creds.exe');
var targetNamePrefix = 'AzureXplatCli:target=';
function ensurePrefix(targetName) {
if (targetName.slice(targetNamePrefix.length) !== targetNamePrefix) {
targetName = targetNamePrefix + targetName;
}
return targetName;
}
function removePrefix(targetName) {
return targetName.slice(targetNamePrefix.length);
}
/**
* list the contents of the credential store, parsing each value.
*
* We ignore everything that wasn't put there by us, we look
* for target names starting with the target name prefix.
*
*
* @return {Stream} object mode stream of credentials.
*/
function list() {
var credsProcess = childProcess.spawn(credExePath,['-s', '-g', '-t', targetNamePrefix + '*']);
return credsProcess.stdout
.pipe(parser())
.pipe(es.mapSync(function (cred) {
cred.targetName = removePrefix(cred.targetName);
return cred;
}));
}
/**
* Get details for a specific credential. Assumes generic credential.
*
* @param {string} targetName target name for credential
* @param {function (err, credential)} callback callback function that receives
* returned credential.
*/
function get(targetName, callback) {
var args = [
'-s',
'-t', ensurePrefix(targetName)
];
var credsProcess = childProcess.spawn(credExePath, args);
var result = null;
var errors = [];
credsProcess.stdout.pipe(parser())
.on('data', function (credential) {
result = credential;
result.targetName = removePrefix(result.targetName);
});
credsProcess.stderr.pipe(es.split())
.on('data', function (line) {
errors.push(line);
});
credsProcess.on('exit', function (code) {
if (code === 0) {
callback(null, result);
} else {
callback(new Error('Getting credential failed, exit code ' + code + ': ' + errors.join(', ')));
}
});
}
/**
* Set the credential for a given key in the credential store.
* Creates or updates, assumes generic credential.
* If credential is buffer, stores buffer contents as binary directly.
* If credential is string, stores UTF-8 encoded binary.
*
* @param {String} targetName target name for entry
* @param {Buffer|String} credential the credential
* @param {Function(err)} callback completion callback
*/
function set(targetName, credential, callback) {
if (_.isString(credential)) {
credential = new Buffer(credential, 'utf8');
}
var args = [
'-a',
'-t', ensurePrefix(targetName),
'-p', credential.toString('hex')
];
childProcess.execFile(credExePath, args,
function (err) {
callback(err);
});
}
/**
* Remove the given key from the credential store.
*
* @param {string} targetName target name to remove.
* if ends with "*" character,
* will delete all targets
* starting with that prefix
* @param {Function(err)} callback completion callback
*/
function remove(targetName, callback) {
var args = [
'-d',
'-t', ensurePrefix(targetName)
];
if (targetName.slice(-1) === '*') {
args.push('-g');
}
childProcess.execFile(credExePath, args,
function (err) {
callback(err);
});
}
_.extend(exports, {
list: list,
set: set,
get: get,
remove: remove
});