From 4b9d7ea6c94aba49af05a2c47b9b049c0e410fb4 Mon Sep 17 00:00:00 2001 From: Jamie Date: Fri, 8 Nov 2024 08:00:18 +1300 Subject: [PATCH] read platform user ids from encrypted file --- lib/misc.js | 42 ++++++++++++++++++++++--- lib/schema/qa3_user_ids.json | 1 + lib/schema/schemaEnv.js | 24 +++++++++------ test/schema/schemaEnvTest.js | 59 ++++++++++++++++++++++++++++++++++++ 4 files changed, 111 insertions(+), 15 deletions(-) create mode 100644 lib/schema/qa3_user_ids.json create mode 100644 test/schema/schemaEnvTest.js diff --git a/lib/misc.js b/lib/misc.js index 5b5ecf4e..9c74d51b 100644 --- a/lib/misc.js +++ b/lib/misc.js @@ -1,15 +1,15 @@ /* * == BSD2 LICENSE == * Copyright (c) 2014, Tidepool Project - * + * * This program is free software; you can redistribute it and/or modify it under * the terms of the associated License, which is identical to the BSD 2-Clause * License as published by the Open Source Initiative at opensource.org. - * + * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the License for more details. - * + * * You should have received a copy of the License along with this program; if * not, you can obtain one from Tidepool Project at tidepool.org. * == BSD2 LICENSE == @@ -18,7 +18,7 @@ 'use strict'; var crypto = require('crypto'); - +var fs = require('fs'); var amoeba = require('amoeba'); var base32hex = amoeba.base32hex; var except = amoeba.except; @@ -45,7 +45,7 @@ var except = amoeba.except; * @param fields an array of values to be concatenated together into a unique string * @returns {string} the base32 encoded hash of the delimited-concatenation of the provided fields (also known as a "unique" id) */ -exports.generateId = function(fields) { +exports.generateId = function (fields) { var hasher = crypto.createHash('sha1'); for (var i = 0; i < fields.length; ++i) { @@ -65,3 +65,35 @@ exports.generateId = function(fields) { return base32hex.encodeBuffer(hasher.digest(), { paddingChar: '-' }); }; +exports.encryptArrayToFile = function (dataArray, filePath, env, serverSecret) { + var iv = `${env}-environment`.substring(0, 16); + var key = serverSecret.substring(0, 32); + var algorithm = 'aes-256-cbc'; + + var encryptedArray = dataArray.map((item) => { + var cipher = crypto.createCipheriv(algorithm, key, iv); + let encrypted = cipher.update(item, 'utf8', 'hex'); + encrypted += cipher.final('hex'); + return encrypted; + }); + fs.writeFileSync(filePath, JSON.stringify(encryptedArray)); +}; + +exports.decryptArrayFromFile = function (filePath, env, serverSecret) { + if (!fs.existsSync(filePath)) { + throw new Error(`Missing required file ${filePath}`); + } + var iv = `${env}-environment`.substring(0, 16); + var key = serverSecret.substring(0, 32); + var algorithm = 'aes-256-cbc'; + var encryptedArray = JSON.parse(fs.readFileSync(filePath, 'utf8')); + + var decryptedArray = encryptedArray.map((item) => { + var decipher = crypto.createDecipheriv(algorithm, key, iv); + let decrypted = decipher.update(item, 'hex', 'utf8'); + decrypted += decipher.final('utf8'); + return decrypted; + }); + + return decryptedArray; +}; diff --git a/lib/schema/qa3_user_ids.json b/lib/schema/qa3_user_ids.json new file mode 100644 index 00000000..fe51488c --- /dev/null +++ b/lib/schema/qa3_user_ids.json @@ -0,0 +1 @@ +[] diff --git a/lib/schema/schemaEnv.js b/lib/schema/schemaEnv.js index 671999c6..37475ac1 100644 --- a/lib/schema/schemaEnv.js +++ b/lib/schema/schemaEnv.js @@ -18,7 +18,19 @@ 'use strict'; var config = require('amoeba').config; -var schema = require('./schema.js'); +var misc = require('../misc.js'); + +function loadEnvironmentUserIds() { + const environment = config.fromEnvironment('POD_NAMESPACE', 'local'); + const serverSecret = config.fromEnvironment('TIDEPOOL_SERVER_SECRET'); + const environmentUserIdsFile = `${__dirname}/../${environment}_user_ids.json`; + + return misc.decryptArrayFromFile( + environmentUserIdsFile, + environment, + serverSecret + ); +} module.exports = (function () { var schemaEnv = {}; @@ -32,14 +44,6 @@ module.exports = (function () { schemaEnv.authRealm = config.fromEnvironment('KEYCLOAK_AUTH_REALM', null); schemaEnv.authUrl = config.fromEnvironment('KEYCLOAK_AUTH_URL', null); - var usersStr = config.fromEnvironment('UPLOADER_PLATFORM_USER_IDS', null); - var platformUsers = []; - if (usersStr) { - platformUsers = usersStr - .split(',') - .map((item) => item.toLowerCase().trim()); - } - schemaEnv.platformUserIds = platformUsers; - + schemaEnv.platformUserIds = loadEnvironmentUserIds(); return schemaEnv; })(); diff --git a/test/schema/schemaEnvTest.js b/test/schema/schemaEnvTest.js new file mode 100644 index 00000000..3f5c3fef --- /dev/null +++ b/test/schema/schemaEnvTest.js @@ -0,0 +1,59 @@ +/* + * == BSD2 LICENSE == + * Copyright (c) 2024, Tidepool Project + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the associated License, which is identical to the BSD 2-Clause + * License as published by the Open Source Initiative at opensource.org. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the License for more details. + * + * You should have received a copy of the License along with this program; if + * not, you can obtain one from Tidepool Project at tidepool.org. + * == BSD2 LICENSE == + */ + +/* global describe, before, beforeEach, it, after */ + +'use strict'; + +var expect = require('salinity').expect; +var misc = require('../../lib/misc.js'); +var fs = require('fs'); + +describe('schema/schemaEnv.js', function () { + const env = Object.assign({}, process.env); + const POD_NAMESPACE = 'test'; + const TIDEPOOL_SERVER_SECRET = 'some kinda secret goes here I guess'; + const USER_IDS = ['123', '456', 'ddbs', 'blahblah']; + const filePath = `${__dirname}/../../lib/${POD_NAMESPACE}_user_ids.json`; + + function setupFile(path, data, env, secret) { + misc.encryptArrayToFile(data, path, env, secret); + } + + function tearDownFile(path) { + fs.unlinkSync(path); + } + + before((done) => { + process.env.POD_NAMESPACE = POD_NAMESPACE; + process.env.TIDEPOOL_SERVER_SECRET = TIDEPOOL_SERVER_SECRET; + setupFile(filePath, USER_IDS, POD_NAMESPACE, TIDEPOOL_SERVER_SECRET); + done(); + }); + + after((done) => { + process.env = env; + tearDownFile(filePath); + done(); + }); + + it('file present gets stored platform users', function (done) { + var schemaEnv = require('../../lib/schema/schemaEnv.js'); + expect(schemaEnv.platformUserIds).to.deep.equal(USER_IDS); + done(); + }); +});