Skip to content

Commit

Permalink
Merge pull request #34 from biscuit-auth/readmes-cleanup
Browse files Browse the repository at this point in the history
Prep for v0.4.0
  • Loading branch information
divarvel authored Apr 6, 2023
2 parents 43809bc + ce0bb6c commit 9cfbe80
Show file tree
Hide file tree
Showing 13 changed files with 231 additions and 71 deletions.
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Biscuit-Wasm
# Biscuit-wasm

This library wraps the [Rust implementation](https://github.com/biscuit-auth) of [Biscuit tokens](https://www.biscuitsec.org) in WebAssembly, for usage in NodeJS and browsers.

It provides an EcmaScript module, along with TypeScript type definitions.
It provides both EcmaScript and CommonJS modules, along with TypeScript type definitions.

## Usage

Expand All @@ -11,7 +11,7 @@ Add this dependency to your `package.json`:
```json
{
"dependencies": {
"@biscuit-auth/biscuit-wasm": "0.4.0-alpha1"
"@biscuit-auth/biscuit-wasm": "0.4.0-beta1"
}
}
```
Expand All @@ -20,14 +20,18 @@ Add this dependency to your `package.json`:

*see the example code in examples/node*

Due to some wasm side dependencies, to work in Node, biscuit-wasm requires that this be added to the application:
The `node` executable must be started with the [`--experimental-wasm-modules` flag](https://nodejs.org/api/esm.html#wasm-modules).

#### Node 16-18

Due to some wasm-side dependencies, to work in Node, biscuit-wasm requires that this be added to the application:

```javascript
import { webcrypto } from 'node:crypto'
globalThis.crypto = webcrypto
```

The `node` executable must also be started with the [`--experimental-wasm-modules` flag](https://nodejs.org/api/esm.html#wasm-modules).
This is no longer necessary starting with node 19.

### In browser

Expand Down
51 changes: 37 additions & 14 deletions examples/node/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import {Biscuit, PrivateKey, KeyPair, Fact, Rule, biscuit, authorizer, block, rule} from '@biscuit-auth/biscuit-wasm';
import { Biscuit, PrivateKey, KeyPair, authorizer, biscuit, block, check, fact, rule } from '@biscuit-auth/biscuit-wasm';
// necessary for esm support, see https://docs.rs/getrandom/latest/getrandom/#nodejs-es-module-support
import { webcrypto } from 'node:crypto'

// this is not required anymore with node19+
if(parseInt(process.version.match(/v(\d+)\.(\d+)\.(\d+)/)[1], 10) <= 18) {
if (parseInt(process.version.match(/v(\d+)\.(\d+)\.(\d+)/)[1], 10) <= 18) {
globalThis.crypto = webcrypto
}

let keypair = new KeyPair();

let pk = PrivateKey.fromString("473b5189232f3f597b5c2f3f9b0d5e28b1ee4e7cce67ec6b7fbf5984157a6b97");
let root = KeyPair.fromPrivateKey(pk);

Expand All @@ -18,13 +16,30 @@ let id = 1234;
let biscuitBuilder = biscuit`user(${id});`;

for (let right of ["read", "write"]) {
biscuitBuilder.merge(block`right(${right})`);
biscuitBuilder.addFact(fact`right(${right})`);
}

let thirdPartyPk = PrivateKey.fromString(
"39c657dbd3f68b09bc8e5fd9887c7cb47a91d1d3883ffbc495ca790552398a92"
);
let thirdPartyRoot = KeyPair.fromPrivateKey(thirdPartyPk);
biscuitBuilder.addCheck(check`check if group("admin") trusting ${thirdPartyRoot.getPublicKey()}`);

let token =
biscuitBuilder
.build(root.getPrivateKey()) // biscuit token
.appendBlock(block`check if user($u)`); // attenuated biscuit token

let thirdPartyRequest = token.getThirdPartyRequest();
let thirdPartyBlock = thirdPartyRequest.createBlock(
thirdPartyPk, block`group("admin");`
);

token = token.appendThirdPartyBlock(
thirdPartyRoot.getPublicKey(),
thirdPartyBlock
);

console.log(token.toString());
let serializedToken = token.toBase64();
console.log("created the token and signed it with the private key");
Expand All @@ -42,14 +57,22 @@ let policy = auth.authorizeWithLimits({
max_time_micro: 100
});
console.log("Authorized the token with the provided rules");
console.log("matched policy: "+ policy);
console.log("matched policy: " + policy);

let otherKeyPair = new KeyPair();
let r = rule`u($id) <- user($id), $id == ${id} trusting authority, ${otherKeyPair.getPublicKey()}`;
console.log(r.toString());
let facts = auth.query(r);
console.log("Queried the token (and the authorization context) and got the following results");
let r1 = rule`u($id) <- user($id)`;
console.log("The token authority block & authorization context can be queried:");
console.log(r1.toString());
let facts1 = auth.query(r1);
console.log(facts1.map(f => f.toString()));

for(let f of facts) {
console.log(f.toString());
}
let r2 = rule`g($id) <- group($id)`;
console.log(r2.toString());
console.log("Blocks are not queried by default:");
let facts2 = auth.query(r2);
console.log(facts2.map(f => f.toString()));

let r3 = rule`g($id) <- group($id) trusting ${thirdPartyRoot.getPublicKey()}`;
console.log("Third-party blocks can be queried by providing their public key");
console.log(r3.toString());
let facts3 = auth.query(r3);
console.log(facts3.map(f => f.toString()));
39 changes: 39 additions & 0 deletions examples/node/package-lock.json

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

2 changes: 2 additions & 0 deletions examples/node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
},
"devDependencies": {
"@wasm-tool/wasm-pack-plugin": "1.0.1",
"typescript": "^5.0.3",
"typescript-language-server": "^3.3.1",
"webpack": "^5.65.0",
"webpack-cli": "^4.9.1"
}
Expand Down
66 changes: 59 additions & 7 deletions js-tests/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ import { test } from "tape";
import { webcrypto } from 'node:crypto'

// this is not required anymore with node19+
if(parseInt(process.version.match(/v(\d+)\.(\d+)\.(\d+)/)[1], 10) <= 18) {
if (parseInt(process.version.match(/v(\d+)\.(\d+)\.(\d+)/)[1], 10) <= 18) {
globalThis.crypto = webcrypto
}

test("keypair generation", function (t) {
test("keypair generation", function(t) {
let pkStr =
"76ac58cc933a3032d65e4d4faf99302fba381930486fd0ce1260654db25ca661";
let pubStr =
Expand All @@ -32,7 +32,7 @@ test("keypair generation", function (t) {
t.end();
});

test("biscuit builder", function (t) {
test("biscuit builder", function(t) {
let userId = "1234";
let builder = biscuit`user(${userId});`;
builder.addFact(fact`fact(${userId})`);
Expand All @@ -51,13 +51,12 @@ check if check("1234");
let pkStr =
"76ac58cc933a3032d65e4d4faf99302fba381930486fd0ce1260654db25ca661";
let pk = PrivateKey.fromString(pkStr);
let root = KeyPair.fromPrivateKey(pk);
builder.build(pk);
t.pass("building biscuit");
t.end();
});

test("block builder", function (t) {
test("block builder", function(t) {
let userId = "1234";
let builder = block`check if user(${userId});`;
builder.addFact(fact`fact(${userId})`);
Expand All @@ -75,7 +74,7 @@ check if check("1234");
t.end();
});

test("authorizer builder", function (t) {
test("authorizer builder", function(t) {
let userId = "1234";
let builder = authorizer`allow if user(${userId});`;
builder.addFact(fact`fact(${userId})`);
Expand All @@ -101,7 +100,7 @@ allow if check("1234");
t.end();
});

test("complete lifecycle", function (t) {
test("complete lifecycle", function(t) {
let pk = PrivateKey.fromString(
"473b5189232f3f597b5c2f3f9b0d5e28b1ee4e7cce67ec6b7fbf5984157a6b97"
);
Expand Down Expand Up @@ -196,3 +195,56 @@ check if true trusting authority, ed25519/41e77e842e5c952a29233992dc8ebbedd2d832
);
t.end();
});

test("third-party blocks", function(t) {
let pk = PrivateKey.fromString(
"473b5189232f3f597b5c2f3f9b0d5e28b1ee4e7cce67ec6b7fbf5984157a6b97"
);
let root = KeyPair.fromPrivateKey(pk);

let thirdPartyPk = PrivateKey.fromString(
"39c657dbd3f68b09bc8e5fd9887c7cb47a91d1d3883ffbc495ca790552398a92"
);
let thirdPartyRoot = KeyPair.fromPrivateKey(thirdPartyPk);

let id = "1234";
let biscuitBuilder = biscuit`user(${id});`;

for (let right of ["read", "write"]) {
biscuitBuilder.addFact(fact`right(${right})`);
}

biscuitBuilder.addCheck(check`check if group("admin") trusting ${thirdPartyRoot.getPublicKey()}`);

let token = biscuitBuilder
.build(root.getPrivateKey()) // biscuit token
.appendBlock(block`check if user($u)`); // attenuated biscuit token

let thirdPartyRequest = token.getThirdPartyRequest();
let thirdPartyBlock = thirdPartyRequest.createBlock(
thirdPartyPk, block`group("admin");`
);

token = token.appendThirdPartyBlock(
thirdPartyRoot.getPublicKey(),
thirdPartyBlock
);
let serializedToken = token.toBase64();
console.log(serializedToken);

let parsedToken = Biscuit.fromBase64(serializedToken, root.getPublicKey());
let auth = authorizer`allow if user(${id})`;
auth.addToken(parsedToken);

let policy = auth.authorize();
t.equal(policy, 0, "authorization suceeded");

let r1 = rule`g($group) <- group($group) trusting ${thirdPartyRoot.getPublicKey()}`;
let facts = auth.query(r1);
t.equal(facts.length, 1, "correct number of query results");
t.equal(facts[0].toString(), `g("admin")`, "correct query result");

let r2 = rule`g($group) <- group($group) trusting authority`;
t.equal(auth.query(r2).length, 0, "correct number of query results");
t.end();
});
27 changes: 27 additions & 0 deletions js-tests/package-lock.json

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

2 changes: 2 additions & 0 deletions js-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
"devDependencies": {
"@wasm-tool/wasm-pack-plugin": "1.0.1",
"nodemon": "^2.0.22",
"typescript": "^5.0.3",
"typescript-language-server": "^3.3.1",
"webpack": "^5.76.3",
"webpack-cli": "^5.0.1"
}
Expand Down
4 changes: 2 additions & 2 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
@@ -1,7 +1,7 @@
{
"name": "@biscuit-auth/biscuit-wasm",
"description": "WebAssembly wrapper for Biscuit authorization tokens",
"version": "0.4.0-beta1",
"version": "0.4.0-beta2",
"license": "Apache-2.0",
"repository": {
"type": "git",
Expand All @@ -13,7 +13,8 @@
"check-format": "prettier -c ./snippets",
"append-snippets": "npm run check-format && cat ./snippets/tagged-templates.js >> module/biscuit.js && cat ./snippets/definitions/tagged-templates.d.ts >> module/biscuit.d.ts",
"remove-pkg-cruft": "rm module/package.json module/.gitignore module/README.md",
"prepare-package": "npm run build && npm run remove-pkg-cruft"
"prepare-package": "npm run build && npm run remove-pkg-cruft",
"prepublishOnly": "npm run prepare-package"
},
"files": [
"module/biscuit_bg.wasm",
Expand Down
Loading

0 comments on commit 9cfbe80

Please sign in to comment.