-
Notifications
You must be signed in to change notification settings - Fork 1
MILAB-5815: resource signature support #1553
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
2c8cdd4
2cd0a79
110a697
385217b
828479a
b05b7cd
8b1b471
d47af3a
de52353
16bdf1e
9eb7a35
c01dc4b
4e6f65f
156422b
b8abbbe
c05891e
9913614
0702bdc
8ac66a7
84698f3
392677f
5322110
1cd84e1
5aa69af
8bd1835
0a2e14a
7a37723
2660124
6db30bb
1a8c22c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| --- | ||
| "@milaboratories/pl-client": minor | ||
| "@milaboratories/pl-drivers": minor | ||
| "@milaboratories/pl-tree": minor | ||
| --- | ||
|
|
||
| Add resource signature propagation for server-side access control. | ||
|
|
||
| - `pl-client`: cross-transaction `SignatureCache`, automatic signature tracking in `PlTransaction` (store/retrieve signatures for all resource and field operations), `setDefaultColor` for color proof on resource creation, `PermissionDeniedError` error type | ||
| - `pl-drivers`: pass `resourceSignature` through proxied APIs (download, upload, logs, progress, ls), encode signatures in remote blob and log handles | ||
| - `pl-tree`: propagate `resourceSignature` in `ResourceInfo`, `ResourceSnapshot`, and `PlTreeResource` state |
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -5,6 +5,18 @@ import { test, expect } from "vitest"; | |||||||||||
|
|
||||||||||||
| import { isTimeoutOrCancelError } from "./errors"; | ||||||||||||
| import { Aborted } from "@milaboratories/ts-helpers"; | ||||||||||||
| import type { LLPlClient } from "./ll_client"; | ||||||||||||
|
|
||||||||||||
| /** Get root resource signature from ListUserResources for use as color proof in tests. */ | ||||||||||||
| async function getRootSignature(client: LLPlClient): Promise<Uint8Array> { | ||||||||||||
| const responses = await client.listUserResources({ limit: 1 }); | ||||||||||||
| for (const msg of responses) { | ||||||||||||
| if (msg.entry.oneofKind === "userRoot" && msg.entry.userRoot.resourceSignature) { | ||||||||||||
| return msg.entry.userRoot.resourceSignature; | ||||||||||||
| } | ||||||||||||
| } | ||||||||||||
| return new Uint8Array(0); | ||||||||||||
| } | ||||||||||||
|
|
||||||||||||
| test("check successful transaction", async () => { | ||||||||||||
| const client = await getTestLLClient(); | ||||||||||||
|
|
@@ -80,6 +92,7 @@ test("check timeout error type (passive)", async () => { | |||||||||||
|
|
||||||||||||
| test("check timeout error type (active)", async () => { | ||||||||||||
| const client = await getTestLLClient(); | ||||||||||||
| const rootSig = await getRootSignature(client); | ||||||||||||
| const tx = client.createTx(true, { timeout: 500 }); | ||||||||||||
|
|
||||||||||||
| try { | ||||||||||||
|
|
@@ -96,6 +109,12 @@ test("check timeout error type (active)", async () => { | |||||||||||
| ); | ||||||||||||
| expect(openResponse.txOpen.tx?.isValid).toBeTruthy(); | ||||||||||||
|
|
||||||||||||
| // Set default color so resource creation succeeds in strict mode | ||||||||||||
| await tx.send( | ||||||||||||
| { oneofKind: "setDefaultColor", setDefaultColor: { colorProof: rootSig } }, | ||||||||||||
| false, | ||||||||||||
| ); | ||||||||||||
|
|
||||||||||||
| const rData = Uint8Array.from([ | ||||||||||||
| (Math.random() * 256) & 0xff, | ||||||||||||
| (Math.random() * 256) & 0xff, | ||||||||||||
|
|
@@ -115,12 +134,13 @@ test("check timeout error type (active)", async () => { | |||||||||||
| type: { name: "TestValue", version: "1" }, | ||||||||||||
| data: rData, | ||||||||||||
| errorIfExists: false, | ||||||||||||
| colorProof: new Uint8Array(0), | ||||||||||||
| }, | ||||||||||||
| }, | ||||||||||||
| false, | ||||||||||||
| ); | ||||||||||||
| const id = (await createResponse).resourceCreateValue.resourceId; | ||||||||||||
| const createResp = (await createResponse).resourceCreateValue; | ||||||||||||
| const id = createResp.resourceId; | ||||||||||||
| const resourceSignature = createResp.resourceSignature ?? new Uint8Array(0); | ||||||||||||
|
Comment on lines
+141
to
+143
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The
Suggested change
|
||||||||||||
|
|
||||||||||||
| while (true) { | ||||||||||||
| const vr = await tx.send( | ||||||||||||
|
|
@@ -129,7 +149,7 @@ test("check timeout error type (active)", async () => { | |||||||||||
| resourceGet: { | ||||||||||||
| resourceId: id, | ||||||||||||
| loadFields: false, | ||||||||||||
| resourceSignature: new Uint8Array(0), | ||||||||||||
| resourceSignature, | ||||||||||||
| }, | ||||||||||||
| }, | ||||||||||||
| false, | ||||||||||||
|
|
@@ -144,6 +164,7 @@ test("check timeout error type (active)", async () => { | |||||||||||
|
|
||||||||||||
| test("check is abort error (active)", async () => { | ||||||||||||
| const client = await getTestLLClient(); | ||||||||||||
| const rootSig = await getRootSignature(client); | ||||||||||||
| const tx = client.createTx(true, { abortSignal: AbortSignal.timeout(100) }); | ||||||||||||
|
|
||||||||||||
| try { | ||||||||||||
|
|
@@ -160,6 +181,12 @@ test("check is abort error (active)", async () => { | |||||||||||
| ); | ||||||||||||
| expect(openResponse.txOpen.tx?.isValid).toBeTruthy(); | ||||||||||||
|
|
||||||||||||
| // Set default color so resource creation succeeds in strict mode | ||||||||||||
| await tx.send( | ||||||||||||
| { oneofKind: "setDefaultColor", setDefaultColor: { colorProof: rootSig } }, | ||||||||||||
| false, | ||||||||||||
| ); | ||||||||||||
|
|
||||||||||||
| const rData = Uint8Array.from([ | ||||||||||||
| Math.random() & 0xff, | ||||||||||||
| Math.random() & 0xff, | ||||||||||||
|
|
@@ -179,12 +206,13 @@ test("check is abort error (active)", async () => { | |||||||||||
| type: { name: "TestValue", version: "1" }, | ||||||||||||
| data: rData, | ||||||||||||
| errorIfExists: false, | ||||||||||||
| colorProof: new Uint8Array(0), | ||||||||||||
| }, | ||||||||||||
| }, | ||||||||||||
| false, | ||||||||||||
| ); | ||||||||||||
| const id = (await createResponse).resourceCreateValue.resourceId; | ||||||||||||
| const createResp = (await createResponse).resourceCreateValue; | ||||||||||||
| const id = createResp.resourceId; | ||||||||||||
| const resourceSignature = createResp.resourceSignature ?? new Uint8Array(0); | ||||||||||||
|
Comment on lines
+213
to
+215
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar to the previous comment, the
Suggested change
|
||||||||||||
|
|
||||||||||||
| while (true) { | ||||||||||||
| const vr = await tx.send( | ||||||||||||
|
|
@@ -193,7 +221,7 @@ test("check is abort error (active)", async () => { | |||||||||||
| resourceGet: { | ||||||||||||
| resourceId: id, | ||||||||||||
| loadFields: false, | ||||||||||||
| resourceSignature: new Uint8Array(0), | ||||||||||||
| resourceSignature, | ||||||||||||
| }, | ||||||||||||
| }, | ||||||||||||
| false, | ||||||||||||
|
|
||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
awaiton already-resolved valuecreateResponseis obtained viaconst createResponse = await tx.send(...)(line 129), so it is already the resolvedServerMessageResponsevalue, not aPromise. The innerawait createResponseon this line re-awaits a non-Promise, which works but is misleading. The same pattern appears in the "check is abort error (active)" test at line 213.Prompt To Fix With AI