Skip to content

Commit

Permalink
Merge pull request #10 from ddimitrioglo/issue_9
Browse files Browse the repository at this point in the history
#AWSAML Major refactoring (w/ breaking changes)
  • Loading branch information
Dmitri Dimitrioglo authored Nov 11, 2018
2 parents 9f1038b + 81640ce commit f11c034
Show file tree
Hide file tree
Showing 17 changed files with 602 additions and 290 deletions.
9 changes: 0 additions & 9 deletions .saml.json

This file was deleted.

17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,16 @@ Inspired by [AWS CLI Access Using SAML 2.0][1] article.

`aws-saml configure`

> Or manually edit `~/.aws/.saml.json` which will look like
> Or manually add/edit `~/.aws-saml/config.json` which should look like
```text
{
"profile": "saml",
"username": "myusername", // or email: [email protected]
"directoryDomain": "https://directory.mycorp.com",
"accountMapping": {
"888999888999": "Account A",
"profile": "saml", # AWS named profile [Required, default: "saml"]
"username": "myusername", # SSO username (login or email) [Required]
"password": false, # SSO password (encrypted with SSH keys) [Optional, default: false]
"directoryDomain": "https://directory.mycorp.com", # Identity provider (aka IdP) [Required]
"aliases": { # AWS accounts aliases [Optional, default: {}]
"888999888999": "workAccount",
...
}
}
Expand All @@ -35,15 +36,15 @@ Inspired by [AWS CLI Access Using SAML 2.0][1] article.
### Usage

* Run `aws-saml login`
* Enter a password
* Enter a username & password
* Chose an account
* Use your AWS CLI commands by adding `--profile saml`

> Ex. `aws s3 ls --profile saml`
### Help

`aws-saml --help`
To get familiar with all the features, just use `aws-saml --help`

### Improvements

Expand Down
74 changes: 33 additions & 41 deletions bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,52 +3,44 @@
'use strict';

const fs = require('fs');
const os = require('os');
const cli = require('commander');
const path = require('path');
const login = require('./login');
const configure = require('./configure');
const parseArgs = require('minimist');
const { version } = require('../package');

function Config() {
this.name = '.saml.json';
this.path = path.join(os.homedir(), '.aws', this.name);
this.template = path.join(__dirname, '..', this.name);
const command = create();

return {
name: this.name,
path: this.path,
template: this.template
};
}

const cfg = new Config();

cli
.version(version, '-v, --version')
.usage('aws-saml [action]');

cli
.command('configure')
.description('configure ~/.aws/.saml.json')
.action(() => {
configure(cfg);
});

cli
.command('login')
.description('login with SAML credentials')
.action(() => {
if (!fs.existsSync(cfg.path)) {
console.log('Please configure ~/.aws/.saml.json first');
process.exit(1);
command
.validate()
.then(() => command.run())
.then(message => {
if (message) {
console.info('✅', message);
}

login(cfg);
process.exit(0);
})
.catch(err => {
console.error('❌', err.message || err || 'Error occurred');
process.exit(1);
});

if (process.argv.length === 2) {
cli.help();
/**
* Command factory
* @returns {Object}
*/
function create() {
const args = parseArgs(process.argv.slice(2));
const command = args._.shift();

try {
const Command = require(path.join(__dirname, '../cmd', command));
delete args._;

return new Command(args);
} catch (e) {
const help = fs.readFileSync(path.join(__dirname, '../help.txt'), 'utf8');
const output = args.hasOwnProperty('v') || args.hasOwnProperty('version') ? version : help;

console.log(output);
process.exit(0);
}
}

cli.parse(process.argv);
42 changes: 0 additions & 42 deletions bin/configure.js

This file was deleted.

146 changes: 0 additions & 146 deletions bin/login.js

This file was deleted.

41 changes: 41 additions & 0 deletions cmd/alias.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
'use strict';

const rlex = require('../src/extra-readline');
const Command = require('../src/command');

class AliasCommand extends Command {
/**
* @return {Promise}
*/
run() {
const config = this.getConfig();
const aliases = this.getConfig('aliases');
const isDelete = this.getOption('delete', 'd', false);
const accountId = this.getOption('account', 'a', false);

if (!accountId || accountId.constructor === Boolean) {
return Promise.reject('Account ID is required');
}

if (isDelete) {
delete aliases[accountId];
this.updateConfig(config);

return Promise.resolve('Done!');
}

return rlex.promiseQuestion(`Alias for account ${accountId} (${aliases[accountId] || accountId}): `).then(answer => {
if (answer) {
aliases[accountId] = answer;
}

return Promise.resolve();
}).then(() => {
this.updateConfig(config);

return Promise.resolve('Done!');
});
}
}

module.exports = AliasCommand;
Loading

0 comments on commit f11c034

Please sign in to comment.