Skip to content

Commit

Permalink
#439 - Appending 'Signature' to author and owner under authorization
Browse files Browse the repository at this point in the history
  • Loading branch information
thehenrytsai committed Oct 4, 2023
1 parent 90484e1 commit 9f22099
Show file tree
Hide file tree
Showing 24 changed files with 51 additions and 52 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 @@ -35,7 +35,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
24 changes: 12 additions & 12 deletions tests/handlers/records-write.spec.ts
Original file line number Diff line number Diff line change
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
2 changes: 1 addition & 1 deletion tests/interfaces/records-write.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ describe('RecordsWrite', () => {

const recordsWrite = await RecordsWrite.create(options);

expect(recordsWrite.message.authorization!.author.signatures[0].signature).to.equal(Encoder.bytesToBase64Url(hardCodedSignature));
expect(recordsWrite.message.authorization!.authorSignature.signatures[0].signature).to.equal(Encoder.bytesToBase64Url(hardCodedSignature));
});

it('should throw if attempting to use `protocols` key derivation encryption scheme on non-protocol-based record', async () => {
Expand Down
2 changes: 1 addition & 1 deletion tests/utils/test-data-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,7 @@ export class TestDataGenerator {
*/
public static generateAuthorization(): AuthorizationModel {
return {
author: TestDataGenerator.generateAuthorizationSignature()
authorSignature: TestDataGenerator.generateAuthorizationSignature()
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ describe('RecordsQuery schema validation', () => {

it('should throw if `owner` is specified in `authorization`', () => {
const authorization = TestDataGenerator.generateAuthorization();
authorization.owner = TestDataGenerator.generateAuthorizationSignature();
authorization.ownerSignature = TestDataGenerator.generateAuthorizationSignature();

const invalidMessage = {
descriptor: {
Expand Down

0 comments on commit 9f22099

Please sign in to comment.