add tests that token is destroyed
adds the `buf` module, which helps converting between buffers and hex strings. there were errors before, so this helped fix the tests.
This commit is contained in:
Родитель
52584b389e
Коммит
02977b3345
|
@ -2,6 +2,8 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const unbuf = require('buf').unbuf.hex;
|
||||
|
||||
const P = require('../promise');
|
||||
|
||||
const config = require('../config');
|
||||
|
@ -9,21 +11,6 @@ const logger = require('../logging').getLogger('fxa.db');
|
|||
const mysql = require('./mysql');
|
||||
const memory = require('./memory');
|
||||
|
||||
function buffer(obj) {
|
||||
if (Buffer.isBuffer(obj)) {
|
||||
return obj;
|
||||
} else if (typeof obj === 'string') {
|
||||
return Buffer(obj, 'hex');
|
||||
}
|
||||
}
|
||||
|
||||
function unbuf(buf) {
|
||||
if (Buffer.isBuffer(buf)) {
|
||||
return buf.toString('hex');
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
function preClients() {
|
||||
var clients = config.get('clients');
|
||||
if (clients && clients.length) {
|
||||
|
@ -53,8 +40,6 @@ function withDriver() {
|
|||
}
|
||||
return p.then(function(store) {
|
||||
logger.debug('connected to "%s" store', config.get('db.driver'));
|
||||
store._unbuf = unbuf;
|
||||
store._buf = buffer;
|
||||
driver = store;
|
||||
}).then(preClients).then(function() {
|
||||
return driver;
|
||||
|
@ -96,3 +81,4 @@ exports.disconnect = function disconnect() {
|
|||
exports._initialClients = function() {
|
||||
return preClients();
|
||||
};
|
||||
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const buf = require('buf').hex;
|
||||
const unbuf = require('buf').unbuf.hex;
|
||||
|
||||
const encrypt = require('../encrypt');
|
||||
const logger = require('../logging').getLogger('fxa.db.memory');
|
||||
const P = require('../promise');
|
||||
|
@ -70,11 +73,11 @@ MemoryStore.prototype = {
|
|||
registerClient: function registerClient(client) {
|
||||
if (client.id) {
|
||||
logger.debug('registerClient: client already has ID?', client.id);
|
||||
client.id = this._buf(client.id);
|
||||
client.id = buf(client.id);
|
||||
} else {
|
||||
client.id = unique.id();
|
||||
}
|
||||
var hex = this._unbuf(client.id);
|
||||
var hex = unbuf(client.id);
|
||||
logger.debug('registerClient', client.name, hex);
|
||||
client.createdAt = new Date();
|
||||
this.clients[hex] = client;
|
||||
|
@ -82,7 +85,7 @@ MemoryStore.prototype = {
|
|||
return P.resolve(client);
|
||||
},
|
||||
getClient: function getClient(id) {
|
||||
return P.resolve(this.clients[this._unbuf(id)]);
|
||||
return P.resolve(this.clients[unbuf(id)]);
|
||||
},
|
||||
generateCode: function generateCode(clientId, userId, email, scope) {
|
||||
var code = {};
|
||||
|
@ -93,14 +96,14 @@ MemoryStore.prototype = {
|
|||
code.createdAt = new Date();
|
||||
var _code = unique.code();
|
||||
code.code = encrypt.hash(_code);
|
||||
this.codes[this._unbuf(code.code)] = code;
|
||||
this.codes[unbuf(code.code)] = code;
|
||||
return P.resolve(_code);
|
||||
},
|
||||
getCode: function getCode(code) {
|
||||
return P.resolve(this.codes[this._unbuf(encrypt.hash(code))]);
|
||||
return P.resolve(this.codes[unbuf(encrypt.hash(code))]);
|
||||
},
|
||||
removeCode: function removeCode(id) {
|
||||
delete this.codes[this._unbuf(id)];
|
||||
delete this.codes[unbuf(id)];
|
||||
return P.resolve();
|
||||
},
|
||||
generateToken: function generateToken(code) {
|
||||
|
@ -116,16 +119,16 @@ MemoryStore.prototype = {
|
|||
var _token = unique.token();
|
||||
var ret = clone(token);
|
||||
token.token = encrypt.hash(_token);
|
||||
store.tokens[store._unbuf(token.token)] = token;
|
||||
store.tokens[unbuf(token.token)] = token;
|
||||
ret.token = _token;
|
||||
return ret;
|
||||
});
|
||||
},
|
||||
getToken: function getToken(token) {
|
||||
return P.resolve(this.tokens[this._unbuf(encrypt.hash(token))]);
|
||||
return P.resolve(this.tokens[unbuf(token)]);
|
||||
},
|
||||
removeToken: function removeToken(id) {
|
||||
delete this.tokens[this._unbuf(id)];
|
||||
delete this.tokens[unbuf(id)];
|
||||
return P.resolve();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
const buf = require('buf').hex;
|
||||
const mysql = require('mysql');
|
||||
|
||||
const encrypt = require('../encrypt');
|
||||
|
@ -99,7 +100,7 @@ MysqlStore.prototype = {
|
|||
var id;
|
||||
if (client.id) {
|
||||
logger.debug('registerClient: client already has ID?', client.id);
|
||||
id = this._buf(client.id);
|
||||
id = buf(client.id);
|
||||
} else {
|
||||
id = unique.id();
|
||||
}
|
||||
|
@ -127,7 +128,7 @@ MysqlStore.prototype = {
|
|||
},
|
||||
getClient: function getClient(_id) {
|
||||
var d = P.defer();
|
||||
var id = this._buf(_id);
|
||||
var id = buf(_id);
|
||||
this._connection.query(QUERY_CLIENT_GET, [id], function(err, rows) {
|
||||
if (err) {
|
||||
return d.reject(err);
|
||||
|
@ -205,7 +206,7 @@ MysqlStore.prototype = {
|
|||
|
||||
getToken: function getToken(token) {
|
||||
var d = P.defer();
|
||||
this._connection.query(QUERY_TOKEN_FIND, [encrypt.hash(token)],
|
||||
this._connection.query(QUERY_TOKEN_FIND, [buf(token)],
|
||||
function(err, rows) {
|
||||
if (err) {
|
||||
logger.error('getToken:', err);
|
||||
|
@ -223,7 +224,7 @@ MysqlStore.prototype = {
|
|||
|
||||
removeToken: function removeToken(id) {
|
||||
var d = P.defer();
|
||||
this._connection.query(QUERY_TOKEN_DELETE, [id], function(err) {
|
||||
this._connection.query(QUERY_TOKEN_DELETE, [buf(id)], function(err) {
|
||||
if (err) {
|
||||
return d.reject(err);
|
||||
}
|
||||
|
|
|
@ -4,10 +4,12 @@
|
|||
|
||||
const crypto = require('crypto');
|
||||
|
||||
const buf = require('buf').hex;
|
||||
|
||||
const config = require('./config');
|
||||
|
||||
exports.hash = function hash(value) {
|
||||
var sha = crypto.createHash(config.get('encrypt.hashAlg'));
|
||||
sha.update(value);
|
||||
sha.update(buf(value));
|
||||
return sha.digest();
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
const util = require('util');
|
||||
|
||||
const unbuf = require('buf').unbuf.hex;
|
||||
const intel = require('intel');
|
||||
|
||||
function JsonFormatter(options) {
|
||||
|
@ -33,7 +34,7 @@ JsonFormatter.prototype.format = function jsonFormat(record) {
|
|||
}
|
||||
} else {
|
||||
for (var k in record.args[0]) {
|
||||
rec[k] = record.args[0][k];
|
||||
rec[k] = unbuf(record.args[0][k]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,16 +5,14 @@
|
|||
|
||||
const Joi = require('joi');
|
||||
|
||||
const unbuf = require('buf').unbuf.hex;
|
||||
|
||||
const AppError = require('../error');
|
||||
const config = require('../config');
|
||||
const db = require('../db');
|
||||
const encrypt = require('../encrypt');
|
||||
const HEX_STRING = /^[0-9a-f]+$/;
|
||||
|
||||
function eq(orig, unhashed) {
|
||||
return orig.toString('hex') === encrypt.hash(unhashed).toString('hex');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
validate: {
|
||||
payload: {
|
||||
|
@ -29,18 +27,18 @@ module.exports = {
|
|||
}
|
||||
},
|
||||
handler: function destroyToken(req, reply) {
|
||||
var token = req.payload.token;
|
||||
var secret = req.payload.client_secret;
|
||||
var token = encrypt.hash(req.payload.token);
|
||||
var secret = encrypt.hash(req.payload.client_secret);
|
||||
|
||||
db.getToken(Buffer(token, 'hex'))
|
||||
db.getToken(token)
|
||||
.then(function(tok) {
|
||||
if (!tok) {
|
||||
throw AppError.invalidToken();
|
||||
}
|
||||
return db.getClient(tok.clientId);
|
||||
}).then(function(client) {
|
||||
if (client && !eq(client.secret, secret)) {
|
||||
throw AppError.incorrectSecret(client && client.id.toString('hex'));
|
||||
if (client && (unbuf(client.secret) !== unbuf(secret))) {
|
||||
throw AppError.incorrectSecret(client && unbuf(client.id));
|
||||
}
|
||||
// if client doesn't exist, but token does, then just clean up
|
||||
return db.removeToken(token);
|
||||
|
|
|
@ -7,6 +7,7 @@ const Joi = require('joi');
|
|||
const AppError = require('../error');
|
||||
const config = require('../config');
|
||||
const db = require('../db');
|
||||
const encrypt = require('../encrypt');
|
||||
|
||||
const HEX_STRING = /^[0-9a-f]+$/;
|
||||
|
||||
|
@ -27,7 +28,7 @@ module.exports = {
|
|||
}
|
||||
},
|
||||
handler: function verify(req, reply) {
|
||||
db.getToken(Buffer(req.payload.token, 'hex'))
|
||||
db.getToken(encrypt.hash(req.payload.token))
|
||||
.then(function(token) {
|
||||
if (!token) {
|
||||
throw AppError.invalidToken();
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
"from": "bluebird@1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-1.2.4.tgz"
|
||||
},
|
||||
"buf": {
|
||||
"version": "0.1.0",
|
||||
"from": "buf@0.1.0"
|
||||
},
|
||||
"convict": {
|
||||
"version": "0.4.2",
|
||||
"from": "convict@0.4.2",
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"bluebird": "1.2.4",
|
||||
"buf": "0.1.0",
|
||||
"convict": "0.4.2",
|
||||
"hapi": "5.1.0",
|
||||
"intel": "1.0.0-b2",
|
||||
|
|
15
test/api.js
15
test/api.js
|
@ -11,6 +11,7 @@ const nock = require('nock');
|
|||
|
||||
const config = require('../lib/config');
|
||||
const db = require('../lib/db');
|
||||
const encrypt = require('../lib/encrypt');
|
||||
const P = require('../lib/promise');
|
||||
const Server = require('./lib/server');
|
||||
const unique = require('../lib/unique');
|
||||
|
@ -586,30 +587,40 @@ describe('/v1', function() {
|
|||
|
||||
describe('/destroy', function() {
|
||||
it('should destroy tokens', function() {
|
||||
var token;
|
||||
return newToken().then(function(res) {
|
||||
token = res.result.access_token;
|
||||
return Server.api.post({
|
||||
url: '/destroy',
|
||||
payload: {
|
||||
token: res.result.access_token,
|
||||
token: token,
|
||||
client_secret: secret
|
||||
}
|
||||
});
|
||||
}).then(function(res) {
|
||||
assert.equal(res.statusCode, 200);
|
||||
return db.getToken(encrypt.hash(token)).then(function(tok) {
|
||||
assert.equal(tok, undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('should not allow unauthorized destruction', function() {
|
||||
var token;
|
||||
return newToken().then(function(res) {
|
||||
token = res.result.access_token;
|
||||
return Server.api.post({
|
||||
url: '/destroy',
|
||||
payload: {
|
||||
token: res.result.access_token,
|
||||
token: token,
|
||||
client_secret: badSecret
|
||||
}
|
||||
});
|
||||
}).then(function(res) {
|
||||
assert.equal(res.statusCode, 400);
|
||||
return db.getToken(encrypt.hash(token)).then(function(tok) {
|
||||
assert(tok);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче