Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 7d8908a
Showing
11 changed files
with
285 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
/node_modules/ | ||
npm-debug.log | ||
.idea | ||
lib-cov | ||
coverage.html |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
test: | ||
@node node_modules/mocha/bin/mocha | ||
|
||
test-cov: lib-cov | ||
@AUTH_EXTRA_COV=1 node_modules/mocha/bin/mocha -R html-cov > coverage.html | ||
|
||
lib-cov: | ||
@node node_modules/jscoverage/bin/jscoverage lib lib-cov | ||
|
||
.PHONY: test test-cov |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
hapi-auth-extra | ||
=============== | ||
|
||
Additional authentication toolbox for HapiJS. | ||
It includes: | ||
* ACL support | ||
* Authentication strategy for API's (Token based) | ||
|
||
How to use it: | ||
-------------- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
module.exports = require('./lib'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/** | ||
* Checks if the user has the wanted roles | ||
* | ||
* @param request | ||
* @param reply | ||
*/ | ||
exports.checkRoles = function(request, reply) { | ||
var user = request.auth.credentials; | ||
var requiredRole = request.pre.role; | ||
if (!exports.isGranted(user.role, requiredRole)) reply(Hapi.error.unauthorized('Unauthorized')); | ||
|
||
reply('Has grants'); | ||
//reply({'bad': 'very'}).takeover().code(500); -- Take over example | ||
}; | ||
|
||
exports.isGranted = function(userRole, requiredRole) { | ||
var userRoles = RoleHierarchy[userRole]; | ||
return (userRoles.indexOf(requiredRole) > -1); | ||
}; | ||
|
||
/** | ||
* Returns a function that returns the required role for an handler | ||
* @param ROLE | ||
* @returns {Function} | ||
*/ | ||
exports.rolePrerequsites = function(ROLE) { | ||
return function(reqeust, reply) { | ||
reply(ROLE); | ||
}; | ||
}; | ||
|
||
/** | ||
* Uses the provided query to fetch the wanted entity. | ||
* | ||
* @param query - function(id, cb) that returns the entity to the callback. | ||
* @param param - The route parameter to use in order to fetch the entity (useually id) | ||
* | ||
* @returns {Function} | ||
*/ | ||
exports.fetchACLEntity = function(query, param) { | ||
return function(request, reply) { | ||
var entityId = request.params[param]; | ||
query(entityId, function(err, entity) { | ||
if (err) return reply(Hapi.error.internal('Bad request', err)); | ||
if (!entity) return reply(Hapi.error.notFound()); | ||
reply(entity); | ||
}); | ||
}; | ||
}; | ||
|
||
/** | ||
* Verifies that the user has permission to access the wanted entity. | ||
* This pre function is depended on fetchACLEntity and must run after it as it needs the entity the verify | ||
* if the user has access to it. | ||
* | ||
* @param role - The wanted role, undefined means any role | ||
* @returns {Function} | ||
*/ | ||
exports.validateACL = function(role) { | ||
return function(request, reply) { | ||
if (!request.pre.entity) throw Error('validateACL must run after fetchACLEntity'); | ||
if (!request.auth.credentials) throw Error('User is required, please make sure this method requires authentication'); | ||
var user = request.auth.credentials, entity = request.pre.entity; | ||
|
||
if(typeof entity.validateACL !== 'function') throw Error(client.constructor.name + ' doesn\'t have validateACL method'); | ||
entity.validateACL(user, role, function(err, isValid) { | ||
if (err) throw Error(err); | ||
|
||
// Not granted | ||
if (!isValid) reply(Hapi.error.unauthorized('Unauthorized', err)); | ||
|
||
// Valid | ||
reply(isValid); | ||
}); | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
/** | ||
* Created by asafdav on 3/11/14. | ||
*/ | ||
var Hoek = require('hoek') | ||
|
||
var Hapi = require('hapi'); | ||
var RoleHierarchy = require('./../model/document/user').RoleHierarchy; | ||
var UserCollection = require('../model/collection/user'); | ||
|
||
|
||
/** | ||
* Implement the passport strategy | ||
* @param username | ||
* @param password | ||
* @param done | ||
*/ | ||
exports.passportLocalStrategy = function(username, password, done) { | ||
UserCollection.login({email: username, password: password}, function(err, user) { | ||
if (err) return done(null, false, { 'message': 'An error occurred' }); | ||
if (!user) return done(null, false, {'message': 'Invalid credentials'}); | ||
|
||
return done(null, user); | ||
}); | ||
}; | ||
|
||
/** | ||
* Implements bearer authenticator | ||
* @param reply | ||
* @returns {Function} | ||
*/ | ||
exports.bearerAuthenticator = function(reply) { | ||
return function(err, user, info) { | ||
if (err) return reply(Hapi.error.unauthorized(err)); | ||
if (!user) return reply(Hapi.error.unauthorized('No user was found for this token')); | ||
return reply(null, { credentials: user }); | ||
} | ||
}; | ||
|
||
/** | ||
* Implements facebook authenticator | ||
* @param accessToken | ||
* @param refreshToken | ||
* @param profile | ||
* @param done | ||
* @returns {*} | ||
*/ | ||
exports.facebookAuthenticator = function(accessToken, refreshToken, profile, done) { | ||
return done(null, false, {message: 'TBD'}); | ||
}; | ||
|
||
/** | ||
* Find the user by token. If there is no user with the given token, set | ||
* the user to `false` to indicate failure. Otherwise, return the | ||
* authenticated `user`. Note that in a production-ready application, one | ||
* would want to validate the token for authenticity. | ||
* | ||
* @param token | ||
* @param done | ||
* @constructor | ||
*/ | ||
exports.BearerStrategy = function(token, done) { | ||
UserCollection.findUserByToken(token, function(err, user) { | ||
if (err) { return done(err); } | ||
if (!user) { return done(null, false); } | ||
|
||
return done(null, user); | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
var Roles = require('./roles'); | ||
|
||
var internals = { | ||
defaults: { | ||
roles: Roles | ||
} | ||
}; | ||
|
||
|
||
exports.register = function (plugin, options, next) { | ||
var settings = Hoek.applyToDefaults(internals.defaults, options || {}); | ||
|
||
plugin.bind({ | ||
config: settings | ||
}); | ||
|
||
plugin.ext('onPostAuth', internals.onPostAuth); | ||
|
||
next(); | ||
}; | ||
|
||
internals.onPostHandler = function(request, next) { | ||
next(); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// TODO - generalize | ||
|
||
var RoleTypes = { | ||
SUPER_ADMIN: 'SUPER_ADMIN', | ||
ADMIN: 'ADMIN', | ||
USER: 'USER', | ||
GUEST: 'GUEST' | ||
}; | ||
|
||
|
||
var RoleHierarchy = {}; | ||
RoleHierarchy[RoleTypes.SUPER_ADMIN] = [RoleTypes.SUPER_ADMIN, RoleTypes.ADMIN, RoleTypes.USER, RoleTypes.GUEST]; | ||
RoleHierarchy[RoleTypes.ADMIN] = [RoleTypes.ADMIN, RoleTypes.USER, RoleTypes.GUEST]; | ||
RoleHierarchy[RoleTypes.USER] = [RoleTypes.USER, RoleTypes.GUEST]; | ||
RoleHierarchy[RoleTypes.GUEST] = [RoleTypes.GUEST]; | ||
|
||
module.exports = { | ||
roles: RoleTypes, | ||
hierarchy: RoleHierarchy | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
{ | ||
"name": "hapi-auth-extra", | ||
"version": "0.0.0", | ||
"description": "Additional auth toolbox for HapiJS including ACL support", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "make test-cov" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git@github.com:asafdav/hapi-auth-extra.git" | ||
}, | ||
"keywords": [ | ||
"hapi", | ||
"auth", | ||
"acl" | ||
], | ||
"author": { | ||
"name": "Asaf David", | ||
"email": "asafdav@gmail.com", | ||
"url": "http://about.me/asafdavid" | ||
}, | ||
"license": "ISC", | ||
"bugs": { | ||
"url": "https://github.com/asafdav/hapi-auth-extra/issues" | ||
}, | ||
"homepage": "https://github.com/asafdav/hapi-auth-extra", | ||
"dependencies": { | ||
"hapi": "^4.1.4", | ||
"hoek": "^2.1.0" | ||
}, | ||
"devDependencies": { | ||
"chai": "^1.9.1", | ||
"jscoverage": "^0.5.0-rc2", | ||
"mocha": "^1.18.2" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
/** | ||
* Created by asafdav on 17/05/14. | ||
*/ | ||
|
||
// External modules | ||
var Chai = require('chai'); | ||
var Hapi = require('hapi'); | ||
|
||
// Internal modules | ||
var libpath = process.env['AUTH_EXTRA_COV'] ? '../lib-cov' : '../lib'; | ||
var Plugin = require(libpath + '/index'); | ||
|
||
|
||
// Declare internals | ||
var internals = {}; | ||
|
||
// Test shortcuts | ||
var expect = Chai.expect; | ||
|
||
describe('Hapi-Auth-Extra', function() { | ||
|
||
describe('onPostAuth', function() { | ||
it('dummy', function(done) { | ||
var server = new Hapi.Server(); | ||
server.route({ method: 'GET', path: '/', handler: function (request, reply) { reply("TEST"); } }); | ||
|
||
server.inject('/', function(res) { | ||
expect(1).to.equal(1); | ||
done(); | ||
}); | ||
}) | ||
}); | ||
|
||
}); |