refactor: authorize request
This commit is contained in:
parent
45e6241e34
commit
446ec49590
@ -302,19 +302,6 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
emailPlugin.retrieveDataByEmailAndPassphrase = function(email, key, passphrase, callback) {
|
|
||||||
emailPlugin.checkPassphrase(email, passphrase, function(err, matches) {
|
|
||||||
if (err) {
|
|
||||||
return callback(err);
|
|
||||||
}
|
|
||||||
if (matches) {
|
|
||||||
return emailPlugin.retrieveByEmailAndKey(email, key, callback);
|
|
||||||
} else {
|
|
||||||
return callback(emailPlugin.errors.INVALID_CODE);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
emailPlugin.deleteByEmailAndKey = function deleteByEmailAndKey(email, key, callback) {
|
emailPlugin.deleteByEmailAndKey = function deleteByEmailAndKey(email, key, callback) {
|
||||||
emailPlugin.db.del(valueKey(email, key), function(error) {
|
emailPlugin.db.del(valueKey(email, key), function(error) {
|
||||||
if (error) {
|
if (error) {
|
||||||
@ -339,6 +326,7 @@
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
async.parallel([
|
async.parallel([
|
||||||
|
|
||||||
function(callback) {
|
function(callback) {
|
||||||
emailPlugin.db.del(emailToPassphrase(email), dismissNotFound(callback));
|
emailPlugin.db.del(emailToPassphrase(email), dismissNotFound(callback));
|
||||||
},
|
},
|
||||||
@ -500,87 +488,111 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function authorizedRequest(withKey, callback) {
|
emailPlugin.authorizeRequest = function(request, withKey, callback) {
|
||||||
return function(request, response) {
|
var credentialsResult = emailPlugin.getCredentialsFromRequest(request);
|
||||||
var credentialsResult = emailPlugin.getCredentialsFromRequest(request);
|
if (_.contains(emailPlugin.errors, credentialsResult)) {
|
||||||
if (_.contains(emailPlugin.errors, credentialsResult)) {
|
return callback(credentialsResult);
|
||||||
return emailPlugin.returnError(credentialsResult, response);
|
}
|
||||||
}
|
|
||||||
var email = credentialsResult.email;
|
var email = credentialsResult.email;
|
||||||
var passphrase = credentialsResult.passphrase;
|
var passphrase = credentialsResult.passphrase;
|
||||||
var key;
|
var key;
|
||||||
if (withKey) {
|
if (withKey) {
|
||||||
key = request.param('key');
|
key = request.param('key');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!passphrase || !email || (withKey && !key)) {
|
||||||
|
return callback(emailPlugin.errors.MISSING_PARAMETER);
|
||||||
|
}
|
||||||
|
|
||||||
|
emailPlugin.checkPassphrase(email, passphrase, function(err, matches) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!passphrase || !email || (withKey && !key)) {
|
if (!matches) {
|
||||||
return emailPlugin.returnError(emailPlugin.errors.MISSING_PARAMETER, response);
|
return callback(emailPlugin.errors.INVALID_CODE);
|
||||||
}
|
}
|
||||||
return callback(email, passphrase, key, request, response);
|
|
||||||
};
|
return callback(null, email, key);
|
||||||
}
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
emailPlugin.authorizeRequestWithoutKey = function(request, callback) {
|
||||||
|
emailPlugin.authorizeRequest(request, false, callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
emailPlugin.authorizeRequestWithKey = function(request, callback) {
|
||||||
|
emailPlugin.authorizeRequest(request, true, callback);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a record from the database
|
* Retrieve a record from the database
|
||||||
*/
|
*/
|
||||||
emailPlugin.retrieve = authorizedRequest(true,
|
emailPlugin.retrieve = function(request, response) {
|
||||||
function(email, passphrase, key, request, response) {
|
emailPlugin.authorizeRequestWithKey(request, function(err, email, key) {
|
||||||
emailPlugin.retrieveDataByEmailAndPassphrase(email, key, passphrase, function(err, value) {
|
if (err) {
|
||||||
|
return emailPlugin.returnError(err, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
emailPlugin.retrieveByEmailAndKey(email, key, function(err, value) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return emailPlugin.returnError(err, response);
|
return emailPlugin.returnError(err, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
emailPlugin.addValidationHeader(response, email, function(err) {
|
emailPlugin.addValidationHeader(response, email, function(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return emailPlugin.returnError(err, response);
|
return emailPlugin.returnError(err, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
response.send(value).end();
|
response.send(value).end();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
);
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a record from the database
|
* Remove a record from the database
|
||||||
*/
|
*/
|
||||||
emailPlugin.erase = authorizedRequest(true,
|
emailPlugin.erase = function(request, response) {
|
||||||
function(email, passphrase, key, request, response) {
|
emailPlugin.authorizeRequestWithKey(request, function(err, email, key) {
|
||||||
emailPlugin.checkPassphrase(email, passphrase, function(err, matches) {
|
if (err) {
|
||||||
if (err || !matches) {
|
return emailPlugin.returnError(err, response);
|
||||||
return emailPlugin.returnError(emailPlugin.errors.INVALID_CODE, response);
|
}
|
||||||
}
|
emailPlugin.deleteByEmailAndKey(email, key, function(err, value) {
|
||||||
emailPlugin.deleteByEmailAndKey(email, key, function(err, value) {
|
if (err) {
|
||||||
if (err) {
|
return emailPlugin.returnError(err, response);
|
||||||
return emailPlugin.returnError(err, response);
|
} else {
|
||||||
} else {
|
return response.json({
|
||||||
return response.json({success: true}).end();
|
success: true
|
||||||
};
|
}).end();
|
||||||
});
|
};
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
);
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a whole profile from the database
|
* Remove a whole profile from the database
|
||||||
*
|
*
|
||||||
* @TODO: This looks very similar to the method above
|
* @TODO: This looks very similar to the method above
|
||||||
*/
|
*/
|
||||||
emailPlugin.eraseProfile = authorizedRequest(false,
|
emailPlugin.eraseProfile = function(request, response) {
|
||||||
function(email, passphrase, unused_key, request, response) {
|
emailPlugin.authorizeRequestWithoutKey(request, function(err, email) {
|
||||||
|
if (err) {
|
||||||
emailPlugin.checkPassphrase(email, passphrase, function(err, matches) {
|
return emailPlugin.returnError(err, response);
|
||||||
if (err || !matches) {
|
}
|
||||||
return emailPlugin.returnError(emailPlugin.errors.INVALID_CODE, response);
|
|
||||||
}
|
emailPlugin.deleteWholeProfile(email, function(err, value) {
|
||||||
emailPlugin.deleteWholeProfile(email, function(err, value) {
|
if (err) {
|
||||||
if (err) {
|
return emailPlugin.returnError(err, response);
|
||||||
return emailPlugin.returnError(err, response);
|
} else {
|
||||||
} else {
|
return response.json({
|
||||||
return response.json({success: true}).end();
|
success: true
|
||||||
};
|
}).end();
|
||||||
});
|
};
|
||||||
});
|
});
|
||||||
}
|
});
|
||||||
);
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -642,32 +654,28 @@
|
|||||||
* @param {Express.Response} response
|
* @param {Express.Response} response
|
||||||
*/
|
*/
|
||||||
emailPlugin.changePassphrase = function(request, response) {
|
emailPlugin.changePassphrase = function(request, response) {
|
||||||
var credentialsResult = emailPlugin.getCredentialsFromRequest(request);
|
|
||||||
if (_.contains(emailPlugin.errors, credentialsResult)) {
|
|
||||||
return emailPlugin.returnError(credentialsResult);
|
|
||||||
}
|
|
||||||
var email = credentialsResult.email;
|
|
||||||
var passphrase = credentialsResult.passphrase;
|
|
||||||
|
|
||||||
var queryData = '';
|
emailPlugin.authorizeRequestWithoutKey(request, function(err, email) {
|
||||||
request.on('data', function(data) {
|
|
||||||
queryData += data;
|
if (err) {
|
||||||
if (queryData.length > MAX_ALLOWED_STORAGE) {
|
return emailPlugin.returnError(err, response);
|
||||||
queryData = '';
|
|
||||||
response.writeHead(413, {
|
|
||||||
'Content-Type': 'text/plain'
|
|
||||||
}).end();
|
|
||||||
request.connection.destroy();
|
|
||||||
}
|
}
|
||||||
}).on('end', function() {
|
|
||||||
var params = querystring.parse(queryData);
|
var queryData = '';
|
||||||
var newPassphrase = params.newPassphrase;
|
request.on('data', function(data) {
|
||||||
if (!email || !passphrase || !newPassphrase) {
|
queryData += data;
|
||||||
return emailPlugin.returnError(emailPlugin.errors.INVALID_REQUEST, response);
|
if (queryData.length > MAX_ALLOWED_STORAGE) {
|
||||||
}
|
queryData = '';
|
||||||
emailPlugin.checkPassphrase(email, passphrase, function(error) {
|
response.writeHead(413, {
|
||||||
if (error) {
|
'Content-Type': 'text/plain'
|
||||||
return emailPlugin.returnError(error, response);
|
}).end();
|
||||||
|
request.connection.destroy();
|
||||||
|
}
|
||||||
|
}).on('end', function() {
|
||||||
|
var params = querystring.parse(queryData);
|
||||||
|
var newPassphrase = params.newPassphrase;
|
||||||
|
if (!newPassphrase) {
|
||||||
|
return emailPlugin.returnError(emailPlugin.errors.INVALID_REQUEST, response);
|
||||||
}
|
}
|
||||||
emailPlugin.savePassphrase(email, newPassphrase, function(error) {
|
emailPlugin.savePassphrase(email, newPassphrase, function(error) {
|
||||||
if (error) {
|
if (error) {
|
||||||
@ -682,7 +690,23 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
// Backwards compatibility
|
// Backwards compatibility
|
||||||
|
//
|
||||||
|
|
||||||
|
emailPlugin.oldRetrieveDataByEmailAndPassphrase = function(email, key, passphrase, callback) {
|
||||||
|
emailPlugin.checkPassphrase(email, passphrase, function(err, matches) {
|
||||||
|
if (err) {
|
||||||
|
return callback(err);
|
||||||
|
}
|
||||||
|
if (matches) {
|
||||||
|
return emailPlugin.retrieveByEmailAndKey(email, key, callback);
|
||||||
|
} else {
|
||||||
|
return callback(emailPlugin.errors.INVALID_CODE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
emailPlugin.oldRetrieve = function(request, response) {
|
emailPlugin.oldRetrieve = function(request, response) {
|
||||||
var email = request.param('email');
|
var email = request.param('email');
|
||||||
@ -692,7 +716,7 @@
|
|||||||
return emailPlugin.returnError(emailPlugin.errors.MISSING_PARAMETER, response);
|
return emailPlugin.returnError(emailPlugin.errors.MISSING_PARAMETER, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
emailPlugin.retrieveDataByEmailAndPassphrase(email, key, secret, function(err, value) {
|
emailPlugin.oldRetrieveDataByEmailAndPassphrase(email, key, secret, function(err, value) {
|
||||||
if (err) {
|
if (err) {
|
||||||
return emailPlugin.returnError(err, response);
|
return emailPlugin.returnError(err, response);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -433,39 +433,115 @@ describe('emailstore test', function() {
|
|||||||
describe('when retrieving data', function() {
|
describe('when retrieving data', function() {
|
||||||
|
|
||||||
it('should validate the secret and return the data', function() {
|
it('should validate the secret and return the data', function() {
|
||||||
request.header = sinon.stub();
|
|
||||||
request.header.onFirstCall().returns(new Buffer('email:pass', 'utf8').toString('base64'));
|
|
||||||
request.param.onFirstCall().returns('key');
|
request.param.onFirstCall().returns('key');
|
||||||
|
|
||||||
plugin.retrieveDataByEmailAndPassphrase = sinon.stub();
|
plugin.authorizeRequestWithKey = sinon.stub().callsArgWith(1,null, 'email','key');
|
||||||
plugin.retrieveDataByEmailAndPassphrase.onFirstCall().callsArgWith(3, null, 'encrypted');
|
plugin.retrieveByEmailAndKey = sinon.stub().yields(null, 'encrypted');
|
||||||
|
|
||||||
response.send.onFirstCall().returnsThis();
|
response.send.onFirstCall().returnsThis();
|
||||||
plugin.addValidationHeader = sinon.stub().callsArg(2);
|
plugin.addValidationHeader = sinon.stub().callsArg(2);
|
||||||
|
|
||||||
plugin.retrieve(request, response);
|
plugin.retrieve(request, response);
|
||||||
|
|
||||||
request.header.calledOnce.should.equal(true);
|
|
||||||
response.send.calledOnce.should.equal(true);
|
response.send.calledOnce.should.equal(true);
|
||||||
|
|
||||||
assert(request.header.firstCall.args[0] === 'authorization');
|
assert(plugin.retrieveByEmailAndKey.firstCall.args[0] === 'email');
|
||||||
assert(plugin.retrieveDataByEmailAndPassphrase.firstCall.args[0] === 'email');
|
assert(plugin.retrieveByEmailAndKey.firstCall.args[1] === 'key');
|
||||||
assert(plugin.retrieveDataByEmailAndPassphrase.firstCall.args[1] === 'key');
|
|
||||||
assert(plugin.retrieveDataByEmailAndPassphrase.firstCall.args[2] === 'pass');
|
|
||||||
assert(response.send.firstCall.args[0] === 'encrypted');
|
assert(response.send.firstCall.args[0] === 'encrypted');
|
||||||
assert(response.end.calledOnce);
|
assert(response.end.calledOnce);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('changing the user password', function() {
|
|
||||||
|
|
||||||
var originalCredentials = plugin.getCredentialsFromRequest;
|
|
||||||
|
|
||||||
|
describe('authorizing requests', function() {
|
||||||
|
var originalCredentials;
|
||||||
beforeEach(function() {
|
beforeEach(function() {
|
||||||
|
originalCredentials = plugin.getCredentialsFromRequest;
|
||||||
|
|
||||||
plugin.getCredentialsFromRequest = sinon.mock();
|
plugin.getCredentialsFromRequest = sinon.mock();
|
||||||
plugin.getCredentialsFromRequest.onFirstCall().returns({
|
plugin.getCredentialsFromRequest.onFirstCall().returns({
|
||||||
email: 'email',
|
email: 'email',
|
||||||
passphrase: 'passphrase'
|
passphrase: 'pass'
|
||||||
});
|
});
|
||||||
|
request.param.onFirstCall().returns('key');
|
||||||
|
|
||||||
|
request.on = sinon.stub();
|
||||||
|
request.on.onFirstCall().callsArgWith(1, 'newPassphrase=newPassphrase');
|
||||||
|
request.on.onFirstCall().returns(request);
|
||||||
|
request.on.onSecondCall().callsArg(1);
|
||||||
|
plugin.checkPassphrase = sinon.stub().callsArgWith(2,null, true);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should authorize a request', function(done){
|
||||||
|
plugin.authorizeRequest(request, false, function(err, email, key) {
|
||||||
|
expect(err).to.be.null;
|
||||||
|
expect(key).to.be.undefined;
|
||||||
|
email.should.be.equal('email');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should authorize a request with key', function(done){
|
||||||
|
plugin.getCredentialsFromRequest.onFirstCall().returns({
|
||||||
|
email: 'email',
|
||||||
|
passphrase: 'pass',
|
||||||
|
});
|
||||||
|
plugin.authorizeRequest(request, true, function(err, email, key) {
|
||||||
|
expect(err).to.be.null;
|
||||||
|
email.should.be.equal('email');
|
||||||
|
key.should.be.equal('key');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not authorize a request when param are missing', function(done){
|
||||||
|
plugin.getCredentialsFromRequest.onFirstCall().returns({
|
||||||
|
email: 'email',
|
||||||
|
});
|
||||||
|
|
||||||
|
plugin.authorizeRequest(request, false, function(err, email, key) {
|
||||||
|
expect(err).not.to.be.null;
|
||||||
|
expect(key).to.be.undefined;
|
||||||
|
expect(email).to.be.undefined;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should not authorize a request when param are missing (case2)', function(done){
|
||||||
|
plugin.getCredentialsFromRequest.onFirstCall().returns({
|
||||||
|
passphrase: 'pass'
|
||||||
|
});
|
||||||
|
|
||||||
|
plugin.authorizeRequest(request, false, function(err, email, key) {
|
||||||
|
expect(err).not.to.be.null;
|
||||||
|
expect(key).to.be.undefined;
|
||||||
|
expect(email).to.be.undefined;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it('should not authorize a request when param are missing (case3)', function(done){
|
||||||
|
request.param.onFirstCall().returns(undefined);
|
||||||
|
plugin.getCredentialsFromRequest.onFirstCall().returns({
|
||||||
|
email: 'email',
|
||||||
|
passphrase: 'pass'
|
||||||
|
});
|
||||||
|
plugin.authorizeRequest(request, true, function(err, email, key) {
|
||||||
|
expect(err).not.to.be.null;
|
||||||
|
expect(key).to.be.undefined;
|
||||||
|
expect(email).to.be.undefined;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
after(function() {
|
||||||
|
plugin.getCredentialsFromRequest = originalCredentials;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('changing the user password', function() {
|
||||||
|
|
||||||
|
|
||||||
|
beforeEach(function() {
|
||||||
request.on = sinon.stub();
|
request.on = sinon.stub();
|
||||||
request.on.onFirstCall().callsArgWith(1, 'newPassphrase=newPassphrase');
|
request.on.onFirstCall().callsArgWith(1, 'newPassphrase=newPassphrase');
|
||||||
request.on.onFirstCall().returns(request);
|
request.on.onFirstCall().returns(request);
|
||||||
@ -478,7 +554,7 @@ describe('emailstore test', function() {
|
|||||||
it('should validate the previous passphrase', function() {
|
it('should validate the previous passphrase', function() {
|
||||||
response.status.onFirstCall().returnsThis();
|
response.status.onFirstCall().returnsThis();
|
||||||
response.json.onFirstCall().returnsThis();
|
response.json.onFirstCall().returnsThis();
|
||||||
plugin.checkPassphrase.onFirstCall().callsArgWith(2, 'error');
|
plugin.authorizeRequestWithoutKey = sinon.stub().callsArgWith(1,'error');
|
||||||
|
|
||||||
plugin.changePassphrase(request, response);
|
plugin.changePassphrase(request, response);
|
||||||
|
|
||||||
@ -489,6 +565,7 @@ describe('emailstore test', function() {
|
|||||||
|
|
||||||
it('should change the passphrase', function() {
|
it('should change the passphrase', function() {
|
||||||
response.json.onFirstCall().returnsThis();
|
response.json.onFirstCall().returnsThis();
|
||||||
|
plugin.authorizeRequestWithoutKey = sinon.stub().callsArgWith(1,null, 'email');
|
||||||
plugin.checkPassphrase.onFirstCall().callsArgWith(2, null);
|
plugin.checkPassphrase.onFirstCall().callsArgWith(2, null);
|
||||||
plugin.savePassphrase.onFirstCall().callsArgWith(2, null);
|
plugin.savePassphrase.onFirstCall().callsArgWith(2, null);
|
||||||
|
|
||||||
@ -496,9 +573,5 @@ describe('emailstore test', function() {
|
|||||||
assert(response.json.calledOnce);
|
assert(response.json.calledOnce);
|
||||||
assert(response.end.calledOnce);
|
assert(response.end.calledOnce);
|
||||||
});
|
});
|
||||||
|
|
||||||
after(function() {
|
|
||||||
plugin.getCredentialsFromRequest = originalCredentials;
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user