Skip to content
This repository has been archived by the owner on Mar 27, 2019. It is now read-only.

Commit

Permalink
Hooking into Vault
Browse files Browse the repository at this point in the history
- Using express backend server to make calls to the Vault API to bypass
CORs
- Adding login, list secrets, and get secrets calls
  • Loading branch information
DJ Enriquez committed Nov 8, 2016
1 parent 1ae4d09 commit 4e8ec55
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 75 deletions.
99 changes: 37 additions & 62 deletions app/components/Home/Home.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@ import Secrets from '../Secrets/Secrets.jsx';
import Health from '../Health/Health.jsx';
import Snackbar from 'material-ui/Snackbar';
import { green500, red500, yellow500 } from 'material-ui/styles/colors.js'
import axios from 'axios';

export default class Home extends React.Component {
constructor(props) {
super(props);
this.renderContent = this.renderContent.bind(this);
this.state = {
secrets: [],
snackbarMessage: '',
snackbarOpen: false,
snackbarType: 'OK'
}
super(props);
this.renderContent = this.renderContent.bind(this);
this.state = {
secrets: [],
snackbarMessage: '',
snackbarOpen: false,
snackbarType: 'OK'
}
}

componentDidMount() {
Expand All @@ -38,71 +39,45 @@ export default class Home extends React.Component {

document.addEventListener("addedKey", (e) => {
let secrets = this.state.secrets;
secrets.push({ key: e.detail.key, value: e.detail.value});
secrets.push({ key: e.detail.key, value: e.detail.value });
this.setState({
secrets: secrets
});
});

document.addEventListener("deleteKey", (e) => {
let newSecrets = _.filter(this.state.secrets, x => x.key !== e.detail.key);
let newSecrets = _.filter(this.state.secrets, x => x.key !== e.detail.key);
this.setState({
secrets: newSecrets
});
});

this.setState({
secrets: [
{
key: 'fake_aws_secret',
value: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'
},
{
key: 'fake_aws_id',
value: 'AKIAIOSFODNN7EXAMPLE'
},
{
key: 'key3',
value: 'val3'
},
{
key: 'key4',
value: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'
},
{
key: 'key5',
value: 'AKIAIOSFODNN7EXAMPLE'
},
{
key: 'key6',
value: 'val3'
},
{
key: 'key7',
value: 'val3'
},
{
key: 'key8',
value: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'
},
{
key: 'key9',
value: 'AKIAIOSFODNN7EXAMPLE'
},
{
key: 'key10',
value: 'val3'
}
]
})
var keys = [];
axios.get(`/listsecrets?vaultaddr=${encodeURI(window.localStorage.getItem("vaultUrl"))}&token=${encodeURI(window.localStorage.getItem("vaultAccessToken"))}`)
.then((resp) => {
console.log(resp.data.data);
keys = resp.data.data.keys;


var secrets = _.map(keys, (key) => {
return {
key: key,
value: ""
}
});

this.setState({
secrets: secrets
});
})
}

renderContent() {
switch(this.props.location.pathname) {
switch (this.props.location.pathname) {
case '/secrets':
return <Secrets secrets={this.state.secrets}/>
return <Secrets secrets={this.state.secrets} />
case '/health':
return <Health/>
return <Health />
default:
return (
<div>
Expand All @@ -115,7 +90,7 @@ export default class Home extends React.Component {
}
}

render () {
render() {
let messageStyle = { backgroundColor: green500 };
if (this.state.snackbarType == 'warn') {
messageStyle = { backgroundColor: yellow500 };
Expand All @@ -130,10 +105,10 @@ export default class Home extends React.Component {
open={this.state.snackbarOpen}
message={this.state.snackbarMessage}
autoHideDuration={2000}
onRequestClose={() => this.setState({snackbarOpen: false})}
/>
<Header/>
<Menu pathname={this.props.location.pathname}/>
onRequestClose={() => this.setState({ snackbarOpen: false })}
/>
<Header />
<Menu pathname={this.props.location.pathname} />
<div id={styles.content}>
{this.renderContent()}
</div>
Expand Down
18 changes: 12 additions & 6 deletions app/components/Login/Login.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,17 @@ export default class Login extends React.Component {
return;
}
axios.post(
`${window.localStorage.getItem("vaultUrl")}/v1/auth/github/login`,
{ "token": this.state.authToken },
{ headers: {'Access-Control-Allow-Originh': '*', 'Content-Type': 'text/plain'}}
'/login',
{ "VaultUrl": window.localStorage.getItem("vaultUrl"), "Creds": {"Type": "GITHUB", "Token": this.state.authToken} }
)
.then((data) => {
let accessToken = _.get(data, 'auth.client_token');
.then((resp) => {
// { client_token: '145a495d-dc52-4539-1de8-94e819ba1317',
// accessor: '1275f43d-1287-7df2-d17a-6956181a5238',
// policies: [ 'default', 'insp-power-user' ],
// metadata: { org: 'Openmail', username: 'djenriquez' },
// lease_duration: 3600,
// renewable: true }
let accessToken = _.get(resp, 'data.client_token');
if(accessToken) {
window.localStorage.setItem("vaultAccessToken",accessToken);
console.log(`Fetched token: ${accessToken}`);
Expand All @@ -61,7 +66,8 @@ export default class Login extends React.Component {
//No access token returned, error
}
})
.catch(() => {
.catch((err) => {
console.error(err.stack);
//something went wrong
});

Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
"react": "^15.3.2",
"react-dom": "^15.3.2",
"react-router": "^3.0.0",
"react-tap-event-plugin": "^1.0.0",
"serve-favicon": "^2.3.0"
"react-tap-event-plugin": "^1.0.0"
}
}
28 changes: 23 additions & 5 deletions server.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
import express from 'express';
import bodyParser from 'body-parser';
import favicon from 'serve-favicon';
var express = require('express');
var bodyParser = require('body-parser');
var path = require('path');
var axios = require('axios');
var _ = require('lodash');
var routeHandler = require('./src/routeHandler');

const PORT = 8000;

var app = express();

app.set('view engine','.html');
app.use('/assets', express.static('dist'));

// parse application/x-www-form-urlencoded
Expand All @@ -24,6 +27,21 @@ app.listen(PORT, () => {
console.log(`Vault UI listening on: ${PORT}`);
});


app.post('/login', (req,res) => {
routeHandler.login(req, res);
});

app.get('/listsecrets', (req, res) => {
routeHandler.listSecrets(req, res);
});

app.get('/secret', (req, res) => {
routeHandler.getSecret(req, res);
})

app.get('/')

app.get('*', function(req, res) {
res.render('index.html');
res.sendFile(path.join(__dirname,'/index.html'));
});
93 changes: 93 additions & 0 deletions src/routeHandler.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
'use strict';
var axios = require('axios');
var _ = require('lodash');

/* Returned body
"auth": {
"renewable": true,
"lease_duration": 2764800,
"metadata": {
"username": "vishalnayak",
"org": "hashicorp"
},
"policies": [
"default",
"dev-policy"
],
"accessor": "f93c4b2d-18b6-2b50-7a32-0fecf88237b8",
"client_token": "1977fceb-3bfa-6c71-4d1f-b64af98ac018"
}
*/
var login = function (req, res) {
let creds = _.get(req, "body.Creds");

let endpoint = '';
let body = {}

switch (creds.Type.toLowerCase()) {
case 'github':
endpoint = '/v1/auth/github/login';
body = {
token: creds.Token
};
}
axios.post(`${_.get(req, "body.VaultUrl")}${endpoint}`, body)
.then((resp) => {
res.json(resp.data.auth);
})
.catch((err) => {
console.error(err.stack);
});
};

/* Returned body
{
"auth": null,
"data": {
"keys": ["foo", "foo/"]
},
"lease_duration": 2764800,
"lease_id": "",
"renewable": false
}
*/
var listSecrets = function (req, res) {
let endpoint = '/v1/secret?list=true';
let vaultAddr = decodeURI(req.query['vaultaddr']);
let config = { headers : { 'X-Vault-Token': decodeURI(req.query['token']) } }
console.log(`${vaultAddr}${endpoint}`);
axios.get(`${vaultAddr}${endpoint}`, config)
.then((resp) => {
res.json(resp.data);
})
.catch((err) => {
console.error(err.stack);
});
}
/* Returned body
{
"foo": "bar"
}
Query params 'secret' and 'vaultaddr' must go through encodeURI()
*/
var getSecret = function (req, res) {
let endpoint = `/v1/secret/${decodeURI(req.query['secret'])}`;
let vaultAddr = decodeURI(req.query['vaultaddr']);
let config = { headers : { 'X-Vault-Token': req.query['token'] } }

axios.get(`${vaultAddr}${endpoint}`, config)
.then((resp) => {
res.json(resp.data.data);
})
.catch((err) => {
console.error(err.stack);
});
}

module.exports = (function () {
return {
login: login,
listSecrets: listSecrets,
getSecret: getSecret
}
})();

0 comments on commit 4e8ec55

Please sign in to comment.