Repository navigation
LiveQuery on Object Role Based don't send events for some users #5131
Description
Issue Description
When a Parse.User is linked in a more than 100 Parse.Role, a LiveQuery on a Role based Parse.Object send events in an unpredictable way, or even not sending events any more !
Steps to reproduce
Make a LiveQuery on Role Based Object with a Parse.User linked in more than 100 Parse.Role
Expected Results
The LiveQuery from the Parse.User receive events correctly
Actual Outcome
The LiveQuery from Parse.User not receive events or receive events in an unpredictable way
Environment Setup
-
Server
- parse-server version : 3, 3.1
- Operating System: Ubuntu LTS
- Hardware: VPS
- Localhost or remote server? (AWS, Heroku, Azure, Digital Ocean, etc): Remote
-
Database
- MongoDB version: 3
- Storage engine: AWS
- Hardware: VPS
- Localhost or remote server? (AWS, mLab, ObjectRocket, Digital Ocean, etc): remote
Logs/Trace
Logs For a User that have more than 100 Parse.Role
show that the
matchACLreturn false value
2018-10-17T19:05:06.909Z - Original null | Current {...,"ACL":{"role:xxxxxxxxx":{"read":true,"write":true}},"__type":"Object","className":"Aptitude","objectId":"xxxxxxxx"} | Match: false, true, false, false(isCurrentMatched) | Query: ClassName:fieldOfTheQuery|["valueForTheQuery"]
The ACL function fail because
isCurrentMatchedequal tofalse
Logs For a User that have less than 100 Parse.Role
show that the
matchACLreturntruevalue
2018-10-17T19:05:06.909Z - Original null | Current {...,"ACL":{"role:xxxxxxxxx":{"read":true,"write":true}},"__type":"Object","className":"Aptitude","objectId":"xxxxxxxx"} | Match: false, true, false, true(isCurrentMatched) | Query: ClassName:fieldOfTheQuery|["valueForTheQuery"]
The ACL function success because
isCurrentMatchedequal totrue
Investigation on Parse.Server 3.1.0
- Target File : Auth.js
- Target Function : getRolesForUser()
- Bug Identified : Parse.Query return just 100 results by default
Auth.prototype.getRolesForUser = function() {
if (this.config) {
const restWhere = {
users: {
__type: 'Pointer',
className: '_User',
objectId: this.user.id,
},
};
const query = new RestQuery(
this.config,
master(this.config),
'_Role',
restWhere,
{}
);
return query.execute().then(({ results }) => results);
}
//!!!!!!The Bug is right there
return new Parse.Query(Parse.Role)
.equalTo('users', this.user)
.find({ useMasterKey: true })
.then(results => results.map(obj => obj.toJSON()));
};- Fast Option for fix that works (tested on my env) : add a
.limit(99999) - Disadvantages : For a Parse.User with a lot (a lot) of Parse.Role, memory leak can appear
Auth.prototype.getRolesForUser = function() {
if (this.config) {
const restWhere = {
users: {
__type: 'Pointer',
className: '_User',
objectId: this.user.id,
},
};
const query = new RestQuery(
this.config,
master(this.config),
'_Role',
restWhere,
{}
);
return query.execute().then(({ results }) => results);
}
//!!!!!!The Bug is right there
return new Parse.Query(Parse.Role)
.limit(999999999)
.equalTo('users', this.user)
.find({ useMasterKey: true })
.then(results => results.map(obj => obj.toJSON()));
};@flovilmart what I was talking about on Twitter
Activity
flovilmart commentedon Oct 18, 2018
You should probably not have that many roles on a single user
flovilmart commentedon Oct 18, 2018
Jokes aside, we should use the .each instead of the query you’re right :) and use the iteration callback to populate an array of all roles. Is it something you’re be willing to make a Pr for?
Moumouls commentedon Oct 18, 2018
In effect
.each()is the appropriate solution. :)acinader commentedon Oct 18, 2018
This is about as good an example of a very simple, contained improvement imaginable.
flovilmart commentedon Oct 18, 2018
@Moumouls so what do you expect to happen? My best guest, the stale bot will close it :)
Moumouls commentedon Oct 18, 2018
Just to get back to the fact that a user should not have so much roles. I may not have fully understood the concept of roles.
In my case we could see it like this:
A user create a folder, this creates a corresponding role, then the person create a file in the current folder (child object) and the role referenced in the folder is then saved in the ACL of the file.
Then the user shares the folder with another user, this allows the new user to automatically access the files in the folder without performing a serial update of the ACLs of the files and potentially creating security holes
I use the Roles that way!
Is this a good use?
Moumouls commentedon Oct 18, 2018
@flovilmart we can mark it as a future improvement! but currently I can't do a patch, when I have more time, I could do a clean PR;)
flovilmart commentedon Oct 18, 2018
I don’t have the time to give you a clean answer
Fix Limitation Role parse-community#5131
Ensure all roles are properly loaded #5131 (#5132)
Moumouls commentedon Oct 20, 2018
Fixed by #5132
Ensure all roles are properly loaded parse-community#5131 (parse-comm…