diff --git a/docs/en/src/SUMMARY.md b/docs/en/src/SUMMARY.md index 1dad68f6..71734d00 100644 --- a/docs/en/src/SUMMARY.md +++ b/docs/en/src/SUMMARY.md @@ -17,6 +17,7 @@ - [Query and Mutation](query_and_mutation.md) - [Subscription](subscription.md) - [Utilities](utilities.md) + - [Field guard](field_guard.md) - [Input value validators](input_value_validators.md) - [Cache control](cache_control.md) - [Cursor connections](cursor_connections.md) diff --git a/docs/en/src/field_guard.md b/docs/en/src/field_guard.md new file mode 100644 index 00000000..1e5bd35f --- /dev/null +++ b/docs/en/src/field_guard.md @@ -0,0 +1,69 @@ +# Field Guard + +You can define `guard` to field of an `Object`. This permit to add checks before run the code logic of the field. +`Guard` are made of rules that you need to define before. A rule is a structure which implement the trait `Guard`. + +```rust +#[derive(Eq, PartialEq, Copy, Clone)] +enum Role { + Admin, + Guest, +} + +struct RoleGuard { + role: Role, +} + +#[async_trait::async_trait] +impl Guard for RoleGuard { + async fn check(&self, ctx: &Context<'_>) -> Result<()> { + if ctx.data_opt::() == Some(&self.role) { + Ok(()) + } else { + Err("Forbidden".into()) + } + } +} +``` + +Once you have defined your rule you can use it in the `guard` field attribute. +This attribute support 4 operators to create complex rules : + +- `and` : perform a `and` operation between two rules. (If one rule return an error the `and` operator will return the error. If both rules return a error it's the first one that will be returned). + +- `or` : perform a `and` operation between two rules. (If both rules return an error the error returned is the first one) + +- `chain` : take a set of rules and run them until one return an error or return `Ok()` if all rules pass. + +- `race` : take a set of rules and run them until one return `Ok()` if they all fail it return the last error. + +```rust +#[derive(SimpleObject)] +struct Query { + #[graphql(guard(RoleGuard(role = "Role::Admin")))] + value: i32, + #[graphql(guard(and( + RoleGuard(role = "Role::Admin"), + UserGuard(username = r#""test""#) + )))] + value2: i32, + #[graphql(guard(or( + RoleGuard(role = "Role::Admin"), + UserGuard(username = r#""test""#) + )))] + value3: i32, + #[graphql(guard(chain( + RoleGuard(role = "Role::Admin"), + UserGuard(username = r#""test""#), + AgeGuard(age = r#"21"#) + )))] + value4: i32, + #[graphql(guard(race( + RoleGuard(role = "Role::Admin"), + UserGuard(username = r#""test""#), + AgeGuard(age = r#"21"#) + )))] + value5: i32, +} +``` +