fix: prevent access to docs in trash from deleted private collections (#2431)

* Check for collection in deleted document

* Add tests

* Use update policy

* Set paranoid to false when fetching deleted doc

* Update policy
This commit is contained in:
Saumya Pandey
2021-08-26 09:35:59 +05:30
committed by GitHub
parent d335670b91
commit 22ba4d0f48
4 changed files with 77 additions and 2 deletions

View File

@ -585,6 +585,7 @@ async function loadDocument({
} }
if (document.deletedAt) { if (document.deletedAt) {
// don't send data if user cannot restore deleted doc
authorize(user, "restore", document); authorize(user, "restore", document);
} else { } else {
authorize(user, "read", document); authorize(user, "read", document);

View File

@ -98,6 +98,74 @@ describe("#documents.info", () => {
expect(share.lastAccessedAt).toBeTruthy(); expect(share.lastAccessedAt).toBeTruthy();
}); });
it("should not return document of a deleted collection, when the user was absent in the collection", async () => {
const user = await buildUser();
const user2 = await buildUser({
teamId: user.teamId,
});
const collection = await buildCollection({
permission: null,
teamId: user.teamId,
createdById: user.id,
});
const doc = await buildDocument({
collectionId: collection.id,
teamId: user.teamId,
userId: user.id,
});
await server.post("/api/collections.delete", {
body: {
id: collection.id,
token: user.getJwtToken(),
},
});
const res = await server.post("/api/documents.info", {
body: {
id: doc.id,
token: user2.getJwtToken(),
},
});
expect(res.status).toEqual(403);
});
it("should return document of a deleted collection, when the user was present in the collection", async () => {
const user = await buildUser();
const collection = await buildCollection({
permission: null,
teamId: user.teamId,
createdById: user.id,
});
const doc = await buildDocument({
collectionId: collection.id,
teamId: user.teamId,
userId: user.id,
});
await server.post("/api/collections.delete", {
body: {
id: collection.id,
token: user.getJwtToken(),
},
});
const res = await server.post("/api/documents.info", {
body: {
id: doc.id,
token: user.getJwtToken(),
},
});
const body = await res.json();
expect(res.status).toEqual(200);
expect(body.data.id).toEqual(doc.id);
});
describe("apiVersion=2", () => { describe("apiVersion=2", () => {
it("should return sharedTree from shareId", async () => { it("should return sharedTree from shareId", async () => {
const { document, collection, user } = await seed(); const { document, collection, user } = await seed();

View File

@ -163,7 +163,7 @@ Document.associate = (models) => {
}, },
}, },
}); });
Document.addScope("withCollection", (userId) => { Document.addScope("withCollection", (userId, paranoid = true) => {
if (userId) { if (userId) {
return { return {
include: [ include: [
@ -172,6 +172,7 @@ Document.associate = (models) => {
method: ["withMembership", userId], method: ["withMembership", userId],
}), }),
as: "collection", as: "collection",
paranoid,
}, },
], ],
}; };
@ -221,7 +222,7 @@ Document.findByPk = async function (id, options = {}) {
const scope = this.scope( const scope = this.scope(
"withUnpublished", "withUnpublished",
{ {
method: ["withCollection", options.userId], method: ["withCollection", options.userId, options.paranoid],
}, },
{ {
method: ["withViews", options.userId], method: ["withViews", options.userId],

View File

@ -135,6 +135,11 @@ allow(User, "permanentDelete", Document, (user, document) => {
allow(User, "restore", Document, (user, document) => { allow(User, "restore", Document, (user, document) => {
if (user.isViewer) return false; if (user.isViewer) return false;
if (!document.deletedAt) return false; if (!document.deletedAt) return false;
if (document.collection && cannot(user, "update", document.collection)) {
return false;
}
return user.teamId === document.teamId; return user.teamId === document.teamId;
}); });