Skip to content

Commit

Permalink
fix: upload/add capability root validation (#136)
Browse files Browse the repository at this point in the history
  • Loading branch information
Alan Shaw authored Nov 4, 2022
1 parent 4baec99 commit aae5b66
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 21 deletions.
10 changes: 5 additions & 5 deletions packages/access/src/capabilities/upload.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,24 @@ export const upload = any.derive({
})

// Right now ucanto does not yet has native `*` support, which means
// `store/add` can not be derived from `*` event though it can be
// derived from `store/*`. As a workaround we just define base capability
// `upload/add` can not be derived from `*` event though it can be
// derived from `upload/*`. As a workaround we just define base capability
// here so all store capabilities could be derived from either `*` or
// `store/*`.
// `upload/*`.
const base = any.or(upload)

const CARLink = Link.match({ code: codec.code, version: 1 })

/**
* `store/add` can be derived from the `store/*` capability
* `upload/add` can be derived from the `upload/*` capability
* as long as with fields match.
*/
export const add = base.derive({
to: capability({
can: 'upload/add',
with: URI.match({ protocol: 'did:' }),
nb: {
root: CARLink.optional(),
root: Link.optional(),
shards: CARLink.array().optional(),
},
derives: (self, from) => {
Expand Down
37 changes: 21 additions & 16 deletions packages/access/test/capabilities/upload.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
service as w3,
mallory as account,
} from '../helpers/fixtures.js'
import { createCarCid, parseCarLink } from '../helpers/utils.js'
import { createCarCid, parseCarLink, createCborCid } from '../helpers/utils.js'

describe('upload capabilities', function () {
// delegation from account to agent
Expand All @@ -33,7 +33,7 @@ describe('upload capabilities', function () {
proofs: [await any],
})
.delegate()
const root = await createCarCid('root')
const root = await createCborCid('root')

const add = Upload.add.invoke({
issuer: bob,
Expand Down Expand Up @@ -72,7 +72,7 @@ describe('upload capabilities', function () {
proofs: [await any],
})

const root = await createCarCid('root')
const root = await createCborCid('root')
const add = Upload.add.invoke({
audience: w3,
issuer: bob,
Expand Down Expand Up @@ -102,15 +102,16 @@ describe('upload capabilities', function () {
})
})

it('creating upload/add throws if shards is contains non CAR cid', async () => {
it('creating upload/add throws if shards contains a non CAR cid', async () => {
const proofs = [await any]
const root = await createCborCid('root')
assert.throws(() => {
Upload.add.invoke({
issuer: alice,
audience: w3,
with: account.did(),
nb: {
root: parseCarLink('bafkqaaa'),
root,
shards: [parseCarLink('bafkqaaa')],
},
proofs,
Expand All @@ -119,6 +120,7 @@ describe('upload capabilities', function () {
})

it('validator fails on upload/add if shard contains non CAR cid', async () => {
const root = await createCborCid('root')
const add = await delegate({
issuer: alice,
audience: w3,
Expand All @@ -127,7 +129,7 @@ describe('upload capabilities', function () {
can: 'upload/add',
with: account.did(),
nb: {
root: parseCarLink('bafkqaaa'),
root,
shards: [parseCarLink('bafkqaaa')],
},
},
Expand All @@ -148,7 +150,7 @@ describe('upload capabilities', function () {

it('upload/add works with shards that are CAR cids', async () => {
const shard = await createCarCid('shard')
const root = await createCarCid('root')
const root = await createCborCid('root')
const add = Upload.add.invoke({
issuer: alice,
audience: w3,
Expand Down Expand Up @@ -180,29 +182,31 @@ describe('upload capabilities', function () {
})
})

it('upload/add capability requires with to be a did', () => {
it('upload/add capability requires with to be a did', async () => {
const root = await createCborCid('root')
assert.throws(() => {
Upload.add.invoke({
issuer: alice,
audience: w3,
// @ts-expect-error - not a CAR cid
with: 'mailto:alice@web.mail',
nb: {
root: parseCarLink('bafkqaaa'),
root,
},
})
}, /Expected did: URI instead got mailto:alice@web.mail/)
})

it('upload/add validation requires with to be a did', async () => {
const root = await createCborCid('root')
const add = await delegate({
issuer: alice,
audience: w3,
capabilities: [
{
can: 'upload/add',
with: 'mailto:alice@web.mail',
root: parseLink('bafkqaaa'),
root,
},
],
proofs: [await any],
Expand Down Expand Up @@ -236,7 +240,7 @@ describe('upload capabilities', function () {
})
.delegate()

const root = await createCarCid('hello')
const root = await createCborCid('root')

const add = Upload.add.invoke({
issuer: bob,
Expand Down Expand Up @@ -266,26 +270,27 @@ describe('upload capabilities', function () {
})

it('upload/add should fail when escalating root', async () => {
const root = await createCborCid('hello')
const delegation = Upload.add
.invoke({
issuer: alice,
audience: bob,
with: account.did(),
nb: {
root: await createCarCid('hello'),
root,
},
proofs: [await any],
})
.delegate()

const root = await createCarCid('hello2')
const root2 = await createCborCid('hello2')

const add = Upload.add.invoke({
issuer: bob,
audience: w3,
with: account.did(),
nb: {
root,
root: root2,
},
proofs: [await delegation],
})
Expand All @@ -301,7 +306,7 @@ describe('upload capabilities', function () {
assert.equal(result.error, true)
assert(
String(result).includes(
'bagbaieraubcexvgwca3dj3xzd7qfheu6wuuiqikqoaoya7bwfj24ta4eqwca violates imposed root constraint bagbaieratxbhji7b2gtwb7gojwmb5rxngrf66flidrobs3ijglyjmtyu4juq'
'bafyreig7xrtnfhkdu4wt3fbufl4bppd5r5ixrowmi5ekw5vjundxynmzj4 violates imposed root constraint bafyreiglqnkzhzh2gyz4zfy7zpi6wcamumrclarakshlocd35l4o63l76q'
)
)
})
Expand All @@ -325,7 +330,7 @@ describe('upload capabilities', function () {
audience: w3,
with: account.did(),
nb: {
root: await createCarCid('world2'),
root: await createCborCid('world2'),
},
proofs: [await delegation],
})
Expand Down
8 changes: 8 additions & 0 deletions packages/access/test/helpers/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ export function parseCarLink(source) {
return /** @type {Ucanto.Link<unknown, 514, number, 1>} */ (parseLink(source))
}

/**
* @param {any} data
*/
export async function createCborCid(data) {
const cbor = await CBOR.write(data)
return cbor.cid
}

/**
* @param {string} source
*/
Expand Down

0 comments on commit aae5b66

Please sign in to comment.