Skip to content

Commit

Permalink
Merge pull request #35 from biscuit-auth/snapshots
Browse files Browse the repository at this point in the history
snapshot printer
  • Loading branch information
divarvel authored Nov 10, 2023
2 parents 1ee0693 + 4093a8f commit 53a4d11
Show file tree
Hide file tree
Showing 7 changed files with 345 additions and 6 deletions.
1 change: 1 addition & 0 deletions demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ <h1>demo biscuit</h1>
<h2>ready-to-use components</h2>
<ul>
<li><a href="token-printer.html">Token printer</a></li>
<li><a href="snapshot-printer.html">Snapshot printer</a></li>
<li><a href="playground.html">Datalog playground</a></li>
<li><a href="token-generator.html">Token generator</a></li>
<li><a href="editor.html">Datalog editor</a></li>
Expand Down
19 changes: 19 additions & 0 deletions demo/snapshot-printer.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>demo biscuit</title>
<link rel="stylesheet" href="/demo/index.css">
<script type="module" src="/src/index.ts"></script>
</head>
<body>
<h1>demo biscuit</h1>

<bc-snapshot-printer showAuthorizer="true" showQuery="true">
</bc-snapshot-printer>


</body>
</html>
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@
"build": "tsc",
"prepublishOnly": "npm run build-lint && tsc && tsc -p tsconfig-cjs.json && cp tree-sitter.js dist/esm && cp tree-sitter.d.ts dist/esm && cp -r assets dist/",
"build-lint": "tsc && eslint src --ext .ts && prettier -c src",
"format": "prettier -w src"
"format": "prettier -w src",
"lint-fix": "eslint src --ext .ts --fix"
},
"dependencies": {
"@biscuit-auth/biscuit-wasm-support": "0.4.0",
"@biscuit-auth/biscuit-wasm-support": "^0.4.1",
"@codemirror/basic-setup": "^0.19.0",
"@codemirror/gutter": "^0.19.5",
"@codemirror/highlight": "^0.19.6",
Expand Down
305 changes: 305 additions & 0 deletions src/bc-snapshot-printer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,305 @@
import { css, html, LitElement } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import "./bc-datalog-editor";
import { initialize } from "./wasm.js";
import { inspect_snapshot } from "@biscuit-auth/biscuit-wasm-support";
import {
AuthorizerError,
AuthorizerResult,
Fact,
LogicError,
Result,
SnapshotInspectionResult,
trimLines,
} from "./lib/adapters";

/**
* TODO DOCS
*/
@customElement("bc-snapshot-printer")
export class BcSnapshotPrinter extends LitElement {
@property()
snapshot = "";

@property()
readonly = false;

@property()
showAuthorizer = false;

@property()
showQuery = false;

@property()
authorizer = "";

@property()
query = "";

@state()
_started = false;

constructor() {
super();
const authorizerChild = this.querySelector(".authorizer");
if (authorizerChild !== null) {
this.authorizer = trimLines(authorizerChild.textContent ?? "");
}
}

firstUpdated() {
initialize().then(() => (this._started = true));
}

_onUpdatedSnapshot(e: InputEvent) {
if (this.readonly) return;
this.snapshot = (e.target as HTMLInputElement).value.trim();
}

_onUpdatedQuery(e: { detail: { code: string } }) {
if (!this.showQuery) return;
this.query = e.detail.code;
}

_onUpdatedAuthorizer(e: { detail: { code: string } }) {
if (!this.showAuthorizer) return;
this.authorizer = e.detail.code;
}

renderSnapshotInput() {
if (this.readonly) {
return html`
<div class="code">
<p>Encoded snapshot</p>
<code>${this.snapshot}</code>
</div>
`;
}
return html`
<div class="code">
<p>Encoded snapshot</p>
<textarea @input=${this._onUpdatedSnapshot}>${this.snapshot}</textarea>
</div>
`;
}

renderNotStarted() {
return html`
<div class="snapshot">
${this.renderSnapshotInput()}
<div class="content">loading biscuit snapshot</div>
</div>
`;
}

renderEmptyToken() {
return html`
${this.renderSnapshotInput()}
<div class="content">Please enter a base64-encoded snapshot</div>
`;
}

renderResult(result: SnapshotInspectionResult) {
if (this.snapshot === "") {
return html`
${this.renderSnapshotInput()}
<div class="content">Please enter a base64-encoded snapshot</div>
`;
}

if (result.snapshot.Err) {
return html`
${this.renderSnapshotInput()}
<div class="content">${result.snapshot.Err}</div>
`;
}

const {
code,
elapsed_micros,
iterations,
authorization_result,
query_result,
} = result.snapshot.Ok!;

const auth_res: Result<AuthorizerResult, AuthorizerError> = {
Ok: {
authorizer_editor: { markers: [] },
authorizer_result: authorization_result,
authorizer_world: [],
token_blocks: [],
},
};

return html`
${this.renderSnapshotInput()}
<div class="content">
<p>Elapsed time: ${elapsed_micros.toString()}μs</p>
<p>Iterations: ${iterations}</p>
<p>Snapshot contents</p>
<bc-datalog-editor code=${code} .marks=${[]} readonly="true">
</bc-datalog-editor>
${this.renderAuthorizerInput()}
<bc-authorizer-result .content=${auth_res}></bc-authorizer-result>
${this.renderQueryInput()}
${query_result && this.renderQueryResult(query_result)}
</div>
`;
}

renderAuthorizerInput() {
if (!this.showAuthorizer) return;

return html`
<p>Extra authorizer code</p>
<bc-datalog-editor
@bc-datalog-editor:update=${(e: { detail: { code: string } }) =>
this._onUpdatedAuthorizer(e)}
>
</bc-datalog-editor>
`;
}

renderQueryInput() {
if (!this.showQuery) return;

return html`
<p>Query snapshot</p>
<bc-datalog-editor
@bc-datalog-editor:update=${(e: { detail: { code: string } }) =>
this._onUpdatedQuery(e)}
>
</bc-datalog-editor>
`;
}

renderQueryResult(result: Result<Array<Fact>, LogicError>) {
if (result.Err) {
console.error(result.Err);
return html`<p>error</p>`;
} else {
return html`<bc-authorizer-content .content=${result.Ok!}>
</bc-authorizer-content>`;
}
}

render() {
if (!this._started) return this.renderNotStarted();
const inspectQuery = {
data: this.snapshot,
extra_authorizer: this.authorizer != "" ? this.authorizer : undefined,
query: this.query != "" ? this.query : undefined,
};
const parseResult = inspect_snapshot(inspectQuery);

return html` <div class="row">${this.renderResult(parseResult)}</div> `;
}

static styles = css`
.row {
display: flex;
flex-direction: column;
text-align: left;
}
.public-key-input {
display: flex;
}
.public-key-input label {
height: 1.5em;
}
#public-key {
margin-left: 1em;
flex-grow: 1;
}
@media (prefers-color-scheme: dark) {
.row {
color: #dee2e6;
background: #131314;
}
textarea {
color: #dee2e6;
background: #131314;
}
}
@media (prefers-color-scheme: light) {
.row {
color: #1d2d35;
background: #fff;
}
}
@media (min-width: 576px) {
.row {
display: flex;
flex-flow: row wrap;
flex-direction: row;
}
.code {
order: 1;
width: 49%;
}
.content {
order: 2;
width: 49%;
}
}
code {
overflow-wrap: anywhere;
padding: 0.2em;
padding-top: 1em;
}
.code {
border: 1px rgba(128, 128, 128, 0.4) solid;
display: flex;
flex-direction: column;
}
textarea {
flex-grow: 1;
border: 0;
}
.content {
border-top: 1px rgba(128, 128, 128, 0.4) solid;
border-right: 1px rgba(128, 128, 128, 0.4) solid;
}
p {
border-bottom: 1px rgba(128, 128, 128, 0.4) solid;
margin-block-start: 0px;
margin-block-end: 0px;
padding: 0.2em;
font-size: 0.8em;
}
.revocation-id,
.external-key {
overflow: hidden;
diplay: inline-block;
text-overflow: ellipsis;
max-width: 100;
}
.revocation-id,
.external-key > .id {
user-select: all;
}
.content code {
user-select: all;
}
bc-datalog-editor {
border-bottom: 1px rgba(128, 128, 128, 0.4) solid;
}
`;
}
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ import "./bc-authorizer-result";
import "./bc-datalog-playground";
import "./bc-token-printer";
import "./bc-token-generator";
import "./bc-snapshot-printer";
export { execute } from "@biscuit-auth/biscuit-wasm-support";
export { initialize } from "./wasm.js";
12 changes: 12 additions & 0 deletions src/lib/adapters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,15 @@ export function trimLines(str: string) {
.map((line: string) => line.trim())
.join("\n");
}

export type SnapshotInspectionResult = {
snapshot: Result<SnapshotData, LogicError>;
};

export type SnapshotData = {
code: string;
iterations: number;
elapsed_micros: bigint;
authorization_result: Result<number, { FailedLogic?: LogicError }>;
query_result?: Result<Array<Fact>, LogicError>;
};

0 comments on commit 53a4d11

Please sign in to comment.