mirror of
https://github.com/HeyPuter/puter.git
synced 2026-08-24 15:07:17 +00:00
test(share): cover access inherited from a parent folder
This commit is contained in:
@@ -66,6 +66,32 @@ describe('ShareService', () => {
|
||||
return entry;
|
||||
};
|
||||
|
||||
/** A directory and a file inside it, so the file inherits the folder's shares. */
|
||||
const makeDirWithFile = async (owner: { id: number; username: string }) => {
|
||||
const dirUuid = uuidv4();
|
||||
const dirName = `d-${dirUuid.slice(0, 8)}`;
|
||||
const dirPath = `/${owner.username}/${dirName}`;
|
||||
const fileUuid = uuidv4();
|
||||
const fileName = `f-${fileUuid.slice(0, 8)}.txt`;
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
|
||||
await server.clients.db.write(
|
||||
'INSERT INTO `fsentries` (`uuid`, `name`, `path`, `user_id`, `is_dir`, `modified`) VALUES (?, ?, ?, ?, 1, ?)',
|
||||
[dirUuid, dirName, dirPath, owner.id, now],
|
||||
);
|
||||
await server.clients.db.write(
|
||||
'INSERT INTO `fsentries` (`uuid`, `name`, `path`, `user_id`, `is_dir`, `modified`) VALUES (?, ?, ?, ?, 0, ?)',
|
||||
[fileUuid, fileName, `${dirPath}/${fileName}`, owner.id, now],
|
||||
);
|
||||
|
||||
const dir = await server.stores.fsEntry.getEntryByPath(dirPath);
|
||||
const file = await server.stores.fsEntry.getEntryByPath(
|
||||
`${dirPath}/${fileName}`,
|
||||
);
|
||||
if (!dir || !file) throw new Error('fsentries not created');
|
||||
return { dir, file };
|
||||
};
|
||||
|
||||
const canRead = async (actor: Actor, path: string) =>
|
||||
server.services.acl.check(
|
||||
actor,
|
||||
@@ -242,6 +268,61 @@ describe('ShareService', () => {
|
||||
).toBe(delegate.user.username);
|
||||
});
|
||||
|
||||
it('reports a share on a file as inherited from the folder', async () => {
|
||||
const owner = await makeUser();
|
||||
const recipient = await makeUser();
|
||||
const { dir, file } = await makeDirWithFile(owner.user);
|
||||
|
||||
await share(owner.actor, {
|
||||
uid: dir.uuid,
|
||||
recipient: { email: recipient.email },
|
||||
mode: 'read',
|
||||
});
|
||||
|
||||
// Nobody was granted the file itself, so its own rows are empty — but
|
||||
// the recipient can reach it, and the owner has to be told so.
|
||||
const rows = await server.services.share.listSharesOf(owner.actor, {
|
||||
uid: file.uuid,
|
||||
});
|
||||
const row = rows.find(
|
||||
(r) => r.holder.username === recipient.user.username,
|
||||
);
|
||||
expect(row).toBeDefined();
|
||||
expect(row?.inheritedFrom).toBe(dir.path);
|
||||
expect(row?.mode).toBe('read');
|
||||
expect(await canRead(recipient.actor, file.path)).toBe(true);
|
||||
});
|
||||
|
||||
it('marks a share on the item itself as not inherited', async () => {
|
||||
const owner = await makeUser();
|
||||
const viaFolder = await makeUser();
|
||||
const direct = await makeUser();
|
||||
const { dir, file } = await makeDirWithFile(owner.user);
|
||||
|
||||
await share(owner.actor, {
|
||||
uid: dir.uuid,
|
||||
recipient: { email: viaFolder.email },
|
||||
mode: 'read',
|
||||
});
|
||||
await share(owner.actor, {
|
||||
uid: file.uuid,
|
||||
recipient: { email: direct.email },
|
||||
mode: 'write',
|
||||
});
|
||||
|
||||
const rows = await server.services.share.listSharesOf(owner.actor, {
|
||||
uid: file.uuid,
|
||||
});
|
||||
expect(
|
||||
rows.find((r) => r.holder.username === direct.user.username)
|
||||
?.inheritedFrom,
|
||||
).toBeNull();
|
||||
expect(
|
||||
rows.find((r) => r.holder.username === viaFolder.user.username)
|
||||
?.inheritedFrom,
|
||||
).toBe(dir.path);
|
||||
});
|
||||
|
||||
it('lets a delegate clear only what it issued', async () => {
|
||||
const owner = await makeUser();
|
||||
const delegate = await makeUser();
|
||||
|
||||
Reference in New Issue
Block a user