Skip to content

Commit

Permalink
improve docs
Browse files Browse the repository at this point in the history
  • Loading branch information
hasanayan committed Mar 22, 2024
1 parent ca06f9a commit 952f84c
Show file tree
Hide file tree
Showing 11 changed files with 314 additions and 152 deletions.
20 changes: 12 additions & 8 deletions docs/react.cerbosprovider.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,12 @@ ReactElement

```typescript
import { Embedded as Cerbos } from "@cerbos/embedded";
import { CerbosProvider } from "@cerbos/react";

// Initialize the Cerbos client using any of the client libraries
// that fit the needs of your application. In this example we are
// using `@cerbos/embedded`.
const client = new Cerbos(...);
// using the client from `@cerbos/embedded`.
const client = new Cerbos();

function MyApp({ children }) {
const user = useUser();
Expand All @@ -67,12 +68,15 @@ function MyApp({ children }) {
<CerbosProvider
client={client}
principal={
// Build and pass the principal object to the provider.
{
id: user ? user.id : "###ANONYMOUS_USER###", // We defined an arbitrary ID for anonymous users here, it will help us identify the checks for anonymous users in the Cerbos logs
roles: user ? user.roles : [], // Pass the roles of the user, it the user is not authenticated, pass an empty array
auxData: ... //optional
}
user
? { // the user is authenticated
id: user.id,
roles: user.roles,
}
: { // the user is not authenticated
id: "###ANONYMOUS_USER###", // Define an arbitrary ID for anonymous users.
roles: ["anonymous"], // Pass a role that represents an anonymous user, at least one is required.
}
}
>
{children}
Expand Down
2 changes: 1 addition & 1 deletion docs/react.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Component to provide the Cerbos client to down the component tree, should be pla

</td><td>

Hook to access the provided Cerbos client. It is perfectly fine to access the client directly, however, consider using one of [useCheckResource()](./react.usecheckresource.md)<!-- -->,[useCheckResources()](./react.usecheckresources.md) or [useIsAllowed()](./react.useisallowed.md) instead. The API they provide might be simpler for your use case as the handle the Async logic for you.
Hook to access the provided Cerbos client. It is perfectly fine to access the client directly, especially when an Async function is required for the check, however, consider using one of [useCheckResource()](./react.usecheckresource.md)<!-- -->,[useCheckResources()](./react.usecheckresources.md) or [useIsAllowed()](./react.useisallowed.md) instead. The API they provide might be simpler for your use case as the handle the Async logic for you.


</td></tr>
Expand Down
29 changes: 16 additions & 13 deletions docs/react.usecerbos.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

## useCerbos() function

Hook to access the provided Cerbos client. It is perfectly fine to access the client directly, however, consider using one of [useCheckResource()](./react.usecheckresource.md)<!-- -->,[useCheckResources()](./react.usecheckresources.md) or [useIsAllowed()](./react.useisallowed.md) instead. The API they provide might be simpler for your use case as the handle the Async logic for you.
Hook to access the provided Cerbos client. It is perfectly fine to access the client directly, especially when an Async function is required for the check, however, consider using one of [useCheckResource()](./react.usecheckresource.md)<!-- -->,[useCheckResources()](./react.usecheckresources.md) or [useIsAllowed()](./react.useisallowed.md) instead. The API they provide might be simpler for your use case as the handle the Async logic for you.

**Signature:**

Expand All @@ -19,27 +19,30 @@ export declare function useCerbos(): ClientWithPrincipal;


```typescript
function SomeFunction() {
import { useCerbos } from "@cerbos/react";

function SomeComponent() {
const cerbos = useCerbos();

const handleClick = async ()=>{
const handleClick = async () => {
const decision = await cerbos.checkResource({
resource: {
kind: "document",
id: "1",
attr: { owner: "user@example.com" },
},
actions: ["view", "edit"],
resource: {
kind: "document",
id: "1",
attr: { owner: "user@example.com" },
},
actions: ["view", "edit"],
});

if(decision.allAllowed()){
if (decision.allAllowed()) {
// do something
}else if(decision.allowedActions().includes('view')){
} else if (decision.allowedActions().includes("view")) {
// do something else
}
}
...
};

return <button onClick={handleClick}>...</div>
return <button onClick={handleClick}>...</button>;
}
```

39 changes: 29 additions & 10 deletions docs/react.usecheckresource.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,34 @@ _(Optional)_


```typescript
const {isLoading, data:decision, error} = useCheckResource({
resource: {
kind: "document",
id: "1",
attr: { owner: "user@example.com" },
},
actions: ["view", "edit"],
});

decision?.isAllowed("view"); // => true
import { useCheckResource } from "@cerbos/react";

function SomeComponent() {
const check = useCheckResource({
resource: {
kind: "document",
id: "1",
attr: { owner: "user@example.com" },
},
actions: ["view", "edit"],
});

if (check.isLoading) {
// show spinner
return "Loading...";
}

if (check.error) {
// handle error
return "Error...";
}

return (
<div>
{check.data.allAllowed() && <button>a button</button>}
{check.data.isAllowed("view") && <button>another button</button>}
</div>
);
}
```

76 changes: 53 additions & 23 deletions docs/react.usecheckresources.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,30 +69,60 @@ _(Optional)_


```typescript
const {isLoading, data:decision, error} = useCheckResources({
resources: [
{
resource: {
kind: "document",
id: "1",
attr: { owner: "user@example.com" },
import { useCheckResources } from "@cerbos/react";

function SomeComponent() {
const check = useCheckResources({
resources: [
{
resource: {
kind: "document",
id: "1",
attr: { owner: "user@example.com" },
},
actions: ["view", "edit"],
},
actions: ["view", "edit"],
},
{
resource: {
kind: "image",
id: "1",
attr: { owner: "user@example.com" },
{
resource: {
kind: "document",
id: "2",
attr: { owner: "another-user@example.com" },
},
actions: ["view", "edit"],
},
actions: ["delete"],
},
],
});

decision?.isAllowed({
resource: { kind: "document", id: "1" },
action: "view",
}); // => true
],
});

if (check.isLoading) {
// show spinner
return "Loading...";
}

if (check.error) {
// handle error
return "Error...";
}

return (
<div>
{check.data.allAllowed({
kind: "document",
id: "1",
}) && <button>a button document 1</button>}
{check.data.allAllowed({
kind: "document",
id: "2",
}) && <button>a button document 2</button>}
{check.data.isAllowed({
resource: { kind: "document", id: "1" },
action: "edit",
}) && <button>another button for document 1</button>}
{check.data.isAllowed({
resource: { kind: "document", id: "2" },
action: "edit",
}) && <button>another button for document 2</button>}
</div>
);
}
```

36 changes: 24 additions & 12 deletions docs/react.useisallowed.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,17 +69,29 @@ _(Optional)_


```typescript
const {
isLoading,
data:decision, // => true
error
} = useIsAllowed({
resource: {
kind: "document",
id: "1",
attr: { owner: "user@example.com" },
},
action: "view",
});
import { useIsAllowed } from "@cerbos/react";

function SomeComponent() {
const check = useIsAllowed({
resource: {
kind: "document",
id: "1",
attr: { owner: "user@example.com" },
},
action: "view",
});

if (check.isLoading) {
// show spinner
return "Loading...";
}

if (check.error) {
// handle error
return "Error...";
}

return <div>{check.data && <button>a button document 1</button>}</div>;
}
```

63 changes: 44 additions & 19 deletions packages/react/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,29 +16,54 @@ $ npm install @cerbos/react

## Example usage

/////TODO////
First initialize a Cerbos client and provide it down the tree by using CerbosProvider

```typescript
import { HTTP } from "@cerbos/http";

const cerbos = new HTTP("http://localhost:3592");

await cerbos.isAllowed({
principal: {
id: "user@example.com",
roles: ["USER"],
attr: { tier: "PREMIUM" },
},
resource: {
kind: "document",
id: "1",
attr: { owner: "user@example.com" },
},
action: "view",
}); // => true
import { Embedded as Cerbos } from "@cerbos/embedded";
import { CerbosProvider } from "@cerbos/react";

// Initialize the Cerbos client using any of the client libraries
// that fit the needs of your application. In this example we are
// using the client from `@cerbos/embedded`.
const client = new Cerbos();

function MyApp({ children }) {
const user = useUser();
return (
<CerbosProvider
client={client}
principal={
user
? { // the user is authenticated
id: user.id,
roles: user.roles,
}
: { // the user is not authenticated
id: "###ANONYMOUS_USER###", // Define an arbitrary ID for anonymous users.
roles: ["anonymous"], // Pass a role that represents an anonymous user, at least one is required.
}
}
>
{children}
</CerbosProvider>
);
}
```

For more details, [see the `HTTP` class documentation](../../docs/http.http.md).
For more details, [see the `CerbosProvider` component documentation](../../docs/react.cerbosprovider.md).

Then consume the client as you need, using one of the provided hooks

```typescript
import { useCerbos } from "@cerbos/react";

function SomeComponent() {
const cerbos = useCerbos();

...
...
}
```

## Further reading

Expand Down
20 changes: 12 additions & 8 deletions packages/react/src/cerbos-provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@ export interface CerbosProviderProps {
* @example
* ```typescript
* import { Embedded as Cerbos } from "@cerbos/embedded";
* import { CerbosProvider } from "@cerbos/react";
*
* // Initialize the Cerbos client using any of the client libraries
* // that fit the needs of your application. In this example we are
* // using `@cerbos/embedded`.
* const client = new Cerbos(...);
* // using the client from `@cerbos/embedded`.
* const client = new Cerbos();
*
* function MyApp({ children }) {
* const user = useUser();
Expand All @@ -43,12 +44,15 @@ export interface CerbosProviderProps {
* <CerbosProvider
* client={client}
* principal={
* // Build and pass the principal object to the provider.
* {
* id: user ? user.id : "###ANONYMOUS_USER###", // We defined an arbitrary ID for anonymous users here, it will help us identify the checks for anonymous users in the Cerbos logs
* roles: user ? user.roles : [], // Pass the roles of the user, it the user is not authenticated, pass an empty array
* auxData: ... //optional
* }
* user
* ? { // the user is authenticated
* id: user.id,
* roles: user.roles,
* }
* : { // the user is not authenticated
* id: "###ANONYMOUS_USER###", // Define an arbitrary ID for anonymous users.
* roles: ["anonymous"], // Pass a role that represents an anonymous user, at least one is required.
* }
* }
* >
* {children}
Expand Down
Loading

0 comments on commit 952f84c

Please sign in to comment.