11 releases (4 stable)
2.0.0 | Apr 12, 2022 |
---|---|
2.0.0-beta.4 | Apr 11, 2022 |
1.0.2 | Apr 8, 2022 |
1.0.1 | Mar 29, 2022 |
0.1.1 | Mar 8, 2022 |
#1288 in Web programming
49 downloads per month
26KB
428 lines
Actix Permissions
Permission and input validation extension for Actix Web. Alternative to actix guard, with access to app data injections, HttpRequest and Payload. Permissions are flexible, take a look at Examples directory for some of the use cases.
You could write a permission check like a function or like a struct.
This code:
async fn is_allowed(
req: HttpRequest
) -> actix_web::Result<bool> {
todo!();
}
is almost the same as writing:
struct IsAllowed;
impl Permission<()> for IsAllowed {
type Future = Ready<actix_web::Result<bool>>;
fn call(&self, req: HttpRequest, ctx: ()) -> Ready<actix_web::Result<bool>> {
todo!();
}
}
Example
Dependencies:
[dependencies]
actix-permissions = "2.0.0"
Code:
use actix_permissions::*;
use actix_web::web::Data;
use actix_web::*;
use serde::Deserialize;
#[derive(Debug, Clone, Deserialize)]
pub struct MyStatus {
pub status: Option<String>,
}
async fn dummy_permission_check(
_req: HttpRequest,
dummy_service: web::Data<DummyService>,
data: web::Query<MyStatus>,
) -> actix_web::Result<bool> {
// Unecessary complicating permission check to show what it can do.
// You have access to request, payload, and all injected dependencies through app_data.
Ok(dummy_service.check(data.status.clone()))
}
struct DummyService;
impl DummyService {
pub fn check(&self, value: Option<String>) -> bool {
value == Some("all".to_string())
}
}
async fn index() -> Result<String, Error> {
Ok("Hi there!".to_string())
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new().app_data(Data::new(DummyService)).service(
web::scope("").route(
"/",
permission()
.check(web::get())
.validate(dummy_permission_check)
.to(index)
.build(),
),
)
})
.bind("127.0.0.1:8888")?
.run()
.await
}
Use Cases
Take a look at Examples directory.
You could use actix-permissions for role based authorization check, like in role-based-authorization example.
hello-world example is just a proof of concept, showing how you can set permission,
access service request, payload and injected services.
Permission Deny
By default, 403 is returned for failed permission checks. You may want to toggle between Unauthorized
and Forbidden
,
maybe customize 403 forbidden messages. That's why check_with_custom_deny
is for.
Take a look at role based authorization example for more info.
Permission chaining
Not implemented more than one. It's because how it's implemented in service.rs
. For every
Permission
there's a FromRequest
impl. Every FromRequest
consumes Payload
, so Payload
needs
to be cloned
each time. If you have a need for permission chaining or have an idea, open a new Issue.
Contributing
This project welcomes all kinds of contributions. No contribution is too small!
If you want to contribute to this project but don't know how to begin or if you need help with something related to this project, feel free to send me an email https://www.eisberg-labs.com/ (contact form at the bottom).
Some pointers on contribution are in Contributing.md
Code of Conduct
This project follows the Rust Code of Conduct.
License
Distributed under the terms of MIT license and Apache license.
Dependencies
~14–25MB
~436K SLoC