Skip to content

Commit

Permalink
feat: rip out special handling of my: and as: capabilities (#109)
Browse files Browse the repository at this point in the history
* fix: optional caveats

backport #105 into 0.9

* stash: current status of schema code

* chore: increase coverage

* fix: get 100 coverage

* chore: optimize typings

* chore: rename decoder to schema

* feat: update decoders to new API

* feat: increase coverage to 100%

* fix: regressions in other packages

* fix: bundler issue

* chore: rip out my: and as: support

* Update packages/validator/test/extra-schema.spec.js
  • Loading branch information
Gozala authored Oct 16, 2022
1 parent e2e03ff commit 3ec8e64
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 441 deletions.
15 changes: 2 additions & 13 deletions packages/interface/src/capability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,17 +298,7 @@ export interface PrincipalOptions {
principal: PrincipalParser
}

export interface IssuingOptions {
/**
* You can provide default set of capabilities per did, which is used to
* validate whether claim is satisfied by `{ with: my:*, can: "*" }`. If
* not provided resolves to `[]`.
*/

my?: (issuer: DID) => Capability[]
}

export interface ProofResolver extends PrincipalOptions, IssuingOptions {
export interface ProofResolver extends PrincipalOptions {
/**
* You can provide a proof resolver that validator will call when UCAN
* links to external proof. If resolver is not provided validator may not
Expand All @@ -318,8 +308,7 @@ export interface ProofResolver extends PrincipalOptions, IssuingOptions {
}

export interface ValidationOptions<C extends ParsedCapability>
extends CanIssue,
IssuingOptions,
extends Partial<CanIssue>,
PrincipalOptions,
ProofResolver {
capability: CapabilityParser<Match<C, any>>
Expand Down
67 changes: 9 additions & 58 deletions packages/validator/src/lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ export { capability } from './capability.js'
export * from './schema.js'
export * as Schema from './schema.js'

const empty = () => []

/**
* @param {UCAN.Link} proof
*/
Expand Down Expand Up @@ -115,7 +113,7 @@ const resolveSources = async ({ delegation }, config) => {
} else {
// otherwise create source objects for it's capabilities, so we could
// track which proof in which capability the are from.
for (const capability of iterateCapabilities(proof, config)) {
for (const capability of proof.capabilities) {
sources.push({
capability,
delegation: proof,
Expand All @@ -130,6 +128,12 @@ const resolveSources = async ({ delegation }, config) => {
return { sources, errors }
}

/**
* @param {API.ParsedCapability} capability
* @param {API.DID} issuer
*/
const isSelfIssued = (capability, issuer) => capability.with === issuer

/**
* @template {API.Ability} A
* @template {API.URI} R
Expand All @@ -141,9 +145,9 @@ const resolveSources = async ({ delegation }, config) => {
*/
export const access = async (
invocation,
{ canIssue, principal, my = empty, resolve = unavailable, capability }
{ canIssue = isSelfIssued, principal, resolve = unavailable, capability }
) => {
const config = { canIssue, my, resolve, principal, capability }
const config = { canIssue, resolve, principal, capability }

const claim = capability.match({
capability: invocation.capabilities[0],
Expand Down Expand Up @@ -334,59 +338,6 @@ class Unauthorized extends Failure {
return { error, name, message, cause, stack }
}
}
const ALL = '*'

/**
* @param {API.Delegation} delegation
* @param {Required<API.IssuingOptions>} options
*/
function* iterateCapabilities({ issuer, capabilities }, { my }) {
const did = issuer.did()
for (const capability of capabilities) {
const uri = parseMyURI(capability.with, did) || parseAsURI(capability.with)
const { can } = capability

if (uri) {
for (const capability of my(uri.did)) {
if (
capability.with.startsWith(uri.protocol) &&
(can === ALL || capability.can === can)
) {
yield capability
}
}
} else {
yield capability
}
}
}

const AS_PATTERN = /as:(.*):(.*)/
const MY = /my:(.*)/

/**
* @param {string} uri
* @returns {{did:API.DID, protocol:string}|null}
*/
const parseAsURI = uri => {
const [, did, kind] = AS_PATTERN.exec(uri) || []
return did != null && kind != null
? {
did: /** @type {API.DID} */ (did),
protocol: kind === ALL ? '' : `${kind}:`,
}
: null
}

/**
* @param {string} uri
* @param {API.DID} did
*/

const parseMyURI = (uri, did) => {
const [, kind] = MY.exec(uri) || []
return kind != null ? { did, protocol: kind === ALL ? '' : `${kind}:` } : null
}

/**
* @template {API.Delegation} T
Expand Down
Loading

0 comments on commit 3ec8e64

Please sign in to comment.