mardi 26 mars 2019

Get Missing or insufficient permissions with get() and exists() rules on query

We tried to list all docs from an 'events' collection. (/event/{eventId}) in each event's doc, a property 'users' (array) exists with all user's id in event. We have another collection 'role' with the role of each user for each event. (/role/{eventId}/userRole/{userId})

We have permission to get one event with

db.collection('event').doc(eventId).get()

But when we tried (from android and web) to make query like

db.collection('event').where("users", "array-contains", user.uid).get()

we got FirebaseError: Missing or insufficient permissions.

Event's rules :

    match /event/{eventId} {
      allow read:
        if isAuth() && 
        inEvent(eventId, request.auth.uid);
      allow create: 
        if isAuth() &&
        checkEventName() &&
        isOwner(database) &&
        request.resource.data.users == [];
      allow update:
        if isAuth() &&
        resource.data.ownerId == request.auth.uid &&
        checkEventName() &&
        isOwner(database) &&
        request.resource.data.mediaCount == resource.data.mediaCount &&
        request.resource.data.users == resource.data.users;
      allow delete:
        if false;
    }

Role's rules :

    match /role/{roleId} {
      allow read: 
        if isAuth();
      allow write:
        if false;

      match /userRole/{userRoleId} {
        allow read:
          if isAuth() &&
          userRoleId == request.auth.uid;
        allow create:
          if isAuth() &&
          userRoleId == request.auth.uid && 
          exists(/databases/$(database)/documents/event/$(roleId)) &&
          request.resource.data.actual is number &&
          request.resource.data.actual >= 0 &&
          request.resource.data.actual <= 10 &&
          request.resource.data.previous is number &&
          request.resource.data.actual == request.resource.data.previous;
        allow update: 
          if isAuth() &&
          userRoleId == request.auth.uid &&
          request.resource.data.actual == 0 &&
          resource.data.actual != 0;
        allow delete: 
          if false;
      }
    }

The role id match the event id.

In event's read rule we have inEvent(eventId, request.auth.uid). When we write

function inEvent(eventID, userID) {
      return true;
}

the query works but if we try something like

return exists(/databases/$(database)/documents/role/$(eventID)/userRole/$(userID));

or

return get(/databases/$(database)/documents/role/$(eventID)/userRole/$(userID)).data.actual >= 10;

we always get permission error

We have checked all data and rules but we don't understand why we can get individual event but not list. What we doing wrong ? Can we use get() and exists() for list permissions ?




Aucun commentaire:

Enregistrer un commentaire