Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Direct use of Boom (0.3.0) #512

Merged
merged 25 commits into from
Feb 11, 2013
Merged
Show file tree
Hide file tree
Changes from all 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
8 changes: 4 additions & 4 deletions examples/validation.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ internals.main();
Try various URLs like:
http://localhost:8080/ // success
http://localhost:8080/?username=test // success
http://localhost:8080/admin?username=walmart&password=worldofwalmartlabs // success
http://localhost:8080/admin?username=walmart // fail
http://localhost:8080/users?email=vnguyen@walmart.com // success
http://localhost:8080/users?email=@walmart.com // fail
http://localhost:8080/admin?username=steve&password=shhhhhh // success
http://localhost:8080/admin?username=steve // fail
http://localhost:8080/users?email=steve@example.com // success
http://localhost:8080/users?email=@example.com // fail
http://localhost:8080/config?choices=1&choices=2 // success
http://localhost:8080/config?choices=1 // success
http://localhost:8080/config // fail
Expand Down
2 changes: 1 addition & 1 deletion examples/views/cms/views/partials/footer.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<footer><p>&copy; @WalmartLabs 2013</p></footer>
<footer><p>&copy; @Someone 2013</p></footer>
16 changes: 8 additions & 8 deletions lib/auth/basic.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

var Cryptiles = require('cryptiles');
var Utils = require('../utils');
var Err = require('../error');
var Boom = require('boom');


// Declare internals
Expand Down Expand Up @@ -33,24 +33,24 @@ internals.Scheme.prototype.authenticate = function (request, callback) {
var req = request.raw.req;
var authorization = req.headers.authorization;
if (!authorization) {
return callback(Err.unauthorized(null, 'Basic'));
return callback(Boom.unauthorized(null, 'Basic'));
}

var parts = authorization.split(/\s+/);

if (parts[0] &&
parts[0].toLowerCase() !== 'basic') {

return callback(Err.unauthorized(null, 'Basic'));
return callback(Boom.unauthorized(null, 'Basic'));
}

if (parts.length !== 2) {
return callback(Err.badRequest('Bad HTTP authentication header format', 'Basic'));
return callback(Boom.badRequest('Bad HTTP authentication header format', 'Basic'));
}

var credentialsParts = new Buffer(parts[1], 'base64').toString().split(':');
if (credentialsParts.length !== 2) {
return callback(Err.badRequest('Bad header internal syntax', 'Basic'));
return callback(Boom.badRequest('Bad header internal syntax', 'Basic'));
}

var credentials = {
Expand All @@ -67,15 +67,15 @@ internals.Scheme.prototype.authenticate = function (request, callback) {

if (!user) {
request.log(['auth', 'error', 'user', 'unknown']);
return callback(Err.unauthorized('Bad username or password', 'Basic'), null, true);
return callback(Boom.unauthorized('Bad username or password', 'Basic'), null, true);
}

if (!user.hasOwnProperty('password') ||
!user.id ||
user.id !== credentials.username) {

request.log(['auth', 'error', 'user', 'invalid']);
return callback(Err.internal('Bad user object received for Basic auth validation'), null, true);
return callback(Boom.internal('Bad user object received for Basic auth validation'), null, true);
}

if (typeof self.settings.hashPasswordFunc === 'function') {
Expand All @@ -86,7 +86,7 @@ internals.Scheme.prototype.authenticate = function (request, callback) {

if (!Cryptiles.fixedTimeComparison(user.password, credentials.password)) {
request.log(['auth', 'error', 'user', 'password']);
return callback(Err.unauthorized('Bad username or password', 'Basic'), null, true);
return callback(Boom.unauthorized('Bad username or password', 'Basic'), null, true);
}

// Authenticated
Expand Down
43 changes: 24 additions & 19 deletions lib/auth/cookie.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Load modules

var Utils = require('../utils');
var Err = require('../error');
var Boom = require('boom');
var Redirection = require('../response/redirection');


Expand All @@ -26,7 +26,8 @@ exports = module.exports = internals.Scheme = function (server, options) {
var cookieOptions = {
encoding: 'iron',
password: this.settings.password,
isSecure: !this.settings.allowInsecure
isSecure: !this.settings.allowInsecure,
path: '/'
};

if (this.settings.ttl) {
Expand All @@ -49,25 +50,13 @@ internals.Scheme.prototype.authenticate = function (request, callback) {

var self = this;

// Decorate request

request.setSession = function (session) {

request.setState(self.settings.cookie, session);
};

request.clearSession = function () {

request.clearState(self.settings.cookie);
};

var validate = function () {

// Check cookie

var session = request.state[self.settings.cookie];
if (!session) {
return unauthenticated(Err.unauthorized());
return unauthenticated(Boom.unauthorized());
}

self.settings.validateFunc(session, function (err, override) {
Expand All @@ -78,7 +67,7 @@ internals.Scheme.prototype.authenticate = function (request, callback) {
}

request.log(['auth', 'validate'], err);
return unauthenticated(Err.unauthorized('Invalid cookie'), session, true);
return unauthenticated(Boom.unauthorized('Invalid cookie'), session, true);
}

if (override) {
Expand All @@ -89,10 +78,10 @@ internals.Scheme.prototype.authenticate = function (request, callback) {
});
};

var unauthenticated = function (err) {
var unauthenticated = function (err, session, wasLogged) {

if (!self.settings.redirectTo) {
return callback(err);
return callback(err, session, wasLogged);
}

var uri = self.settings.redirectTo;
Expand All @@ -107,10 +96,26 @@ internals.Scheme.prototype.authenticate = function (request, callback) {
uri += self.settings.appendNext + '=' + encodeURIComponent(request.url.path);
}

return callback(new Redirection(uri));
return callback(new Redirection(uri), session, wasLogged);
};

validate();
};


internals.Scheme.prototype.extend = function (request) {

var self = this;

// Decorate request

request.setSession = function (session) {

request.setState(self.settings.cookie, session);
};

request.clearSession = function () {

request.clearState(self.settings.cookie);
};
};
2 changes: 1 addition & 1 deletion lib/auth/hawk.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

var Hawk = require('hawk');
var Utils = require('../utils');
var Err = require('../error');
var Boom = require('boom');


// Declare internals
Expand Down
51 changes: 31 additions & 20 deletions lib/auth/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ var Hawk = require('./hawk');
var Basic = require('./basic');
var Cookie = require('./cookie');
var Utils = require('../utils');
var Err = require('../error');
var Boom = require('boom');
var Log = require('hapi-log');


Expand All @@ -30,6 +30,7 @@ exports = module.exports = internals.Auth = function (server, options) {
// Load strategies

this.strategies = {};
this.extensions = [];
for (var name in settings) {
if (settings.hasOwnProperty(name)) {
var strategy = settings[name];
Expand All @@ -46,6 +47,12 @@ exports = module.exports = internals.Auth = function (server, options) {
case 'cookie': this.strategies[name] = new Cookie(this.server, strategy); break;
default: this.strategies[name] = strategy.implementation; break;
}

if (this.strategies[name].extend &&
typeof this.strategies[name].extend === 'function') {

this.extensions.push(this.strategies[name]);
}
}
}

Expand All @@ -55,6 +62,14 @@ exports = module.exports = internals.Auth = function (server, options) {

internals.Auth.authenticate = function (request, next) {

// Extend requests with loaded strategies

if (request.server.auth) {
for (var i = 0, il = request.server.auth.extensions.length; i < il; ++i) {
request.server.auth.extensions[i].extend(request);
}
}

// Modes: required, optional, try, none

var config = request.route.auth;
Expand Down Expand Up @@ -97,7 +112,7 @@ internals.Auth.prototype.authenticate = function (request, next) {
return next();
}

return next(Err.unauthorized('Missing authentication', authErrors));
return next(Boom.unauthorized('Missing authentication', authErrors));
}

var strategy = self.strategies[config.strategies[strategyPos++]]; // Increments counter after fetching current strategy
Expand All @@ -109,24 +124,21 @@ internals.Auth.prototype.authenticate = function (request, next) {
// Unauthenticated

if (!err && !session) {
return next(Err.internal('Authentication response missing both error and session'));
return next(Boom.internal('Authentication response missing both error and session'));
}

if (err) {
if (!wasLogged) {
request.log(['auth', 'unauthenticated'], err);
}

if (err instanceof Error === false) { // Not an actual error (e.g. redirect, custom response)
return next(err);
}

if (!err.isMissing ||
err.code !== 401) { // An actual error (not just missing authentication)
if (err instanceof Error === false || // Not an actual error (e.g. redirect, custom response)
!err.isMissing || // Missing authentication (did not fail)
err.response.code !== 401) { // An actual error (not just missing authentication)

if (config.mode === 'try') {
request.session = session;
request.log(['auth', 'unauthenticated', 'try']);
request.log(['auth', 'unauthenticated', 'try'], err);
return next();
}

Expand All @@ -135,9 +147,8 @@ internals.Auth.prototype.authenticate = function (request, next) {

// Try next strategy

var response = err.toResponse();
if (response.headers['WWW-Authenticate']) {
authErrors.push(response.headers['WWW-Authenticate']);
if (err.response.headers['WWW-Authenticate']) {
authErrors.push(err.response.headers['WWW-Authenticate']);
}

return authenticate();
Expand All @@ -153,7 +164,7 @@ internals.Auth.prototype.authenticate = function (request, next) {
(!session.scope || session.scope.indexOf(config.scope) === -1)) {

request.log(['auth', 'error', 'scope'], { got: session.scope, need: config.scope });
return next(Err.forbidden('Insufficient scope (\'' + config.scope + '\' expected)'));
return next(Boom.forbidden('Insufficient scope (\'' + config.scope + '\' expected)'));
}

// Check TOS
Expand All @@ -163,39 +174,39 @@ internals.Auth.prototype.authenticate = function (request, next) {
(!session.ext || !session.ext.tos || session.ext.tos < tos)) {

request.log(['auth', 'error', 'tos'], { min: tos, received: session.ext && session.ext.tos });
return next(Err.forbidden('Insufficient TOS accepted'));
return next(Boom.forbidden('Insufficient TOS accepted'));
}

// Check entity

var entity = config.entity || 'any';

// Entity: any
// Entity: 'any'

if (entity === 'any') {
request.log(['auth']);
request.isAuthenticated = true;
return next();
}

// Entity: user
// Entity: 'user'

if (entity === 'user') {
if (!session.user) {
request.log(['auth', 'error'], 'User session required');
return next(Err.forbidden('Application session cannot be used on a user endpoint'));
return next(Boom.forbidden('Application session cannot be used on a user endpoint'));
}

request.log(['auth']);
request.isAuthenticated = true;
return next();
}

// Entity: app
// Entity: 'app'

if (session.user) {
request.log(['auth', 'error'], 'App session required');
return next(Err.forbidden('User session cannot be used on an application endpoint'));
return next(Boom.forbidden('User session cannot be used on an application endpoint'));
}

request.log(['auth']);
Expand Down
2 changes: 1 addition & 1 deletion lib/auth/oz.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

var Oz = require('oz');
var Utils = require('../utils');
var Err = require('../error');
var Boom = require('boom');


// Declare internals
Expand Down
6 changes: 3 additions & 3 deletions lib/batch.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Load modules

var Async = require('async');
var Err = require('./error');
var Boom = require('boom');


// Declare internals
Expand Down Expand Up @@ -42,7 +42,7 @@ exports.config = {
};

if (!request.payload.requests) {
return request.reply(Err.badRequest('Request missing requests array'));
return request.reply(Boom.badRequest('Request missing requests array'));
}

for (var i = 0, il = request.payload.requests.length; i < il; ++i) {
Expand All @@ -67,7 +67,7 @@ exports.config = {
internals.process(request, requests, resultsData, request.reply);
}
else {
request.reply(Err.badRequest(errorMessage));
request.reply(Boom.badRequest(errorMessage));
}
}
};
Expand Down
3 changes: 2 additions & 1 deletion lib/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ exports.server = {
state: {
cookies: {
parse: true, // Parse content of req.headers.cookie
failAction: 'error' // Action on bad cookie - 'error': return 400, 'log': log and continue, 'ignore': continue
failAction: 'error', // Action on bad cookie - 'error': return 400, 'log': log and continue, 'ignore': continue
clearInvalid: false // Automatically instruct the client to remove the invalid cookie
}
},

Expand Down
11 changes: 0 additions & 11 deletions lib/error.js

This file was deleted.

Loading