Skip to content

Commit f8b1d9f

Browse files
committed
Merge remote-tracking branch 'upstream/master' into test-configurations
2 parents 843f289 + 8441dd2 commit f8b1d9f

File tree

8 files changed

+101
-16
lines changed

8 files changed

+101
-16
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
## Parse Server Changelog
22

3+
### 2.1.2 (2/19/2016)
4+
5+
* Change: The S3 file adapter constructor requires a bucket name
6+
* Fix: Parse Query should throw if improperly encoded
7+
* Fix: Issue where roles were not used in some requests
8+
* Fix: serverURL will no longer default to api.parse.com/1
9+
310
### 2.1.1 (2/18/2016)
411

512
* Experimental: Schemas API support for DELETE operations

spec/ParseRole.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ describe('Parse Role testing', () => {
4949
}).then((x) => {
5050
x.set('foo', 'baz');
5151
// This should fail:
52-
return x.save();
52+
return x.save({},{sessionToken: ""});
5353
}).then((x) => {
5454
fail('Should not have been able to save.');
5555
}, (e) => {

spec/RestQuery.spec.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ var cache = require('../src/cache');
44
var Config = require('../src/Config');
55
var rest = require('../src/rest');
66

7+
var querystring = require('querystring');
8+
var request = require('request');
9+
710
var config = new Config('test');
811
var nobody = auth.nobody(config);
912

@@ -92,4 +95,49 @@ describe('rest query', () => {
9295
}).catch((error) => { console.log(error); });
9396
});
9497

98+
it('query with wrongly encoded parameter', (done) => {
99+
rest.create(config, nobody, 'TestParameterEncode', {foo: 'bar'}
100+
).then(() => {
101+
return rest.create(config, nobody,
102+
'TestParameterEncode', {foo: 'baz'});
103+
}).then(() => {
104+
var headers = {
105+
'X-Parse-Application-Id': 'test',
106+
'X-Parse-REST-API-Key': 'rest'
107+
};
108+
request.get({
109+
headers: headers,
110+
url: 'http://localhost:8378/1/classes/TestParameterEncode?'
111+
+ querystring.stringify({
112+
where: '{"foo":{"$ne": "baz"}}',
113+
limit: 1
114+
}).replace('=', '%3D'),
115+
}, (error, response, body) => {
116+
expect(error).toBe(null);
117+
var b = JSON.parse(body);
118+
expect(b.code).toEqual(Parse.Error.INVALID_QUERY);
119+
expect(b.error).toEqual('Improper encode of parameter');
120+
done();
121+
});
122+
}).then(() => {
123+
var headers = {
124+
'X-Parse-Application-Id': 'test',
125+
'X-Parse-REST-API-Key': 'rest'
126+
};
127+
request.get({
128+
headers: headers,
129+
url: 'http://localhost:8378/1/classes/TestParameterEncode?'
130+
+ querystring.stringify({
131+
limit: 1
132+
}).replace('=', '%3D'),
133+
}, (error, response, body) => {
134+
expect(error).toBe(null);
135+
var b = JSON.parse(body);
136+
expect(b.code).toEqual(Parse.Error.INVALID_QUERY);
137+
expect(b.error).toEqual('Improper encode of parameter');
138+
done();
139+
});
140+
});
141+
});
142+
95143
});

src/Auth.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ Auth.prototype.getUserRoles = function() {
8080
return Promise.resolve(this.userRoles);
8181
}
8282
if (this.rolePromise) {
83-
return rolePromise;
83+
return this.rolePromise;
8484
}
8585
this.rolePromise = this._loadRoles();
8686
return this.rolePromise;

src/RestWrite.js

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ function RestWrite(config, auth, className, query, data, originalData) {
2727
this.auth = auth;
2828
this.className = className;
2929
this.storage = {};
30+
this.runOptions = {};
3031

3132
if (!query && data.objectId) {
3233
throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, 'objectId ' +
@@ -66,6 +67,8 @@ function RestWrite(config, auth, className, query, data, originalData) {
6667
// status and location are optional.
6768
RestWrite.prototype.execute = function() {
6869
return Promise.resolve().then(() => {
70+
return this.getUserAndRoleACL();
71+
}).then(() => {
6972
return this.validateSchema();
7073
}).then(() => {
7174
return this.handleInstallation();
@@ -88,6 +91,25 @@ RestWrite.prototype.execute = function() {
8891
});
8992
};
9093

94+
// Uses the Auth object to get the list of roles, adds the user id
95+
RestWrite.prototype.getUserAndRoleACL = function() {
96+
if (this.auth.isMaster) {
97+
return Promise.resolve();
98+
}
99+
100+
this.runOptions.acl = ['*'];
101+
102+
if( this.auth.user ){
103+
return this.auth.getUserRoles().then((roles) => {
104+
roles.push(this.auth.user.id);
105+
this.runOptions.acl = this.runOptions.acl.concat(roles);
106+
return Promise.resolve();
107+
});
108+
}else{
109+
return Promise.resolve();
110+
}
111+
};
112+
91113
// Validates this operation against the schema.
92114
RestWrite.prototype.validateSchema = function() {
93115
return this.config.database.validateObject(this.className, this.data);
@@ -690,18 +712,10 @@ RestWrite.prototype.runDatabaseOperation = function() {
690712
throw new Parse.Error(Parse.Error.INVALID_ACL, 'Invalid ACL.');
691713
}
692714

693-
var options = {};
694-
if (!this.auth.isMaster) {
695-
options.acl = ['*'];
696-
if (this.auth.user) {
697-
options.acl.push(this.auth.user.id);
698-
}
699-
}
700-
701715
if (this.query) {
702716
// Run an update
703717
return this.config.database.update(
704-
this.className, this.query, this.data, options).then((resp) => {
718+
this.className, this.query, this.data, this.runOptions).then((resp) => {
705719
this.response = resp;
706720
this.response.updatedAt = this.updatedAt;
707721
});
@@ -714,7 +728,7 @@ RestWrite.prototype.runDatabaseOperation = function() {
714728
this.data.ACL = ACL;
715729
}
716730
// Run a create
717-
return this.config.database.create(this.className, this.data, options)
731+
return this.config.database.create(this.className, this.data, this.runOptions)
718732
.then(() => {
719733
var resp = {
720734
objectId: this.data.objectId,

src/Routers/ClassesRouter.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,22 @@
22
import PromiseRouter from '../PromiseRouter';
33
import rest from '../rest';
44

5+
import url from 'url';
6+
57
export class ClassesRouter {
68
// Returns a promise that resolves to a {response} object.
79
handleFind(req) {
810
let body = Object.assign(req.body, req.query);
911
let options = {};
12+
let allowConstraints = ['skip', 'limit', 'order', 'count', 'keys',
13+
'include', 'redirectClassNameForKey', 'where'];
14+
15+
for (var key in body) {
16+
if (allowConstraints.indexOf(key) === -1) {
17+
throw new Parse.Error(Parse.Error.INVALID_QUERY, 'Improper encode of parameter');
18+
}
19+
}
20+
1021
if (body.skip) {
1122
options.skip = Number(body.skip);
1223
}

src/index.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ function ParseServer({
7272
facebookAppIds = [],
7373
enableAnonymousUsers = true,
7474
oauth = {},
75-
serverURL,
75+
serverURL = '',
7676
}) {
7777
if (!appId || !masterKey) {
7878
throw 'You must provide an appId and masterKey!';
@@ -128,9 +128,7 @@ function ParseServer({
128128

129129
// Initialize the node client SDK automatically
130130
Parse.initialize(appId, javascriptKey, masterKey);
131-
if (serverURL) {
132-
Parse.serverURL = serverURL;
133-
}
131+
Parse.serverURL = serverURL;
134132

135133
// This app serves the Parse API directly.
136134
// It's the equivalent of https://api.parse.com/1 in the hosted Parse API.

src/rest.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,19 @@ function del(config, auth, className, objectId) {
5656
});
5757
}
5858
return Promise.resolve({});
59+
}).then(() => {
60+
if (!auth.isMaster) {
61+
return auth.getUserRoles();
62+
}else{
63+
return Promise.resolve();
64+
}
5965
}).then(() => {
6066
var options = {};
6167
if (!auth.isMaster) {
6268
options.acl = ['*'];
6369
if (auth.user) {
6470
options.acl.push(auth.user.id);
71+
options.acl = options.acl.concat(auth.userRoles);
6572
}
6673
}
6774

0 commit comments

Comments
 (0)