Skip to content
This repository has been archived by the owner on Jan 7, 2018. It is now read-only.

Commit

Permalink
Merge pull request #21 from NREL/common-error-data-variables
Browse files Browse the repository at this point in the history
Setup error data for easier overriding of URL variables.
  • Loading branch information
GUI committed Oct 9, 2015
2 parents 6c1704b + f5926a8 commit f998b37
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 19 deletions.
19 changes: 11 additions & 8 deletions config/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -85,39 +85,42 @@ apiSettings:
</body>
</html>
error_data:
common:
signup_url: "{{base_url}}"
contact_url: "{{base_url}}/contact/"
not_found:
status_code: 404
code: NOT_FOUND
message: The requested URL was not found on this server.
api_key_missing:
status_code: 403
code: API_KEY_MISSING
message: No api_key was supplied. Get one at {{baseUrl}}
message: No api_key was supplied. Get one at {{signup_url}}
api_key_invalid:
status_code: 403
code: API_KEY_INVALID
message: An invalid api_key was supplied. Get one at {{baseUrl}}
message: An invalid api_key was supplied. Get one at {{signup_url}}
api_key_disabled:
status_code: 403
code: API_KEY_DISABLED
message: The api_key supplied has been disabled. Contact us at {{baseUrl}}/contact for assistance
message: The api_key supplied has been disabled. Contact us at {{contact_url}} for assistance
api_key_unverified:
status_code: 403
code: API_KEY_UNVERIFIED
message: The api_key supplied has not been verified yet. Please check your e-mail to verify the API key. Contact us at {{baseUrl}}/contact for assistance
message: The api_key supplied has not been verified yet. Please check your e-mail to verify the API key. Contact us at {{contact_url}} for assistance
api_key_unauthorized:
status_code: 403
code: API_KEY_UNAUTHORIZED
message: The api_key supplied is not authorized to access the given service. Contact us at {{baseUrl}}/contact for assistance
message: The api_key supplied is not authorized to access the given service. Contact us at {{contact_url}} for assistance
over_rate_limit:
status_code: 429
code: OVER_RATE_LIMIT
message: You have exceeded your rate limit. Try again later or contact us at {{baseUrl}}/contact for assistance
message: You have exceeded your rate limit. Try again later or contact us at {{contact_url}} for assistance
internal_server_error:
status_code: 500
code: INTERNAL_SERVER_ERROR
message: An unexpected error has occurred. Try again later or contact us at {{baseUrl}}/contact for assistance
message: An unexpected error has occurred. Try again later or contact us at {{contact_url}} for assistance
https_required:
status_code: 400
code: HTTPS_REQUIRED
message: "Requests must be made over HTTPS. Try accessing the API at: {{httpsUrl}}"
message: "Requests must be made over HTTPS. Try accessing the API at: {{https_url}}"
1 change: 1 addition & 0 deletions lib/gatekeeper/middleware/https_requirements.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ _.extend(HttpsRequirements.prototype, {
response.end(body);
} else {
utils.errorHandler(request, response, 'https_required', {
https_url: httpsUrl,
httpsUrl: httpsUrl,
});
}
Expand Down
30 changes: 26 additions & 4 deletions lib/gatekeeper/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ var _ = require('lodash'),
Negotiator = require('negotiator'),
url = require('url');

exports.errorHandler = function(request, response, error, data) {
exports.errorHandler = function(request, response, error, errorSpecificData) {
var availableMediaTypes = ['application/json', 'application/xml', 'text/csv', 'text/html'];

// Prefer the format from the extension given in the URL.
Expand Down Expand Up @@ -44,14 +44,36 @@ exports.errorHandler = function(request, response, error, data) {
// introduce in multi-line templates and XML doesn't like if there's any
// leading space before the XML declaration.
var templateContent = settings.error_templates[format].replace(/^\s+|\s+$/g, '');

var commonErrorData = settings.error_data.common;
if(!commonErrorData || !_.isPlainObject(commonErrorData)) {
commonErrorData = {};
logger.error({ error_type: error }, 'Common error data not found.');
}

var errorData = settings.error_data[error];
if(!errorData || !_.isPlainObject(errorData)) {
errorData = settings.error_data.internal_server_error;
logger.error({ error_type: error }, 'Error data not found for error type: ' + error);
}
data = _.merge({
baseUrl: request.base,
}, data || {}, errorData);

var data = _.merge({
base_url: request.base,
}, commonErrorData);

// Support legacy camel-case capitalization of variables. Moving forward,
// we're trying to clean things up and standardize on snake-case.
if(!data.baseUrl) {
data.baseUrl = data.base_url;
}
if(!data.signupUrl) {
data.signupUrl = data.signup_url;
}
if(!data.contactUrl) {
data.contactUrl = data.contact_url;
}

data = _.merge(data, errorSpecificData || {}, errorData);

var prop;
for(prop in data) {
Expand Down
101 changes: 94 additions & 7 deletions test/server/formatted_errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,102 @@ describe('formatted error responses', function() {
});

describe('data variables', function() {
shared.runServer();
shared.runServer({
apis: [
{
frontend_host: 'localhost',
backend_host: 'example.com',
url_matches: [
{
frontend_prefix: '/',
backend_prefix: '/',
}
],
settings: {
error_data: {
api_key_missing: {
embedded: 'base_url: {{base_url}} signup_url: {{signup_url}} contact_url: {{contact_url}}',
embedded_legacy: 'baseUrl: {{baseUrl}} signupUrl: {{signupUrl}} contactUrl: {{contactUrl}}',
},
},
error_templates: {
json: '{' +
'"base_url": {{base_url}},' +
'"baseUrl": {{baseUrl}},' +
'"signup_url": {{signup_url}},' +
'"signupUrl": {{signupUrl}},' +
'"contact_url": {{contact_url}},' +
'"contactUrl": {{contactUrl}},' +
'"embedded": {{embedded}},' +
'"embedded_legacy": {{embedded_legacy}} ' +
'}',
},
},
},
],
});

it('substitutes the base_url variable', function(done) {
request.get('http://localhost:9333/base_url.json', function(error, response, body) {
var data = JSON.parse(body);
data.base_url.should.eql('http://localhost:9333');
done();
});
});

it('substitutes the baseUrl variable', function(done) {
Factory.create('api_user', { disabled_at: new Date() }, function(user) {
request.get('http://localhost:9333/hello.json?api_key=' + user.api_key, function(error, response, body) {
var data = JSON.parse(body);
data.error.message.should.include(' http://localhost:9333/contact ');
done();
});
request.get('http://localhost:9333/baseUrl.json', function(error, response, body) {
var data = JSON.parse(body);
data.baseUrl.should.eql('http://localhost:9333');
done();
});
});

it('substitutes the signup_url variable', function(done) {
request.get('http://localhost:9333/signup_url.json', function(error, response, body) {
var data = JSON.parse(body);
data.signup_url.should.eql('http://localhost:9333');
done();
});
});

it('substitutes the signupUrl variable', function(done) {
request.get('http://localhost:9333/signupUrl.json', function(error, response, body) {
var data = JSON.parse(body);
data.signupUrl.should.eql('http://localhost:9333');
done();
});
});

it('substitutes the contact_url variable', function(done) {
request.get('http://localhost:9333/contact_url.json', function(error, response, body) {
var data = JSON.parse(body);
data.contact_url.should.eql('http://localhost:9333/contact/');
done();
});
});

it('substitutes the contactUrl variable', function(done) {
request.get('http://localhost:9333/contactUrl.json', function(error, response, body) {
var data = JSON.parse(body);
data.contactUrl.should.eql('http://localhost:9333/contact/');
done();
});
});

it('substitutes variables embedded inside of other variables', function(done) {
request.get('http://localhost:9333/embedded.json', function(error, response, body) {
var data = JSON.parse(body);
data.embedded.should.eql('base_url: http://localhost:9333 signup_url: http://localhost:9333 contact_url: http://localhost:9333/contact/');
done();
});
});

it('substitutes legacy camel case variables embedded inside of other variables', function(done) {
request.get('http://localhost:9333/embedded_legacy.json', function(error, response, body) {
var data = JSON.parse(body);
data.embedded_legacy.should.eql('baseUrl: http://localhost:9333 signupUrl: http://localhost:9333 contactUrl: http://localhost:9333/contact/');
done();
});
});
});
Expand Down

0 comments on commit f998b37

Please sign in to comment.