# rocket-grants
> Extension for [`rocket`] to authorize requests.
[![Crates.io Downloads Badge](https://img.shields.io/crates/d/rocket-grants)](https://crates.io/crates/rocket-grants)
[![crates.io](https://img.shields.io/crates/v/rocket-grants)](https://crates.io/crates/rocket-grants)
[![Documentation](https://docs.rs/rocket-grants/badge.svg)](https://docs.rs/rocket-grants)
![Apache 2.0 or MIT licensed](https://img.shields.io/crates/l/rocket-grants)
To check user access to specific endpoints, you can use built-in `proc-macro` or do it manually.
## How to use
1. Declare your own authorities extraction function
The easiest way is to declare a function with the following signature:
```rust,ignore
// You can use custom type instead of String
async fn extract(req: &rocket::Request<'_>) -> Option>
```
2. Add fairing to your application using the extraction function defined in step 1
```rust,ignore
rocket::build().mount("/api", rocket::routes![endpoint])
.attach(GrantsFairing::with_extractor_fn(|req| {
Box::pin(extract(req)) // example with a separate async function `extract`, but you can write a closure right here
}))
```
> Steps 1 and 2 can be replaced by integration with your custom fairing.
3. Protect your endpoints in any convenient way from the examples below:
### Example of `proc-macro` way protection
```rust,no_run
#[rocket_grants::protect("OP_READ_SECURED_INFO")]
#[rocket::get("/")]
async fn macro_secured() -> &'static str {
"ADMIN_RESPONSE"
}
```
Example of ABAC-like protection and custom permission type
Here is an example using the `ty` and `expr` attributes. But these are independent features.
`expr` allows you to include some checks in the macro based on function params, it can be combined with authorities by using `all`/`any`.
`ty` allows you to use a custom type for the authority (then the fairing needs to be configured).
Take a look at an [enum-role example](examples/enum-role/main.rs)
```rust,ignore
use enums::Role::{self, ADMIN};
use dto::User;
#[rocket_grants::protect("USER", expr = "user_id == user.id")]
#[rocket::post("/secure/", data = "")]
async fn role_macro_secured_with_params(user_id: i32, user: Json) -> &'static str {
"some secured info with parameters"
}
#[rocket_grants::protect(any("ADMIN", expr = "user.is_super_user()"))]
#[rocket::post("/secure/admin/", data = "")]
async fn admin_or_super_user(user_id: i32, user: Json) -> &'static str {
"some secured info with parameters"
}
```
### Example of manual way protection
```rust,no_run
use rocket_grants::authorities::{AuthDetails, AuthoritiesCheck};
#[rocket::get("/")]
async fn manual_secure(details: AuthDetails) -> &'static str {
if details.has_authority("ROLE_ADMIN") {
return "ADMIN_RESPONSE"
}
"OTHER_RESPONSE"
}
```
You can find more [`examples`] in the git repository folder and [`documentation`].
# Error customization
Custom error responses can be specified using Rocket catchers. See the Rocket documentation for [catchers](https://doc.rust-lang.org/cargo/commands/cargo-doc.html).
You can set up custom responses for:
`401 Unauthorized` - when it wasn't possible to obtain authorization data from the request in your extractor.
`403 Forbidden` - when the permissions did not match the specified for the endpoint.
## Supported `rocket` versions
* For `rocket-grants: 0.1.*` supported version of `rocket` is `0.5.*`
[`examples`]: https://github.com/DDtKey/protect-endpoints/tree/main/rocket-grants/examples
[`documentation`]: https://docs.rs/rocket-grants
[`rocket`]: https://github.com/SergioBenitez/Rocket
[`poem-grants`]: https://github.com/DDtKey/protect-endpoints/tree/main/poem-grants