Skip to content

Commit 3ac0f70

Browse files
committed
Implement zcap refresh policy fetch endpoint.
1 parent dc13471 commit 3ac0f70

3 files changed

Lines changed: 37 additions & 27 deletions

File tree

lib/middleware.js

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,19 +69,21 @@ export function verifyRefreshableZcapDelegation() {
6969
return asyncHandler(async function verifyRefreshZcap(req, res, next) {
7070
const {body: capability} = req;
7171

72-
// these params are always present where this middleware is present
73-
const {profileId, delegateId} = req.params;
74-
75-
// confirm the zcap controller (delegate) matches the route `delegateId`
76-
if(capability.controller !== delegateId) {
72+
// confirm the invoked zcap controller matches the controller of the zcap
73+
// that is to be refreshed
74+
if(capability.controller !== req.zcap.controller) {
7775
throw new BedrockError(
78-
`The given capability's controller does not match the refresh ` +
79-
`endpoint; the capability controller must be "${delegateId}".`, {
76+
`The controller "${capability.controller}" of the capability to be ` +
77+
`refreshed must equal the invoked capability's controller ` +
78+
`${req.zcap.controller}.`, {
8079
name: 'NotAllowedError',
8180
details: {httpStatusCode: 403, public: true}
8281
});
8382
}
8483

84+
// `profileId` param always present where this middleware is used
85+
const {profileId} = req.params;
86+
8587
// verify CapabilityDelegation
8688
let delegator;
8789
const capture = {};

lib/refreshedZcapCache.js

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,23 +17,15 @@ bedrock.events.on('bedrock.init', async () => {
1717
REFRESHED_ZCAP_CACHE = new LruCache(cfg.caches.refreshedZcap);
1818
});
1919

20-
export async function getRefreshedZcap({profileId, delegateId, capability}) {
21-
const key = _createCacheKey({profileId, delegateId, capability});
22-
const fn = () => _getUncached({profileId, delegateId, capability});
20+
export async function getRefreshedZcap({profileId, capability}) {
21+
const key = _createCacheKey({profileId, capability});
22+
const fn = () => _getUncached({profileId, capability});
2323
return REFRESHED_ZCAP_CACHE.memoize({key, fn});
2424
}
2525

26-
function _createCacheKey({profileId, delegateId, capability}) {
27-
const json = {profileId, delegateId, canonicalZcap: canonicalize(capability)};
28-
const hash = createHash('sha256').update(json, 'utf8').digest('base64url');
29-
return hash;
30-
}
31-
32-
async function _getUncached({profileId, delegateId, capability}) {
33-
// get the policy for the profile + controller (delegate)
34-
let policy;
26+
export async function getRefreshZcapPolicy({profileId, delegateId}) {
3527
try {
36-
policy = await brZcapStorage.policies.get({profileId, delegateId});
28+
return brZcapStorage.policies.get({profileId, delegateId});
3729
} catch(e) {
3830
// no matching policy, so refresh is denied
3931
if(e.name === 'NotFoundError') {
@@ -46,6 +38,18 @@ async function _getUncached({profileId, delegateId, capability}) {
4638
}
4739
throw e;
4840
}
41+
}
42+
43+
function _createCacheKey({profileId, capability}) {
44+
const json = {profileId, canonicalZcap: canonicalize(capability)};
45+
const hash = createHash('sha256').update(json, 'utf8').digest('base64url');
46+
return hash;
47+
}
48+
49+
async function _getUncached({profileId, capability}) {
50+
// get the policy for the profile + controller (delegate)
51+
const {controller: delegateId} = capability;
52+
const policy = await getRefreshZcapPolicy({profileId, delegateId});
4953

5054
// get the profile signer associated with the policy
5155
// FIXME: perhaps allow "any root profile agent" to be used, requiring

lib/zcaps.js

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
import * as bedrock from '@bedrock/core';
55
import * as middleware from './middleware.js';
66
import * as schemas from '../schemas/bedrock-profile-http.js';
7+
import {getRefreshedZcap, getRefreshZcapPolicy} from './refreshedZcapCache.js';
78
import {asyncHandler} from '@bedrock/express';
89
import cors from 'cors';
9-
import {getRefreshedZcap} from './refreshedZcapCache.js';
1010
import {createValidateMiddleware as validate} from '@bedrock/validation';
1111

1212
// FIXME: use below
@@ -125,9 +125,9 @@ bedrock.events.on('bedrock-express.configure.routes', app => {
125125
middleware.authorizeProfileZcapRequest(),
126126
middleware.verifyRefreshableZcapDelegation(),
127127
asyncHandler(async (req, res) => {
128-
const {profileId, delegateId} = req.params;
128+
const {profileId} = req.params;
129129
const {body: capability} = req;
130-
const zcap = await getRefreshedZcap({profileId, delegateId, capability});
130+
const zcap = await getRefreshedZcap({profileId, capability});
131131
res.json({zcap});
132132
}));
133133

@@ -136,9 +136,13 @@ bedrock.events.on('bedrock-express.configure.routes', app => {
136136
app.post(
137137
routes.viewablePolicy,
138138
middleware.authorizeProfileZcapRequest(),
139-
asyncHandler(async (/*req, res*/) => {
140-
// FIXME: implement; use `controller` of invoked zcap to determine
141-
// `delegateId` to look up policy details
142-
throw new Error('Not implemented');
139+
asyncHandler(async (req, res) => {
140+
// use `controller` of invoked zcap to determine `delegateId` to look up
141+
// policy details
142+
const {profileId} = req.params;
143+
const {controller: delegateId} = req.zcap;
144+
const policy = await getRefreshZcapPolicy({profileId, delegateId});
145+
// FIXME: attenuate policy
146+
res.json({policy});
143147
}));
144148
});

0 commit comments

Comments
 (0)