Skip to content

Commit

Permalink
Merge pull request #101 from Cox-Automotive/develop
Browse files Browse the repository at this point in the history
3.0.0 Release
  • Loading branch information
brianantonelli authored Aug 27, 2018
2 parents 09cb606 + a68f64e commit fd44c96
Show file tree
Hide file tree
Showing 25 changed files with 391 additions and 173 deletions.
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ To see a what options are available to a command ask for help on it:

Since ALKS requires you to pass your credentials, we've made the CLI provide multiple ways of handling this.

1. **Recommended:** Store your password in the keychain. We offer the ability to store your password securely using build in OS functionality. On OS X we use Keychain, on Windows we use Credential Vault and on Linux we use netrc. To store your password simply run `alks developer login` and follow the prompt. You can remove your password at any time by running `alks developer logout`.
1. **Recommended:** Store your password in the keychain. We offer the ability to store your password securely using built in OS functionality. On MacOS we use Keychain, on Windows we use Credential Vault and on Linux we use netrc. To store your password simply run `alks developer login` and follow the prompt. You can remove your password at any time by running `alks developer logout`.
2. Provide your password as an argument, simply pass `-p 'my pass!'`. Note this will appear in your Bash history.
3. Create an environment variable called `ALKS_PASSWORD` whose value is your password.
4. Type your password. If we do not find a password we will prompt you on each use.
Expand All @@ -64,6 +64,12 @@ We will attempt to lookup your password in the following order:
3. Keystore
4. Prompt user

### Two Factor Authentication

The preferred authentication mechanism is two-factor authentication. Simply log into the ALKS GUI and get your refresh token which we will securely store just like your password.

*Note:* Credential authentication will be removed in a future release of the ALKS CLI.

## Docker

If you would rather run the ALKS CLI as a Docker container, simply run the following:
Expand Down Expand Up @@ -94,6 +100,14 @@ docker run -it -e PLATFORM=windows -v %USERPROFILE%:/root coxauto/alks-cli sessi

`alks developer logout` - Remove your login credentials from the OS keychain.

### `developer login2fa`

`alks developer login2fa` - Store your 2FA refresh token in the OS keychain.

### `developer logout2fa`

`alks developer logout2fa` - Remove your 2FA refresh token from the OS keychain.

### `developer info`

`alks developer info` - Show your current developer configuration
Expand Down Expand Up @@ -272,4 +286,5 @@ ALKS CLI will output in a variety of formats, it uses the developer default (set
* `set`: Outputs environment variables via `SET`
* `powershell`: Outputs environment variables for Windows PowerShell
* `fishshell`: Outputs environment variables for Fishshell
* `terraform`: Outputs environment variables prefixed with `ALKS`
* `terraformenv`: Outputs environment variables prefixed with `ALKS`
* `terraformarg`: Outputs environment arguments to pass to a Docker run call prefixed with `ALKS`
2 changes: 2 additions & 0 deletions bin/alks-developer
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ program
.command('info', 'shows current developer configuration')
.command('login', 'stores password')
.command('logout', 'removes password')
.command('login2fa', 'stores your alks refresh token')
.command('logout2fa', 'removes your alks refresh token')
.parse(process.argv);

utils.subcommandSuggestion(program, 'developer');
18 changes: 9 additions & 9 deletions bin/alks-developer-accounts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ function accountExport(account){
while(match = accountRegex.exec(account)){
if(match && account.indexOf('ALKS_') === -1){ // ignore legacy accounts
var accountName = getUniqueAccountName([ match[6].toLowerCase(), match[4].toLowerCase() ].join('_'));
accounts.push(accountName)
accounts.push(accountName);
console.log(exportCmd + ' ' + accountName + '="' + account + '"');
}
}
Expand All @@ -59,21 +59,21 @@ async.waterfall([
utils.log(program, logger, 'getting developer');
Developer.getDeveloper(callback);
},
// get auth
function(developer, callback){
Developer.getPassword(program, function(err, password){
utils.log(program, logger, 'getting password');
callback(err, developer, password);
utils.log(program, logger, 'getting auth');
Developer.getAuth(program, function(err, auth){
callback(err, developer, auth);
});
},
function(developer, password, callback){
function(developer, auth, callback){
utils.log(program, logger, 'getting alks accounts');
alks.getAccounts(developer.server, developer.userid, password, { debug: program.verbose, ua: utils.getUA() }, function(err, alksAccounts){
callback(err, developer, password, alksAccounts);
alks.getAccounts(developer.server, developer.userid, auth, { debug: program.verbose, ua: utils.getUA() }, function(err, alksAccounts){
callback(err, developer, auth, alksAccounts);
});
}
],
function(err, developer, password, alksAccounts){

function(err, developer, auth, alksAccounts){
_.each(alksAccounts, function(val, key){
var data = [ val.account, val.role ]

Expand Down
38 changes: 24 additions & 14 deletions bin/alks-developer-configure
Original file line number Diff line number Diff line change
Expand Up @@ -56,34 +56,44 @@ async.waterfall([
},
// check for existing password
function(previousData, server, userid, callback){
Developer.getPasswordFromKeystore(function(pass){
callback(null, previousData, server, userid, pass);
utils.log(program, logger, 'getting existing auth');
Developer.getAuth(program, function(err, auth){
callback(err, previousData, server, userid, auth);
});
},
function(previousData, server, userid, auth, callback){
utils.log(program, logger, 'getting existing password');
Developer.getPasswordFromKeystore(function(password){
auth.password = password;
callback(null, previousData, server, userid, auth);
});
},
// ask for password
function(previousData, server, userid, currentPassword, callback){
function(previousData, server, userid, auth, callback){
utils.log(program, logger, 'getting password');
Developer.getPasswordFromPrompt(function(err, password){
callback(err, previousData, server, userid, password);
}, 'Network Password', currentPassword);
auth.password = password;
callback(err, previousData, server, userid, auth);
}, 'Network Password', auth.password);
},
// ask if they want to save password
function(previousData, server, userid, password, callback){
function(previousData, server, userid, auth, callback){
inquirer.prompt([
{
type: 'confirm',
name: 'savePassword',
message: 'Save password',
}
]).then(function(answers){
callback(null, previousData, server, userid, password, answers.savePassword);
callback(null, previousData, server, userid, auth, answers.savePassword);
});
},
// request list of accounts from ALKS
function(previousData, server, userid, password, savePassword, callback){
function(previousData, server, userid, auth, savePassword, callback){
utils.log(program, logger, 'Getting ALKS accounts');
var prompt = 'Please select your default ALKS account/role';

program.password = password; // this ensures getALKSAccount() doesnt prompt..
program.auth = auth; // this ensures getALKSAccount() doesnt prompt..
var opts = {
prompt: prompt,
dontDefault: true,
Expand All @@ -98,11 +108,11 @@ async.waterfall([
}
}

callback(null, previousData, server, userid, password, savePassword, data? data.alksAccount : '', data? data.alksRole : '');
callback(null, previousData, server, userid, auth, savePassword, data? data.alksAccount : '', data? data.alksRole : '');
});
},
// select output format
function(previousData, server, userid, password, savePassword, alksAccount, alksRole, callback){
function(previousData, server, userid, auth, savePassword, alksAccount, alksRole, callback){
utils.log(program, logger, 'Getting output formats');

var promptData = {
Expand All @@ -115,10 +125,10 @@ async.waterfall([
};

utils.getStdErrPrompt()([ promptData ]).then(function(answers){
callback(null, server, userid, password, savePassword, alksAccount, alksRole, answers.outputFormat);
callback(null, server, userid, auth, savePassword, alksAccount, alksRole, answers.outputFormat);
});
}
], function(err, server, userid, password, savePassword, alksAccount, alksRole, outputFormat){
], function(err, server, userid, auth, savePassword, alksAccount, alksRole, outputFormat){
// did any of our steps have issues?
if(err){
return utils.errorAndExit('Error configuring developer: ' + err.message);
Expand All @@ -127,7 +137,7 @@ async.waterfall([
var developerPayload = {
server: server,
userid: userid,
password: password,
password: auth.password,
savePassword: savePassword,
alksAccount: alksAccount,
alksRole: alksRole,
Expand Down
25 changes: 13 additions & 12 deletions bin/alks-developer-favorites
Original file line number Diff line number Diff line change
Expand Up @@ -30,31 +30,32 @@ async.waterfall([
utils.log(program, logger, 'getting developer');
Developer.getDeveloper(callback);
},
// get auth
function(developer, callback){
Developer.getPassword(program, function(err, password){
utils.log(program, logger, 'getting password');
callback(err, developer, password);
utils.log(program, logger, 'getting auth');
Developer.getAuth(program, function(err, auth){
callback(err, developer, auth);
});
},
function(developer, password, callback){
function(developer, auth, callback){
utils.log(program, logger, 'getting alks accounts');
alks.getAccounts(developer.server, developer.userid, password, { debug: program.verbose, ua: utils.getUA() }, function(err, alksAccounts){
callback(err, developer, password, alksAccounts);
alks.getAccounts(developer.server, developer.userid, auth, { debug: program.verbose, ua: utils.getUA() }, function(err, alksAccounts){
callback(err, developer, auth, alksAccounts);
});
},
function(developer, password, accounts, callback){
function(developer, auth, accounts, callback){
utils.log(program, logger, 'getting favorite accounts');
Developer.getFavorites(function(err, data){
callback(null, developer, password, accounts, data.favorites);
callback(null, developer, auth, accounts, data.favorites);
});
}
],
function(err, developer, password, alksAccounts, favorites){
function(err, developer, auth, alksAccounts, favorites){
var choices = [],
deferred = [];

utils.log(program, logger, 'rendering favorite accounts');
choices.push(new inquirer.Separator(' = Standard = '))
choices.push(new inquirer.Separator(' = Standard = '));
_.each(alksAccounts, function(val, key){
if(!val.iam){
var name = [val.account, val.role].join(Developer.getAccountDelim());
Expand All @@ -63,10 +64,10 @@ function(err, developer, password, alksAccounts, favorites){
checked: _.contains(favorites, name)
});
}
else deferred.push(val)
else deferred.push(val);
});

choices.push(new inquirer.Separator(' = IAM = '))
choices.push(new inquirer.Separator(' = IAM = '));
_.each(deferred, function(val, key){
var name = [val.account, val.role].join(Developer.getAccountDelim());
choices.push({
Expand Down
8 changes: 8 additions & 0 deletions bin/alks-developer-info
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,12 @@ async.series({
Developer.getDeveloper(callback);
},
password: function(callback){
utils.log(program, logger, 'getting password');
Developer.getPassword(null, callback); // null means dont prompt
},
token: function(callback){
utils.log(program, logger, 'getting 2fa token');
Developer.getToken(function(token){ callback(null, token); });
}
},
function(err, results){
Expand All @@ -53,6 +58,9 @@ function(err, results){

var password = !_.isEmpty(results.password) ? '**********' : clc.red('NOT SET');
table.push(['Password', password]);
console.log(JSON.stringify(results, null, 4));
var token = !_.isEmpty(results.token) ? results.token.substring(0,4) + '**********' : clc.red('NOT SET');
table.push(['2FA Token', token]);

console.error(clc.white.underline.bold('\nDeveloper Configuration'));
console.error(clc.white(table.toString()));
Expand Down
8 changes: 4 additions & 4 deletions bin/alks-developer-login
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ Developer.getPasswordFromPrompt(function(err, password){
else{
console.error(clc.white('Password saved!'));
}
});

utils.log(program, logger, 'checking for updates');
utils.checkForUpdate();
Developer.trackActivity(logger);
utils.log(program, logger, 'checking for updates');
utils.checkForUpdate();
Developer.trackActivity(logger);
});
});
55 changes: 55 additions & 0 deletions bin/alks-developer-login2fa
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#!/usr/bin/env node
'use strict';

process.title = 'ALKS';

var program = require('commander'),
clc = require('cli-color'),
_ = require('underscore'),
opn = require('opn'),
alks = require('alks-node'),
config = require('../package.json'),
utils = require('../lib/utils'),
Developer = require('../lib/developer');

program
.version(config.version)
.description('stores your alks refresh token')
.option('-v, --verbose', 'be verbose')
.parse(process.argv);

var logger = 'dev-login-2fa';

utils.log(program, logger, 'loading developer');
Developer.getDeveloper(function(err, data){
console.error('Opening ALKS 2FA Page.. Be sure to login using Okta..');
opn(data.server.replace(/rest/, 'login/getToken.htm'));
console.error('Please copy your refresh token from ALKS and paste below..');

Developer.getPasswordFromPrompt(function(err, refreshToken){
utils.log(program, logger, 'exchanging refresh token for access token');

alks.refreshTokenToAccessToken(data, refreshToken, { debug: program.verbose, ua: utils.getUA() }, function(err, data){
if(err){
return utils.errorAndExit('Error validating refresh token. ' + err.message);
}

console.error(clc.white('Refresh token validated!'));
Developer.storeToken(refreshToken, function(err, saved){
if(!saved){
utils.log(program, logger, 'error saving token! ' + err.message);
utils.passwordSaveErrorHandler(err);
}
else{
console.error(clc.white('Refresh token saved!'));
}

utils.log(program, logger, 'checking for updates');
utils.checkForUpdate();
Developer.trackActivity(logger);

setTimeout(function(){ process.exit(0); }, 1000); // needed for if browser is still open
});
});
}, 'Refresh Token');
});
30 changes: 30 additions & 0 deletions bin/alks-developer-logout2fa
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/usr/bin/env node
'use strict';

process.title = 'ALKS';

var program = require('commander'),
clc = require('cli-color'),
_ = require('underscore'),
config = require('../package.json'),
utils = require('../lib/utils'),
Developer = require('../lib/developer');

program
.version(config.version)
.description('removes alks refresh token')
.option('-v, --verbose', 'be verbose')
.parse(process.argv);

var logger = 'dev-logout2fa';

if(Developer.removeToken()){
console.error(clc.white('Token removed!'));
}
else{
console.error(clc.red.bold('Error removing toking!'));
}

utils.log(program, logger, 'checking for updates');
utils.checkForUpdate();
Developer.trackActivity(logger);
4 changes: 2 additions & 2 deletions bin/alks-iam-createltk
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ if(!_.isUndefined(alksAccount) && _.isUndefined(alksRole)){
alksRole = utils.tryToExtractRole(alksAccount);
}

Iam.getIAMAccount(program, logger, alksAccount, alksRole, filterFaves, function(err, developer, password, alksAccount, alksRole){
Iam.getIAMAccount(program, logger, alksAccount, alksRole, filterFaves, function(err, developer, auth, alksAccount, alksRole){
if(err){
return utils.errorAndExit(err);
}
Expand All @@ -57,7 +57,7 @@ Iam.getIAMAccount(program, logger, alksAccount, alksRole, filterFaves, function(
data.alksRole = alksRole;
utils.log(program, logger, 'calling api to create ltk: ' + iamUsername);

alks.createLongTermKey(data, password, iamUsername, { debug: program.verbose, ua: utils.getUA() }, function(err, data){
alks.createLongTermKey(data, auth, iamUsername, { debug: program.verbose, ua: utils.getUA() }, function(err, data){
if(err){
return utils.errorAndExit(err);
}
Expand Down
Loading

0 comments on commit fd44c96

Please sign in to comment.