First part of schemas PUT

This commit is contained in:
Drew Gross
2016-02-09 11:26:46 -08:00
parent 6db40f0bf4
commit cef5a5fabf
2 changed files with 148 additions and 20 deletions

View File

@@ -94,7 +94,7 @@ describe('schemas', () => {
headers: restKeyHeaders, headers: restKeyHeaders,
}, (error, response, body) => { }, (error, response, body) => {
expect(response.statusCode).toEqual(401); expect(response.statusCode).toEqual(401);
expect(body.error).toEqual('unauthorized'); expect(body.error).toEqual('master key not specified');
done(); done();
}); });
}); });
@@ -318,4 +318,101 @@ describe('schemas', () => {
done(); done();
}); });
}); });
it('requires the master key to modify schemas', done => {
request.post({
url: 'http://localhost:8378/1/schemas/NewClass',
headers: masterKeyHeaders,
json: true,
body: {},
}, (error, response, body) => {
request.put({
url: 'http://localhost:8378/1/schemas/NewClass',
headers: noAuthHeaders,
json: true,
body: {},
}, (error, response, body) => {
expect(response.statusCode).toEqual(403);
expect(body.error).toEqual('unauthorized');
done();
});
});
});
it('rejects class name mis-matches', done => {
request.put({
url: 'http://localhost:8378/1/schemas/NewClass',
headers: masterKeyHeaders,
json: true,
body: {className: 'WrongClassName'}
}, (error, response, body) => {
expect(response.statusCode).toEqual(400);
expect(body.code).toEqual(Parse.Error.INVALID_CLASS_NAME);
expect(body.error).toEqual('class name mismatch between WrongClassName and NewClass');
});
});
it('refuses to add fields to non-existent classes', done => {
request.put({
url: 'http://localhost:8378/1/schemas/NoClass',
headers: masterKeyHeaders,
json: true,
body: {
fields: {
newField: {type: 'String'}
}
}
}, (error, response, body) => {
expect(response.statusCode).toEqual(400);
expect(body.code).toEqual(Parse.Error.INVALID_CLASS_NAME);
expect(body.error).toEqual('class NoClass does not exist');
done();
});
});
it('put with no modifications returns all fields', done => {
var obj = hasAllPODobject();
obj.save()
.then(() => {
request.put({
url: 'http://localhost:8378/1/schemas/HasAllPOD'
headers: masterKeyHeaders,
json: true,
body: {},
}, (error, response, body) => {
expect(body).toEqual(plainOldDataSchema);
done();
});
});
});
it('lets you add fields', done => {
request.post({
url: 'http://localhost:8378/1/schemas/NewClass',
headers: masterKeyHeaders,
json: true,
body: {},
}, (error, response, body) => {
request.put({
url: 'http://localhost:8378/1/schemas/NewClass',
headers: masterKeyHeaders,
json: true,
body: {
fields: {
newField: {type: 'String'}
}
}
}, (error, response, body) => {
expect(body).toEqual('blah');
request.get({
url: 'http://localhost:8378/1/schemas/NewClass',
headers: masterKeyHeaders,
json: true,
}, (error, response, body) => {
expect(body).toEqual('blah');
done();
});
});
})
});
}); });

View File

@@ -7,6 +7,23 @@ var express = require('express'),
var router = new PromiseRouter(); var router = new PromiseRouter();
function masterKeyRequiredResponse() {
return Promise.resolve({
status: 401,
response: {error: 'master key not specified'},
})
}
function classNameMismatchResponse(bodyClass, pathClass) {
return Promise.resolve({
status: 400,
response: {
code: Parse.Error.INVALID_CLASS_NAME,
error: 'class name mismatch between ' + bodyClass + ' and ' + pathClass,
}
});
}
function mongoFieldTypeToSchemaAPIType(type) { function mongoFieldTypeToSchemaAPIType(type) {
if (type[0] === '*') { if (type[0] === '*') {
return { return {
@@ -55,10 +72,7 @@ function mongoSchemaToSchemaAPIResponse(schema) {
function getAllSchemas(req) { function getAllSchemas(req) {
if (!req.auth.isMaster) { if (!req.auth.isMaster) {
return Promise.resolve({ return masterKeyRequiredResponse();
status: 401,
response: {error: 'master key not specified'},
});
} }
return req.config.database.collection('_SCHEMA') return req.config.database.collection('_SCHEMA')
.then(coll => coll.find({}).toArray()) .then(coll => coll.find({}).toArray())
@@ -69,10 +83,7 @@ function getAllSchemas(req) {
function getOneSchema(req) { function getOneSchema(req) {
if (!req.auth.isMaster) { if (!req.auth.isMaster) {
return Promise.resolve({ return masterKeyRequiredResponse();
status: 401,
response: {error: 'unauthorized'},
});
} }
return req.config.database.collection('_SCHEMA') return req.config.database.collection('_SCHEMA')
.then(coll => coll.findOne({'_id': req.params.className})) .then(coll => coll.findOne({'_id': req.params.className}))
@@ -88,20 +99,11 @@ function getOneSchema(req) {
function createSchema(req) { function createSchema(req) {
if (!req.auth.isMaster) { if (!req.auth.isMaster) {
return Promise.resolve({ return masterKeyRequiredResponse();
status: 401,
response: {error: 'master key not specified'},
});
} }
if (req.params.className && req.body.className) { if (req.params.className && req.body.className) {
if (req.params.className != req.body.className) { if (req.params.className != req.body.className) {
return Promise.resolve({ return classNameMismatchResponse(req.body.className, req.params.className);
status: 400,
response: {
code: Parse.Error.INVALID_CLASS_NAME,
error: 'class name mismatch between ' + req.body.className + ' and ' + req.params.className,
},
});
} }
} }
var className = req.params.className || req.body.className; var className = req.params.className || req.body.className;
@@ -123,9 +125,38 @@ function createSchema(req) {
})); }));
} }
function modifySchema(req) {
if (!req.auth.isMaster) {
return masterKeyRequiredResponse();
}
if (req.body.className && req.body.className != req.params.className) {
return classNameMismatchResponse(req.body.className, req.path.className);
}
if (!req.body.fields) {
req.body.fields = {};
}
return req.config.database.loadSchema()
.then(schema => schema.hasClass(req.params.className))
.then(hasClass => {
if (!hasClass) {
return Promise.resolve({
status: 400,
response: {
code: Parse.Error.INVALID_CLASS_NAME,
error: 'class ' + req.params.className + ' does not exist',
}
});
}
});
}
router.route('GET', '/schemas', getAllSchemas); router.route('GET', '/schemas', getAllSchemas);
router.route('GET', '/schemas/:className', getOneSchema); router.route('GET', '/schemas/:className', getOneSchema);
router.route('POST', '/schemas', createSchema); router.route('POST', '/schemas', createSchema);
router.route('POST', '/schemas/:className', createSchema); router.route('POST', '/schemas/:className', createSchema);
router.route('PUT', '/schemas/:className', modifySchema);
module.exports = router; module.exports = router;