GSoC Week3

Date: June 27, 2022 → July 3, 2022

Tasks overview

  • Add CI and tests for poem-casbin
  • Take a look at casbin-grpc
  • research

Task 1 Add CI and tests for poem-casbin

First I add CI for poem-casbin, ci.yml is bases on which from actix-casbin-auth, but I made some minor changes: change branch name from master to main , and upgrade actions/checkout to v3.

The workflow will run following checks when there’s push/pull_request to main branch:

  • cargo build
  • cargo test --no-default-features --features runtime-tokio
  • cargo test --no-default-features --features runtime-async-std
  • cargo clippy -- -D warnings
  • cargo fmt --all -- --check

This is what we got:

Untitled

Then I started to add some tests and examples to poem-casbin, I also use actix-casbin-auth as reference, it has 3 test files:

  • test_middleware.rs: test basic middleware function
  • test_middleware_domain.rs: test middleware function with domain
  • test_set_enforcer.rs: test initializing middleware using set_enforcer()

In the tests, first it implements a fake authentication middleware called FakeAuth, which just simply insert a CasbinVals with subject alice and domain domain1 to request’s exetensions:

1
2
3
4
5
6
7
8
9
10
11
fn call(&self, req: ServiceRequest) -> Self::Future {
let svc = self.service.clone();

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

Then it wraps its endpoints in FakeAuth and casbin middleware:

1
2
3
4
5
6
7
8
let mut app = test::init_service(
App::new()
.wrap(casbin_middleware.clone())
.wrap(FakeAuth)
.route("/pen/1", web::get().to(|| HttpResponse::Ok()))
.route("/book/{id}", web::get().to(|| HttpResponse::Ok())),
)
.await;

As for poem, it’s a little different. To use test in poem, we have to enable test feature of it, then we can test like below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
use poem::{handler, test::TestClient, Route};

#[handler]
fn index() -> &'static str {
"hello"
}

let app = Route::new().at("/", index);
let cli = TestClient::new(app);

// send request
let resp = cli.get("/").send().await;
// check the status code
resp.assert_status_is_ok();
// check the body string
resp.assert_text("hello").await;

And poem use with to wrap endpoints with middlewares:

1
2
3
4
5
6
let app = Route::new()
.at("/pen/1", get(endpoint))
.at("/pen/2", get(endpoint))
.at("/book/:id", get(endpoint))
.with(casbin_middleware)
.with(FakeAuth);

Note that casbin_middleware must be precedent than FakeAuth.

And I learned that to switch runtime I can use cfg_attr:

1
2
3
4
5
#[cfg_attr(feature = "runtime-tokio", tokio::test)]
#[cfg_attr(feature = "runtime-async-std", async_std::test)]
async fn test_middleware() {
//...
}

I made 2 PRs which got merged:

Next week I’ll add README for this project.

Task 2 Take a look at grpc-casbin

For now, casbin-grpc build fails with bunch of errors:

Untitled

There are mainly 2 issues:

First, most functions of Cabin trait are not implemented:

Untitled

Second, new_adapter function only supports FileAdapter now:

Untitled

I think I can work on this repo to complete it in the next few weeks.

Research on real-world application

After talked with my mentor last week, I know that casdoor-rust-sdk is assigned to another student, and I need to think of a new task.

I want to do something solid, and don’t want to use Rust just to write a web application. So after I researched a while, I think I can either:

  • combine casbin-rs and yew to implement a front-end access control framework like:

    https://github.com/tower1229/Vue-Access-Control

  • dufs is a distinctive utility file server that supports accessing control, we can maintain a fork of it and use casbin-rs as access control backend

    https://github.com/sigoden/dufs

  • complete grpc-casbin and colaborate with Siddhesh Kanawade on casbin-raft, as there are actually a lot of work to do