diff --git a/app/controllers/users/users.authentication.server.controller.js b/app/controllers/users/users.authentication.server.controller.js
index a912157a..9558ed97 100644
--- a/app/controllers/users/users.authentication.server.controller.js
+++ b/app/controllers/users/users.authentication.server.controller.js
@@ -95,4 +95,112 @@ exports.oauthCallback = function(strategy) {
});
})(req, res, next);
};
+};
+
+/**
+ * Helper function to save or update a OAuth user profile
+ */
+exports.saveOAuthUserProfile = function(req, providerUserProfile, done) {
+ if (!req.user) {
+ // Define a search query fields
+ var searchMainProviderIdentifierField = 'providerData.' + providerUserProfile.providerIdentifierField;
+ var searchAdditionalProviderIdentifierField = 'additionalProvidersData.' + providerUserProfile.provider + '.' + providerUserProfile.providerIdentifierField;
+
+ // Define main provider search query
+ var mainProviderSearchQuery = {};
+ mainProviderSearchQuery.provider = providerUserProfile.provider;
+ mainProviderSearchQuery[searchMainProviderIdentifierField] = providerUserProfile.providerData[providerUserProfile.providerIdentifierField];
+
+ // Define additional provider search query
+ var additionalProviderSearchQuery = {};
+ additionalProviderSearchQuery[searchAdditionalProviderIdentifierField] = providerUserProfile.providerData[providerUserProfile.providerIdentifierField];
+
+ // Define a search query to find existing user with current provider profile
+ var searchQuery = {
+ $or: [mainProviderSearchQuery, additionalProviderSearchQuery]
+ };
+
+ User.findOne(searchQuery, function(err, user) {
+ if (err) {
+ return done(err);
+ } else {
+ if (!user) {
+ var possibleUsername = providerUserProfile.username || ((providerUserProfile.email) ? providerUserProfile.email.split('@')[0] : '');
+
+ User.findUniqueUsername(possibleUsername, null, function(availableUsername) {
+ user = new User({
+ firstName: providerUserProfile.firstName,
+ lastName: providerUserProfile.lastName,
+ username: availableUsername,
+ displayName: providerUserProfile.displayName,
+ email: providerUserProfile.email,
+ provider: providerUserProfile.provider,
+ providerData: providerUserProfile.providerData
+ });
+
+ // And save the user
+ user.save(function(err) {
+ return done(err, user);
+ });
+ });
+ } else {
+ return done(err, user);
+ }
+ }
+ });
+ } else {
+ // User is already logged in, join the provider data to the existing user
+ var user = req.user;
+
+ // Check if user exists, is not signed in using this provider, and doesn't have that provider data already configured
+ if (user.provider !== providerUserProfile.provider && (!user.additionalProvidersData || !user.additionalProvidersData[providerUserProfile.provider])) {
+ // Add the provider data to the additional provider data field
+ if (!user.additionalProvidersData) user.additionalProvidersData = {};
+ user.additionalProvidersData[providerUserProfile.provider] = providerUserProfile.providerData;
+
+ // Then tell mongoose that we've updated the additionalProvidersData field
+ user.markModified('additionalProvidersData');
+
+ // And save the user
+ user.save(function(err) {
+ return done(err, user, '/#!/settings/accounts');
+ });
+ } else {
+ return done(new Error('User is already connected using this provider'), user);
+ }
+ }
+};
+
+/**
+ * Remove OAuth provider
+ */
+exports.removeOAuthProvider = function(req, res, next) {
+ var user = req.user;
+ var provider = req.param('provider');
+
+ if (user && provider) {
+ // Delete the additional provider
+ if (user.additionalProvidersData[provider]) {
+ delete user.additionalProvidersData[provider];
+
+ // Then tell mongoose that we've updated the additionalProvidersData field
+ user.markModified('additionalProvidersData');
+ }
+
+ user.save(function(err) {
+ if (err) {
+ return res.status(400).send({
+ message: errorHandler.getErrorMessage(err)
+ });
+ } else {
+ req.login(user, function(err) {
+ if (err) {
+ res.status(400).send(err);
+ } else {
+ res.jsonp(user);
+ }
+ });
+ }
+ });
+ }
};
\ No newline at end of file
diff --git a/app/controllers/users/users.profile.server.controller.js b/app/controllers/users/users.profile.server.controller.js
index 3fcf730f..ee902cc1 100644
--- a/app/controllers/users/users.profile.server.controller.js
+++ b/app/controllers/users/users.profile.server.controller.js
@@ -53,112 +53,4 @@ exports.update = function(req, res) {
*/
exports.me = function(req, res) {
res.jsonp(req.user || null);
-};
-
-/**
- * Helper function to save or update a OAuth user profile
- */
-exports.saveOAuthUserProfile = function(req, providerUserProfile, done) {
- if (!req.user) {
- // Define a search query fields
- var searchMainProviderIdentifierField = 'providerData.' + providerUserProfile.providerIdentifierField;
- var searchAdditionalProviderIdentifierField = 'additionalProvidersData.' + providerUserProfile.provider + '.' + providerUserProfile.providerIdentifierField;
-
- // Define main provider search query
- var mainProviderSearchQuery = {};
- mainProviderSearchQuery.provider = providerUserProfile.provider;
- mainProviderSearchQuery[searchMainProviderIdentifierField] = providerUserProfile.providerData[providerUserProfile.providerIdentifierField];
-
- // Define additional provider search query
- var additionalProviderSearchQuery = {};
- additionalProviderSearchQuery[searchAdditionalProviderIdentifierField] = providerUserProfile.providerData[providerUserProfile.providerIdentifierField];
-
- // Define a search query to find existing user with current provider profile
- var searchQuery = {
- $or: [mainProviderSearchQuery, additionalProviderSearchQuery]
- };
-
- User.findOne(searchQuery, function(err, user) {
- if (err) {
- return done(err);
- } else {
- if (!user) {
- var possibleUsername = providerUserProfile.username || ((providerUserProfile.email) ? providerUserProfile.email.split('@')[0] : '');
-
- User.findUniqueUsername(possibleUsername, null, function(availableUsername) {
- user = new User({
- firstName: providerUserProfile.firstName,
- lastName: providerUserProfile.lastName,
- username: availableUsername,
- displayName: providerUserProfile.displayName,
- email: providerUserProfile.email,
- provider: providerUserProfile.provider,
- providerData: providerUserProfile.providerData
- });
-
- // And save the user
- user.save(function(err) {
- return done(err, user);
- });
- });
- } else {
- return done(err, user);
- }
- }
- });
- } else {
- // User is already logged in, join the provider data to the existing user
- var user = req.user;
-
- // Check if user exists, is not signed in using this provider, and doesn't have that provider data already configured
- if (user.provider !== providerUserProfile.provider && (!user.additionalProvidersData || !user.additionalProvidersData[providerUserProfile.provider])) {
- // Add the provider data to the additional provider data field
- if (!user.additionalProvidersData) user.additionalProvidersData = {};
- user.additionalProvidersData[providerUserProfile.provider] = providerUserProfile.providerData;
-
- // Then tell mongoose that we've updated the additionalProvidersData field
- user.markModified('additionalProvidersData');
-
- // And save the user
- user.save(function(err) {
- return done(err, user, '/#!/settings/accounts');
- });
- } else {
- return done(new Error('User is already connected using this provider'), user);
- }
- }
-};
-
-/**
- * Remove OAuth provider
- */
-exports.removeOAuthProvider = function(req, res, next) {
- var user = req.user;
- var provider = req.param('provider');
-
- if (user && provider) {
- // Delete the additional provider
- if (user.additionalProvidersData[provider]) {
- delete user.additionalProvidersData[provider];
-
- // Then tell mongoose that we've updated the additionalProvidersData field
- user.markModified('additionalProvidersData');
- }
-
- user.save(function(err) {
- if (err) {
- return res.status(400).send({
- message: errorHandler.getErrorMessage(err)
- });
- } else {
- req.login(user, function(err) {
- if (err) {
- res.status(400).send(err);
- } else {
- res.jsonp(user);
- }
- });
- }
- });
- }
};
\ No newline at end of file
diff --git a/app/routes/users.server.routes.js b/app/routes/users.server.routes.js
index 4ddb7394..929a88a2 100644
--- a/app/routes/users.server.routes.js
+++ b/app/routes/users.server.routes.js
@@ -47,6 +47,10 @@ module.exports = function(app) {
// Setting the linkedin oauth routes
app.route('/auth/linkedin').get(passport.authenticate('linkedin'));
app.route('/auth/linkedin/callback').get(users.oauthCallback('linkedin'));
+
+ // Setting the github oauth routes
+ app.route('/auth/github').get(passport.authenticate('github'));
+ app.route('/auth/github/callback').get(users.oauthCallback('github'));
// Finish by binding the user middleware
app.param('userId', users.userByID);
diff --git a/config/env/development.js b/config/env/development.js
index 51401116..3a3d0173 100644
--- a/config/env/development.js
+++ b/config/env/development.js
@@ -25,6 +25,11 @@ module.exports = {
clientSecret: process.env.LINKEDIN_SECRET || 'APP_SECRET',
callbackURL: 'http://localhost:3000/auth/linkedin/callback'
},
+ github: {
+ clientID: process.env.GITHUB_ID || 'APP_ID',
+ clientSecret: process.env.GITHUB_SECRET || 'APP_SECRET',
+ callbackURL: 'http://localhost:3000/auth/github/callback'
+ },
mailer: {
from: process.env.MAILER_FROM || 'MAILER_FROM',
options: {
diff --git a/config/env/production.js b/config/env/production.js
index 6a2bf895..5461d5f9 100644
--- a/config/env/production.js
+++ b/config/env/production.js
@@ -40,6 +40,11 @@ module.exports = {
clientSecret: process.env.LINKEDIN_SECRET || 'APP_SECRET',
callbackURL: 'http://localhost:3000/auth/linkedin/callback'
},
+ github: {
+ clientID: process.env.GITHUB_ID || 'APP_ID',
+ clientSecret: process.env.GITHUB_SECRET || 'APP_SECRET',
+ callbackURL: 'http://localhost:3000/auth/github/callback'
+ },
mailer: {
from: process.env.MAILER_FROM || 'MAILER_FROM',
options: {
diff --git a/config/env/test.js b/config/env/test.js
index 060d6751..927a1d56 100644
--- a/config/env/test.js
+++ b/config/env/test.js
@@ -26,6 +26,11 @@ module.exports = {
clientSecret: process.env.LINKEDIN_SECRET || 'APP_SECRET',
callbackURL: 'http://localhost:3000/auth/linkedin/callback'
},
+ github: {
+ clientID: process.env.GITHUB_ID || 'APP_ID',
+ clientSecret: process.env.GITHUB_SECRET || 'APP_SECRET',
+ callbackURL: 'http://localhost:3000/auth/github/callback'
+ },
mailer: {
from: process.env.MAILER_FROM || 'MAILER_FROM',
options: {
diff --git a/config/strategies/github.js b/config/strategies/github.js
new file mode 100644
index 00000000..eb1cfe76
--- /dev/null
+++ b/config/strategies/github.js
@@ -0,0 +1,40 @@
+'use strict';
+
+/**
+ * Module dependencies.
+ */
+var passport = require('passport'),
+ url = require('url'),
+ GithubStrategy = require('passport-github').Strategy,
+ config = require('../config'),
+ users = require('../../app/controllers/users');
+
+module.exports = function() {
+ // Use github strategy
+ passport.use(new GithubStrategy({
+ clientID: config.github.clientID,
+ clientSecret: config.github.clientSecret,
+ callbackURL: config.github.callbackURL,
+ passReqToCallback: true
+ },
+ function(req, accessToken, refreshToken, profile, done) {
+ // Set the provider data and include tokens
+ var providerData = profile._json;
+ providerData.accessToken = accessToken;
+ providerData.refreshToken = refreshToken;
+
+ // Create the user OAuth profile
+ var providerUserProfile = {
+ displayName: profile.displayName,
+ email: profile.emails[0].value,
+ username: profile.username,
+ provider: 'github',
+ providerIdentifierField: 'id',
+ providerData: providerData
+ };
+
+ // Save the user OAuth profile
+ users.saveOAuthUserProfile(req, providerUserProfile, done);
+ }
+ ));
+};
\ No newline at end of file
diff --git a/package.json b/package.json
index d90f4e9e..dbf3c636 100755
--- a/package.json
+++ b/package.json
@@ -37,6 +37,7 @@
"passport-twitter": "~1.0.2",
"passport-linkedin": "~0.1.3",
"passport-google-oauth": "~0.1.5",
+ "passport-github": "~0.1.5",
"lodash": "~2.4.1",
"forever": "~0.11.0",
"bower": "~1.3.8",
diff --git a/public/modules/core/services/menus.client.service.js b/public/modules/core/services/menus.client.service.js
index 27402617..d2366d1d 100644
--- a/public/modules/core/services/menus.client.service.js
+++ b/public/modules/core/services/menus.client.service.js
@@ -5,7 +5,7 @@ angular.module('core').service('Menus', [
function() {
// Define a set of default roles
- this.defaultRoles = ['user'];
+ this.defaultRoles = ['*'];
// Define the menus object
this.menus = {};
@@ -13,10 +13,14 @@ angular.module('core').service('Menus', [
// A private function for rendering decision
var shouldRender = function(user) {
if (user) {
- for (var userRoleIndex in user.roles) {
- for (var roleIndex in this.roles) {
- if (this.roles[roleIndex] === user.roles[userRoleIndex]) {
- return true;
+ if (!!~this.roles.indexOf('*')) {
+ return true;
+ } else {
+ for (var userRoleIndex in user.roles) {
+ for (var roleIndex in this.roles) {
+ if (this.roles[roleIndex] === user.roles[userRoleIndex]) {
+ return true;
+ }
}
}
}
@@ -87,7 +91,7 @@ angular.module('core').service('Menus', [
menuItemClass: menuItemType,
uiRoute: menuItemUIRoute || ('/' + menuItemURL),
isPublic: ((isPublic === null || typeof isPublic === 'undefined') ? this.menus[menuId].isPublic : isPublic),
- roles: roles || this.defaultRoles,
+ roles: ((roles === null || typeof roles === 'undefined') ? this.menus[menuId].roles : roles),
position: position || 0,
items: [],
shouldRender: shouldRender
@@ -111,7 +115,7 @@ angular.module('core').service('Menus', [
link: menuItemURL,
uiRoute: menuItemUIRoute || ('/' + menuItemURL),
isPublic: ((isPublic === null || typeof isPublic === 'undefined') ? this.menus[menuId].items[itemIndex].isPublic : isPublic),
- roles: roles || this.defaultRoles,
+ roles: ((roles === null || typeof roles === 'undefined') ? this.menus[menuId].items[itemIndex].roles : roles),
position: position || 0,
shouldRender: shouldRender
});
diff --git a/public/modules/users/img/buttons/github.png b/public/modules/users/img/buttons/github.png
new file mode 100644
index 00000000..6ff6672f
Binary files /dev/null and b/public/modules/users/img/buttons/github.png differ
diff --git a/public/modules/users/views/authentication/signin.client.view.html b/public/modules/users/views/authentication/signin.client.view.html
index 4b7db025..1a1768ef 100644
--- a/public/modules/users/views/authentication/signin.client.view.html
+++ b/public/modules/users/views/authentication/signin.client.view.html
@@ -13,6 +13,9 @@
+
+
+
+
+
+