From e6df7c2c7a32a3071defb9a316b7684b608d67ea Mon Sep 17 00:00:00 2001
From: Lloyd Hilaiel <lloyd@hilaiel.com>
Date: Tue, 3 Jul 2012 17:54:39 +0100
Subject: [PATCH] don't issue certificates for emails that require
 reverification

---
 lib/db.js                    |  1 +
 lib/db/json.js               |  9 +++++++++
 lib/db/mysql.js              | 11 +++++++++++
 lib/wsapi/cert_key.js        | 29 ++++++++++++++++++-----------
 tests/forgotten-pass-test.js |  3 +--
 5 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/lib/db.js b/lib/db.js
index 27826a0fb..379ed4909 100644
--- a/lib/db.js
+++ b/lib/db.js
@@ -79,6 +79,7 @@ exports.onReady = function(f) {
   'emailKnown',
   'emailToUID',
   'emailType',
+  'emailIsVerified',
   'emailsBelongToSameAccount',
   'haveVerificationSecret',
   'isStaged',
diff --git a/lib/db/json.js b/lib/db/json.js
index 739cc2603..1d63f174c 100644
--- a/lib/db/json.js
+++ b/lib/db/json.js
@@ -104,6 +104,15 @@ exports.emailKnown = function(email, cb) {
   process.nextTick(function() { cb(null, m.length > 0) });
 };
 
+exports.emailIsVerified = function(email, cb) {
+  sync();
+  var m = jsel.match(".emails ." + ESC(email), db.users);
+  process.nextTick(function() {
+    if (!m.length) cb("no such email");
+    else cb(null, m[0].verified);
+  });
+};
+
 exports.emailType = function(email, cb) {
   sync();
   var m = jsel.match(".emails ." + ESC(email), db.users);
diff --git a/lib/db/mysql.js b/lib/db/mysql.js
index 18df02d44..263620ed5 100644
--- a/lib/db/mysql.js
+++ b/lib/db/mysql.js
@@ -226,6 +226,17 @@ exports.emailType = function(email, cb) {
   );
 }
 
+exports.emailIsVerified = function(email, cb) {
+  client.query(
+    "SELECT verified FROM email WHERE address = ?", [ email ],
+    function(err, rows) {
+      if (rows && rows.length > 0) cb(err, !!rows[0].verified);
+      else cb('no such email');
+    }
+  );
+};
+
+
 exports.isStaged = function(email, cb) {
   client.query(
     "SELECT COUNT(*) as N FROM staged WHERE email = ?", [ email ],
diff --git a/lib/wsapi/cert_key.js b/lib/wsapi/cert_key.js
index 0f0c81ef3..0c0cb3e11 100644
--- a/lib/wsapi/cert_key.js
+++ b/lib/wsapi/cert_key.js
@@ -21,18 +21,25 @@ exports.process = function(req, res) {
   db.userOwnsEmail(req.session.userid, req.body.email, function(err, owned) {
     if (err) return wsapi.databaseDown(res, err);
 
-    // not same account? big fat error
-    if (!owned) return httputils.badRequest(res, "that email does not belong to you");
+      // not same account? big fat error
+      if (!owned) return httputils.badRequest(res, "that email does not belong to you");
 
-    // forward to the keysigner!
-    var keysigner = urlparse(config.get('keysigner_url'));
-    keysigner.path = '/wsapi/cert_key';
-    forward(keysigner, req, res, function(err) {
-      if (err) {
-        logger.error("error forwarding request to keysigner: " + err);
-        httputils.serverError(res, "can't contact keysigner");
-        return;
-      }
+    // secondary addresses in the database may be "unverified".  this occurs when
+    // a user forgets their password.  We will not issue certs for unverified email
+    // addresses
+    db.emailIsVerified(req.body.email, function(err, verified) {
+      if (!verified) return httputils.forbidden(res, "that email requires (re)verification");
+
+      // forward to the keysigner!
+      var keysigner = urlparse(config.get('keysigner_url'));
+      keysigner.path = '/wsapi/cert_key';
+      forward(keysigner, req, res, function(err) {
+        if (err) {
+          logger.error("error forwarding request to keysigner: " + err);
+          httputils.serverError(res, "can't contact keysigner");
+          return;
+        }
+      });
     });
   });
 };
diff --git a/tests/forgotten-pass-test.js b/tests/forgotten-pass-test.js
index f9f97bb31..a4342dea9 100755
--- a/tests/forgotten-pass-test.js
+++ b/tests/forgotten-pass-test.js
@@ -338,8 +338,7 @@ suite.addBatch({
         }).call(this);
       },
       "is forbidden" : function(err, r) {
-        assert.strictEqual(r.code, 401);
-        assert.strictEqual(JSON.parse(r.body).success, false);
+        assert.strictEqual(r.code, 403);
       }
     }
   }
-- 
GitLab