Skip to content

Commit 7d2b7b7

Browse files
author
Guy Bedford
authored
feat: dynamic backends clientCertificate with SecretStore fromBytes, rawbytes (#796)
1 parent 1e54f05 commit 7d2b7b7

40 files changed

+5571
-4175
lines changed

.github/workflows/dependencies.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ jobs:
1111
steps:
1212
- uses: actions/[email protected]
1313
with:
14-
allow-licenses: Apache-2.0, MIT, BSD-3-Clause, ISC, BSD-2-Clause, MIT OR (CC0-1.0 AND MIT), CC0-1.0 OR MIT OR (CC0-1.0 AND MIT), CC-BY-3.0, CC0-1.0, MIT OR Apache-2.0, MIT AND Apache-2.0, MIT OR WTFPL, BSD-2-Clause OR (MIT OR Apache-2.0), Python-2.0, ISC AND MIT, Apache-2.0 AND MIT, MIT/Apache-2.0, Apache-2.0 OR MIT, (Apache-2.0 OR MIT) AND BSD-3-Clause, Zlib OR Apache-2.0 OR MIT, MIT OR Apache-2.0 OR Zlib, MIT OR (Apache-2.0 OR Zlib)
14+
allow-licenses: Apache-2.0, MIT, BSD-3-Clause, ISC, BSD-2-Clause, MIT OR (CC0-1.0 AND MIT), CC0-1.0 OR MIT OR (CC0-1.0 AND MIT), CC-BY-3.0, CC0-1.0, MIT OR Apache-2.0, MIT AND Apache-2.0, MIT OR WTFPL, BSD-2-Clause OR (MIT OR Apache-2.0), Python-2.0, ISC AND MIT, Apache-2.0 AND MIT, MIT/Apache-2.0, Apache-2.0 OR MIT, (Apache-2.0 OR MIT) AND BSD-3-Clause, Zlib OR Apache-2.0 OR MIT, MIT OR Apache-2.0 OR Zlib, MIT OR (Apache-2.0 OR Zlib), (Apache-2.0 WITH LLVM-exception)
1515
fail-on-scopes: runtime

integration-tests/js-compute/fixtures/app/src/dynamic-backend.js

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,6 @@ routes.set("/backend/timeout", async () => {
278278

279279
// constructor
280280
{
281-
282281
routes.set("/backend/constructor/called-as-regular-function", async () => {
283282
let error = assertThrows(() => {
284283
Backend()
@@ -1386,6 +1385,64 @@ routes.set("/backend/timeout", async () => {
13861385
return pass('ok')
13871386
});
13881387
}
1388+
1389+
// clientCertificate property
1390+
{
1391+
routes.set("/backend/constructor/parameter-clientCertificate-property-invalid", async () => {
1392+
let error = assertThrows(() => {
1393+
new Backend({ name: 'clientCertificate-clientCertificate-property-invalid', target: 'a', clientCertificate: "" })
1394+
}, TypeError, `Backend constructor: clientCertificate must be an object containing 'certificate' and 'key' properties`)
1395+
if (error) { return error }
1396+
return pass('ok')
1397+
});
1398+
routes.set("/backend/constructor/parameter-clientCertificate-certificate-property-missing", async () => {
1399+
let error = assertThrows(() => {
1400+
new Backend({ name: 'clientCertificate-clientCertificate-certificate-property-missing', target: 'a', clientCertificate: {} })
1401+
}, TypeError, `Backend constructor: clientCertificate 'certificate' must be a certificate string`)
1402+
if (error) { return error }
1403+
return pass('ok')
1404+
});
1405+
routes.set("/backend/constructor/parameter-clientCertificate-certificate-property-invalid", async () => {
1406+
let error = assertThrows(() => {
1407+
new Backend({ name: 'clientCertificate-clientCertificate-certificate-property-invalid', target: 'a', clientCertificate: { certificate: "" } })
1408+
}, TypeError, `Backend constructor: clientCertificate 'certificate' can not be an empty string`)
1409+
if (error) { return error }
1410+
return pass('ok')
1411+
});
1412+
routes.set("/backend/constructor/parameter-clientCertificate-key-property-missing", async () => {
1413+
let error = assertThrows(() => {
1414+
new Backend({ name: 'clientCertificate-clientCertificate-key-property-missing', target: 'a', clientCertificate: { certificate: "a" } })
1415+
}, TypeError, `Backend constructor: clientCertificate 'key' must be a SecretStoreEntry instance`)
1416+
if (error) { return error }
1417+
return pass('ok')
1418+
});
1419+
routes.set("/backend/constructor/parameter-clientCertificate-key-property-invalid", async () => {
1420+
let error = assertThrows(() => {
1421+
new Backend({ name: 'clientCertificate-clientCertificate-key-property-invalid', target: 'a', clientCertificate: { certificate: "a", key: "" } })
1422+
}, TypeError, `Backend constructor: clientCertificate 'key' must be a SecretStoreEntry instance`)
1423+
if (error) { return error }
1424+
return pass('ok')
1425+
});
1426+
routes.set("/backend/constructor/parameter-clientCertificate-key-property-fake", async () => {
1427+
let error = assertThrows(() => {
1428+
new Backend({ name: 'clientCertificate-clientCertificate-key-property-fake', target: 'a', clientCertificate: { certificate: "a", key: Object.create(SecretStoreEntry.prototype) } })
1429+
}, TypeError, `Backend constructor: clientCertificate 'key' must be a SecretStoreEntry instance`)
1430+
if (error) { return error }
1431+
return pass('ok')
1432+
});
1433+
routes.set("/backend/constructor/parameter-clientCertificate-valid", async () => {
1434+
if (isRunningLocally()) {
1435+
return pass('ok')
1436+
}
1437+
let backend = new Backend({ name: 'clientCertificate-clientCertificate-valid', target: 'http-me.glitch.me', clientCertificate: { certificate: "a", key: SecretStore.fromBytes(new Uint8Array([1, 2, 3])) } })
1438+
let res = await fetch('https://http-me.glitch.me/headers', {
1439+
backend,
1440+
cacheOverride: new CacheOverride("pass"),
1441+
})
1442+
console.error(res);
1443+
return pass('ok')
1444+
});
1445+
}
13891446
}
13901447

13911448
// exists

integration-tests/js-compute/fixtures/app/src/secret-store.js

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ import fc from './fast-check.js';
117117
routes.set("/secret-store/get/called-as-constructor", () => {
118118
let error = assertThrows(() => {
119119
new SecretStore.prototype.get('1')
120-
}, TypeError, `SecretStore.prototype.get is not a constructor`)
120+
}, TypeError)
121121
if (error) { return error }
122122
return pass()
123123
});
@@ -238,6 +238,37 @@ import fc from './fast-check.js';
238238
return pass()
239239
});
240240
}
241+
242+
// SecretStore.fromBytes static method
243+
{
244+
routes.set("/secret-store/from-bytes/invalid", async () => {
245+
let error = assertThrows(() => {
246+
SecretStore.fromBytes("blah")
247+
}, TypeError, `SecretStore.fromBytes: bytes must be an ArrayBuffer or ArrayBufferView object`)
248+
if (error) { return error }
249+
return pass()
250+
});
251+
routes.set("/secret-store/from-bytes/valid", async () => {
252+
let result, error;
253+
result = SecretStore.fromBytes(new Uint8Array([1, 2, 3]));
254+
error = assert(result instanceof SecretStoreEntry, true, `(SecretStore.fromBytes(Uint8Array) instanceof SecretStoreEntry)`)
255+
if (error) { return error }
256+
error = assert(result.rawBytes(), new Uint8Array([1, 2, 3]), `(SecretStore.fromBytes(Uint8Array).rawBytes() === Uint8Array)`)
257+
if (error) { return error }
258+
result = SecretStore.fromBytes(new Uint16Array([4, 5, 6]));
259+
error = assert(result instanceof SecretStoreEntry, true, `(SecretStore.fromBytes(Uint16Array) instanceof SecretStoreEntry)`)
260+
if (error) { return error }
261+
// (can rely on Wasm being little endian)
262+
error = assert(result.rawBytes(), new Uint8Array([4, 0, 5, 0, 6, 0]), `(SecretStore.fromBytes(Uint16Array).rawBytes() === Uint8Array)`)
263+
if (error) { return error }
264+
result = SecretStore.fromBytes(new Uint16Array([7, 8, 9]).buffer);
265+
error = assert(result instanceof SecretStoreEntry, true, `(SecretStore.fromBytes(ArrayBuffer) instanceof SecretStoreEntry)`)
266+
if (error) { return error }
267+
error = assert(result.rawBytes(), new Uint8Array([7, 0, 8, 0, 9, 0]), `(SecretStore.fromBytes(ArrayBuffer).rawBytes() === Uint8Array)`)
268+
if (error) { return error }
269+
return pass()
270+
});
271+
}
241272
}
242273
// SecretStoreEntry
243274
{
@@ -290,7 +321,7 @@ function SecretStoreEntryInterfaceTests() {
290321
if (error) { return error }
291322

292323
actual = Reflect.ownKeys(SecretStoreEntry.prototype)
293-
expected = ["constructor", "plaintext"]
324+
expected = ["constructor", "plaintext", "rawBytes"]
294325
error = assert(actual, expected, `Reflect.ownKeys(SecretStoreEntry.prototype)`)
295326
if (error) { return error }
296327

@@ -354,7 +385,7 @@ function SecretStoreEntryInterfaceTests() {
354385

355386
function SecretStoreInterfaceTests() {
356387
let actual = Reflect.ownKeys(SecretStore)
357-
let expected = ["prototype", "length", "name"]
388+
let expected = ["prototype", "fromBytes", "length", "name"]
358389
let error = assert(actual, expected, `Reflect.ownKeys(SecretStore)`)
359390
if (error) { return error }
360391

integration-tests/js-compute/fixtures/app/tests-starlingmonkey.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,28 @@
1010
"GET /cache-override/constructor/valid-mode",
1111
"GET /cache-override/fetch/mode-none",
1212
"GET /cache-override/fetch/mode-pass",
13+
"GET /secret-store/exposed-as-global",
14+
"GET /secret-store/interface",
15+
"GET /secret-store/constructor/called-as-regular-function",
16+
"GET /secret-store/constructor/parameter-calls-7.1.17-ToString",
17+
"GET /secret-store/constructor/empty-parameter",
18+
"GET /secret-store/constructor/found-store",
19+
"GET /secret-store/constructor/missing-store",
20+
"GET /secret-store/constructor/invalid-name",
21+
"GET /secret-store/get/called-as-constructor",
22+
"GET /secret-store/get/called-unbound",
23+
"GET /secret-store/get/key-parameter-calls-7.1.17-ToString",
24+
"GET /secret-store/get/key-parameter-not-supplied",
25+
"GET /secret-store/get/key-parameter-empty-string",
26+
"GET /secret-store/get/key-parameter-255-character-string",
27+
"GET /secret-store/get/key-parameter-256-character-string",
28+
"GET /secret-store/get/key-parameter-invalid-string",
29+
"GET /secret-store/get/key-does-not-exist-returns-null",
30+
"GET /secret-store/get/key-exists",
31+
"GET /secret-store/from-bytes/invalid",
32+
"GET /secret-store/from-bytes/valid",
33+
"GET /secret-store-entry/interface",
34+
"GET /secret-store-entry/plaintext",
1335
"GET /simple-cache/interface",
1436
"GET /simple-store/constructor/called-as-regular-function",
1537
"GET /simple-cache/constructor/throws",
@@ -258,6 +280,13 @@
258280
"GET /backend/constructor/parameter-sniHostname-property-empty-string",
259281
"GET /backend/constructor/parameter-sniHostname-property-calls-7.1.17-ToString",
260282
"GET /backend/constructor/parameter-sniHostname-property-valid-string",
283+
"GET /backend/constructor/parameter-clientCertificate-property-invalid",
284+
"GET /backend/constructor/parameter-clientCertificate-certificate-property-missing",
285+
"GET /backend/constructor/parameter-clientCertificate-certificate-property-invalid",
286+
"GET /backend/constructor/parameter-clientCertificate-key-property-missing",
287+
"GET /backend/constructor/parameter-clientCertificate-key-property-invalid",
288+
"GET /backend/constructor/parameter-clientCertificate-key-property-fake",
289+
"GET /backend/constructor/parameter-clientCertificate-valid",
261290
"GET /backend/health/called-as-constructor-function",
262291
"GET /backend/health/empty-parameter",
263292
"GET /backend/health/parameter-calls-7.1.17-ToString",

0 commit comments

Comments
 (0)