Permalink
Browse files

consolidate db.checkAuth and db.checkAuthHash - move all bcrypt knowl…

…edge out of the persistence layer
  • Loading branch information...
1 parent 3d4ecd1 commit 6ec2fa4947b502545edef455bc4d216a683ed9d3 @lloyd lloyd committed Jul 20, 2011
Showing with 29 additions and 35 deletions.
  1. +10 −17 browserid/lib/db.js
  2. +17 −15 browserid/lib/wsapi.js
  3. +2 −3 browserid/tests/db-test.js
View
27 browserid/lib/db.js
@@ -1,6 +1,5 @@
const sqlite = require('sqlite'),
- path = require('path'),
- bcrypt = require('bcrypt');
+ path = require('path');
var VAR_DIR = path.join(path.dirname(__dirname), "var");
@@ -13,7 +12,7 @@ var ready = false;
var waiting = [];
// async break allow database path to be configured by calling code
-// a touch tricky cause client must set dbPath before releasing
+// a touch tricky cause client must set dbPath before releasing
// control of the runloop
setTimeout(function() {
db.open(exports.dbPath, function (error) {
@@ -200,7 +199,7 @@ exports.stageEmail = function(existing_email, new_email, pubkey) {
return secret;
};
-/* invoked when a user clicks on a verification URL in their email */
+/* invoked when a user clicks on a verification URL in their email */
exports.gotVerificationSecret = function(secret, cb) {
if (!g_staged.hasOwnProperty(secret)) return cb("unknown secret");
@@ -257,23 +256,17 @@ exports.gotVerificationSecret = function(secret, cb) {
}
};
-exports.checkAuth = function(email, pass, cb) {
+// check authentication credentials for a given email address. This will invoke the
+// users callback with the authentication (password/hash/whatever - the database layer
+// doesn't care). callback will be passed undefined if email cannot be found
+exports.checkAuth = function(email, cb) {
db.execute("SELECT users.password FROM emails, users WHERE users.id = emails.user AND emails.address = ?",
[ email ],
function (error, rows) {
- cb(rows.length === 1 && bcrypt.compare_sync(pass, rows[0].password));
+ cb(rows.length !== 1 ? undefined : rows[0].password);
});
};
-exports.checkAuthHash = function(email, hash, cb) {
- db.execute("SELECT users.password FROM emails, users WHERE users.id = emails.user AND emails.address = ? AND users.password = ?",
- [ email, hash ],
- function (error, rows) {
- cb(rows.length === 1);
- });
-};
-
-
/* a high level operation that attempts to sync a client's view with that of the
* server. email is the identity of the authenticated channel with the user,
* identities is a map of email -> pubkey.
@@ -291,7 +284,7 @@ exports.getSyncResponse = function(email, identities, cb) {
key_refresh: [ ]
};
- // get the user id associated with this account
+ // get the user id associated with this account
emailToUserID(email, function(userID) {
if (userID === undefined) {
cb("no such email: " + email);
@@ -320,7 +313,7 @@ exports.getSyncResponse = function(email, identities, cb) {
// #3
// XXX todo
- cb(undefined, respBody);
+ cb(undefined, respBody);
}
});
});
View
32 browserid/lib/wsapi.js
@@ -87,10 +87,10 @@ function setup(app) {
};
httputils.jsonResponse(resp, true);
-
+
// let's now kick out a verification email!
email.sendVerificationEmail(stageParams.email, stageParams.site, secret);
-
+
} catch(e) {
// we should differentiate tween' 400 and 500 here.
httputils.badRequest(resp, e.toString());
@@ -105,14 +105,14 @@ function setup(app) {
httputils.badRequest(resp, "api abuse: registration_status called without a pending email addition/verification");
return;
}
-
+
// Is the current session trying to add an email, or register a new one?
if (req.session.pendingAddition) {
// this is a pending email addition, it requires authentication
if (!isAuthed(req, resp)) {
return httputils.badRequest(resp, "requires authentication");
}
-
+
// check if the currently authenticated user has the email stored under pendingAddition
// in their acct.
db.emailsBelongToSameAccount(req.session.pendingAddition,
@@ -128,10 +128,10 @@ function setup(app) {
} else {
// this is a pending registration, let's check if the creds stored on the
// session are good yet.
-
+
var v = req.session.pendingVerification;
- db.checkAuthHash(v.email, v.hash, function(authed) {
- if (authed) {
+ db.checkAuth(v.email, function(hash) {
+ if (hash === v.hash) {
delete req.session.pendingVerification;
req.session.authenticatedUser = v.email;
httputils.jsonResponse(resp, "complete");
@@ -141,28 +141,30 @@ function setup(app) {
});
}
});
-
-
+
+
app.get('/wsapi/authenticate_user', checkParams(["email", "pass"]), function(req, resp) {
- db.checkAuth(req.query.email, req.query.pass, function(rv) {
- if (rv) {
+ db.checkAuth(req.query.email, function(hash) {
+ var success = bcrypt.compare_sync(req.query.pass, hash);
+
+ if (success) {
if (!req.session) req.session = {};
req.session.authenticatedUser = req.query.email;
}
- httputils.jsonResponse(resp, rv);
+ httputils.jsonResponse(resp, success);
});
});
-
+
// FIXME: need CSRF protection
app.get('/wsapi/add_email', checkAuthed, checkParams(["email", "pubkey", "site"]), function (req, resp) {
try {
// upon success, stage_user returns a secret (that'll get baked into a url
// and given to the user), on failure it throws
var secret = db.stageEmail(req.session.authenticatedUser, req.query.email, req.query.pubkey);
-
+
// store the email being added in session data
req.session.pendingAddition = req.query.email;
-
+
httputils.jsonResponse(resp, true);
// let's now kick out a verification email!
View
5 browserid/tests/db-test.js
@@ -142,10 +142,9 @@ suite.addBatch({
assert.strictEqual(r.length, 3);
}
}
-});
-
+});
-// XXX: remaining APIs to test
+// XXX: remaining APIs to test
// exports.addEmailToAccount
// exports.cancelAccount
// exports.checkAuth

0 comments on commit 6ec2fa4

Please sign in to comment.