From 66ae136a967a07f98fbb1563dd18fe1092a5abf2 Mon Sep 17 00:00:00 2001 From: anvaka Date: Sat, 12 Jul 2014 19:57:56 -0700 Subject: [PATCH 1/6] Updated heroku instructions --- README.md | 63 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index d4b1f24..58ac082 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This is a real bummer. So we built Gatekeeper, which is the missing piece you ne Gatekeeper works well with [Github.js](http://github.com/michael/github), which helps you accessing the [Github API](http://developer.github.com/v3/) from the browser. ## API - + ``` GET http://localhost:9999/authenticate/TEMPORARY_CODE ``` @@ -18,7 +18,7 @@ GET http://localhost:9999/authenticate/TEMPORARY_CODE Also see the [documentation on Github](http://developer.github.com/v3/oauth/). 1. Redirect users to request GitHub access. - + ``` GET https://github.com/login/oauth/authorize ``` @@ -26,13 +26,13 @@ Also see the [documentation on Github](http://developer.github.com/v3/oauth/). 2. GitHub redirects back to your site including a temporary code you need for the next step. You can grab it like so: - + ```js var code = window.location.href.match(/\?code=(.*)/)[1]; ``` - + 3. Request the actual token using your instance of Gatekeeper, which knows your `client_secret`. - + ```js $.getJSON('http://localhost:9999/authenticate/'+code, function(data) { console.log(data.token); @@ -41,14 +41,14 @@ Also see the [documentation on Github](http://developer.github.com/v3/oauth/). ## Setup your Gatekeeper -1. Clone it +1. Clone it ``` - git clone git@github.com:prose/gatekeeper.git + git clone git@github.com:anvaka/gatekeeper.git ``` -2. Install Dependencies - +2. Install Dependencies + ``` cd gatekeeper && npm install ``` @@ -79,26 +79,43 @@ Also see the [documentation on Github](http://developer.github.com/v3/oauth/). ## Deploy on Heroku +0. Install [heroku CLI](https://devcenter.heroku.com/articles/heroku-command). +Login to heroku: + +``` +heroku login +``` + 1. Create a new Heroku app - - ``` - cake heroku:create - ``` + +``` +heroku apps:create +``` 2. Rename it (optional) - - ``` - heroku apps:rename NEW_NAME - ``` + +``` +heroku apps:rename NEW_NAME +``` 3. Provide OAUTH_CLIENT_ID and OAUTH_CLIENT_SECRET: - ``` - cake -c OAUTH_CLIENT_ID -s OAUTH_CLIENT_SECRET heroku:config - ``` +``` +heroku config:set OAUTH_CLIENT_ID=your_client_id +heroku config:set OAUTH_CLIENT_SECRET=yor_client_secret +``` 4. Push changes to heroku - ``` - cake heroku:push - ``` +``` +git push heroku master +``` + +5. Verify it is working: + +``` +curl your_app_name.herokuapp.com/ +``` + +Should return something like `Cannot GET /` + From 583c19531b69a24f7a22c716e72994b8429a2f9a Mon Sep 17 00:00:00 2001 From: anvaka Date: Tue, 15 Jul 2014 22:34:16 -0700 Subject: [PATCH 2/6] Added support for usecases This will let developers save some CPU cycles and not deploy one heroku app per domain --- README.md | 103 +++++++++++++++++++++++++++++++++------------------- config.json | 12 ++++-- server.js | 75 +++++++++++++++++++++++++------------- 3 files changed, 123 insertions(+), 67 deletions(-) diff --git a/README.md b/README.md index 58ac082..4e78e9a 100644 --- a/README.md +++ b/README.md @@ -19,63 +19,91 @@ Also see the [documentation on Github](http://developer.github.com/v3/oauth/). 1. Redirect users to request GitHub access. - ``` - GET https://github.com/login/oauth/authorize - ``` +``` +GET https://github.com/login/oauth/authorize +``` 2. GitHub redirects back to your site including a temporary code you need for the next step. - You can grab it like so: +You can grab it like so: - ```js - var code = window.location.href.match(/\?code=(.*)/)[1]; - ``` +```js +var code = window.location.href.match(/\?code=(.*)/)[1]; +``` 3. Request the actual token using your instance of Gatekeeper, which knows your `client_secret`. - ```js - $.getJSON('http://localhost:9999/authenticate/'+code, function(data) { - console.log(data.token); - }); - ``` +```js +$.getJSON('http://localhost:9999/authenticate/'+code, function(data) { + console.log(data.token); +}); +``` ## Setup your Gatekeeper 1. Clone it - ``` - git clone git@github.com:anvaka/gatekeeper.git - ``` +``` +git clone git@github.com:anvaka/gatekeeper.git +``` 2. Install Dependencies - ``` - cd gatekeeper && npm install - ``` +``` +cd gatekeeper && npm install +``` 3. Adjust config.json - ```js - { - "client_id": "GITHUB_APPLICATION_CLIENT_ID", - "client_secret": "GITHUB_APPLICATION_CLIENT_SECRET", - "host": "github.com", - "port": 443, - "path": "/login/oauth/access_token", - "method": "POST", - "server": { - "port": 9999 - } - } - ``` - - You can also set environment variables to override the settings if you don't want Git to track your adjusted config.json file. Just use UPPER_CASE keys. +```js +{ + "default" : { + "client_id": "GITHUB_APPLICATION_CLIENT_ID", + "client_secret": "GITHUB_APPLICATION_CLIENT_SECRET" + }, + "oauth_host": "github.com", + "oauth_port": 443, + "oauth_path": "/login/oauth/access_token", + "oauth_method": "POST" +} +``` + +If you want to support multiple apps (e.g. one for localhost development, one +for beta and one for production), you can adjust your config with use case name: + +```js +{ + "local": { + "client_id": "GITHUB_APPLICATION_LOCAL_CLIENT_ID", + "client_secret": "GITHUB_APPLICATION_LOCAL_CLIENT_SECRET" + }, + "beta": { + "client_id": "GITHUB_APPLICATION_BETA_CLIENT_ID", + "client_secret": "GITHUB_APPLICATION_BETA_CLIENT_SECRET" + }, + "default" : { + "client_id": "GITHUB_APPLICATION_CLIENT_ID", + "client_secret": "GITHUB_APPLICATION_CLIENT_SECRET" + }, + "oauth_host": "github.com", + "oauth_port": 443, + "oauth_path": "/login/oauth/access_token", + "oauth_method": "POST" +} +``` + +You can also set environment variables to override the settings if you don't +want Git to track your adjusted config.json file: + +``` sh +export BETA='{"client_id": "CLIENT_ID", "client_secret": "CLIENT_SECRET"}' +``` 4. Serve it - ``` - $ node server.js - ``` +``` +$ node server.js +``` ## Deploy on Heroku @@ -101,8 +129,7 @@ heroku apps:rename NEW_NAME 3. Provide OAUTH_CLIENT_ID and OAUTH_CLIENT_SECRET: ``` -heroku config:set OAUTH_CLIENT_ID=your_client_id -heroku config:set OAUTH_CLIENT_SECRET=yor_client_secret +heroku config:set DEFAULT='{"client_id": "CLIENT_ID", "client_secret": "CLIENT_SECRET"}' ``` 4. Push changes to heroku diff --git a/config.json b/config.json index 2c39adb..731c907 100644 --- a/config.json +++ b/config.json @@ -1,8 +1,14 @@ { - "oauth_client_id": "GITHUB_APPLICATION_CLIENT_ID", - "oauth_client_secret": "GITHUB_APPLICATION_CLIENT_SECRET", + "localhost" : { + "client_id": "GITHUB_APPLICATION_CLIENT_ID", + "client_secret": "GITHUB_APPLICATION_CLIENT_SECRET" + }, + "default" : { + "client_id": "GITHUB_APPLICATION_CLIENT_ID", + "client_secret": "GITHUB_APPLICATION_CLIENT_SECRET" + }, "oauth_host": "github.com", "oauth_port": 443, "oauth_path": "/login/oauth/access_token", "oauth_method": "POST" -} \ No newline at end of file +} diff --git a/server.js b/server.js index a340294..4372673 100644 --- a/server.js +++ b/server.js @@ -1,18 +1,23 @@ -var url = require('url'), - http = require('http'), - https = require('https'), - fs = require('fs'), - qs = require('querystring'), - express = require('express'), - app = express(); +var url = require('url'), + http = require('http'), + https = require('https'), + fs = require('fs'), + qs = require('querystring'), + express = require('express'), + app = express(); + console.log(process.env); // Load config defaults from JSON file. // Environment variables override defaults. function loadConfig() { - var config = JSON.parse(fs.readFileSync(__dirname+ '/config.json', 'utf-8')); - for (var i in config) { - config[i] = process.env[i.toUpperCase()] || config[i]; - } + var config = require('./config.json'); + Object.keys(config).forEach(function(key) { + var envValue = process.env[key.toUpperCase()]; + if (!envValue) return; + + config[key] = (typeof config[key] === 'object') ? JSON.parse(envValue) : envValue; + }); + console.log('Configuration'); console.log(config); return config; @@ -20,10 +25,17 @@ function loadConfig() { var config = loadConfig(); -function authenticate(code, cb) { +function authenticate(code, useCase, cb) { + var oauth = config[useCase] || config.default; + + if (!oauth) { + cb(new Error('Could not find oauth settings'), null); + return; + } + var data = qs.stringify({ - client_id: config.oauth_client_id, - client_secret: config.oauth_client_secret, + client_id: oauth.client_id, + client_secret: oauth.client_secret, code: code }); @@ -32,13 +44,17 @@ function authenticate(code, cb) { port: config.oauth_port, path: config.oauth_path, method: config.oauth_method, - headers: { 'content-length': data.length } + headers: { + 'content-length': data.length + } }; var body = ""; var req = https.request(reqOptions, function(res) { res.setEncoding('utf8'); - res.on('data', function (chunk) { body += chunk; }); + res.on('data', function(chunk) { + body += chunk; + }); res.on('end', function() { cb(null, qs.parse(body).access_token); }); @@ -46,14 +62,16 @@ function authenticate(code, cb) { req.write(data); req.end(); - req.on('error', function(e) { cb(e.message); }); + req.on('error', function(e) { + cb(e.message); + }); } // Convenience for allowing CORS on routes - GET only -app.all('*', function (req, res, next) { - res.header('Access-Control-Allow-Origin', '*'); - res.header('Access-Control-Allow-Methods', 'GET, OPTIONS'); +app.all('*', function(req, res, next) { + res.header('Access-Control-Allow-Origin', '*'); + res.header('Access-Control-Allow-Methods', 'GET, OPTIONS'); res.header('Access-Control-Allow-Headers', 'Content-Type'); next(); }); @@ -61,15 +79,20 @@ app.all('*', function (req, res, next) { app.get('/authenticate/:code', function(req, res) { console.log('authenticating code:' + req.params.code); - authenticate(req.params.code, function(err, token) { - var result = err || !token ? {"error": "bad_code"} : { "token": token }; - console.log(result); - res.json(result); - }); + authenticate(req.params.code, req.params. + case, function(err, token) { + var result = err || !token ? { + "error": "bad_code" + } : { + "token": token + }; + console.log(result); + res.json(result); + }); }); var port = process.env.PORT || config.port || 9999; -app.listen(port, null, function (err) { +app.listen(port, null, function(err) { console.log('Gatekeeper, at your service: http://localhost:' + port); }); From 331570f206d425afd734aedf41e52a3fc46378c7 Mon Sep 17 00:00:00 2001 From: anvaka Date: Tue, 15 Jul 2014 22:44:45 -0700 Subject: [PATCH 3/6] Formatting --- README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 4e78e9a..8ac1c15 100644 --- a/README.md +++ b/README.md @@ -19,25 +19,25 @@ Also see the [documentation on Github](http://developer.github.com/v3/oauth/). 1. Redirect users to request GitHub access. -``` -GET https://github.com/login/oauth/authorize -``` + ``` + GET https://github.com/login/oauth/authorize + ``` 2. GitHub redirects back to your site including a temporary code you need for the next step. -You can grab it like so: + You can grab it like so: -```js -var code = window.location.href.match(/\?code=(.*)/)[1]; -``` + ```js + var code = window.location.href.match(/\?code=(.*)/)[1]; + ``` 3. Request the actual token using your instance of Gatekeeper, which knows your `client_secret`. -```js -$.getJSON('http://localhost:9999/authenticate/'+code, function(data) { - console.log(data.token); -}); -``` + ```js + $.getJSON('http://localhost:9999/authenticate/'+code, function(data) { + console.log(data.token); + }); + ``` ## Setup your Gatekeeper From 585c2b6447244fbc76ff8e14c72cacc485430e2f Mon Sep 17 00:00:00 2001 From: anvaka Date: Tue, 15 Jul 2014 22:45:31 -0700 Subject: [PATCH 4/6] more formatting --- README.md | 104 +++++++++++++++++++++++++++--------------------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index 8ac1c15..0d59678 100644 --- a/README.md +++ b/README.md @@ -43,67 +43,67 @@ Also see the [documentation on Github](http://developer.github.com/v3/oauth/). 1. Clone it -``` -git clone git@github.com:anvaka/gatekeeper.git -``` + ``` + git clone git@github.com:anvaka/gatekeeper.git + ``` 2. Install Dependencies -``` -cd gatekeeper && npm install -``` + ``` + cd gatekeeper && npm install + ``` 3. Adjust config.json -```js -{ - "default" : { - "client_id": "GITHUB_APPLICATION_CLIENT_ID", - "client_secret": "GITHUB_APPLICATION_CLIENT_SECRET" - }, - "oauth_host": "github.com", - "oauth_port": 443, - "oauth_path": "/login/oauth/access_token", - "oauth_method": "POST" -} -``` - -If you want to support multiple apps (e.g. one for localhost development, one -for beta and one for production), you can adjust your config with use case name: - -```js -{ - "local": { - "client_id": "GITHUB_APPLICATION_LOCAL_CLIENT_ID", - "client_secret": "GITHUB_APPLICATION_LOCAL_CLIENT_SECRET" - }, - "beta": { - "client_id": "GITHUB_APPLICATION_BETA_CLIENT_ID", - "client_secret": "GITHUB_APPLICATION_BETA_CLIENT_SECRET" - }, - "default" : { - "client_id": "GITHUB_APPLICATION_CLIENT_ID", - "client_secret": "GITHUB_APPLICATION_CLIENT_SECRET" - }, - "oauth_host": "github.com", - "oauth_port": 443, - "oauth_path": "/login/oauth/access_token", - "oauth_method": "POST" -} -``` - -You can also set environment variables to override the settings if you don't -want Git to track your adjusted config.json file: - -``` sh -export BETA='{"client_id": "CLIENT_ID", "client_secret": "CLIENT_SECRET"}' -``` + ```js + { + "default" : { + "client_id": "GITHUB_APPLICATION_CLIENT_ID", + "client_secret": "GITHUB_APPLICATION_CLIENT_SECRET" + }, + "oauth_host": "github.com", + "oauth_port": 443, + "oauth_path": "/login/oauth/access_token", + "oauth_method": "POST" + } + ``` + + If you want to support multiple apps (e.g. one for localhost development, one + for beta and one for production), you can adjust your config with use case name: + + ```js + { + "local": { + "client_id": "GITHUB_APPLICATION_LOCAL_CLIENT_ID", + "client_secret": "GITHUB_APPLICATION_LOCAL_CLIENT_SECRET" + }, + "beta": { + "client_id": "GITHUB_APPLICATION_BETA_CLIENT_ID", + "client_secret": "GITHUB_APPLICATION_BETA_CLIENT_SECRET" + }, + "default" : { + "client_id": "GITHUB_APPLICATION_CLIENT_ID", + "client_secret": "GITHUB_APPLICATION_CLIENT_SECRET" + }, + "oauth_host": "github.com", + "oauth_port": 443, + "oauth_path": "/login/oauth/access_token", + "oauth_method": "POST" + } + ``` + + You can also set environment variables to override the settings if you don't + want Git to track your adjusted config.json file: + + ``` sh + export BETA='{"client_id": "CLIENT_ID", "client_secret": "CLIENT_SECRET"}' + ``` 4. Serve it -``` -$ node server.js -``` + ``` + $ node server.js + ``` ## Deploy on Heroku From c309996e143cd8f2189f396c97f986b4782e654c Mon Sep 17 00:00:00 2001 From: anvaka Date: Tue, 15 Jul 2014 22:50:49 -0700 Subject: [PATCH 5/6] Proeprly passing use case argument --- server.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/server.js b/server.js index 4372673..e09f771 100644 --- a/server.js +++ b/server.js @@ -6,7 +6,6 @@ var url = require('url'), express = require('express'), app = express(); - console.log(process.env); // Load config defaults from JSON file. // Environment variables override defaults. function loadConfig() { @@ -78,9 +77,9 @@ app.all('*', function(req, res, next) { app.get('/authenticate/:code', function(req, res) { - console.log('authenticating code:' + req.params.code); - authenticate(req.params.code, req.params. - case, function(err, token) { + console.log('authenticating code:', req.params.code); + console.log('use case: ', req.query.case); + authenticate(req.params.code, req.query.case, function(err, token) { var result = err || !token ? { "error": "bad_code" } : { From 8fdf45477aa48f352db65c00de5f15a96ad15693 Mon Sep 17 00:00:00 2001 From: anvaka Date: Tue, 15 Jul 2014 22:51:40 -0700 Subject: [PATCH 6/6] Updated demo --- README.md | 52 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 0d59678..02ea2cc 100644 --- a/README.md +++ b/README.md @@ -108,41 +108,53 @@ Also see the [documentation on Github](http://developer.github.com/v3/oauth/). ## Deploy on Heroku 0. Install [heroku CLI](https://devcenter.heroku.com/articles/heroku-command). -Login to heroku: + Login to heroku: -``` -heroku login -``` + ``` + heroku login + ``` 1. Create a new Heroku app -``` -heroku apps:create -``` + ``` + heroku apps:create + ``` 2. Rename it (optional) -``` -heroku apps:rename NEW_NAME -``` + ``` + heroku apps:rename NEW_NAME + ``` 3. Provide OAUTH_CLIENT_ID and OAUTH_CLIENT_SECRET: -``` -heroku config:set DEFAULT='{"client_id": "CLIENT_ID", "client_secret": "CLIENT_SECRET"}' -``` + ``` + heroku config:set DEFAULT='{"client_id": "CLIENT_ID", "client_secret": "CLIENT_SECRET"}' + ``` 4. Push changes to heroku -``` -git push heroku master -``` + ``` + git push heroku master + ``` 5. Verify it is working: -``` -curl your_app_name.herokuapp.com/ -``` + ``` + curl your_app_name.herokuapp.com/ + ``` -Should return something like `Cannot GET /` + Should return something like `Cannot GET /` + + To actually trade github code for an access token call: + + ``` + curl your_app_name.herokuapp.com/authenticate/code + ``` + + If you want to use a particular use case (e.g. beta), declared in your config: + + ``` + curl your_app_name.herokuapp.com/authenticate/code?case=beta + ```