From 92f99f859281729fac9783efd0b0e0869b5a5657 Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Sun, 4 Sep 2016 10:17:13 -0400 Subject: [PATCH 1/4] Adds repro for issue #2246 --- spec/schemas.spec.js | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/spec/schemas.spec.js b/spec/schemas.spec.js index 83f7aa45b0..2b8813e4e6 100644 --- a/spec/schemas.spec.js +++ b/spec/schemas.spec.js @@ -1628,4 +1628,41 @@ describe('schemas', () => { done(); }); }); + + it('regression test for #2246', done => { + let profile = new Parse.Object('UserProfile'); + let user = new Parse.User(); + function initialize() { + return user.save({ + username: 'user', + password: 'password' + }).then(() => { + return profile.save({user}).then(() => { + return user.save({ + userProfile: profile + }, {useMasterKey: true}); + }); + }); + } + + initialize().then(() => { + return setPermissionsOnClass('UserProfile', { + 'readUserFields': ['user'], + 'writeUserFields': ['user'] + }, true); + }).then(() => { + return Parse.User.logIn('user', 'password') + }).then(() => { + let query = new Parse.Query('_User'); + query.include('userProfile'); + return query.get(user.id); + }).then((user) => { + console.log(user.toJSON()); + expect(user.get('userProfile')).not.toBeUndefined(); + done(); + }, (err) => { + jfail(err); + done(); + }); + }); }); From 2efa2f4a844bdefb99662428e63ae6ffafffdca9 Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Sun, 4 Sep 2016 10:18:00 -0400 Subject: [PATCH 2/4] Provide fix for issue #2246 --- src/Controllers/DatabaseController.js | 1 + src/RestQuery.js | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Controllers/DatabaseController.js b/src/Controllers/DatabaseController.js index 4cfe679105..618d304795 100644 --- a/src/Controllers/DatabaseController.js +++ b/src/Controllers/DatabaseController.js @@ -859,6 +859,7 @@ DatabaseController.prototype.addPointerPermissions = function(schema, className, // the ACL should have exactly 1 user if (perms && perms[field] && perms[field].length > 0) { // No user set return undefined + // If the length is > 1, that means we didn't dedup users correctly if (userACL.length != 1) { return; } diff --git a/src/RestQuery.js b/src/RestQuery.js index 0dc95ff341..5e919f9c4a 100644 --- a/src/RestQuery.js +++ b/src/RestQuery.js @@ -149,8 +149,8 @@ RestQuery.prototype.getUserAndRoleACL = function() { return Promise.resolve(); } return this.auth.getUserRoles().then((roles) => { - roles.push(this.auth.user.id); - this.findOptions.acl = roles; + // Concat with the roles to prevent duplications on multiple calls + this.findOptions.acl = this.findOptions.acl.concat(roles); return Promise.resolve(); }); }; From f7c5ce8a3db8fe47e6ece7b486ca18871d68d4b3 Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Sun, 4 Sep 2016 12:10:43 -0400 Subject: [PATCH 3/4] Nit with Set to deduplicate the acl array --- src/RestQuery.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/RestQuery.js b/src/RestQuery.js index 5e919f9c4a..0c28014d6a 100644 --- a/src/RestQuery.js +++ b/src/RestQuery.js @@ -150,7 +150,8 @@ RestQuery.prototype.getUserAndRoleACL = function() { } return this.auth.getUserRoles().then((roles) => { // Concat with the roles to prevent duplications on multiple calls - this.findOptions.acl = this.findOptions.acl.concat(roles); + const aclSet = new Set([].concat(this.findOptions.acl, roles)); + this.findOptions.acl = Array.from(aclSet); return Promise.resolve(); }); }; From adbb53016da5220be36aa818d8d9ebce558f3e65 Mon Sep 17 00:00:00 2001 From: Florent Vilmart Date: Sun, 4 Sep 2016 13:08:43 -0400 Subject: [PATCH 4/4] remove debuging console.log --- spec/schemas.spec.js | 1 - 1 file changed, 1 deletion(-) diff --git a/spec/schemas.spec.js b/spec/schemas.spec.js index 2b8813e4e6..0acf3ac043 100644 --- a/spec/schemas.spec.js +++ b/spec/schemas.spec.js @@ -1657,7 +1657,6 @@ describe('schemas', () => { query.include('userProfile'); return query.get(user.id); }).then((user) => { - console.log(user.toJSON()); expect(user.get('userProfile')).not.toBeUndefined(); done(); }, (err) => {