From 471dad248a8ebc8463e48de8f6909a96d55752ad Mon Sep 17 00:00:00 2001 From: Aubrey Keus Date: Mon, 6 Apr 2020 12:17:47 -0400 Subject: [PATCH] Add API key requirement --- package.json | 2 +- src/controllers/feedback.js | 6 +++++- src/verification.js | 15 ++++++++++++++- test/feedback.js | 4 ++++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index e82b4943..b8ee7132 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "start": "./node_modules/.bin/babel-node src/index.js", "lint": "standard", "verify": "node tools/verify.js", - "test": "S3_DOWNLOAD_KEY=1 S3_DOWNLOAD_SECRET=1 BEHIND_FASTLY=1 tap test/*.js", + "test": "S3_DOWNLOAD_KEY=1 S3_DOWNLOAD_SECRET=1 BEHIND_FASTLY=1 API_KEYS=a,b,c tap test/*.js", "test-win": "set BEHIND_FASTLY=1 && tap test/*.js" }, "author": "Brave", diff --git a/src/controllers/feedback.js b/src/controllers/feedback.js index 4b40789a..87743f9f 100644 --- a/src/controllers/feedback.js +++ b/src/controllers/feedback.js @@ -3,6 +3,7 @@ const Boom = require('boom') const moment = require('moment') const storage = require('../storage') const uuid = require('uuid/v4') +const verification = require('../verification') const FEEDBACK_COLLECTION = process.env.FEEDBACK_COLLECTION || 'feedback' @@ -59,7 +60,10 @@ exports.setup = (runtime) => { try { // phase 2 - to be implemented - rate limit on IP address - // phase 2 - to be implemented - callout to referral server to verify api key + // verify API key + if (!verification.isValidAPIKey(request.payload.api_key)) { + return reply(Boom.notAcceptable('invalid api key')) + } // build event const storageObject = buildStorageObject(request.payload) diff --git a/src/verification.js b/src/verification.js index c1d62314..75eb6838 100644 --- a/src/verification.js +++ b/src/verification.js @@ -1,3 +1,4 @@ +const _ = require('underscore') const moment = require('moment') // verification libraries @@ -12,6 +13,13 @@ const verifiers = [ linuxCore.variousVersions, ] +const API_KEYS = _.object( + (process.env.API_KEYS || '') + .split(',') + .map((k) => { return k.trim() }) + .map((k) => { return [k, true] }) +) + // public function to determine is a request should be verified, and if so, // if the usage ping is valid (by iterating over a set of verifiers) const isUsagePingValid = (request, usage, apiKeys = [], tlsSignatures = []) => { @@ -33,7 +41,12 @@ const writeFilteredUsagePing = (mg, usage, cb) => { filteredCollection.insertOne(usage, cb) } +const isValidAPIKey = (k) => { + return !!API_KEYS[k] +} + module.exports = { isUsagePingValid, - writeFilteredUsagePing + writeFilteredUsagePing, + isValidAPIKey, } diff --git a/test/feedback.js b/test/feedback.js index 59394ec8..a530f20c 100644 --- a/test/feedback.js +++ b/test/feedback.js @@ -2,6 +2,7 @@ const tap = require('tap') const moment = require('moment') const feedback = require('../src/controllers/feedback') +const verification = require('../src/verification') tap.test('feedback', (t) => { let results = feedback.buildStorageObject({ @@ -22,5 +23,8 @@ tap.test('feedback', (t) => { t.equal(feedback.successResult('1').status, 'ok', 'ok result well formed') t.ok(feedback.successResult('1').id, 'ok result has id') + t.ok(verification.isValidAPIKey('a'), 'verification key found') + t.notok(verification.isValidAPIKey('z'), 'verification key not found') + t.done() })