protect_salvo/
lib.rs

1#![doc(
2    html_logo_url = "https://raw.githubusercontent.com/DDtKey/protect-endpoints/main/protect-salvo/logo.png"
3)]
4//! A crate to protect your endpoints in [`salvo`].
5//!
6//! For built-in configuration, you can use [`GrantsLayer`] tower compatible middleware.
7//!
8//! To check user access to specific services, you can use [`proc-macro`] or manual.
9//!
10//! [`permissions`]: authorities
11//! [`proc-macro`]: proc_macro
12//! [`salvo`]: https://github.com/salvo-rs/salvo
13//! [`salvo_extra`]: https://crates.io/crates/salvo_extra
14#![doc = include_str!("../README.md")]
15
16use protect_endpoints_core::tower::middleware::GrantsLayer as CoreGrantsLayer;
17use salvo::http::ReqBody;
18
19/// Re-export of the `salvo_extra` crate with enabled tower-compatibility.
20pub use salvo_extra;
21
22pub mod authorities;
23
24pub type GrantsLayer<Extractor, Type, Err> =
25    CoreGrantsLayer<Extractor, salvo::hyper::Request<ReqBody>, Type, Err>;
26
27/// Procedural macros for checking user authorities (permissions or roles).
28///
29/// # Examples
30/// ```
31/// use salvo::prelude::*;
32/// use serde::{Serialize, Deserialize};
33///
34/// // User should be ADMIN with OP_GET_SECRET permission
35/// #[protect_salvo::protect("ROLE_ADMIN", "OP_GET_SECRET")]
36/// #[handler]
37/// async fn macro_secured() -> &'static str {
38///     "some secured info"
39/// }
40///
41/// // User should be ADMIN and MANAGER
42/// #[protect_salvo::protect("ADMIN", "MANAGER")]
43/// #[handler]
44/// async fn role_macro_secured() -> &'static str {
45///     "some secured info"
46/// }
47///
48/// #[derive(serde::Deserialize, Extractible)]
49/// struct UserParams { user_id: i32 }
50/// struct User { id: i32 }
51///
52/// // Additional security condition to ensure the protection of the endpoint.
53/// // Compares user_id from the request path with the user.id from the request extensions (might be populated by custom middleware, for example).
54/// #[protect_salvo::protect("USER", expr = "Some(params.user_id) == req.extensions().get::<User>().map(|u| u.id)")]
55/// #[handler]
56/// async fn role_macro_secured_with_params(params: UserParams, req: &mut Request) -> &'static str {
57///     "some secured info with parameters"
58/// }
59///
60/// // You own type is also supported (need to configure middleware for this type as well):
61/// #[protect_salvo::protect("Role::Admin", "Role::Manager", ty = "Role")]
62/// #[handler]
63/// async fn role_enum_macro_secured() -> &'static str {
64///     "some secured info"
65/// }
66/// #[derive(Eq, PartialEq, Hash)] // required bounds
67/// enum Role { Admin, Manager }
68///
69/// ```
70#[cfg(feature = "macro-check")]
71pub mod proc_macro {
72    pub use protect_endpoints_proc_macro::protect_salvo as protect;
73}
74
75/// Just a shortcut for proc-macros
76#[cfg(feature = "macro-check")]
77pub use proc_macro::*;