Skip to content

Commit

Permalink
Fix: Add dbId to MakeFilePublicRequest to make shared files public (#63)
Browse files Browse the repository at this point in the history
  • Loading branch information
perfectmak authored Feb 26, 2021
1 parent 396377f commit 5445187
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 26 deletions.
95 changes: 75 additions & 20 deletions integration_tests/sharing_interactions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,31 @@ async function acceptNotification(inviteeStorage: UserStorage, notification: Not
});
}

const uploadTxtContent = async (
storage: UserStorage,
txtContent = 'Some manual text should be in the file',
fileName = 'top.txt'): Promise<{ txtContent: string; response: AddItemsEventData; }> => {
const uploadResponse = await storage.addItems({
bucket: 'personal',
files: [
{
path: fileName,
data: txtContent,
mimeType: 'plain/text',
},
],
});

const response = await new Promise<AddItemsEventData>((resolve) => {
uploadResponse.once('done', resolve);
});

return {
txtContent,
response,
};
};

describe('Users sharing data', () => {
it('users can share, accept and view shared files', async () => {
const { user: user1 } = await authenticateAnonymousUser();
Expand All @@ -52,26 +77,11 @@ describe('Users sharing data', () => {
const user2Pk = Buffer.from(user2.identity.public.pubKey).toString('hex');
const user3Pk = Buffer.from(user3.identity.public.pubKey).toString('hex');

const txtContent = 'Some manual text should be in the file';

const storage1 = new UserStorage(user1, TestStorageConfig);
const uploadResponse = await storage1.addItems({
bucket: 'personal',
files: [
{
path: 'top.txt',
data: txtContent,
mimeType: 'plain/text',
},
],
});

await new Promise<AddItemsEventData>((resolve) => {
uploadResponse.once('done', resolve);
});

await storage1.initMailbox();

await uploadTxtContent(storage1);

const storage2 = new UserStorage(user2, TestStorageConfig);
await storage2.initMailbox();

Expand Down Expand Up @@ -117,7 +127,7 @@ describe('Users sharing data', () => {
expect(received.notifications[0].relatedObject?.inviterPublicKey).to.equal(user1Pk);
expect(received.notifications[0].relatedObject?.itemPaths[0].bucket).to.equal('personal');
expect(received.notifications[0].relatedObject?.itemPaths[0].path).to.equal('/top.txt');
console.log('dbid: ', received.notifications[0].relatedObject?.itemPaths[0].dbId);
// console.log('dbid: ', received.notifications[0].relatedObject?.itemPaths[0].dbId);
expect(received.notifications[0].relatedObject?.itemPaths[0].dbId).not.to.be.null;
expect(received.notifications[0].relatedObject?.itemPaths[0].uuid).to.equal(ld.items[0].uuid);
expect(received.notifications[0].relatedObject?.itemPaths[0].bucketKey).not.to.be.null;
Expand All @@ -131,7 +141,6 @@ describe('Users sharing data', () => {
const storage3 = new UserStorage(user3, TestStorageConfig);
await storage3.initMailbox();

console.log('Resharing second time');
const share2Result = await storage2.shareViaPublicKey({
publicKeys: [{
id: '[email protected]',
Expand All @@ -144,12 +153,58 @@ describe('Users sharing data', () => {
}],
});

console.log('second share result: ', share2Result);
const secondReceivedNotifs = await storage3.getNotifications();
// accept the notification
await acceptNotification(storage3, secondReceivedNotifs.notifications[0], user2);
}).timeout(TestsDefaultTimeout);

it('should allow invited users to make file publicly accessible', async () => {
const { user: user1 } = await authenticateAnonymousUser();
const { user: user2 } = await authenticateAnonymousUser();
const user2Pk = Buffer.from(user2.identity.public.pubKey).toString('hex');
const storage1 = new UserStorage(user1, TestStorageConfig);
await storage1.initMailbox();
const storage2 = new UserStorage(user2, { ...TestStorageConfig, debugMode: true });
await storage2.initMailbox();

const { txtContent } = await uploadTxtContent(storage1);
await storage1.shareViaPublicKey({
publicKeys: [{
id: '[email protected]',
pk: user2Pk,
}],
paths: [{
bucket: 'personal',
path: '/top.txt',
}],
});

const received = await storage2.getNotifications();
await acceptNotification(storage2, received.notifications[0], user1);
// console.log('Accepted notification', { notif: received.notifications[0] });

// make shared file public
await storage2.setFilePublicAccess({
bucket: 'personal',
path: '/top.txt',
dbId: received.notifications[0].relatedObject?.itemPaths[0].dbId,
allowAccess: true,
});
// console.log('Made file publicly accessible');

// verify anonymous user can access file
const { user: anonymousUser } = await authenticateAnonymousUser();
const anonymousStorage = new UserStorage(anonymousUser, TestStorageConfig);

// console.log('Opening public file by uuid');
const fileResponse = await anonymousStorage.openFileByUuid({
uuid: received.notifications[0].relatedObject?.itemPaths[0].uuid || '',
});

const actualTxtContent = await fileResponse.consumeStream();
expect(new TextDecoder('utf8').decode(actualTxtContent)).to.equal(txtContent);
}).timeout(TestsDefaultTimeout);

it('users can receive sharing notifications subscription events', async () => {
const { user: user1 } = await authenticateAnonymousUser();
const { user: user2 } = await authenticateAnonymousUser();
Expand Down
5 changes: 5 additions & 0 deletions packages/storage/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,11 @@ export interface OpenUuidFileRequest {
export interface MakeFilePublicRequest {
path: string;
bucket: string;
/**
* DbId where file is location, optional but required for instances where the file is a shared file.
*
*/
dbId?: string;
/**
* Specifies if public access to file should be accessible.
*
Expand Down
19 changes: 13 additions & 6 deletions packages/storage/src/userStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -538,6 +538,7 @@ export class UserStorage {
throw new FileNotFoundError();
}

this.logger.info({ fileMetadata }, 'Opening file by uuid');
try {
client.withThread(fileMetadata.dbId);
const bucketKey = fileMetadata.bucketKey || '';
Expand Down Expand Up @@ -595,24 +596,30 @@ export class UserStorage {
public async setFilePublicAccess(request: MakeFilePublicRequest): Promise<void> {
const metadataStore = await this.getMetadataStore();
const client = this.getUserBucketsClient();
const bucket = await this.getOrCreateBucket(client, request.bucket);
const path = sanitizePath(request.path);
let metadata: FileMetadata | undefined;
if (request.dbId) {
metadata = await metadataStore.findFileMetadata(request.bucket, request.dbId, path);
client.withThread(request.dbId);
} else {
const bucket = await this.getOrCreateBucket(client, request.bucket);
metadata = await metadataStore.findFileMetadata(request.bucket, bucket.dbId, path);
}

const metadata = await metadataStore.findFileMetadata(bucket.slug, bucket.dbId, path);
this.logger.info({ metadata, request }, 'Request setFilePublicAccess');
if (metadata === undefined) {
throw new DirEntryNotFoundError(path, bucket.slug);
throw new DirEntryNotFoundError(path, request.bucket);
}

const roles = new Map();
if (request.allowAccess) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
await metadataStore.setFilePublic(metadata!);
await metadataStore.setFilePublic(metadata);
roles.set('*', PathAccessRole.PATH_ACCESS_ROLE_WRITER);
} else {
roles.set('*', PathAccessRole.PATH_ACCESS_ROLE_UNSPECIFIED);
}

await client.pushPathAccessRoles(bucket.root?.key || '', path, roles);
await client.pushPathAccessRoles(metadata.bucketKey || '', path, roles);
}

/**
Expand Down

0 comments on commit 5445187

Please sign in to comment.