jkogara
jkogara

Reputation: 97

Flutter Firestore - PERMISSION_DENIED: Missing or insufficient permissions

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

Answers (1)

jkogara
jkogara

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

Related Questions