Skip to content

Commit

Permalink
Add organization authentication (#55)
Browse files Browse the repository at this point in the history
* Add organization authentication

* Add organization authentication

* Add new dotenv files

* Fix gCloud deployment

* Separate dev and prod keys
  • Loading branch information
danabreo authored Jul 10, 2020
1 parent eaf053d commit c33569d
Show file tree
Hide file tree
Showing 14 changed files with 218 additions and 44 deletions.
10 changes: 10 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Rename this file to .env.[dev|prod]
# When making changes to any .env file:
# Update .env.[dev|prod]
# Update values from Team Drive
# Update values in cloudbuild.yaml and clouddeploy.yaml
# Update values to gCloud build triggers

PASSPORT_CLIENT_ID=
PASSPORT_CLIENT_SECRET=
BASE_URL=
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ web_modules/
.yarn-integrity

# dotenv environment variables file
.env
.env.dev
.env.prod
.env.test

# parcel-bundler cache (https://parceljs.org/)
Expand Down
65 changes: 48 additions & 17 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,3 @@
/**
* Module dependencies.
*/

var express = require('express');
var http = require('http');
var path = require('path');
var handlebars = require('express-handlebars')

var app = express();
const PROD_WARNING_MESSAGE = `
██  ██  █████  ██████  ███  ██ ██ ███  ██  ██████  ██ 
██  ██ ██   ██ ██   ██ ████  ██ ██ ████  ██ ██       ██ 
Expand All @@ -20,20 +10,48 @@ You are running the app using production config (Firestore Database, Map API key
If you are developing the app locally, please use "npm run dev" to start the app.
`;

// Show production warning message and load API keys.
if (process.env.NODE_ENV === 'production') {
console.log(PROD_WARNING_MESSAGE);
require('dotenv').config({path: ".env.prod"});
} else {
require('dotenv').config({path: ".env.dev"});
}

// Module dependencies.
const express = require('express');
const http = require('http');
const path = require('path');
const handlebars = require('express-handlebars')
const passport = require('passport');
const cookieSession = require('cookie-session');
require('./passport-auth');

var app = express();

// Environments configs.
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.engine('handlebars', handlebars());
app.set('view engine', 'handlebars');
app.use(express.urlencoded());
app.use('/static', express.static('public'));
app.use(cookieSession({
name: 'auth-session',
keys: ['key1', 'key2'],
}));
app.use(passport.initialize());
app.use(passport.session());

// Load API keys.
require('dotenv').config();

// Show production warning message.
if (process.env.NODE_ENV === 'production') {
console.log(PROD_WARNING_MESSAGE);
// Authentication middleware
const isLoggedIn = (req, res, next) => {
if (req.user) {
next();
} else {
// TODO: Redirect users back to login page.
res.sendStatus(401);
}
}

// Routes.
Expand All @@ -44,7 +62,20 @@ app.get('/discover', discover.view);
app.get('/discover/:filter', discover.getOrganizations);

const dashboard = require('./routes/dashboard');
app.get('/dashboard/:id/:page?', dashboard.view);
app.get('/dashboard/:page?', isLoggedIn, dashboard.view);

app.get('/auth/google',
passport.authenticate('google', {scope: ['profile']}));

app.get('/auth/google/callback',
passport.authenticate('google', {failureRedirect: '/'}),
(req, res) => res.redirect('/dashboard'));

app.get('/auth/logout', (req, res) => {
req.session = null;
req.logout();
res.redirect('/');
});

const data = require('./routes/data');
app.get('/data', data.view);
Expand Down
7 changes: 4 additions & 3 deletions gcp/cloudbuild.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ steps:
args: ['install']
- name: node
entrypoint: npm
args: ["run", "create-env"]
args: ["run", "create-env-dev"]
env:
- 'MAPS_KEY=${_MAPS_PROD_KEY}'
- 'PASSPORT_CLIENT_ID=${_PASSPORT_PROD_CLIENT_ID}'
- 'PASSPORT_CLIENT_SECRET=${_PASSPORT_PROD_CLIENT_SECRET}'
- 'PASSPORT_CLIENT_ID=${_PASSPORT_DEV_CLIENT_ID}'
- 'PASSPORT_CLIENT_SECRET=${_PASSPORT_DEV_CLIENT_SECRET}'
- 'BASE_URL=${_BASE_URL}'
- name: node
entrypoint: npm
args: ['test']
3 changes: 2 additions & 1 deletion gcp/clouddeploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ steps:
args: ['install']
- name: node
entrypoint: npm
args: ["run", "create-env"]
args: ["run", "create-env-prod"]
env:
- 'MAPS_KEY=${_MAPS_PROD_KEY}'
- 'PASSPORT_CLIENT_ID=${_PASSPORT_PROD_CLIENT_ID}'
- 'PASSPORT_CLIENT_SECRET=${_PASSPORT_PROD_CLIENT_SECRET}'
- 'BASE_URL=${_BASE_URL}'
- name: node
entrypoint: npm
args: ['test']
Expand Down
98 changes: 98 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"description": "Skeleton app for Node.js based STEP capstone project. ",
"main": "index.js",
"scripts": {
"create-env": "printenv > .env",
"create-env-dev": "printenv > .env.dev",
"create-env-prod": "printenv > .env.prod",
"test": "./node_modules/.bin/mocha --exit",
"start": "NODE_ENV=production node app.js",
"dev": "NODE_ENV=development node app.js"
Expand All @@ -21,9 +22,12 @@
"homepage": "https://github.com/ccyang314/step-node-starter#readme",
"dependencies": {
"@google-cloud/firestore": "^4.0.0",
"cookie-session": "^1.4.0",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"express-handlebars": "^4.0.4"
"express-handlebars": "^4.0.4",
"passport": "^0.4.1",
"passport-google-oauth20": "^2.0.0"
},
"devDependencies": {
"chai": "^4.2.0",
Expand Down
14 changes: 14 additions & 0 deletions passport-auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
var passport = require('passport');
const GoogleStrategy = require('passport-google-oauth20').Strategy;

passport.use(new GoogleStrategy({
clientID: process.env.PASSPORT_CLIENT_ID,
clientSecret: process.env.PASSPORT_CLIENT_SECRET,
callbackURL: process.env.BASE_URL + "auth/google/callback"
},
(accessToken, refreshToken, profile, cb) => cb(null, profile)
));

passport.serializeUser((user, done) => done(null, user));

passport.deserializeUser((user, done) => done(null, user));
12 changes: 12 additions & 0 deletions public/css/navbar.css
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,15 @@ a {
#login-button:hover {
background-color: #409726;
}

#logout-button {
font-weight: bold;
padding: 6px 20px;
border-radius: 15px;
background-color: #ff5144;
color: white;
}

#logout-button:hover {
background-color: #d63e33;
}
7 changes: 6 additions & 1 deletion routes/dashboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@ exports.view = function (req, res) {
var pageName = 'dashboardProfile';
if (pageParam === 'categories') pageName = 'dashboardCategories';

var orgName = "Organization";

// Simulation of database retrieving known user's information.
if (req.user.id === '101861107470846011638') orgName = "Google";

res.render(
pageName,
{
layout: 'dashboard',
id: req.params.id,
id: orgName,
editable: pageParam === 'edit',
}
)
Expand Down
4 changes: 2 additions & 2 deletions test/test-discover.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ const request = require('request');
const app = require('../app');

it('Discover page content', function(done) {
request('http://localhost:3000/discover' , function(error, response, body) {
request(process.env.BASE_URL + 'discover' , function(error, response, body) {
expect(body).to.contain("Google STEP App");
expect(body).to.contain("All"); // check for search drop down
done();
});
});

it('Discover page status', function(done) {
request('http://localhost:3000/discover' , function(error, response, body) {
request(process.env.BASE_URL + 'discover' , function(error, response, body) {
expect(response.statusCode).to.equal(200);
done();
});
Expand Down
Loading

0 comments on commit c33569d

Please sign in to comment.