这是我对stackoverflow提出的第一个问题,所以请让我知道我是否缺少该问题的某些方面,这是优选的还是必需的。
我的目标是了解当创建的文档缺少下面列出的Firestore规则要求的字段时,为什么下面显示的Mocha测试通过了。
摩卡测试代码(请注意,项目ID已检查且正在运行,但此处省略)
const assert = require("assert");
const firebase = require("@firebase/rules-unit-testing");
const { firestore } = require("firebase-admin");
const { debug } = require("console");
const MY_PROJECT_ID = "####";
const myID = "user_abc";
const theirID = "user_def";
const myAuth = {uid: myID, email: "[email protected]"};
const theirAuth = {uid: theirID};
function getFirestore(auth) {
return firebase.initializeTestApp({projectId: MY_PROJECT_ID, auth: auth}).firestore();
}
function getAdminFirestore() {
return firebase.initializeAdminApp({projectId: MY_PROJECT_ID}).firestore();
}
beforeEach(async ()=>{
await firebase.clearFirestoreData({projectId:MY_PROJECT_ID});
});
describe("Our Social App", () => {
it("Can overwrite an existing post with allowed fields", async()=>{
const postPath = "/posts/post_123";
const admin = getAdminFirestore();
await admin.doc(postPath).set({authorID:myID, content:"content",
visibility:"private",
headline:"headline"});
const db = getFirestore(myAuth);
const docRef = db.doc(postPath);
await firebase.assertSucceeds(docRef.set({}));
});
});
after(async ()=>{
await firebase.clearFirestoreData({projectId:MY_PROJECT_ID});
});
消防站规则
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
function documentFieldsCheckOut(requiredFields, allowedFields){
let requiredAndAllowed = requiredFields.concat(allowedFields);
return request.resource.data.keys().hasAll(requiredFields) &&
request.resource.data.keys().hasOnly(requiredAndAllowed);
}
function updateHasOnlyAllowedFields(allowedFields){
return debug(request.resource.data.keys()).hasOnly(allowedFields);
}
match /{document=**} {
allow read, write: if false;
}
match /posts/{postID} {
allow update: if ((resource.data.authorID == request.auth.uid) || userIsModerator())
&& updateHasOnlyAllowedFields(["visibility", "content"]);
allow create: if (request.resource.data.authorID == request.auth.uid) &&
documentFieldsCheckOut(["authorID", "content", "visibility", "headline"],
["photo", "location", "tags"]);
}
}
}
注意:注释掉await admin.doc(postPath).set({authorID:myID, content:"content", visibility:"private", headline:"headline"});
会导致测试按预期失败。
此外,将.set更改为.updateawait firebase.assertSucceeds(docRef.set({}));
也会导致测试按预期失败。
如果我对您的理解正确,那么您会问为什么此呼叫成功:
const admin = getAdminFirestore();
admin.doc(postPath).set({authorID:myID, content:"content",
visibility:"private",
headline:"headline"});
使用管理特权的调用会绕过数据库的安全规则。因此,无论您使用什么安全规则,此调用都不会被他们拒绝。
第二个写操作是不同的:
const db = getFirestore(myAuth);
const docRef = db.doc(postPath);
docRef.set({})
这次,据我所知,您将通过非管理员引用,这意味着写入必须遵守安全规则才能被接受。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句