Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
LiranCohen committed Oct 17, 2024
1 parent adbfeb6 commit 1b3b05c
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 6 deletions.
2 changes: 0 additions & 2 deletions packages/api/src/dwn-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -788,7 +788,6 @@ export class DwnApi {
* payload must be read again (e.g., if the data stream is consumed).
*/
remoteOrigin : request.from,
protocolRole : request.message.protocolRole,
delegateDid : this.delegateDid,
data : entry.data,
initialWrite : entry.initialWrite,
Expand Down Expand Up @@ -831,7 +830,6 @@ export class DwnApi {
connectedDid : this.connectedDid,
delegateDid : this.delegateDid,
permissionsApi : this.permissionsApi,
protocolRole : request.message.protocolRole,
request
})
};
Expand Down
5 changes: 5 additions & 0 deletions packages/api/src/record.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,9 @@ export type RecordDeleteParams = {

/** The timestamp indicating when the record was deleted. */
dateModified?: DwnMessageDescriptor[DwnInterface.RecordsDelete]['messageTimestamp'];

/** The protocol role under which this record will be deleted. */
protocolRole?: RecordOptions['protocolRole'];
};

/**
Expand Down Expand Up @@ -353,12 +356,14 @@ export class Record implements RecordModel {
descriptor : this._descriptor,
attestation : this._attestation,
authorization : this._authorization,
protocolRole : this._protocolRole,
encryption : this._encryption,
}));
} else {
message = JSON.parse(JSON.stringify({
descriptor : this._descriptor,
authorization : this._authorization,
protocolRole : this._protocolRole,
}));
}

Expand Down
125 changes: 124 additions & 1 deletion packages/api/tests/dwn-api.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { DwnApi } from '../src/dwn-api.js';
import { testDwnUrl } from './utils/test-config.js';
import emailProtocolDefinition from './fixtures/protocol-definitions/email.json' assert { type: 'json' };
import photosProtocolDefinition from './fixtures/protocol-definitions/photos.json' assert { type: 'json' };
import { DwnInterfaceName, DwnMethodName, Jws, PermissionsProtocol, Poller, Time } from '@tbd54566975/dwn-sdk-js';
import { DwnConstant, DwnInterfaceName, DwnMethodName, Jws, PermissionsProtocol, Poller, Time } from '@tbd54566975/dwn-sdk-js';
import { PermissionGrant } from '../src/permission-grant.js';
import { Record } from '../src/record.js';
import { TestDataGenerator } from './utils/test-data-generator.js';
Expand Down Expand Up @@ -1055,6 +1055,129 @@ describe('DwnApi', () => {
expect(await result.record?.data.json()).to.deep.equal(dataJson);
});

it.only('ensure that a protocolRole used to query is also used to read the data of the result', async () => {
// Scenario: Bob installs a photo protocol and creates an album. They grant a role to Alice as a participant of the album.
// Bob then adds 3 photos to the album. Alice uses the role to add a photo to the album.
// NOTE: We are purposfully making these photos larger than the max allowed size to the creation of a RecordsRead to read the large data.
// Alice then queries the album and reads the photos using the protocolRole.
// Alice then is able to read the data of each of the records.

// Configure the photos protocol on Alice and Bob's local and remote DWNs.
const { status: bobProtocolStatus, protocol: bobProtocol } = await dwnBob.protocols.configure({
message: {
definition: photosProtocolDefinition
}
});
expect(bobProtocolStatus.code).to.equal(202);
const { status: bobRemoteProtocolStatus } = await bobProtocol.send(bobDid.uri);
expect(bobRemoteProtocolStatus.code).to.equal(202);

// Bob creates an album
const { status: albumCreateStatus, record: albumRecord } = await dwnBob.records.create({
data: 'My Album',
message: {
protocol : photosProtocolDefinition.protocol,
protocolPath : 'album',
schema : photosProtocolDefinition.types.album.schema,
dataFormat : 'text/plain'
}
});
expect(albumCreateStatus.code).to.equal(202);
const { status: albumSendStatus } = await albumRecord.send();
expect(albumSendStatus.code).to.equal(202);

// Bob makes Alice a `participant` and sends the record to her and his own remote node.
const { status: participantCreateStatus, record: participantRecord} = await dwnBob.records.create({
data : 'test',
message : {
parentContextId : albumRecord.contextId,
recipient : aliceDid.uri,
protocol : photosProtocolDefinition.protocol,
protocolPath : 'album/participant',
schema : photosProtocolDefinition.types.participant.schema,
dataFormat : 'text/plain'
}
});
expect(participantCreateStatus.code).to.equal(202);
const { status: bobParticipantSendStatus } = await participantRecord.send(bobDid.uri);
expect(bobParticipantSendStatus.code).to.equal(202);

// bob adds 3 photos to the album
for (let i = 0; i < 3; i++) {
const { status: photoCreateStatus, record: photoRecord } = await dwnBob.records.create({
data: TestDataGenerator.randomString(DwnConstant.maxDataSizeAllowedToBeEncoded + 1),
message: {
parentContextId : albumRecord.contextId,
protocol : photosProtocolDefinition.protocol,
protocolPath : 'album/photo',
schema : photosProtocolDefinition.types.photo.schema,
dataFormat : 'text/plain',
}
});
expect(photoCreateStatus.code).to.equal(202);
const { status: photoSendStatus } = await photoRecord.send();
expect(photoSendStatus.code).to.equal(202);
}

// alice uses the role to add a photo to the album
const { status: photoCreateStatusAlice, record: photoRecordAlice } = await dwnAlice.records.create({
store: false,
data: TestDataGenerator.randomString(DwnConstant.maxDataSizeAllowedToBeEncoded + 1),
message: {
parentContextId : albumRecord.contextId,
protocol : photosProtocolDefinition.protocol,
protocolPath : 'album/photo',
protocolRole : 'album/participant',
schema : photosProtocolDefinition.types.photo.schema,
dataFormat : 'text/plain'
}
});
expect(photoCreateStatusAlice.code).to.equal(202);
const { status: albumSendStatusAlice } = await photoRecordAlice.send(bobDid.uri);
expect(albumSendStatusAlice.code).to.equal(202);

//SANITY: Alice attempts to fetch the photos without the role, she should only see her own photo
const { status: alicePhotosReadResultWithoutRole, records: alicePhotosRecordsWithoutRole } = await dwnAlice.records.query({
from : bobDid.uri,
message : {
filter: {
protocol: photosProtocolDefinition.protocol,
protocolPath: 'album/photo',
contextId: albumRecord.contextId
}
}
});
expect(alicePhotosReadResultWithoutRole.code).to.equal(200);
expect(alicePhotosRecordsWithoutRole).to.exist;
expect(alicePhotosRecordsWithoutRole).to.have.lengthOf(1);

// Attempt to read the data of the photo, which should succeed
const readResultWithoutRole = await alicePhotosRecordsWithoutRole[0].data.text();
expect(readResultWithoutRole.length).to.equal(DwnConstant.maxDataSizeAllowedToBeEncoded + 1);

// Alice fetches all of the photos from the album
const alicePhotosReadResult = await dwnAlice.records.query({
from : bobDid.uri,
message : {
protocolRole: 'album/participant',
filter: {
protocol: photosProtocolDefinition.protocol,
protocolPath: 'album/photo',
contextId: albumRecord.contextId
}
}
});
expect(alicePhotosReadResult.status.code).to.equal(200);
expect(alicePhotosReadResult.records).to.exist;
expect(alicePhotosReadResult.records).to.have.lengthOf(4);

// attempt to read data from the photos
for (const record of alicePhotosReadResult.records) {
const readResult = await record.data.text();
expect(readResult.length).to.equal(DwnConstant.maxDataSizeAllowedToBeEncoded + 1);
}
});

it('creates a role record for another user that they can use to create role-based records', async () => {
/**
* WHAT IS BEING TESTED?
Expand Down
6 changes: 3 additions & 3 deletions packages/api/tests/fixtures/protocol-definitions/photos.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
{
"role": "friend",
"can": [
"create", "update"
"create", "update", "read", "query", "subscribe"
]
}
],
Expand All @@ -54,7 +54,7 @@
{
"role": "album/participant",
"can": [
"create", "update"
"create", "update", "read", "query", "subscribe"
]
}
]
Expand All @@ -64,7 +64,7 @@
{
"role": "album/participant",
"can": [
"create", "update"
"create", "update", "read", "query", "subscribe"
]
},
{
Expand Down

0 comments on commit 1b3b05c

Please sign in to comment.