Reputation: 487
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
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