Skip to content

Commit

Permalink
fix: sync space names from proofs (storacha#1193)
Browse files Browse the repository at this point in the history
space names are stored as facts in proofs in the special `ucan:*`
delegation from email to agent e.g.

```yaml
iss: did:mailto:protocol.ai:oli
att:
  - can: *
    with: ucan:*
fct:
  - {"access/confirm":{"/":"bafyreidadrwbxueiuhtbph2tj2m7a6nizpx7sbtqotbfkkjsoytn3dg2t4"},"access/request":{"/":"bafyreigmlliovbpxka2borbdaw6zpsai4qzmzv5nv7syl7nagecxjcub6e"}}
prf:
  - {"iss":"did:key:z6Mku56ywWspVnzkcVQbeSkw6egVRSNKVSYgS38HhKcUJRiN","aud":"did:mailto:protocol.ai:oli","v":"0.9.1","s":{"/":{"bytes":"7aEDQPgUVQFVOoLmijx8O7Li9zyc7iIHEDnCwiqr+LcV9CyHd/KzUg1Ige7Okh+ipVMOKy2EvG8dGjWfsdAAbUVPMwo"}},"exp":null,"att":[{"can":"*","with":"did:key:z6Mku56ywWspVnzkcVQbeSkw6egVRSNKVSYgS38HhKcUJRiN"}],"fct":[{"space":{"name":"fruits"}}],"prf":[],"/":"bafyreihhlz5yjci6h7vdrlgn5xnyc65e3unp3dx2yrspepwoftaxszxpxa"}
```

this will be fixed more robustly by the proposed re-imagining of the
client as a stateless view over the stored ucans, but i'd like to land
this fix asap, as it's currently you dont' get to see your existing
space names when calling login in a new agent.

fixes: storacha#1176

License: MIT

---------

Signed-off-by: Oli Evans <oli@protocol.ai>
  • Loading branch information
olizilla authored Nov 29, 2023
1 parent 24aed89 commit f552036
Showing 1 changed file with 43 additions and 15 deletions.
58 changes: 43 additions & 15 deletions packages/access-client/src/agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,14 @@ import { attest } from '@web3-storage/capabilities/ucan'
import * as Access from './access.js'
import * as Space from './space.js'

import { invoke, delegate, DID, Delegation, Schema } from '@ucanto/core'
import {
invoke,
delegate,
DID,
Delegation,
Schema,
isDelegation,
} from '@ucanto/core'
import { isExpired, isTooEarly, canDelegateCapability } from './delegations.js'
import { AgentData, getSessionProofs } from './agent-data.js'
import { UCAN } from '@web3-storage/capabilities'
Expand Down Expand Up @@ -621,24 +628,45 @@ export async function addSpacesFromDelegations(agent, delegations) {
})
}

for (const delegation of delegations) {
// We only consider delegations to this agent as those are only spaces that
// this agent will be able to interact with.
if (delegation.audience.did() === agent.did()) {
// TODO: we need a more robust way to determine which spaces a user has access to
// it may or may not involve look at delegations
const allows = ucanto.Delegation.allows(delegation)

for (const [did, value] of Object.entries(allows)) {
// If we discovered a delegation to any DID, we add it to the spaces list.
if (did.startsWith('did:key') && Object.keys(value).length > 0) {
await data.addSpace(/** @type {API.DID} */ (did), {
name: '',
})
// spaces we find along the way.
const spaces = new Map()
// only consider ucans with this agent as the audience
const ours = delegations.filter((x) => x.audience.did() === agent.did())
// space names are stored as facts in proofs in the special `ucan:*` delegation from email to agent.
const ucanStars = ours.filter(
(x) => x.capabilities[0].can === '*' && x.capabilities[0].with === 'ucan:*'
)
for (const delegation of ucanStars) {
for (const proof of delegation.proofs) {
if (
!isDelegation(proof) ||
!proof.capabilities[0].with.startsWith('did:key')
) {
continue
}
const space = Space.fromDelegation(proof)
spaces.set(space.did(), space.meta)
}
}

// Find any other spaces the user may have access to
for (const delegation of ours) {
// TODO: we need a more robust way to determine which spaces a user has access to
// it may or may not involve look at delegations
const allows = ucanto.Delegation.allows(delegation)
for (const [resource, value] of Object.entries(allows)) {
// If we discovered a delegation to any DID, we add it to the spaces list.
if (resource.startsWith('did:key') && Object.keys(value).length > 0) {
if (!spaces.has(resource)) {
spaces.set(resource, {})
}
}
}
}

for (const [did, meta] of spaces) {
await data.addSpace(did, meta)
}
}

/**
Expand Down

0 comments on commit f552036

Please sign in to comment.