From a54e1fb403f0b07bf720c841d8232bfd8a136864 Mon Sep 17 00:00:00 2001 From: Benjamin Goering <171782+gobengo@users.noreply.github.com> Date: Thu, 16 Mar 2023 15:19:43 -0700 Subject: [PATCH 1/2] wip --- .../test/access-client-agent.test.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/packages/access-api/test/access-client-agent.test.js b/packages/access-api/test/access-client-agent.test.js index 95aeec860..44637eeab 100644 --- a/packages/access-api/test/access-client-agent.test.js +++ b/packages/access-api/test/access-client-agent.test.js @@ -1,6 +1,9 @@ /* eslint-disable unicorn/consistent-function-scoping */ import { context } from './helpers/context.js' -import { createTesterFromContext } from './helpers/ucanto-test-utils.js' +import { + assertNotError, + createTesterFromContext, +} from './helpers/ucanto-test-utils.js' import * as principal from '@ucanto/principal' import { addProvider, @@ -333,6 +336,20 @@ for (const accessApiVariant of /** @type {const} */ ([ // try to addProvider await addProvider(deviceB, spaceCreation.did, account, provider) + + // try to space/info as deviceB + const spaceInfoResult = await deviceB.invokeAndExecute( + w3caps.Space.info, + { + with: spaceCreation.did, + } + ) + assertNotError(spaceInfoResult) + assert.notEqual( + spaceInfoResult.error, + true, + 'spaceInfoResult is not an error' + ) }) }) } From e67ed9869573238f0db14e1aef55e0efa1fe8588 Mon Sep 17 00:00:00 2001 From: Benjamin Goering <171782+gobengo@users.noreply.github.com> Date: Thu, 16 Mar 2023 15:54:04 -0700 Subject: [PATCH 2/2] authorize claims as account --- .../test/access-client-agent.test.js | 27 ++++++++++++++++--- packages/access-client/src/agent.js | 22 ++++++++++----- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/packages/access-api/test/access-client-agent.test.js b/packages/access-api/test/access-client-agent.test.js index 44637eeab..7c338ea8d 100644 --- a/packages/access-api/test/access-client-agent.test.js +++ b/packages/access-api/test/access-client-agent.test.js @@ -324,20 +324,37 @@ for (const accessApiVariant of /** @type {const} */ ([ deviceB.connection, await watchForEmail(emails, 100, abort.signal) ) - // claim delegations after confirmation - const deviceBClaimed = await claimDelegations( + // claim delegations aud=deviceB.issuer + const deviceBIssuerClaimed = await claimDelegations( deviceB, deviceB.issuer.did(), { addProofs: true, } ) - assert.equal(deviceBClaimed.length, 2, 'deviceB claimed delegations') + assert.equal( + deviceBIssuerClaimed.length, + 2, + 'deviceBIssuerClaimed delegations' + ) + // claim delegations aud=account + const deviceBAccountClaimed = await claimDelegations( + deviceB, + account.did(), + { + addProofs: true, + } + ) + assert.equal( + deviceBAccountClaimed.length, + 1, + 'deviceBAccountClaimed delegations' + ) // try to addProvider await addProvider(deviceB, spaceCreation.did, account, provider) - // try to space/info as deviceB + // issuer + account proofs should authorize deviceB to invoke space/info const spaceInfoResult = await deviceB.invokeAndExecute( w3caps.Space.info, { @@ -350,6 +367,8 @@ for (const accessApiVariant of /** @type {const} */ ([ true, 'spaceInfoResult is not an error' ) + assert.ok(!spaceInfoResult.error) + assert.deepEqual(spaceInfoResult.did, spaceCreation.did) }) }) } diff --git a/packages/access-client/src/agent.js b/packages/access-client/src/agent.js index c62d1da0e..996746b90 100644 --- a/packages/access-client/src/agent.js +++ b/packages/access-client/src/agent.js @@ -43,6 +43,7 @@ const PRINCIPAL = DID.parse('did:web:web3.storage') * @param {Ucanto.DID} space * @param {Ucanto.Principal>} account * @param {Ucanto.Capabilities} capabilities + * @param {Ucanto.Delegation[]} proofs * @returns */ async function createIssuerSaysAccountCanAdminSpace( @@ -54,12 +55,14 @@ async function createIssuerSaysAccountCanAdminSpace( can: '*', with: space, }, - ] + ], + proofs = [] ) { return ucanto.delegate({ issuer, audience: account, capabilities, + proofs, }) } @@ -519,6 +522,7 @@ export class Agent { // claim delegations here because we will need an ucan/attest from the service to // pair with the session delegation we just claimed to make it work await claimDelegations(this, this.issuer.did(), { addProofs: true }) + await claimDelegations(this, account.did(), { addProofs: true }) } /** @@ -536,16 +540,22 @@ export class Agent { * @param {Ucanto.Principal>} account */ async #delegateSpaceAccessToAccount(space, account) { - const spaceSaysAccountCanAdminSpace = - await createIssuerSaysAccountCanAdminSpace(this.issuer, space, account) + const issuerSaysAccountCanAdminSpace = + await createIssuerSaysAccountCanAdminSpace( + this.issuer, + space, + account, + undefined, + this.proofs([{ with: space, can: '*' }]) + ) return this.invokeAndExecute(Access.delegate, { audience: this.connection.id, with: space, expiration: Infinity, nb: { delegations: { - [spaceSaysAccountCanAdminSpace.cid.toString()]: - spaceSaysAccountCanAdminSpace.cid, + [issuerSaysAccountCanAdminSpace.cid.toString()]: + issuerSaysAccountCanAdminSpace.cid, }, }, proofs: [ @@ -555,7 +565,7 @@ export class Agent { this.issuer ), // must be embedded here because it's referenced by cid in .nb.delegations - spaceSaysAccountCanAdminSpace, + issuerSaysAccountCanAdminSpace, ], }) }