Skip to content

Commit 809bab4

Browse files
committed
docs(readme): rewrite guard docs
1 parent 9b5934d commit 809bab4

File tree

1 file changed

+39
-16
lines changed

1 file changed

+39
-16
lines changed

README.md

+39-16
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ interface RestGuard {
598598
}
599599
```
600600

601-
Let's implement a simple Guard to forbid any access to unpublished `Book` entities:
601+
Let's take a look at a simple example of a Guard responsible to forbid access to unpublished `Book` entities:
602602

603603
```ts
604604
@rest.guard("published-only")
@@ -612,50 +612,73 @@ class BookPublishedOnlyGuard implements RestGuard {
612612
}
613613
```
614614

615-
Remember to provide our Guard in the `http` scope:
615+
We must decorate a Guard with the `@rest.guard()` decorator to bind a group name for the Guard, which will be used to bind the Guard to specific Actions. In this case, the bound group name is `"publish-only"`, which means all Actions in this module with group name `"published-only"` will be protected by the `BookPublishedOnlyGuard`:
616616

617617
```ts
618-
{
619-
providers: [{ provide: BookPublishedOnlyGuard, scope: "http" }];
618+
@rest.resource(Book, "books")
619+
class BookResource implements RestResource<Book> {
620+
// ...
621+
@rest.action("GET", ":pk")
622+
@http.group("published-only")
623+
async retrieve(): Promise<Response> {
624+
// ...
625+
}
620626
}
621627
```
622628

623-
> Once provided, the guard will be available through the whole application. There's no need to put it in `exports`.
624-
625-
Guards must be bound to a group name using the `@rest.guard()` decorator. In our case, all Actions with group name `published-only` will be protected by our `BookPublishedOnlyGuard`:
629+
We can apply the `@http.group()` decorator to the Resource to prepend some group to all its Actions, which can be quite useful when we want all the Actions in the Resource to be protected by the Guard:
626630

627631
```ts
628632
@rest.resource(Book, "books")
633+
@http.group("published-only")
629634
class BookResource implements RestResource<Book> {
630635
// ...
631636
@rest.action("GET", ":pk")
632-
@http.group("published-only")
633637
async retrieve(): Promise<Response> {
634638
// ...
635639
}
636640
}
637641
```
638642

639-
The order of Guards is determined by the order of groups. Usually the Guard responsible for authentication should be invoked first:
643+
Usually all Guards should be provided in the `http` scope, because we have to inject some `http` scoped providers to get the contextual information, e.g. `HttpRequest`, `RestCrudActionContext` and `HttpRequestParsed`. In this case, the Guard is making use of `RestCrudActionContext`, so it must be provided in the `http` scope:
640644

641645
```ts
642-
@http.group('auth-required', "published-only")
643-
async retrieve(): Promise<Response> {
644-
// ...
646+
{
647+
provides: [{ provide: BookPublishedOnlyGuard, scope: "http" }];
645648
}
646649
```
647650

648-
If all the Actions in a Resource should be protected by a Guard, we can prepend the group to all the Actions by applying the `@http.group()` decorator directly at the Resource:
651+
If a Guard is not exported, only Actions in modules where the Guard can be injected are able be protected by this Guard. We'll need to put it in `exports` to share it among other modules:
652+
653+
```ts
654+
{
655+
provides: [{ provide: BookPublishedOnlyGuard, scope: "http" }];
656+
exports: [BookPublishedOnlyGuard],
657+
}
658+
```
659+
660+
The order of Guards is determined by the order of groups. If we want the requests to go through an authorization Guard first, we'll need to position the corresponding group before any other Guard-bound groups.
661+
662+
```ts
663+
@http.group('auth-required', "owned-only")
664+
action() {}
665+
```
666+
667+
Applying `@http.group()` to a Resource will **prepend** groups to Actions, so Guards bound to Actions using `@http.group()` at the Resource level will be invoked earlier than the ones at the Action level. Therefore we can avoid repeating the group if we want all the Actions in a Resource to be handled by the authentication Guard first:
649668

650669
```ts
651-
@rest.resource(Book, "books")
652670
@http.group("auth-required")
653-
class BookResource implements RestResource<Book> {
671+
class MyResource implements RestResource<MyEntity> {
654672
// ...
673+
@http.group("owned-only")
674+
action() {}
655675
}
656676
```
657677

658-
> Guards are invoked on `httpWorkflow.onAuth` event with order `200`, and when an HTTP Error is thrown the state of the http workflow will jump to `httpWorkflow.onAccessDenied`.
678+
### Details in HTTP Workflow
679+
680+
- Guards are invoked at the `onAuth` state with `200` order
681+
- The state of the HTTP Workflow will jump from `onAuth` to `onAccessDenied` when an HTTP Error is thrown from Guards
659682

660683
## Resource Inheritance
661684

0 commit comments

Comments
 (0)