From 032011e77961b99b5f4b17c66b125d8cbd6f3bb1 Mon Sep 17 00:00:00 2001 From: Adarsh A <104344230+adarsh-a-tw@users.noreply.github.com> Date: Thu, 5 Oct 2023 01:20:10 +0530 Subject: [PATCH] Normalize schema and protocol in create method of permission-grant (#532) * Normalize schema and protocol in create method of permission-grant (#530) Signed-off-by: Adarsh A * refactor to keep tests consistent and give better assurance of normalization (#530) Signed-off-by: Adarsh A * update test coverage in README.md Signed-off-by: Adarsh A --------- Signed-off-by: Adarsh A Co-authored-by: Diane Huxley --- README.md | 2 +- src/interfaces/permissions-grant.ts | 7 ++- tests/interfaces/permissions-grant.spec.ts | 55 +++++++++++++++++++++- 3 files changed, 60 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ca5a8a9f0..fa94e930b 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ Here's to a thrilling Hacktoberfest voyage with us! 🎉 # Decentralized Web Node (DWN) SDK Code Coverage -![Statements](https://img.shields.io/badge/statements-98.07%25-brightgreen.svg?style=flat) ![Branches](https://img.shields.io/badge/branches-95.3%25-brightgreen.svg?style=flat) ![Functions](https://img.shields.io/badge/functions-95.14%25-brightgreen.svg?style=flat) ![Lines](https://img.shields.io/badge/lines-98.07%25-brightgreen.svg?style=flat) +![Statements](https://img.shields.io/badge/statements-98.07%25-brightgreen.svg?style=flat) ![Branches](https://img.shields.io/badge/branches-95.32%25-brightgreen.svg?style=flat) ![Functions](https://img.shields.io/badge/functions-95.14%25-brightgreen.svg?style=flat) ![Lines](https://img.shields.io/badge/lines-98.07%25-brightgreen.svg?style=flat) - [Introduction](#introduction) - [Installation](#installation) diff --git a/src/interfaces/permissions-grant.ts b/src/interfaces/permissions-grant.ts index 9cf91beae..3fa44abd8 100644 --- a/src/interfaces/permissions-grant.ts +++ b/src/interfaces/permissions-grant.ts @@ -8,6 +8,7 @@ import { removeUndefinedProperties } from '../utils/object.js'; import { validateMessageSignatureIntegrity } from '../core/auth.js'; import { DwnError, DwnErrorCode } from '../core/dwn-error.js'; import { DwnInterfaceName, DwnMethodName, Message } from '../core/message.js'; +import { normalizeProtocolUrl, normalizeSchemaUrl } from '../utils/url.js'; export type PermissionsGrantOptions = { messageTimestamp?: string; @@ -42,6 +43,10 @@ export class PermissionsGrant extends Message { } static async create(options: PermissionsGrantOptions): Promise { + const scope = { ...options.scope } as RecordsPermissionScope; + scope.protocol = scope.protocol !== undefined ? normalizeProtocolUrl(scope.protocol) : undefined; + scope.schema = scope.schema !== undefined ? normalizeSchemaUrl(scope.schema) : undefined; + const descriptor: PermissionsGrantDescriptor = { interface : DwnInterfaceName.Permissions, method : DwnMethodName.Grant, @@ -52,7 +57,7 @@ export class PermissionsGrant extends Message { grantedBy : options.grantedBy, grantedFor : options.grantedFor, permissionsRequestId : options.permissionsRequestId, - scope : options.scope, + scope : scope, conditions : options.conditions, }; diff --git a/tests/interfaces/permissions-grant.spec.ts b/tests/interfaces/permissions-grant.spec.ts index 33f783d41..4ee90d08e 100644 --- a/tests/interfaces/permissions-grant.spec.ts +++ b/tests/interfaces/permissions-grant.spec.ts @@ -6,6 +6,7 @@ import type { PermissionScope } from '../../src/index.js'; import { getCurrentTimeInHighPrecision } from '../../src/utils/time.js'; import { PermissionsConditionPublication } from '../../src/types/permissions-types.js'; import { PermissionsGrant } from '../../src/interfaces/permissions-grant.js'; +import type { RecordsPermissionScope } from '../../src/types/permissions-types.js'; import { Secp256k1 } from '../../src/utils/secp256k1.js'; import { Temporal } from '@js-temporal/polyfill'; import { TestDataGenerator } from '../utils/test-data-generator.js'; @@ -35,6 +36,56 @@ describe('PermissionsGrant', () => { expect(message.descriptor.description).to.eql('drugs'); }); + describe('scope property normalizations', async () => { + it('ensures that `schema` is normalized', async () => { + const { privateJwk } = await Secp256k1.generateKeyPair(); + const authorizationSigner = new PrivateKeySigner({ privateJwk, keyId: 'did:jank:bob' }); + + const scope: PermissionScope = { + interface : DwnInterfaceName.Records, + method : DwnMethodName.Write, + schema : 'example.com/', + }; + + const { message } = await PermissionsGrant.create({ + dateExpires : getCurrentTimeInHighPrecision(), + description : 'schema normalization test', + grantedBy : 'did:jank:bob', + grantedTo : 'did:jank:alice', + grantedFor : 'did:jank:bob', + scope : scope, + authorizationSigner + }); + + + expect((message.descriptor.scope as RecordsPermissionScope).schema).to.equal('http://example.com'); + }); + + it('ensures that `protocol` is normalized', async () => { + const { privateJwk } = await Secp256k1.generateKeyPair(); + const authorizationSigner = new PrivateKeySigner({ privateJwk, keyId: 'did:jank:bob' }); + + const scope: PermissionScope = { + interface : DwnInterfaceName.Records, + method : DwnMethodName.Write, + protocol : 'example.com/', + }; + + const { message } = await PermissionsGrant.create({ + dateExpires : getCurrentTimeInHighPrecision(), + description : 'protocol normalization test', + grantedBy : 'did:jank:bob', + grantedTo : 'did:jank:alice', + grantedFor : 'did:jank:bob', + scope : scope, + authorizationSigner + }); + + + expect((message.descriptor.scope as RecordsPermissionScope).protocol).to.equal('http://example.com'); + }); + }); + describe('scope validations', () => { it('ensures that `schema` and protocol related fields `protocol`, `contextId` or `protocolPath`', async () => { const { privateJwk } = await Secp256k1.generateKeyPair(); @@ -129,7 +180,7 @@ describe('PermissionsGrant', () => { expect(permissionsGrant.message.descriptor.grantedBy).to.eq(permissionsRequest.message.descriptor.grantedBy); expect(permissionsGrant.message.descriptor.grantedTo).to.eq(permissionsRequest.message.descriptor.grantedTo); expect(permissionsGrant.message.descriptor.grantedFor).to.eq(permissionsRequest.message.descriptor.grantedFor); - expect(permissionsGrant.message.descriptor.scope).to.eq(permissionsRequest.message.descriptor.scope); + expect(permissionsGrant.message.descriptor.scope).to.eql(permissionsRequest.message.descriptor.scope); expect(permissionsGrant.message.descriptor.conditions).to.eq(permissionsRequest.message.descriptor.conditions); expect(permissionsGrant.message.descriptor.permissionsRequestId).to.eq(await Message.getCid(permissionsRequest.message)); }); @@ -168,7 +219,7 @@ describe('PermissionsGrant', () => { expect(permissionsGrant.message.descriptor.grantedBy).to.eq(overrides.grantedBy); expect(permissionsGrant.message.descriptor.grantedTo).to.eq(overrides.grantedTo); expect(permissionsGrant.message.descriptor.grantedFor).to.eq(overrides.grantedFor); - expect(permissionsGrant.message.descriptor.scope).to.eq(overrides.scope); + expect(permissionsGrant.message.descriptor.scope).to.eql(overrides.scope); expect(permissionsGrant.message.descriptor.conditions).to.eq(overrides.conditions); expect(permissionsGrant.message.descriptor.permissionsRequestId).to.eq(await Message.getCid(permissionsRequest.message)); });