Merge pull request #748 from drew-gross/touch-up-features-endpoint

Touch up features endpoint
This commit is contained in:
Drew
2016-03-02 16:43:12 -08:00
5 changed files with 62 additions and 61 deletions

View File

@@ -5,7 +5,7 @@ const request = require("request");
describe('features', () => {
it('set and get features', (done) => {
features.setFeature('users', {
features.setFeature('push', {
testOption1: true,
testOption2: false
});
@@ -14,10 +14,10 @@ describe('features', () => {
var expected = {
testOption1: true,
testOption2: false
testOption2: false
};
expect(_features.users).toEqual(expected);
expect(_features.push).toEqual(expected);
done();
});
@@ -29,7 +29,7 @@ describe('features', () => {
it('requires the master key to get all schemas', done => {
request.get({
url: 'http://localhost:8378/1/features',
url: 'http://localhost:8378/1/serverInfo',
json: true,
headers: {
'X-Parse-Application-Id': 'test',

View File

@@ -1,4 +1,5 @@
var request = require('request');
var parseServerPackage = require('../package.json');
var MockEmailAdapterWithOptions = require('./MockEmailAdapterWithOptions');
describe('server', () => {
@@ -153,4 +154,18 @@ describe('server', () => {
})).toThrow('SimpleMailgunAdapter requires an API Key and domain.');
done();
});
it('can report the server version', done => {
request.get({
url: 'http://localhost:8378/1/serverInfo',
headers: {
'X-Parse-Application-Id': 'test',
'X-Parse-Master-Key': 'test',
},
json: true,
}, (error, response, body) => {
expect(body.parseServerVersion).toEqual(parseServerPackage.version);
done();
})
});
});

View File

@@ -1,13 +1,15 @@
import PromiseRouter from '../PromiseRouter';
import { version } from '../../package.json';
import PromiseRouter from '../PromiseRouter';
import * as middleware from "../middlewares";
import { getFeatures } from '../features';
export class FeaturesRouter extends PromiseRouter {
mountRoutes() {
this.route('GET','/features', middleware.promiseEnforceMasterKeyAccess, () => {
this.route('GET','/serverInfo', middleware.promiseEnforceMasterKeyAccess, () => {
return { response: {
results: [getFeatures()]
} };
features: getFeatures(),
parseServerVersion: version,
} };
});
}
}

View File

@@ -14,26 +14,18 @@
* Features that use Adapters should specify the feature options through
* the setFeature method in your controller and feature
* Reference PushController and ParsePushAdapter as an example.
*
*
* NOTE: When adding new endpoints be sure to update this list both (features, featureSwitch)
* if you are planning to have a UI consume it.
* if you are planning to have a UI consume it.
*/
// default features
let features = {
analytics: {
slowQueries: false,
performanceAnalysis: false,
retentionAnalysis: false,
},
classes: {},
files: {},
functions: {},
globalConfig: {
create: true,
read: true,
update: true,
delete: true,
create: false,
read: false,
update: false,
delete: false,
},
hooks: {
create: false,
@@ -41,15 +33,19 @@ let features = {
update: false,
delete: false,
},
iapValidation: {},
installations: {},
logs: {
info: true,
error: true,
level: false,
size: false,
order: false,
until: false,
from: false,
},
push: {
immediatePush: false,
scheduledPush: false,
storedPushData: false,
pushAudiences: false,
},
publicAPI: {},
push: {},
roles: {},
schemas: {
addField: true,
removeField: true,
@@ -58,27 +54,15 @@ let features = {
clearAllDataFromClass: false,
exportClass: false,
},
sessions: {},
users: {},
};
// master switch for features
let featuresSwitch = {
analytics: true,
classes: true,
files: true,
functions: true,
globalConfig: true,
hooks: true,
iapValidation: true,
installations: true,
logs: true,
publicAPI: true,
push: true,
roles: true,
schemas: true,
sessions: true,
users: true,
};
/**
@@ -94,7 +78,7 @@ function setFeature(key, value) {
function getFeatures() {
let result = {};
Object.keys(features).forEach((key) => {
if (featuresSwitch[key]) {
if (featuresSwitch[key] && features[key]) {
result[key] = features[key];
}
});

View File

@@ -10,12 +10,13 @@ var batch = require('./batch'),
multer = require('multer'),
Parse = require('parse/node').Parse;
//import passwordReset from './passwordReset';
import cache from './cache';
import Config from './Config';
import parseServerPackage from '../package.json';
import ParsePushAdapter from './Adapters/Push/ParsePushAdapter';
//import passwordReset from './passwordReset';
import PromiseRouter from './PromiseRouter';
import requiredParameter from './requiredParameter';
import { AnalyticsRouter } from './Routers/AnalyticsRouter';
import { ClassesRouter } from './Routers/ClassesRouter';
import { FeaturesRouter } from './Routers/FeaturesRouter';
@@ -23,28 +24,27 @@ import { FileLoggerAdapter } from './Adapters/Logger/FileLoggerAdapter';
import { FilesController } from './Controllers/FilesController';
import { FilesRouter } from './Routers/FilesRouter';
import { FunctionsRouter } from './Routers/FunctionsRouter';
import { GridStoreAdapter } from './Adapters/Files/GridStoreAdapter';
import { IAPValidationRouter } from './Routers/IAPValidationRouter';
import { LogsRouter } from './Routers/LogsRouter';
import { HooksRouter } from './Routers/HooksRouter';
import { PublicAPIRouter } from './Routers/PublicAPIRouter';
import { GlobalConfigRouter } from './Routers/GlobalConfigRouter';
import { GridStoreAdapter } from './Adapters/Files/GridStoreAdapter';
import { HooksController } from './Controllers/HooksController';
import { UserController } from './Controllers/UserController';
import { HooksRouter } from './Routers/HooksRouter';
import { IAPValidationRouter } from './Routers/IAPValidationRouter';
import { InstallationsRouter } from './Routers/InstallationsRouter';
import { loadAdapter } from './Adapters/AdapterLoader';
import { LoggerController } from './Controllers/LoggerController';
import { LogsRouter } from './Routers/LogsRouter';
import { PublicAPIRouter } from './Routers/PublicAPIRouter';
import { PushController } from './Controllers/PushController';
import { PushRouter } from './Routers/PushRouter';
import { randomString } from './cryptoUtils';
import { RolesRouter } from './Routers/RolesRouter';
import { S3Adapter } from './Adapters/Files/S3Adapter';
import { SchemasRouter } from './Routers/SchemasRouter';
import { SessionsRouter } from './Routers/SessionsRouter';
import { setFeature } from './features';
import { UserController } from './Controllers/UserController';
import { UsersRouter } from './Routers/UsersRouter';
import requiredParameter from './requiredParameter';
import { randomString } from './cryptoUtils';
// Mutate the Parse object to add the Cloud Code handlers
addParseCloud();
@@ -106,11 +106,11 @@ function ParseServer({
passwordResetSuccess: undefined
},
}) {
setFeature('serverVersion', parseServerPackage.version);
// Initialize the node client SDK automatically
Parse.initialize(appId, javascriptKey || 'unused', masterKey);
Parse.serverURL = serverURL;
if (databaseAdapter) {
DatabaseAdapter.setAdapter(databaseAdapter);
}
@@ -144,7 +144,7 @@ function ParseServer({
const hooksController = new HooksController(appId, collectionPrefix);
const userController = new UserController(emailControllerAdapter, appId, { verifyUserEmails });
cache.apps.set(appId, {
masterKey: masterKey,
serverURL: serverURL,
@@ -173,7 +173,7 @@ function ParseServer({
if (process.env.FACEBOOK_APP_ID) {
cache.apps.get(appId)['facebookAppIds'].push(process.env.FACEBOOK_APP_ID);
}
Config.validate(cache.apps.get(appId));
// This app serves the Parse API directly.
@@ -186,7 +186,7 @@ function ParseServer({
}));
api.use('/', bodyParser.urlencoded({extended: false}), new PublicAPIRouter().expressApp());
// TODO: separate this from the regular ParseServer object
if (process.env.TESTING == 1) {
api.use('/', require('./testing-routes').router);
@@ -215,17 +215,17 @@ function ParseServer({
if (process.env.PARSE_EXPERIMENTAL_CONFIG_ENABLED || process.env.TESTING) {
routers.push(new GlobalConfigRouter());
}
if (process.env.PARSE_EXPERIMENTAL_HOOKS_ENABLED || process.env.TESTING) {
routers.push(new HooksRouter());
}
let routes = routers.reduce((memo, router) => {
return memo.concat(router.routes);
}, []);
let appRouter = new PromiseRouter(routes);
batch.mountOnto(appRouter);
api.use(appRouter.expressApp());