From 9bc636dc5c436f55821be1a5f3b48f34466959d4 Mon Sep 17 00:00:00 2001 From: Nikita Lutsenko Date: Fri, 26 Feb 2016 20:55:17 -0800 Subject: [PATCH 1/5] Cleanup, remove unusued methods and unify cache.js. --- src/Auth.js | 6 ++--- src/Config.js | 9 +++---- src/cache.js | 58 ++++++++++++++++++------------------------- src/index.js | 6 ++--- src/middlewares.js | 14 +++++------ src/rest.js | 2 +- src/testing-routes.js | 7 +++--- src/triggers.js | 4 +-- 8 files changed, 46 insertions(+), 60 deletions(-) diff --git a/src/Auth.js b/src/Auth.js index 642f34ab84..d944307f75 100644 --- a/src/Auth.js +++ b/src/Auth.js @@ -43,7 +43,7 @@ function nobody(config) { // Returns a promise that resolves to an Auth object var getAuthForSessionToken = function(config, sessionToken) { - var cachedUser = cache.getUser(sessionToken); + var cachedUser = cache.users.get(sessionToken); if (cachedUser) { return Promise.resolve(new Auth(config, false, cachedUser)); } @@ -65,8 +65,8 @@ var getAuthForSessionToken = function(config, sessionToken) { delete obj.password; obj['className'] = '_User'; obj['sessionToken'] = sessionToken; - var userObject = Parse.Object.fromJSON(obj); - cache.setUser(sessionToken, userObject); + let userObject = Parse.Object.fromJSON(obj); + cache.users.set(sessionToken, userObject); return new Auth(config, false, userObject); }); }; diff --git a/src/Config.js b/src/Config.js index 8ceeb0e1ce..988efb1e11 100644 --- a/src/Config.js +++ b/src/Config.js @@ -7,15 +7,12 @@ import cache from './cache'; export class Config { constructor(applicationId: string, mount: string) { let DatabaseAdapter = require('./DatabaseAdapter'); - - let cacheInfo = cache.apps[applicationId]; - this.valid = !!cacheInfo; - if (!this.valid) { + let cacheInfo = cache.apps.get(applicationId); + if (!cacheInfo) { return; } this.applicationId = applicationId; - this.collectionPrefix = cacheInfo.collectionPrefix || ''; this.masterKey = cacheInfo.masterKey; this.clientKey = cacheInfo.clientKey; this.javascriptKey = cacheInfo.javascriptKey; @@ -25,7 +22,7 @@ export class Config { this.facebookAppIds = cacheInfo.facebookAppIds; this.enableAnonymousUsers = cacheInfo.enableAnonymousUsers; this.allowClientClassCreation = cacheInfo.allowClientClassCreation; - this.database = DatabaseAdapter.getDatabaseConnection(applicationId, this.collectionPrefix); + this.database = DatabaseAdapter.getDatabaseConnection(applicationId, cacheInfo.collectionPrefix); this.hooksController = cacheInfo.hooksController; this.filesController = cacheInfo.filesController; this.pushController = cacheInfo.pushController; diff --git a/src/cache.js b/src/cache.js index a737a91d02..8893f29b1b 100644 --- a/src/cache.js +++ b/src/cache.js @@ -1,45 +1,35 @@ -export var apps = {}; -export var stats = {}; -export var isLoaded = false; -export var users = {}; +/** @flow weak */ -export function getApp(app, callback) { - if (apps[app]) return callback(true, apps[app]); - return callback(false); +export function CacheStore() { + let dataStore: {[id:KeyType]:ValueType} = {}; + return { + get: (key: KeyType): ValueType => { + return dataStore[key]; + }, + set(key: KeyType, value: ValueType): void { + dataStore[key] = value; + }, + remove(key: KeyType): void { + delete dataStore[key]; + }, + clear(): void { + dataStore = {}; + } + }; } -export function updateStat(key, value) { - stats[key] = value; -} - -export function getUser(sessionToken) { - if (users[sessionToken]) return users[sessionToken]; - return undefined; -} - -export function setUser(sessionToken, userObject) { - users[sessionToken] = userObject; -} - -export function clearUser(sessionToken) { - delete users[sessionToken]; -} +const apps = CacheStore(); +const users = CacheStore(); //So far used only in tests -export function clearCache() { - apps = {}; - stats = {}; - users = {}; +export function clearCache(): void { + apps.clear(); + users.clear(); } export default { apps, - stats, - isLoaded, - getApp, - updateStat, - clearUser, - getUser, - setUser, + users, clearCache, + CacheStore }; diff --git a/src/index.js b/src/index.js index ad715902f5..93c7ef1730 100644 --- a/src/index.js +++ b/src/index.js @@ -126,7 +126,7 @@ function ParseServer({ const loggerController = new LoggerController(loggerControllerAdapter); const hooksController = new HooksController(appId, collectionPrefix); - cache.apps[appId] = { + cache.apps.set(appId, { masterKey: masterKey, collectionPrefix: collectionPrefix, clientKey: clientKey, @@ -142,11 +142,11 @@ function ParseServer({ enableAnonymousUsers: enableAnonymousUsers, allowClientClassCreation: allowClientClassCreation, oauth: oauth - }; + }); // To maintain compatibility. TODO: Remove in v2.1 if (process.env.FACEBOOK_APP_ID) { - cache.apps[appId]['facebookAppIds'].push(process.env.FACEBOOK_APP_ID); + cache.apps.get(appId)['facebookAppIds'].push(process.env.FACEBOOK_APP_ID); } // This app serves the Parse API directly. diff --git a/src/middlewares.js b/src/middlewares.js index 8acece2da4..c1a8eb71fa 100644 --- a/src/middlewares.js +++ b/src/middlewares.js @@ -35,7 +35,7 @@ function handleParseHeaders(req, res, next) { var fileViaJSON = false; - if (!info.appId || !cache.apps[info.appId]) { + if (!info.appId || !cache.apps.get(info.appId)) { // See if we can find the app id on the body. if (req.body instanceof Buffer) { // The only chance to find the app id is if this is a file @@ -44,12 +44,10 @@ function handleParseHeaders(req, res, next) { fileViaJSON = true; } - if (req.body && req.body._ApplicationId - && cache.apps[req.body._ApplicationId] - && ( - !info.masterKey - || - cache.apps[req.body._ApplicationId]['masterKey'] === info.masterKey) + if (req.body && + req.body._ApplicationId && + cache.apps.get(req.body._ApplicationId) && + (!info.masterKey || cache.apps.get(req.body._ApplicationId).masterKey === info.masterKey) ) { info.appId = req.body._ApplicationId; info.javascriptKey = req.body._JavaScriptKey || ''; @@ -84,7 +82,7 @@ function handleParseHeaders(req, res, next) { req.body = new Buffer(base64, 'base64'); } - info.app = cache.apps[info.appId]; + info.app = cache.apps.get(info.appId); req.config = new Config(info.appId, mount); req.database = req.config.database; req.info = info; diff --git a/src/rest.js b/src/rest.js index dbf526161e..d624f0682a 100644 --- a/src/rest.js +++ b/src/rest.js @@ -46,7 +46,7 @@ function del(config, auth, className, objectId) { .then((response) => { if (response && response.results && response.results.length) { response.results[0].className = className; - cache.clearUser(response.results[0].sessionToken); + cache.users.remove(response.results[0].sessionToken); inflatedObject = Parse.Object.fromJSON(response.results[0]); return triggers.maybeRunTrigger(triggers.Types.beforeDelete, auth, inflatedObject, null, config.applicationId); } diff --git a/src/testing-routes.js b/src/testing-routes.js index 3823946faf..f36b49e4ba 100644 --- a/src/testing-routes.js +++ b/src/testing-routes.js @@ -10,10 +10,11 @@ var router = express.Router(); // creates a unique app in the cache, with a collection prefix function createApp(req, res) { var appId = cryptoUtils.randomHexString(32); - cache.apps[appId] = { + // TODO: (nlutsenko) This doesn't work and should die, since there are no controllers on this configuration. + cache.apps.set(appId, { 'collectionPrefix': appId + '_', 'masterKey': 'master' - }; + }); var keys = { 'application_id': appId, 'client_key': 'unused', @@ -42,7 +43,7 @@ function dropApp(req, res) { return res.status(401).send({"error": "unauthorized"}); } req.database.deleteEverything().then(() => { - delete cache.apps[req.config.applicationId]; + cache.apps.remove(req.config.applicationId); res.status(200).send({}); }); } diff --git a/src/triggers.js b/src/triggers.js index 23e8f4a79e..5220ce79a4 100644 --- a/src/triggers.js +++ b/src/triggers.js @@ -157,8 +157,8 @@ export function maybeRunTrigger(triggerType, auth, parseObject, originalParseObj var response = getResponseObject(request, resolve, reject); // Force the current Parse app before the trigger Parse.applicationId = applicationId; - Parse.javascriptKey = cache.apps[applicationId].javascriptKey || ''; - Parse.masterKey = cache.apps[applicationId].masterKey; + Parse.javascriptKey = cache.apps.get(applicationId).javascriptKey || ''; + Parse.masterKey = cache.apps.get(applicationId).masterKey; trigger(request, response); }); }; From 49a4b74f7cc6543fa9ca725c83e9ff3b8c29b9f9 Mon Sep 17 00:00:00 2001 From: Nikita Lutsenko Date: Fri, 26 Feb 2016 21:18:37 -0800 Subject: [PATCH 2/5] Fix missing return type on requiredParameter.js. --- src/requiredParameter.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/requiredParameter.js b/src/requiredParameter.js index 0355285c79..f6d5dd4278 100644 --- a/src/requiredParameter.js +++ b/src/requiredParameter.js @@ -1,2 +1,2 @@ -/* @flow */ -export default (errorMessage: string) => {throw errorMessage} +/** @flow */ +export default (errorMessage: string): any => { throw errorMessage } From daa5f11122c97761897820107dc84bdbdfe89f5c Mon Sep 17 00:00:00 2001 From: Nikita Lutsenko Date: Fri, 26 Feb 2016 21:17:04 -0800 Subject: [PATCH 3/5] Remove 'database' field from request and make all database requests go through config. --- src/Routers/UsersRouter.js | 2 +- src/middlewares.js | 1 - src/testing-routes.js | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Routers/UsersRouter.js b/src/Routers/UsersRouter.js index 592bdc0b0a..4cba3edb0d 100644 --- a/src/Routers/UsersRouter.js +++ b/src/Routers/UsersRouter.js @@ -75,7 +75,7 @@ export class UsersRouter extends ClassesRouter { } let user; - return req.database.find('_User', { username: req.body.username }) + return req.config.database.find('_User', { username: req.body.username }) .then((results) => { if (!results.length) { throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Invalid username/password.'); diff --git a/src/middlewares.js b/src/middlewares.js index c1a8eb71fa..b9a8d6ec4b 100644 --- a/src/middlewares.js +++ b/src/middlewares.js @@ -84,7 +84,6 @@ function handleParseHeaders(req, res, next) { info.app = cache.apps.get(info.appId); req.config = new Config(info.appId, mount); - req.database = req.config.database; req.info = info; var isMaster = (info.masterKey === req.config.masterKey); diff --git a/src/testing-routes.js b/src/testing-routes.js index f36b49e4ba..f91c14a1e1 100644 --- a/src/testing-routes.js +++ b/src/testing-routes.js @@ -32,7 +32,7 @@ function clearApp(req, res) { if (!req.auth.isMaster) { return res.status(401).send({"error": "unauthorized"}); } - req.database.deleteEverything().then(() => { + return req.config.database.deleteEverything().then(() => { res.status(200).send({}); }); } @@ -42,7 +42,7 @@ function dropApp(req, res) { if (!req.auth.isMaster) { return res.status(401).send({"error": "unauthorized"}); } - req.database.deleteEverything().then(() => { + return req.config.database.deleteEverything().then(() => { cache.apps.remove(req.config.applicationId); res.status(200).send({}); }); From d30c3e90df3657995445188ebd2d2df307c7224c Mon Sep 17 00:00:00 2001 From: Nikita Lutsenko Date: Fri, 26 Feb 2016 21:24:42 -0800 Subject: [PATCH 4/5] Remove useless method in index.js. --- src/index.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/index.js b/src/index.js index 93c7ef1730..dae92ee4b6 100644 --- a/src/index.js +++ b/src/index.js @@ -220,13 +220,6 @@ function addParseCloud() { global.Parse = Parse; } -function getClassName(parseClass) { - if (parseClass && parseClass.className) { - return parseClass.className; - } - return parseClass; -} - module.exports = { ParseServer: ParseServer, S3Adapter: S3Adapter From 768a781f989b6b9f6ff9c6c64a62d6c58273c315 Mon Sep 17 00:00:00 2001 From: Nikita Lutsenko Date: Fri, 26 Feb 2016 22:16:06 -0800 Subject: [PATCH 5/5] Fix wrong order of resetting data in test helper. --- spec/helper.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/helper.js b/spec/helper.js index c7474afe96..92231393ce 100644 --- a/spec/helper.js +++ b/spec/helper.js @@ -52,13 +52,13 @@ delete defaultConfiguration.cloud; // Allows testing specific configurations of Parse Server var setServerConfiguration = configuration => { - api = new ParseServer(configuration); + server.close(); + cache.clearCache(); app = express(); + api = new ParseServer(configuration); app.use('/1', api); - cache.clearCache(); - server.close(); server = app.listen(port); -} +}; var restoreServerConfiguration = () => setServerConfiguration(defaultConfiguration);