Allennick
Allennick

Reputation: 487

Cannot check a firestore document from cloud storage ruels

I'm writing Cloud Storage rules for my Firebase project but I'm having a problem with a custom function. I have a collection in Firestore called "boats" that includes the admin users of my app. So all the documents in boats belong to admin accounts. These are my rules:

rules_version = '2';
service firebase.storage {
  
  match /b/{bucket}/o {
    function isPdf() {
    return request.resource.contentType.matches('application/pdf');
  }
  function isOwner(boatId) {
    return request.auth.uid == boatId;
  }
  function isBoat(boatId) {
    return firestore.exists(/databases/$(database)/documents/boats/$(boatId)) && request.auth.uid == boatId;
  }
    match /boats/{boatId} {      
      allow delete, update: if isOwner(boatId);

      match /pdfs/{pdfId} {
        allow create: if isBoat(request.auth.uid);
        allow read: if true;
        allow delete: if isOwner(boatId);
      }
    }
  }
}

I'm writing my unit tests but one of them is failing, this is the faulty one:

test('should let the boat upload a pdf inside his folder in storage', async () => {
    const [boat] = rulesTesting.getBoatsUID();
    const authenticatedContext = testingEnvironment.authenticatedContext(boat);
    const storage = authenticatedContext.storage();
    const pdfRef = storage.ref(`boats/${boat}/pdfs/test.pdf`);
    const filePath = __dirname + '/blank.pdf';
    const file = fs.readFileSync(filePath);
    const isUserABoat = await isBoat(boat);
    
    expect(isUserABoat).toBe(true);
    await assertSucceeds(
        uploadBytes(pdfRef, file, { contentType: 'application/pdf' })
    );
});

This test fails with this message:

FirebaseError: Firebase Storage: User does not have permission to access 'boats/UMfO7ywISlNrQkywo9ODEXt2zUm1/pdfs/test.pdf'. (storage/unauthorized)

I don't know why, everything seems correct. The line:

expect(isUserABoat).toBe(true)

passes, so I'm sure that the UID I'm using is a boat. I'm starting the tests with this command:

firebase emulators:exec --import ./firestore_backup/2023-04-24T11:34:08_97940 "npm run test ./src/tests/storageRules/boats.test.ts"

Upvotes: 0

Views: 20

Answers (1)

Allennick
Allennick

Reputation: 487

So after reading a second time the documentation about Firestore integration in Cloud Storage rules I've found out that the bug was inside the "isBoat" function. Here's the correct rule:

 function isBoat(boatId) {
    return firestore.exists(/databases/(default)/documents/boats/$(boatId)) && request.auth.uid == boatId;
  }

Upvotes: 0

Related Questions