Hello, I am trying to define Rules in my app service for the following use case:
I want to limit the pool of documents in a collection that each user can access. I have set up custom user data for each user. One of the fields in the custom user data is an array with the ids of the documents that the user can access from the collection. My attempt to define Document Permissions on the collection seems to not be working:
{
"_id": {
"$in": "%%user.custom_data.allowed_ids"
}
}
Any ideas?
Hi,
Do you mind sending me your app URL (looks like https://realm.mongodb.com/groups/<group-id>/apps/<app-id>
) so I can take a further look? For context, we recently changed where and how flexible sync permissions are defined for new apps, and I’m interested in seeing if your app was affected by that change at all.
Thanks,
Jonathan
Hey @Damian_Danev,
I took a look at your app, and didn’t find anything immediately suspicious. Based off the way that you described it, I’m assuming that the above expression corresponds to the “Read Document Filter”. What was the specific behavior that you were seeing that caused a problem? Were there documents that were being sent down to the client that were not expected? Was there an error that your app was running into?
A few things I’d also like to confirm:
- In the custom user data, could you make sure that:
a. The linked user id field is a string
b. The allowed_ids field contains a list of ObjectIDs
- (If there are multiple roles defined in the rule) The role containing the above expression is being applied (we log which role is applied during a sync session, see below screenshot)
- The role does not inherit write access (ie, the “Write Document Filter” does not evaluate to true in the sync session)
Jonathan
Sorry, I should’ve been more specific.
This is a document inside collection plots:
{
"_id":{
"$oid":"63fe58578fd1b60e9636478a"
},
"name":"asdnd",
"gro_id":"63fb8bebe2f721ef732ad540"
}
This is a document inside the custom user data collection called users:
{
"_id":{
"$oid":"63fa9a794c4b020beaa5ff86"
},
"user_id":"63fa9a794c4b020beaa5ff81",
"email":"someemail",
"role":"scout",
"user_ids":[
""
],
"plots":[
"63fe58578fd1b60e9636478a"
]
}
This is a Rule I’ve applied to plots collection:
{
"roles": [
{
"name": "scout",
"apply_when": {
"%%user.custom_data.role": "scout"
},
"document_filters": {
"write": {
"_id": {
"$in": "%%user.custom_data.plots"
}
},
"read": {
"_id": {
"$in": "%%user.custom_data.plots"
}
}
},
"read": true,
"write": false,
"insert": false,
"delete": false,
"search": true
}
]
}
I just want users of a certain role to only be able to read documents whose ids are inside a field in the user’s custom data. With this setup, I do not get any documents on my React Native realm. I think I might be failing on the point you made about object ids being a string because I am comparing it to the plot object id:
"_id":{
"$oid":"63fa9a794c4b020beaa5ff86"
},
Yeah, I think converting plots
in the custom user data collection to be a list of ObjectIDs would potentially resolve the issue then. Let me know if that works!
I managed to solve the problem with the plots rules using strings only.
Now I have a similar problem with just the users collection. I want realm clients to be able to read user documents based on a list of user ids I provide for them in the same collection (user_ids)
Example:
inside the users collection I have these two users:
{
"_id":{
"$oid":"63fb8bebe2f721ef732ad540"
},
"user_id":"63fb8bebe2f721ef732ad534",
"email":"manager",
"role":"manager",
"user_ids":[
"63fa9a794c4b020beaa5ff81"
]
}
{
"_id":{
"$oid":"63fa9a794c4b020beaa5ff86"
},
"user_id":"63fa9a794c4b020beaa5ff81",
"email":"intern",
"role":"intern",
"user_ids":[]
}
I want to make a rule so that a manager can only read intern users that are associated with him through the user_ids field. (I am also open to other suggestions). Just in case it’s not clear: users is the custom user data collection that’s linked with the app users. user_id is the linked field that holds the id of the app user and is also a queryable field.
I thought this would be the correct rule:
{
"roles":[
{
"name":"manager",
"apply_when":{
"%%user.custom_data.role":"manager"
},
"document_filters":{
"write":{
"user_id":{
"$in":"%%user.custom_data.user_ids"
}
},
"read":{
"user_id":{
"$in":"%%user.custom_data.user_ids"
}
}
},
"read":true,
"write":true,
"insert":false,
"delete":false,
"search":true
},
]
}
But my mobile app just gets stuck loading when I want to sync as a manager user.
When I set the document rule to:
{
"roles":[
{
"name":"manager",
"apply_when":{
"%%user.custom_data.role":"manager"
},
"document_filters":{
"write":{
"user_id":{
"$in":["63fa9a794c4b020beaa5ff81"]
}
},
"read":{
"user_id":{
"$in":["63fa9a794c4b020beaa5ff81"]
}
}
},
"read":true,
"write":true,
"insert":false,
"delete":false,
"search":true
},
]
}
Then the app functions properly, but when using "$in":"%%user.custom_data.user_ids"
then it doesn’t work. Any idea why?
Okay. I think I found out what the problem was, even tho the solution puzzles me…
I had to add user_ids
as a queryable field
.