Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: authorize claims as account, not only this.issuer #556

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 40 additions & 4 deletions packages/access-api/test/access-client-agent.test.js
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -321,18 +324,51 @@ 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)

// issuer + account proofs should authorize deviceB to invoke space/info
const spaceInfoResult = await deviceB.invokeAndExecute(
w3caps.Space.info,
{
with: spaceCreation.did,
}
)
assertNotError(spaceInfoResult)
assert.notEqual(
spaceInfoResult.error,
true,
'spaceInfoResult is not an error'
)
assert.ok(!spaceInfoResult.error)
assert.deepEqual(spaceInfoResult.did, spaceCreation.did)
})
})
}
Expand Down
22 changes: 16 additions & 6 deletions packages/access-client/src/agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const PRINCIPAL = DID.parse('did:web:web3.storage')
* @param {Ucanto.DID} space
* @param {Ucanto.Principal<Ucanto.DID<'mailto'>>} account
* @param {Ucanto.Capabilities} capabilities
* @param {Ucanto.Delegation[]} proofs
* @returns
*/
async function createIssuerSaysAccountCanAdminSpace(
Expand All @@ -54,12 +55,14 @@ async function createIssuerSaysAccountCanAdminSpace(
can: '*',
with: space,
},
]
],
proofs = []
) {
return ucanto.delegate({
issuer,
audience: account,
capabilities,
proofs,
})
}

Expand Down Expand Up @@ -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 })
}

/**
Expand All @@ -536,16 +540,22 @@ export class Agent {
* @param {Ucanto.Principal<Ucanto.DID<'mailto'>>} 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: [
Expand All @@ -555,7 +565,7 @@ export class Agent {
this.issuer
),
// must be embedded here because it's referenced by cid in .nb.delegations
spaceSaysAccountCanAdminSpace,
issuerSaysAccountCanAdminSpace,
],
})
}
Expand Down