Reputation: 97
I have the following simple rules set up in my firestore database.
service cloud.firestore {
match /databases/{database}/documents {
function isSignedIn() {
return request.auth != null;
}
match /organisations/{orgID}/{document=**} {
allow list, read, write: if isSignedIn() && request.auth.claims.organisation_uuid == orgID;
}
}
}
The intent is that any authenticated user can access all of the documents that are a part of their organisation. An example collection that I expect users to be able to access is the tasks subcollection shown below
"organisations": [
"$orgID": {
"tasks": [
"taskID1": {
...
},
"taskID2": {
...
},
]
}
The user is authenticating using a custom JWT token using a service account that looks like this
{
"iss":"[email protected]",
"sub":"[email protected]",
"aud":"$correct-audience-string",
"iat":1532937868,
"uid":"e13e07a8-f7f2-4c7a-a02f-be729601e62e",
"exp":1532941468,
"claims":{
"organisation_uuid":"9cb3ebae-d16e-4898-a784-f0aac513fcb8"
}
}
The claims section above corresponds to the request.auth.claims.organisation_uuid == orgID
rule from my db security rules.
Requests simulated in the firestore web console for a single document work fine but a query constructed using the flutter cloud_store
library that looks like this
Firestore.instance
.collection('organisations')
.document(technician.organisation_uuid)
.collection('tasks')
.where("assignee_uuid", isEqualTo: technician.uuid);
Results in the exception com.google.firebase.firestore.FirebaseFirestoreException: PERMISSION_DENIED: Missing or insufficient permissions.
-
I can't identify the problem with my rules as all the documents under that organisation should be accessible by the authenticated user. Any insight is gratefully appreciated.
Upvotes: 0
Views: 3470
Reputation: 97
So I think the problem with this is the .claims
part of my custom token not being available on the request object, I updated my rules to the following and everything works as expected
service cloud.firestore {
match /databases/{database}/documents {
function isSignedIn() {
return request.auth != null;
}
function isInTheCorrectOrganisation(orgID){
return get(/databases/$(database)/documents/organisations/$(orgID)/technicians/$(request.auth.uid)).data.organisation_uuid == orgID;
}
match /organisations/{orgID}/{document=**} {
allow read, write: if isSignedIn() && isInTheCorrectOrganisation(orgID);
}
}
}
It appears to me as though there's either a bug in how the custom JWT tokens claims are evaluated or I have misread the documentation, clarification would be great.
Upvotes: 1