Skip to content

Commit

Permalink
capabilities satisifiers
Browse files Browse the repository at this point in the history
  • Loading branch information
bucko13 committed Feb 10, 2022
1 parent 4c75ea8 commit a824a0a
Show file tree
Hide file tree
Showing 6 changed files with 238 additions and 109 deletions.
62 changes: 61 additions & 1 deletion src/satisfiers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import {
InvalidServicesError,
SERVICES_CAVEAT_CONDITION,
decodeServicesCaveat,
InvalidCapabilitiesError,
SERVICE_CAPABILITIES_SUFFIX,
decodeCapabilitiesValue,
} from '.'

/**
Expand Down Expand Up @@ -44,24 +47,31 @@ export const createServicesSatisfier = (targetService: string): Satisfier => {
satisfyPrevious: (prev: Caveat, curr: Caveat): boolean => {
const prevServices = decodeServicesCaveat(prev.value.toString())
const currentServices = decodeServicesCaveat(curr.value.toString())
let previouslyAllowed = new Map()

// making typescript happy
if (!Array.isArray(prevServices) || !Array.isArray(currentServices))
throw new InvalidServicesError()

// Construct a set of the services we were previously
// allowed to access.
let previouslyAllowed = new Map()
previouslyAllowed = prevServices.reduce(
(prev, current) => prev.set(current.name, current.tier),
previouslyAllowed
)

// The caveat should not include any new services that
// weren't previously allowed.
for (const service of currentServices) {
if (!previouslyAllowed.has(service.name)) return false
// confirm that previous service tier cannot be higher than current
const prevTier: number = previouslyAllowed.get(service.name)
if (prevTier > service.tier) return false
}

return true
},

satisfyFinal: (caveat: Caveat): boolean => {
const services = decodeServicesCaveat(caveat.value.toString())
// making typescript happy
Expand All @@ -74,3 +84,53 @@ export const createServicesSatisfier = (targetService: string): Satisfier => {
},
}
}

export const createCapabilitiesSatisfier = (
service: string,
targetCapability: string
): Satisfier => {
// validate targetService
if (typeof targetCapability !== 'string') throw new InvalidCapabilitiesError()
if (typeof service !== 'string') throw new InvalidCapabilitiesError()

return {
condition: service + SERVICE_CAPABILITIES_SUFFIX,
satisfyPrevious: (prev: Caveat, curr: Caveat): boolean => {
const prevCapabilities = decodeCapabilitiesValue(prev.value.toString())
const currentCapabilities = decodeCapabilitiesValue(curr.value.toString())

// making typescript happy
if (
!Array.isArray(prevCapabilities) ||
!Array.isArray(currentCapabilities)
)
throw new InvalidServicesError()

// Construct a set of the service's capabilities we were
// previously allowed to access.
let previouslyAllowed = new Set()
previouslyAllowed = prevCapabilities.reduce(
(prev, current) => prev.add(current),
previouslyAllowed
)

// The caveat should not include any new service
// capabilities that weren't previously allowed.
for (const capability of currentCapabilities) {
if (!previouslyAllowed.has(capability)) return false
}

return true
},
satisfyFinal: (caveat: Caveat): boolean => {
const capabilities = decodeCapabilitiesValue(caveat.value.toString())
// making typescript happy
if (!Array.isArray(capabilities)) throw new InvalidServicesError()

for (const capability of capabilities) {
if (capability === targetCapability) return true
}
return false
},
}
}
8 changes: 8 additions & 0 deletions src/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,11 @@ export const createNewCapabilitiesCaveat = (
comp: '=',
})
}

export const decodeCapabilitiesValue = (value: string): string[] => {
if (typeof value !== 'string') throw new InvalidCapabilitiesError()
return value
.toString()
.split(',')
.map((s: string) => s.trim())
}

0 comments on commit a824a0a

Please sign in to comment.