Skip to content

Commit

Permalink
Merge branch 'main' into 530-normalize-schema-and-protocol
Browse files Browse the repository at this point in the history
* main:
  decentralized-identity#439 - Appended 'Signature' to` author` and `owner` under `authorization` (decentralized-identity#536)
  • Loading branch information
Diane Huxley committed Oct 4, 2023
2 parents 6685729 + 2f1ab5e commit 5dce58c
Show file tree
Hide file tree
Showing 24 changed files with 56 additions and 57 deletions.
10 changes: 5 additions & 5 deletions json-schemas/authorization-owner.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@
"type": "object",
"additionalProperties": false,
"properties": {
"author": {
"authorSignature": {
"$ref": "https://identity.foundation/dwn/json-schemas/general-jws.json"
},
"owner": {
"ownerSignature": {
"$ref": "https://identity.foundation/dwn/json-schemas/general-jws.json"
}
},
"description": "`author` can exist by itself. But if `owner` is present, then `author` must also exist",
"description": "`authorSignature` can exist by itself. But if `ownerSignature` is present, then `authorSignature` must also exist",
"dependencies": {
"owner": [
"author"
"ownerSignature": [
"authorSignature"
]
}
}
2 changes: 1 addition & 1 deletion json-schemas/authorization.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"type": "object",
"additionalProperties": false,
"properties": {
"author": {
"authorSignature": {
"$ref": "https://identity.foundation/dwn/json-schemas/general-jws.json"
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export async function authenticate(authorizationModel: AuthorizationModel | unde
throw new DwnError(DwnErrorCode.AuthenticateJwsMissing, 'Missing JWS.');
}

const verifier = new GeneralJwsVerifier(authorizationModel.author);
const verifier = new GeneralJwsVerifier(authorizationModel.authorSignature);
await verifier.verify(didResolver);
}

Expand Down
8 changes: 4 additions & 4 deletions src/core/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export abstract class Message<M extends GenericMessage> {
this.message = message;

if (message.authorization !== undefined) {
this.authorSignaturePayload = Jws.decodePlainObjectPayload(message.authorization.author);
this.authorSignaturePayload = Jws.decodePlainObjectPayload(message.authorization.authorSignature);
this.author = Message.getAuthor(message as GenericMessage);
}
}
Expand Down Expand Up @@ -73,7 +73,7 @@ export abstract class Message<M extends GenericMessage> {
return undefined;
}

const author = Jws.getSignerDid(message.authorization.author.signatures[0]);
const author = Jws.getSignerDid(message.authorization.authorSignature.signatures[0]);
return author;
}

Expand Down Expand Up @@ -125,9 +125,9 @@ export abstract class Message<M extends GenericMessage> {
const authPayloadBytes = new TextEncoder().encode(authPayloadStr);

const builder = await GeneralJwsBuilder.create(authPayloadBytes, [signer]);
const authorJws = builder.getJws();
const authorSignature = builder.getJws();

const authorization = { author: authorJws };
const authorization = { authorSignature };
return authorization;
}

Expand Down
2 changes: 1 addition & 1 deletion src/core/protocol-authorization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ export class ProtocolAuthorization {
const author = incomingMessage.author;
const actionRules = inboundMessageRuleSet.$actions;

if (incomingMessage.message.authorization?.owner !== undefined) {
if (incomingMessage.message.authorization?.ownerSignature !== undefined) {
// if incoming message is a write retained by this tenant, we by design bypass allowed action verification
// NOTE: the "owner === tenant" check is already done before this method is invoked
return;
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/events-get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class EventsGet extends Message<EventsGetMessage> {

public static async parse(message: EventsGetMessage): Promise<EventsGet> {
Message.validateJsonSchema(message);
await validateMessageSignatureIntegrity(message.authorization.author, message.descriptor);
await validateMessageSignatureIntegrity(message.authorization.authorSignature, message.descriptor);

return new EventsGet(message);
}
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/messages-get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class MessagesGet extends Message<MessagesGetMessage> {
Message.validateJsonSchema(message);
this.validateMessageCids(message.descriptor.messageCids);

await validateMessageSignatureIntegrity(message.authorization.author, message.descriptor);
await validateMessageSignatureIntegrity(message.authorization.authorSignature, message.descriptor);

return new MessagesGet(message);
}
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/permissions-grant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export type CreateFromPermissionsRequestOverrides = {
export class PermissionsGrant extends Message<PermissionsGrantMessage> {

public static async parse(message: PermissionsGrantMessage): Promise<PermissionsGrant> {
await validateMessageSignatureIntegrity(message.authorization.author, message.descriptor);
await validateMessageSignatureIntegrity(message.authorization.authorSignature, message.descriptor);
PermissionsGrant.validateScope(message);

return new PermissionsGrant(message);
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/permissions-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export type PermissionsRequestOptions = {
export class PermissionsRequest extends Message<PermissionsRequestMessage> {

public static async parse(message: PermissionsRequestMessage): Promise<PermissionsRequest> {
await validateMessageSignatureIntegrity(message.authorization.author, message.descriptor);
await validateMessageSignatureIntegrity(message.authorization.authorSignature, message.descriptor);

return new PermissionsRequest(message);
}
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/permissions-revoke.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export type PermissionsRevokeOptions = {

export class PermissionsRevoke extends Message<PermissionsRevokeMessage> {
public static async parse(message: PermissionsRevokeMessage): Promise<PermissionsRevoke> {
await validateMessageSignatureIntegrity(message.authorization.author, message.descriptor);
await validateMessageSignatureIntegrity(message.authorization.authorSignature, message.descriptor);

return new PermissionsRevoke(message);
}
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/protocols-configure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export class ProtocolsConfigure extends Message<ProtocolsConfigureMessage> {
public static async parse(message: ProtocolsConfigureMessage): Promise<ProtocolsConfigure> {
Message.validateJsonSchema(message);
ProtocolsConfigure.validateProtocolDefinition(message.descriptor.definition);
await validateMessageSignatureIntegrity(message.authorization.author, message.descriptor);
await validateMessageSignatureIntegrity(message.authorization.authorSignature, message.descriptor);

return new ProtocolsConfigure(message);
}
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/protocols-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class ProtocolsQuery extends Message<ProtocolsQueryMessage> {

public static async parse(message: ProtocolsQueryMessage): Promise<ProtocolsQuery> {
if (message.authorization !== undefined) {
await validateMessageSignatureIntegrity(message.authorization.author, message.descriptor);
await validateMessageSignatureIntegrity(message.authorization.authorSignature, message.descriptor);
}

if (message.descriptor.filter !== undefined) {
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/records-delete.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export type RecordsDeleteOptions = {
export class RecordsDelete extends Message<RecordsDeleteMessage> {

public static async parse(message: RecordsDeleteMessage): Promise<RecordsDelete> {
await validateMessageSignatureIntegrity(message.authorization.author, message.descriptor);
await validateMessageSignatureIntegrity(message.authorization.authorSignature, message.descriptor);

const recordsDelete = new RecordsDelete(message);
return recordsDelete;
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/records-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export class RecordsQuery extends Message<RecordsQueryMessage> {

public static async parse(message: RecordsQueryMessage): Promise<RecordsQuery> {
if (message.authorization !== undefined) {
await validateMessageSignatureIntegrity(message.authorization.author, message.descriptor);
await validateMessageSignatureIntegrity(message.authorization.authorSignature, message.descriptor);
}

if (message.descriptor.filter.protocol !== undefined) {
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/records-read.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export class RecordsRead extends Message<RecordsReadMessage> {

public static async parse(message: RecordsReadMessage): Promise<RecordsRead> {
if (message.authorization !== undefined) {
await validateMessageSignatureIntegrity(message.authorization.author, message.descriptor);
await validateMessageSignatureIntegrity(message.authorization.authorSignature, message.descriptor);
}

const recordsRead = new RecordsRead(message);
Expand Down
19 changes: 9 additions & 10 deletions src/interfaces/records-write.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,11 @@ export class RecordsWrite {

if (message.authorization !== undefined) {
this._author = Message.getAuthor(message as GenericMessage);
this._authorSignaturePayload = Jws.decodePlainObjectPayload(message.authorization.author);
this._authorSignaturePayload = Jws.decodePlainObjectPayload(message.authorization.authorSignature);


if (message.authorization.owner !== undefined) {
this._owner = Jws.getSignerDid(message.authorization.owner.signatures[0]);
this._ownerSignaturePayload = Jws.decodePlainObjectPayload(message.authorization.owner);
if (message.authorization.ownerSignature !== undefined) {
this._owner = Jws.getSignerDid(message.authorization.ownerSignature.signatures[0]);
this._ownerSignaturePayload = Jws.decodePlainObjectPayload(message.authorization.ownerSignature);
}
}

Expand All @@ -190,10 +189,10 @@ export class RecordsWrite {
public static async parse(message: RecordsWriteMessage): Promise<RecordsWrite> {
// asynchronous checks that are required by the constructor to initialize members properly

await validateMessageSignatureIntegrity(message.authorization.author, message.descriptor, 'RecordsWriteSignaturePayload');
await validateMessageSignatureIntegrity(message.authorization.authorSignature, message.descriptor, 'RecordsWriteSignaturePayload');

if (message.authorization.owner !== undefined) {
await validateMessageSignatureIntegrity(message.authorization.owner, message.descriptor, 'RecordsWriteSignaturePayload');
if (message.authorization.ownerSignature !== undefined) {
await validateMessageSignatureIntegrity(message.authorization.ownerSignature, message.descriptor, 'RecordsWriteSignaturePayload');
}

await RecordsWrite.validateAttestationIntegrity(message);
Expand Down Expand Up @@ -414,7 +413,7 @@ export class RecordsWrite {
permissionsGrantId
);

this._message.authorization = { author: authorSignature };
this._message.authorization = { authorSignature };

// there is opportunity to optimize here as the payload is constructed within `createAuthorization(...)`
this._authorSignaturePayload = Jws.decodePlainObjectPayload(authorSignature);
Expand Down Expand Up @@ -447,7 +446,7 @@ export class RecordsWrite {
permissionsGrantId
);

this._message.authorization!.owner = ownerSignature;
this._message.authorization!.ownerSignature = ownerSignature;

this._ownerSignaturePayload = Jws.decodePlainObjectPayload(ownerSignature);
this._owner = owner;
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/snapshots-create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export type SnapshotsCreateOptions = {
export class SnapshotsCreate extends Message<SnapshotsCreateMessage> {

public static async parse(message: SnapshotsCreateMessage): Promise<SnapshotsCreate> {
await validateMessageSignatureIntegrity(message.authorization.author, message.descriptor);
await validateMessageSignatureIntegrity(message.authorization.authorSignature, message.descriptor);

return new SnapshotsCreate(message);
}
Expand Down
4 changes: 2 additions & 2 deletions src/types/message-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ export type GenericMessage = {
* The data model for the `authorization` property in a DWN message.
*/
export type AuthorizationModel = {
author: GeneralJws;
owner?: GeneralJws;
authorSignature: GeneralJws;
ownerSignature?: GeneralJws;
};

/**
Expand Down
2 changes: 1 addition & 1 deletion tests/handlers/protocols-configure.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export function testProtocolsConfigureHandler(): void {
const authorizationPayloadBytes = Encoder.objectToBytes(protocolsConfigure.authorSignaturePayload!);

const jwsBuilder = await GeneralJwsBuilder.create(authorizationPayloadBytes, [signer1, signer2]);
message.authorization = { author: jwsBuilder.getJws() };
message.authorization = { authorSignature: jwsBuilder.getJws() };

TestStubGenerator.stubDidResolver(didResolver, [author]);

Expand Down
2 changes: 1 addition & 1 deletion tests/handlers/protocols-query.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export function testProtocolsQueryHandler(): void {
const authorizationPayloadBytes = Encoder.objectToBytes(authorizationPayload);
const signer = Jws.createSigner(author);
const jwsBuilder = await GeneralJwsBuilder.create(authorizationPayloadBytes, [signer]);
message.authorization = { author: jwsBuilder.getJws() };
message.authorization = { authorSignature: jwsBuilder.getJws() };

const reply = await dwn.processMessage(tenant, message);

Expand Down
32 changes: 16 additions & 16 deletions tests/handlers/records-write.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,8 @@ export function testRecordsWriteHandler(): void {
expect(data).to.eql(dataBytes);
});

describe('owner tests', () => {
it('should use `owner` for authorization when it is given - flat-space', async () => {
describe('owner signature tests', () => {
it('should use `ownerSignature` for authorization when it is given - flat-space', async () => {
// scenario: Alice fetch a message authored by Bob from Bob's DWN and retains (writes) it in her DWN
const alice = await DidKeyResolver.generate();
const bob = await DidKeyResolver.generate();
Expand Down Expand Up @@ -353,7 +353,7 @@ export function testRecordsWriteHandler(): void {
expect(ArrayUtility.byteArraysEqual(dataFetched, dataBytes!)).to.be.true;
});

it('should use `owner` for authorization when it is given - protocol-space', async () => {
it('should use `ownerSignature` for authorization when it is given - protocol-space', async () => {
// scenario: Alice and Bob both have the same protocol which does NOT allow external entities to write,
// but Alice can store a message authored by Bob as a owner in her own DWN
const alice = await DidKeyResolver.generate();
Expand Down Expand Up @@ -403,7 +403,7 @@ export function testRecordsWriteHandler(): void {
expect(ArrayUtility.byteArraysEqual(dataFetched, bobRecordsWrite.dataBytes!)).to.be.true;
});

it('should throw if `owner` in `authorization` is mismatching with the tenant - flat-space', async () => {
it('should throw if `ownerSignature` in `authorization` is mismatching with the tenant - flat-space', async () => {
// scenario: Carol attempts to store a message with Alice being the owner, and should fail
const alice = await DidKeyResolver.generate();
const bob = await DidKeyResolver.generate();
Expand Down Expand Up @@ -536,9 +536,9 @@ export function testRecordsWriteHandler(): void {
const descriptorCid = await Cid.computeCid(message.descriptor);
const recordId = await RecordsWrite.getEntryId(alice.did, message.descriptor);
const authorizationSigner = Jws.createSigner(alice);
const signature = await RecordsWrite['createAuthorizationSignature'](recordId, message.contextId, descriptorCid, message.attestation, message.encryption, authorizationSigner, undefined);
const authorSignature = await RecordsWrite['createAuthorizationSignature'](recordId, message.contextId, descriptorCid, message.attestation, message.encryption, authorizationSigner, undefined);
message.recordId = recordId;
message.authorization = { author: signature };
message.authorization = { authorSignature };

const reply = await dwn.processMessage(alice.did, message, dataStream);
expect(reply.status.code).to.equal(400);
Expand All @@ -557,9 +557,9 @@ export function testRecordsWriteHandler(): void {
const descriptorCid = await Cid.computeCid(message.descriptor);
const recordId = await RecordsWrite.getEntryId(alice.did, message.descriptor);
const authorizationSigner = Jws.createSigner(alice);
const signature = await RecordsWrite['createAuthorizationSignature'](recordId, message.contextId, descriptorCid, message.attestation, message.encryption, authorizationSigner, undefined);
const authorSignature = await RecordsWrite['createAuthorizationSignature'](recordId, message.contextId, descriptorCid, message.attestation, message.encryption, authorizationSigner, undefined);
message.recordId = recordId;
message.authorization = { author: signature };
message.authorization = { authorSignature };

const reply = await dwn.processMessage(alice.did, message, dataStream);
expect(reply.status.code).to.equal(400);
Expand All @@ -578,9 +578,9 @@ export function testRecordsWriteHandler(): void {
const descriptorCid = await Cid.computeCid(message.descriptor);
const recordId = await RecordsWrite.getEntryId(alice.did, message.descriptor);
const authorizationSigner = Jws.createSigner(alice);
const signature = await RecordsWrite['createAuthorizationSignature'](recordId, message.contextId, descriptorCid, message.attestation, message.encryption, authorizationSigner, undefined);
const authorSignature = await RecordsWrite['createAuthorizationSignature'](recordId, message.contextId, descriptorCid, message.attestation, message.encryption, authorizationSigner, undefined);
message.recordId = recordId;
message.authorization = { author: signature };
message.authorization = { authorSignature };

const reply = await dwn.processMessage(alice.did, message, dataStream);
expect(reply.status.code).to.equal(400);
Expand All @@ -598,9 +598,9 @@ export function testRecordsWriteHandler(): void {
const descriptorCid = await Cid.computeCid(message.descriptor);
const recordId = await RecordsWrite.getEntryId(alice.did, message.descriptor);
const authorizationSigner = Jws.createSigner(alice);
const signature = await RecordsWrite['createAuthorizationSignature'](recordId, message.contextId, descriptorCid, message.attestation, message.encryption, authorizationSigner, undefined);
const authorSignature = await RecordsWrite['createAuthorizationSignature'](recordId, message.contextId, descriptorCid, message.attestation, message.encryption, authorizationSigner, undefined);
message.recordId = recordId;
message.authorization = { author: signature };
message.authorization = { authorSignature };

const reply = await dwn.processMessage(alice.did, message, dataStream);
expect(reply.status.code).to.equal(400);
Expand Down Expand Up @@ -2063,7 +2063,7 @@ export function testRecordsWriteHandler(): void {
recordsWrite.message = {
...recordsWrite.message,
attestation,
authorization: { author: authorSignature }
authorization: { authorSignature }
};

// Send records write message
Expand Down Expand Up @@ -2919,7 +2919,7 @@ export function testRecordsWriteHandler(): void {
const authorizationPayloadBytes = Encoder.objectToBytes(authorizationPayload);
const signer = Jws.createSigner(author);
const jwsBuilder = await GeneralJwsBuilder.create(authorizationPayloadBytes, [signer]);
message.authorization = { author: jwsBuilder.getJws() };
message.authorization = { authorSignature: jwsBuilder.getJws() };

const tenant = author.did;
const didResolver = TestStubGenerator.createDidResolverStub(author);
Expand All @@ -2943,7 +2943,7 @@ export function testRecordsWriteHandler(): void {
const authorizationPayloadBytes = Encoder.objectToBytes(authorizationPayload);
const signer = Jws.createSigner(author);
const jwsBuilder = await GeneralJwsBuilder.create(authorizationPayloadBytes, [signer]);
message.authorization = { author: jwsBuilder.getJws() };
message.authorization = { authorSignature: jwsBuilder.getJws() };

const tenant = author.did;
const didResolver = sinon.createStubInstance(DidResolver);
Expand Down Expand Up @@ -3010,7 +3010,7 @@ export function testRecordsWriteHandler(): void {
authorizationPayload.attestationCid = await Cid.computeCid(attestationPayload);
const authorizationPayloadBytes = Encoder.objectToBytes(authorizationPayload);
const authorizationBuilder = await GeneralJwsBuilder.create(authorizationPayloadBytes, [signer]);
message.authorization = { author: authorizationBuilder.getJws() };
message.authorization = { authorSignature: authorizationBuilder.getJws() };

const didResolver = TestStubGenerator.createDidResolverStub(author);
const messageStore = stubInterface<MessageStore>();
Expand Down
Loading

0 comments on commit 5dce58c

Please sign in to comment.