Skip to content
This repository has been archived by the owner on Jun 13, 2023. It is now read-only.

1 integrate passport GitHub auth #114

Merged
merged 14 commits into from
Mar 17, 2015
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion app/client/src/modules/app/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,19 @@ module.exports =
//load other app modules here, e.g.:
//require('./account').name
])
.config(function ($urlRouterProvider) {
.config(function ($urlRouterProvider, $httpProvider) {
$urlRouterProvider.otherwise('/');
$httpProvider.interceptors.push('authInterceptor');
}).factory('authInterceptor', function ($rootScope, $q, $location) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't need the $rootScope dep

return {
responseError(response) {
if (response.status === 401) {
console.log('redirecting to login');
$location.path('/login');
//$cookieStore.remove('token');
}

return $q.reject(response);
}
};
});
1 change: 1 addition & 0 deletions app/client/src/modules/app/main/login.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<a href="/auth/github">Login with GitHub</a>
4 changes: 4 additions & 0 deletions app/client/src/modules/app/main/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ module.exports =
url: '/',
templateUrl: 'app/main/main.html',
controller: 'mainController as ctrl'
})
.state('login', {
url: '/login',
templateUrl: 'app/main/login.html'
});
})
.controller('mainController', function () {
Expand Down
1 change: 1 addition & 0 deletions app/server/apps/repos/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
/**
* Business logic routes for working with repos.
*/

var express = require('express'),
jefferson = require('express-jefferson'),
conf = require('./routes'),
Expand Down
8 changes: 4 additions & 4 deletions app/server/apps/repos/routes.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use strict';
var auth = require('../../middleware/auth'),
var auth = require('../../middleware/authenticate'),
repos = require('../../middleware/repos'),
send = require('../../middleware/send'),
permissions = require('../../middleware/permissions');
Expand All @@ -10,7 +10,7 @@ module.exports = {
method: 'GET',
path: '/repos',
middleware: [
auth.authenticate,
auth.isAuthenticated,
repos.listRepos,
repos.listReposPermission,
repos.listReposLinks,
Expand All @@ -21,7 +21,7 @@ module.exports = {
method: 'GET',
path: '/repos/:id',
middleware: [
auth.authenticate,
auth.isAuthenticated,
repos.readRepo,
send.json
]
Expand All @@ -30,7 +30,7 @@ module.exports = {
method: 'PUT',
path: '/repos/:id/users/:username/permissions/:permission',
middleware: [
auth.authenticate,
auth.isAuthenticated,
permissions.editRepoPermissionForUser,
send.noContent
]
Expand Down
1 change: 1 addition & 0 deletions app/server/apps/users/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
/**
* Business logic routes for working with repos.
*/

var express = require('express'),
jefferson = require('express-jefferson'),
conf = require('./routes'),
Expand Down
8 changes: 4 additions & 4 deletions app/server/apps/users/routes.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use strict';
var auth = require('../../middleware/auth'),
var auth = require('../../middleware/authenticate'),
users = require('../../middleware/users'),
permissions = require('../../middleware/permissions'),
send = require('../../middleware/send');
Expand All @@ -9,7 +9,7 @@ module.exports = {
method: 'GET',
path: '/users',
middleware: [
auth.authenticate,
auth.isAuthenticated,
users.listUsers,
users.listUsersPermission,
users.listUsersLinks,
Expand All @@ -20,7 +20,7 @@ module.exports = {
method: 'GET',
path: '/users/:username',
middleware: [
auth.authenticate,
auth.isAuthenticated,
users.readUser,
send.json
]
Expand All @@ -29,7 +29,7 @@ module.exports = {
method: 'PUT',
path: '/users/:username/repos/:id/permissions/:permission',
middleware: [
auth.authenticate,
auth.isAuthenticated,
permissions.editRepoPermissionForUser,
send.noContent
]
Expand Down
19 changes: 18 additions & 1 deletion app/server/components/repositories/users.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
'use strict';

var userUtil = require('./util/users'),
Bluebird = require('bluebird');
Bluebird = require('bluebird'),
permUtil = require('./util/permissions');

module.exports = {

Expand All @@ -14,6 +15,22 @@ module.exports = {

getUser (username) {
return userUtil.getGithubUser(username);
},

getPermissions (repoId, users) {
return permUtil.getPermissionMap().then(map => {
let userMap = map[repoId];
users.forEach(user => {
user.permission = userMap[user.username] || permUtil.getDefaultPermissions();
});
return users;
});
},

isMember (username) {
return userUtil.isMember(username).then(function (data) {
return "204 No Content" === data.meta.success;
});
}

};
8 changes: 7 additions & 1 deletion app/server/components/repositories/util/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ var provider = require('./provider'),
convertGithubUser;

convertGithubUser = (user) => {
console.log('user', user);
return {
username: user.login,
name: user.name,
Expand All @@ -24,5 +23,12 @@ module.exports = {
getGithubUsers() {
var args = provider.getDefaultListArgs();
return provider.github.getUsers(args).then(users => users.map(user => convertGithubUser(user)));
},

isMember(username) {
return provider.github.isMember({
org: provider.github.config.org,
username: username
});
}
};
1 change: 1 addition & 0 deletions app/server/components/services/github.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ module.exports = {
config: {
org: org
},
isMember: Bluebird.promisify(github.orgs.getMember),
getUsers: Bluebird.promisify(github.orgs.getMembers),
getUser: Bluebird.promisify(github.user.getFrom),
getRepos: Bluebird.promisify(github.repos.getFromOrg),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The aliases of these are a little inconsistent? Member vs user

Expand Down
32 changes: 30 additions & 2 deletions app/server/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,43 @@

exports.start = () => {

var express = require('express'),
// HACKING IN CONFIG OBJECT HERE
var config = {
server: {
port: '3000',
api_prefix: '/api/v1',
hostname: 'localhost'
},
github: {
clientID: process.env.GITHUB_CLIENTID,
clientSecret: process.env.GITHUB_CLIENT_KEY,
authRoute: '/auth/github',
authCallbackRoute: '/auth/github/callback',
failureCallback: '/auth/failure'
},
session: {
secret: 'keyboard cat',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this useful for anyone forking the app, or should it be pulled out as an env variable?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should maybe do something like process.env.SESSION_SECRET || 'keyboard cat'.

resave: false,
saveUninitialized: true,
cookie: {
secure: false
}
}},
express = require('express'),
mountie = require('express-mountie'),
http = require('http'),
path = require('path'),
session = require('express-session'),
passport = require('./passport'),
app = express();

app.set('port', 3000);
app.use(session(config.session));

passport.setup(app, config);

app.set('port', config.server.port);
app.use(express.static(path.resolve(__dirname, '../../app/client/build')));

mountie({
parent: app,
src: path.join(__dirname, 'apps'),
Expand Down
15 changes: 15 additions & 0 deletions app/server/middleware/authenticate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
'use strict';

var users = require('../components/repositories/users');

module.exports = {
isAuthenticated (req, res, next) {
var authenticated = req.isAuthenticated();

if (authenticated && users.isMember(req.session.passport.user.username)) {
next();
} else {
res.send(401);
}
}
};
2 changes: 1 addition & 1 deletion app/server/middleware/repos.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ module.exports = {

let repos = req.entity,
user = req.query.permission_user,
username = req.auth.username;
username = req.session.passport.user.username;

if (user) {
permissionRepository.getRepoPermissionsForUser(repos, username).then(permissions => {
Expand Down
2 changes: 1 addition & 1 deletion app/server/middleware/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ module.exports = {

let repoId = req.query.permission_repo,
users = req.entity,
username = req.auth.username;
username = req.session.passport.user.username;

if (repoId) {
permissionRepository.getUserPermissionForRepo(username, repoId).then(permission => {
Expand Down
64 changes: 64 additions & 0 deletions app/server/passport.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
'use strict';


var passport = require('passport'),
GitHubStrategy = require('passport-github').Strategy,
debug = require('debug')('app:passport');

module.exports = {
/**
* Sets up passport-github for authentication by creating routes on the app for retrieving oauth tokens from
* github.
*
* @param app the app that will use the githug authentication
* @param config configuration from the app using the authenticator
*/
setup: function (app, config) {
passport.use(new GitHubStrategy({
clientID: config.github.clientID,
clientSecret: config.github.clientSecret,
callbackURL: "http://" + config.server.hostname + ":" + config.server.port + config.github.authCallbackRoute
},
function (accessToken, refreshToken, profile, done) {
done(null, { username: profile.username, displayName: profile.displayName, id: profile.id, token: accessToken });
}));

passport.serializeUser(function (user, done) {
debug("serialize user");
debug(user);
done(null, user);
});

passport.deserializeUser(function (user, done) {
debug("deserialize user");
debug(user);
done(null, user);
});

app.use(passport.initialize());
app.use(passport.session());


app.get('/auth/authenticated', function (req, res) {
var authenticated = req.isAuthenicated();
if (authenticated) {
res.send(200);
} else {
res.send(401);
}
});
app.get(config.github.authRoute, passport.authenticate('github'));
app.get(config.github.authCallbackRoute, passport.authenticate('github',
{ failureRedirect: config.github.failureRedirect, session: true }),
function (req, res) {
var authenticated = req.isAuthenticated();
debug("authenticated? " + authenticated);
// TODO: redirect to initial request location...
res.redirect('/');
}
);
app.get(config.github.failureCallback, function (req, res, next) {
res.send(401);
});
}
};
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,14 @@
"bluebird": "^2.9.13",
"debug": "^2.1.3",
"express": "^4.12.0",
"express-session": "^1.10.3",
"express-jefferson": "^1.0.0",
"express-mountie": "^3.0.0",
"github": "^0.2.3",
"json-mask": "0.3.4"
"json-mask": "0.3.4",
"method-override": "^2.3.1",
"passport": "^0.2.1",
"passport-github": "^0.1.5"
},
"devDependencies": {
"babelify": "^5.0.4",
Expand Down