From b3defa66554c64c1c69720e292f86c3c962607b1 Mon Sep 17 00:00:00 2001 From: Vlad Filippov Date: Mon, 11 Jan 2016 15:29:44 -0500 Subject: [PATCH] quick auth --- config.json | 4 ++ index.js | 69 ++++++++++++++++++++++++-- package.json | 4 ++ public/index.js | 9 ---- {public => static}/index.css | 10 ++++ {public => static}/index.html | 6 ++- static/index.js | 87 +++++++++++++++++++++++++++++++++ {public => static}/spinner.gif | Bin static_secure/out.json | 1 + 9 files changed, 177 insertions(+), 13 deletions(-) create mode 100644 config.json delete mode 100644 public/index.js rename {public => static}/index.css (86%) rename {public => static}/index.html (68%) create mode 100644 static/index.js rename {public => static}/spinner.gif (100%) create mode 100644 static_secure/out.json diff --git a/config.json b/config.json new file mode 100644 index 0000000..2847f5c --- /dev/null +++ b/config.json @@ -0,0 +1,4 @@ +{ + "auth_jku": "https://www.googleapis.com/oauth2/v3/certs", + "client_id": "501118371406-3nuvgor9inia5mqmmm24ff1pmjss2j84.apps.googleusercontent.com" +} diff --git a/index.js b/index.js index 64c3fa4..e983b25 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,5 @@ var Xray = require('x-ray'); +var JWTool = require('fxa-jwtool'); var async = require('async'); var _ = require('lodash'); var fs = require('fs'); @@ -30,14 +31,76 @@ async.map(dashboards, findOutput, function(err, results){ var output = {} var output = _.extend({}, finalResults); if (! err && results) { - fs.writeFile('public/out.json', JSON.stringify(output)) + fs.writeFile('static_secure/out.json', JSON.stringify(output)) } }); var express = require('express') var serveStatic = require('serve-static') +var bodyParser = require('body-parser') +var session = require('express-session') var app = express() +app.use(session({ secret: 'todosecret', cookie: { maxAge: 60000 }})) -app.use(serveStatic('public/', {'index': ['index.html']})) -app.listen(10157) \ No newline at end of file +app.use(bodyParser.urlencoded()); +app.use(bodyParser.json()); + +app.use(serveStatic('static/', {'index': ['index.html']})) +app.use('/static_secure/out.json', function(req, res, next){ + if(req.session && req.session.email){ + return res.sendFile(__dirname + '/static_secure/out.json'); + } else { + res.sendStatus(403); + } +}); + + + +var jwtool = new JWTool(['https://www.googleapis.com/oauth2/v3/certs']) + +app.post('/api/auth', function (req, res) { + if (! req.body.idtoken) { + return res.send(401) + } + // Verify the idtoken's (JWT) signature with the key set from the configured JKU. + // (Google's jwt include a `kid` but no `jku`) + jwtool.verify(req.body.idtoken, { jku: 'https://www.googleapis.com/oauth2/v3/certs' }) + .then( + function (data) { + // ensure the token meets all of our criteria + if ( + data.aud === '501118371406-3nuvgor9inia5mqmmm24ff1pmjss2j84.apps.googleusercontent.com' + && data.exp > (Date.now() / 1000) + && data.hd === 'mozilla.com' + ) { + // set a cookie for authenticating against our other endpoints + req.session.email = data.email + res.send(data) + } + else { + // this user is not authorized + res.sendStatus(401) + } + }, + function (err) { + // the token was not valid + res.send(500, err) + } + ) +}) + +app.get('/config', function (req, res) { + res.type('application/javascript') + res.send('var client_id = "501118371406-3nuvgor9inia5mqmmm24ff1pmjss2j84.apps.googleusercontent.com"') +}); + +app.post('/api/logout', function(req, res) { + if (req.session) { + req.session.email = null; + } + res.sendStatus(200); +}); + +app.listen(10157) +console.log('Started on port 10157!') \ No newline at end of file diff --git a/package.json b/package.json index 651dc60..6199742 100644 --- a/package.json +++ b/package.json @@ -4,13 +4,17 @@ "description": "", "main": "index.js", "scripts": { + "start": "node index.js", "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "MPL-2.0", "dependencies": { "async": "1.5.0", + "body-parser": "^1.14.2", "express": "4.13.3", + "express-session": "^1.13.0", + "fxa-jwtool": "^0.7.2", "lodash": "3.10.1", "serve-static": "1.10.0", "x-ray": "2.0.2" diff --git a/public/index.js b/public/index.js deleted file mode 100644 index 5bf453c..0000000 --- a/public/index.js +++ /dev/null @@ -1,9 +0,0 @@ -$.getJSON( "out.json", function( data ) { - var items = []; - $.each( data, function( key, val ) { - items.push(""); - }); - - $('#placeholder').html(items) - -}); \ No newline at end of file diff --git a/public/index.css b/static/index.css similarity index 86% rename from public/index.css rename to static/index.css index cb072a2..2f045ee 100644 --- a/public/index.css +++ b/static/index.css @@ -15,6 +15,16 @@ h1 { padding-top: 20px; } +button { + background: orange; + border: 0; + color: white; + font-weight: bold; + font-size: 34px; + padding: 10px; + margin: 10px; +} + img { max-width: 400px; padding: 5px; diff --git a/public/index.html b/static/index.html similarity index 68% rename from public/index.html rename to static/index.html index f9127ed..3194526 100644 --- a/public/index.html +++ b/static/index.html @@ -12,9 +12,13 @@

fxa-telemetry-dashboards (CONFIDENTIAL)

10% Sample rate. Updated every Thursday.

-
+ + +
+ + diff --git a/static/index.js b/static/index.js new file mode 100644 index 0000000..9f1a2cc --- /dev/null +++ b/static/index.js @@ -0,0 +1,87 @@ +;window.loggedInEmail = null + +function logout() { + $.post('/api/logout'); + $('#placeholder').html(''); +} + +function updateUI(data) { + window.loggedInEmail = data ? data.email : null + + if (loggedInEmail) { + $('#spinner').show(); + $('#login').hide(); + $('#logout').show(); + $.getJSON('static_secure/out.json', function (data) { + var items = []; + $.each(data, function (key, val) { + items.push(''); + }); + + $('#placeholder').html(items) + + }); + } else { + $('#logout').hide(); + $('#login').show(); + logout(); + } +} + + +function signInChanged(signedIn) { + console.log('signed in: ' + signedIn) +} + +function userChanged(user) { + var id_token = user.getAuthResponse().id_token + console.log('user changed: ' + id_token) + if (id_token) { + $.ajax({ + type: 'POST', + url: '/api/auth', // this creates a cookie used to authenicate other api requests + data: 'idtoken=' + id_token, + contentType: 'application/x-www-form-urlencoded', + dataType: 'json', + success: updateUI, + error: logout + }) + } + else { + // this case triggers when the page is loaded and a user is not logged in + updateUI() + } +} + +gapi.load( + 'auth2', + function () { + // initialize the auth api with our client_id provided by Google in their + // dev console and restrict login to accounts on the mozilla hosted domain. + // https://developers.google.com/identity/sign-in/web/devconsole-project + // + // client_id is set by