Firestore Rules multi organization multi user access rights list help

79 views
Skip to first unread message

Thomas Gangsøy

unread,
Sep 23, 2018, 10:48:12 AM9/23/18
to Firebase Google Group

Hello.

I am trying to set up a ruleset for a new Firestore project where we have the following root collections:

users
organisation

Under users we have users/userid/ar/organisationid (ar for access rights)

This document should define what access rights the user have for a given organisation. The point being that many users can have access to one or more organisation in this saas application.

I want all the documents and all the subcollections under the organisation to be checked agains this access right.

This works perfectly get and write, but listing of data gives an access error, and the only way i found to restrict the list data is to add an array on the document that list the users, and also filter on this client side. This is not a solution that is maintainable for production since there will be alot of subcollections with many documents.

Is there any suggestions? Any other way i can make the listing work for firestore? Is there better way to structure the data, or anything I am missing?

Only other way i can see is to use functions to do the check server side for the listing, but then we loose the awesome stuff in @angular/fire.

Filtering client side is not good enough security.

Thank you.

Rules as of now:

service cloud.firestore {
  match
/databases/{database}/documents {
 
    match
/users/{userId} {
      allow read
, write: if request.auth.uid == userId;
      match
/ar/{organisationDoc} {
        allow read
: if request.auth.uid == userId;
        allow write
: if false;
     
}
   
}    
   
   
// read
    match
/organisations/{oId} {
      allow
get: if exists(/databases/$(database)/documents/users/$(request.auth.uid)/ar/$(oId));
      allow list
: if request.auth.uid in resource.data.users;
     
      match
/{all=**} {
        allow
get: if exists(/databases/$(database)/documents/users/$(request.auth.uid)/ar/$(oId));
        allow list
: if request.auth.uid in resource.data.users;
     
}
   
}
   
   
// write
    match
/organisations/{oId} {
      allow create
: if get(/databases/$(database)/documents/users/$(request.auth.uid)/ar/$(oId)).data.create == true;
      allow update
: if get(/databases/$(database)/documents/users/$(request.auth.uid)/ar/$(oId)).data.update == true;
      allow
delete: if get(/databases/$(database)/documents/users/$(request.auth.uid)/ar/$(oId)).data.delete == true;

      match
/{all=**} {
        allow create
: if get(/databases/$(database)/documents/users/$(request.auth.uid)/ar/$(oId)).data.create == true;
        allow update
: if get(/databases/$(database)/documents/users/$(request.auth.uid)/ar/$(oId)).data.update == true;
        allow
delete: if get(/databases/$(database)/documents/users/$(request.auth.uid)/ar/$(oId)).data.delete == true;
     
}
   
}
   
 
}
}


Reply all
Reply to author
Forward
0 new messages