Skip to content

Commit 12f24fc

Browse files
committed
Turns out we can't have delete by object ID because of ACLs...
1 parent 8566734 commit 12f24fc

File tree

4 files changed

+36
-21
lines changed

4 files changed

+36
-21
lines changed

spec/ParseAPI.spec.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ describe('miscellaneous', function() {
3939
expect(data.get('password')).toBeUndefined();
4040
done();
4141
}, function(err) {
42-
console.log(err);
4342
fail(err);
43+
done();
4444
});
4545
});
4646

spec/ParseHooks.spec.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,9 @@ describe('Hooks', () => {
5858
.then((res) => {
5959
// Find again! but should be deleted
6060
return Parse.Hooks.getFunction("My-Test-Function")
61-
.then((res) => {
61+
.then(res => {
6262
fail("Failed to delete hook")
63+
fail(res)
6364
done();
6465
return Promise.resolve();
6566
}, (err) => {

src/Adapters/Storage/Mongo/MongoStorageAdapter.js

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -159,27 +159,38 @@ export class MongoStorageAdapter {
159159
.then(collection => collection.insertOne(mongoObject));
160160
}
161161

162-
// Remove the object with the given ID. If the object does not exist, reject with OBJECT_NOT_FOUND.
163-
// If there is a different type of error, reject with INTERNAL_SERVER_ERROR and a message
164-
// that doesn't leak info to the client.
165-
deleteObject(className, objectId) {
162+
// Remove all objects that match the given parse query. Parse Query should be in Parse Format.
163+
// If no objects match, reject with OBJECT_NOT_FOUND. If objects are found and deleted, resolve with nothing.
164+
// If there is some other error, reject with INTERNAL_SERVER_ERROR.
165+
166+
// Currently accepts the acl, schemaController, validate
167+
// for lecacy reasons, Parse Server should later integrate acl into the query. Database adapters
168+
// shouldn't know about acl.
169+
170+
// Currently resolves with empty object because thats what HooksController expects, but that should change.
171+
deleteObjectsByQuery(className, query, acl, schemaController, validate) {
166172
return this.adaptiveCollection(className)
167-
.then(collection => collection.deleteOne({ _id: objectId }))
168-
.then(({ deletedCount }) => {
169-
if (deletedCount === 1) {
170-
return Promise.resolve();
171-
} else {
173+
.then(collection => {
174+
let mongoWhere = transform.transformWhere(
175+
schemaController,
176+
className,
177+
query,
178+
{ validate }
179+
);
180+
if (acl) {
181+
mongoWhere = transform.addWriteACL(mongoWhere, acl);
182+
}
183+
return collection.deleteMany(mongoWhere)
184+
})
185+
.then(({ result }) => {
186+
if (result.n === 0) {
187+
172188
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Object not found.');
173189
}
174-
}, error => {
175-
throw new Parse.Error(Parse.Error.INTERNAL_SERVER_ERROR, 'Database adapter error.');
190+
return Promise.resolve({});
176191
});
177192
}
178193

179-
//
180-
deleteObjectsByQuery(className, query) {
181-
}
182-
183194
get transform() {
184195
return transform;
185196
}

src/Controllers/DatabaseController.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -284,17 +284,20 @@ DatabaseController.prototype.removeRelation = function(key, fromClassName, fromI
284284
// acl: a list of strings. If the object to be updated has an ACL,
285285
// one of the provided strings must provide the caller with
286286
// write permissions.
287-
DatabaseController.prototype.destroy = function(className, { objectId, ...query}, { acl } = {}) {
287+
DatabaseController.prototype.destroy = function(className, query, { acl } = {}) {
288288
const isMaster = acl !== undefined;
289289
const aclGroup = acl || [];
290290

291291
return this.loadSchema()
292292
.then(schemaController => {
293293
return (isMaster ? Promise.resolve() : schemaController.validatePermission(className, aclGroup, 'delete'))
294294
.then(() => {
295-
if (query !== {} || !objectId) {
296-
if (objectId) {
297-
query.objectId = objectId;
295+
// delete by query
296+
return this.adapter.deleteObjectsByQuery(className, query, acl, schemaController, !this.skipValidation)
297+
.catch(error => {
298+
// When deleting sessions while changing passwords, don't throw an error if they don't have any sessions.
299+
if (className === "_Session" && error.code === Parse.Error.OBJECT_NOT_FOUND) {
300+
return Promise.resolve({});
298301
}
299302

300303
// delete by query

0 commit comments

Comments
 (0)