formatting, add helper func for POST endpoints

This commit is contained in:
Andrew Zhu
2019-02-05 13:09:56 -08:00
parent b94f5ebb4b
commit d1d22c0d89

View File

@@ -1,47 +1,47 @@
Router.map(function() { Router.map(function () {
this.route("vmixCharacter", { this.route("vmixCharacter", {
path: "/vmix-character/:_id/", path: "/vmix-character/:_id/",
where: "server", where: "server",
action: function() { action: function () {
this.response.setHeader("Content-Type", "application/json"); this.response.setHeader("Content-Type", "application/json");
var query = this.params.query; var query = this.params.query;
var key = query && query.key; var key = query && query.key;
ifKeyValid(key, this.response, "vmixCharacter", () => ifKeyValid(key, this.response, "vmixCharacter", () =>
this.response.end(vMixCharacter(this.params._id)) this.response.end(vMixCharacter(this.params._id))
); );
}, },
}); });
this.route("vmixParty", { this.route("vmixParty", {
path: "/vmix-party/:_id/", path: "/vmix-party/:_id/",
where: "server", where: "server",
action: function() { action: function () {
this.response.setHeader("Content-Type", "application/json"); this.response.setHeader("Content-Type", "application/json");
var query = this.params.query; var query = this.params.query;
var key = query && query.key; var key = query && query.key;
ifKeyValid(key, this.response, "vmixParty", () => ifKeyValid(key, this.response, "vmixParty", () =>
this.response.end(vMixParty(this.params._id)) this.response.end(vMixParty(this.params._id))
); );
}, },
}); });
this.route("jsonCharacterSheet", { this.route("jsonCharacterSheet", {
path: "/character/:_id/json", path: "/character/:_id/json",
where: "server", where: "server",
action: function() { action: function () {
this.response.setHeader("Content-Type", "application/json"); this.response.setHeader("Content-Type", "application/json");
var query = this.params.query; var query = this.params.query;
var key = query && query.key; var key = query && query.key;
ifKeyValid(key, this.response, "jsonCharacterSheet", () => { ifKeyValid(key, this.response, "jsonCharacterSheet", () => {
if (canViewCharacter(this.params._id, userIdFromKey(key))){ if (canViewCharacter(this.params._id, userIdFromKey(key))) {
this.response.end(JSONExport(this.params._id)) this.response.end(JSONExport(this.params._id))
} else { } else {
this.response.writeHead(403, "You do not have permission to view this character"); this.response.writeHead(403, "You do not have permission to view this character");
this.response.end(); this.response.end();
} }
} }
); );
}, },
}); });
this.route("getUserId", { // GET /api/user?username=:un this.route("getUserId", { // GET /api/user?username=:un
path: "/api/user", path: "/api/user",
@@ -67,35 +67,50 @@ Router.map(function() {
}); });
}); });
var ifKeyValid = function(apiKey, response, method, callback){ var ifPostOK = function (router, endpoint, callback) {
if (!apiKey){ router.response.setHeader("Content-Type", "application/json");
response.writeHead(403, "You must use an api key to access this api"); var header = router.request.headers;
response.end(); var key = header && header['Authorization'];
} else if (!isKeyValid(apiKey)){ ifKeyValid(key, router.response, endpoint, () => {
response.writeHead(403, "API key is invalid"); if (canEditCharacter(router.params._id, userIdFromKey(key))) {
response.end(); callback();
} else if (isRateLimited(apiKey, method)){ } else {
response.writeHead(429, "Too many requests"); router.response.writeHead(403, "You do not have permission to edit this character");
response.end(JSON.stringify({ router.response.end();
"timeToReset": rateLimiter.check({apiKey: apiKey, method: method}).timeToReset }
})); }
} else { );
rateLimiter.increment({apiKey: apiKey, method: method})
callback();
}
}; };
var isKeyValid = function(apiKey){ var ifKeyValid = function (apiKey, response, method, callback) {
var user = Meteor.users.findOne({apiKey}); if (!apiKey) {
if (!user) return false; response.writeHead(403, "You must use an api key to access this api");
var blackListed = Blacklist.findOne({userId: user._id}); response.end();
return !blackListed; } else if (!isKeyValid(apiKey)) {
response.writeHead(403, "API key is invalid");
response.end();
} else if (isRateLimited(apiKey, method)) {
response.writeHead(429, "Too many requests");
response.end(JSON.stringify({
"timeToReset": rateLimiter.check({apiKey: apiKey, method: method}).timeToReset
}));
} else {
rateLimiter.increment({apiKey: apiKey, method: method});
callback();
}
}; };
var userIdFromKey = function(apiKey){ var isKeyValid = function (apiKey) {
var user = Meteor.users.findOne({apiKey}); // we know user exists from isKeyValid var user = Meteor.users.findOne({apiKey});
return user._id; if (!user) return false;
} var blackListed = Blacklist.findOne({userId: user._id});
return !blackListed;
};
var userIdFromKey = function (apiKey) {
var user = Meteor.users.findOne({apiKey}); // we know user exists from isKeyValid
return user._id;
};
var rateLimiter = new RateLimiter(); var rateLimiter = new RateLimiter();
rateLimiter.addRule({apiKey: String}, 5, 5000); rateLimiter.addRule({apiKey: String}, 5, 5000);
@@ -103,12 +118,12 @@ rateLimiter.addRule({apiKey: String, method: "vmixCharacter"}, 2, 10000);
rateLimiter.addRule({apiKey: String, method: "vmixParty"}, 2, 10000); rateLimiter.addRule({apiKey: String, method: "vmixParty"}, 2, 10000);
rateLimiter.addRule({apiKey: String, method: "jsonCharacterSheet"}, 5, 5000); rateLimiter.addRule({apiKey: String, method: "jsonCharacterSheet"}, 5, 5000);
var isRateLimited = function(apiKey, method){ var isRateLimited = function (apiKey, method) {
const limited = !rateLimiter.check({apiKey: apiKey, method: method}).allowed const limited = !rateLimiter.check({apiKey: apiKey, method: method}).allowed;
if (limited) { if (limited) {
console.log(`Rate limit hit by API key ${apiKey}`); console.log(`Rate limit hit by API key ${apiKey}`);
return true; return true;
} else { } else {
return false; return false;
} }
}; };