Actix Casbin Middleware

Crates.io Docs CI codecov

Casbin access control middleware for actix-web framework

Install

Add it to Cargo.toml

rust actix-casbin-auth = "0.3.1" actix-rt = "1.1.1" actix-web = "2.0.0"

Requirement

Casbin only takes charge of permission control, so you need to implement an Authentication Middleware to identify user.

You should put actix_casbin_auth::CasbinVals which contains subject(username) and domain(optional) into Extension.

For example:

```rust use std::cell::RefCell; use std::pin::Pin; use std::rc::Rc; use std::task::{Context, Poll};

use actixservice::{Service, Transform}; use actixweb::{dev::ServiceRequest, dev::ServiceResponse, Error, HttpMessage}; use futures::future::{ok, Future, Ready};

use actixcasbinauth::CasbinVals;

pub struct FakeAuth;

impl Transform for FakeAuth where S: Service, Error = Error>, S::Future: 'static, B: 'static, { type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; type InitError = (); type Transform = FakeAuthMiddleware; type Future = Ready>;

fn new_transform(&self, service: S) -> Self::Future {
    ok(FakeAuthMiddleware {
        service: Rc::new(RefCell::new(service)),
    })
}

}

pub struct FakeAuthMiddleware { service: Rc>, }

impl Service for FakeAuthMiddleware where S: Service, Error = Error> + 'static, S::Future: 'static, B: 'static, { type Request = ServiceRequest; type Response = ServiceResponse; type Error = Error; type Future = Pin>>>;

fn poll_ready(&mut self, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
    self.service.poll_ready(cx)
}

fn call(&mut self, req: ServiceRequest) -> Self::Future {
    let mut svc = self.service.clone();

    Box::pin(async move {
        let vals = CasbinVals {
            subject: String::from("alice"),
            domain: None,
        };
        req.extensions_mut().insert(vals);
        svc.call(req).await
    })
}

} ````

Example

```rust use actixcasbinauth::casbin::{DefaultModel, FileAdapter, Result}; use actixcasbinauth::CasbinService; use actix_web::{web, App, HttpResponse, HttpServer};

[allow(dead_code)]

mod fake_auth;

[actix_rt::main]

async fn main() -> Result<()> { let m = DefaultModel::fromfile("examples/rbacrestfulkeymatch2model.conf").await?; let a = FileAdapter::new("examples/rbacrestfulkeymatch2_policy.csv"); //You can also use diesel-adapter or sqlx-adapter

let casbin_middleware = CasbinService::new(m, a).await;

casbin_middleware.write().await;

HttpServer::new(move || {
    App::new()
        .wrap(casbin_middleware.clone())
        .wrap(FakeAuth)          
        .route("/pen/1", web::get().to(|| HttpResponse::Ok()))
        .route("/book/{id}", web::get().to(|| HttpResponse::Ok()))
})
.bind("127.0.0.1:8080")?
.run()
.await?;

Ok(())

} ```

License

This project is licensed under