GSoC Week2
Date: June 20, 2022 → June 26, 2022
Tasks Overview
- implement casbin middleware for poem
- resolve an issue of sqlx-adapter
- fix casbin-rs benchmark workflow
- research poem-openapi and discuss on casdoor-rust-sdk
Task 1 Poem-casbin
This week, I plan to write code for poem-casbin.
First, to get familiar with what casbin middleware do and how to implement it, I take a look at existing casbin middlewares.
For example:
https://github.com/casbin-rs/actix-casbin-auth
This repository is casbin-rs access control middleware for actix-web framwork
To figure out what does this code do, I have to first learn how to write middleware for actix. I found an awesome tutorial here:
Demystifying Actix Web Middleware
To implement a middleware, we must implement Transform
and Service
traits.
Actix’s Service
represents anything that takes a request and returns a response, it looks like:
1 | pub trait Service<Req> { |
We’ll mainly work on call()
function, and this is the main part of axtix-casbin-auth.
The Transform
implementation’s only job is to create new middleware instances that wrap other services, it looks like:
1 | pub trait Transform<S, Req> { |
Here we have to implement new_transform()
function to wrap casbin enforcer and actix service together, like:
1 | fn new_transform(&self, service: S) -> Self::Future { |
Note this middleware only takes care of authorization, so user should put actix_casbin_auth::CasbinVals
which contains subject
(username) and domain
(optional) into extension
before calling this middleware.
1 | let vals = CasbinVals { |
Now I focus on call()
function of Service
trait:
First, it gets path and action (method) of request, then gets CasbinVals
from extension
.
1 | let option_vals = req.extensions().get::<CasbinVals>().map(|x| x.to_owned()); |
Then he calls enforce_mut()
to authorize this request and returns response depending enforce result.
Also, I take a look at tests to see how to use this middleware, I found it quite easy to use, just wrap endpoint in middlwares like:
1 | let mut app = test::init_service( |
After learning actix-casbin-auth
I’m clear about what work casbin middleware does. So I turned to learn how to write poem middleware.
There are not many tutorial on implementing middleware for poem, but poem provides bunch of middleware examples in https://github.com/poem-web/poem/tree/master/examples/poem . So I took a look at these examples and figured out how to implement middleware for poem.
Just like actix, we have to implement two traits: Middleware
and Endpoint
.
Middleware
is like Transform
in actix, it wraps other services, it looks like:
1 | pub traitMiddleware<E:Endpoint> { |
Endpoint
is like Service
in actix, it takes a request and returns a response, it looks like:
1 | pub trait Endpoint: Send + Sync { |
Now I know how to write middleware in poem, so I start implementing casbin middleware for it, this is my first PR:
https://github.com/casbin-rs/poem-casbin/pull/1
Task 2 Resolve sqlx-adapter issue
https://github.com/casbin-rs/sqlx-adapter/issues/65
This issue has some update, one user complains that why DATABASE_URL
must be presented instead of to be optional.
It’s because sqlx-adapter uses query!
marco to statically check SQL queries.
According to docs of sqlx, to use query!
:
- The
DATABASE_URL
environment variable must be set at build-time to point to a database server with the schema that the query string will be checked against. All variants ofquery!()
use dotenv so this can be in a.env
file instead. - Or,
sqlx-data.json
must exist at the workspace root.
To use sqlx-data.json
, you can follow the docs for offline mode.
query!
can be configured to not require a live database connection for compilation, but it requires a couple extra steps:
- Run
cargo install sqlx-cli
. - In your project with
DATABASE_URL
set (or in a.env
file) and the database server running, runcargo sqlx prepare
. - Check the generated
sqlx-data.json
file into version control. - Don’t have
DATABASE_URL
set during compilation.
Your project can now be built without a database connection (you must omit DATABASE_URL
or else it will still try to connect). To update the generated file simply run cargo sqlx prepare
again.
Note: As sqlx-adapter has generated sqlx-data.json
for postgres, so when using postgres you don’t need provide DATABASE_URL
or sqlx-data.json
. But for mysql and sqlite, you must provide DATABASE_URL
or sqlx-data.json
However, it would be better if we can generate sqlx-data.json
for all three kinds of database in sqlx-adapter
, so users won’t bother setting DATABASE_URL
or generating sqlx-data.json
by themselves. I’ve been tried a while but found cargo sqlx prepare
would just overwrite sqlx-data.json
.
I’ve been reading related issues like:
https://github.com/launchbadge/sqlx/issues/1223
https://github.com/launchbadge/sqlx/issues/121
but found them not very helpful, so I open an issue at sqlx:
https://github.com/launchbadge/sqlx/issues/1927
No one reply to me though.
Task 3 casbin-rs benchmark workflow
Last week I found benchmark workflow doesn’t work well that it fails to post comment to PR.
I’ve searching a while for this issue and reading some related discussions/issues:
https://github.com/actions/first-interaction/issues/10
GitHub actions are severely limited on PRs
Automatic token authentication - GitHub Docs
“Resource not accessible by integration” for adding a comment to a PR via action
The reason is GITHUB_TOKEN only has read permission to pull requests when access by forked repos, so when a new PR is coming, running workflows only has read-only permission (of course not allowed to post comment), that’s why we get 403 here: https://github.com/casbin/casbin-rs/runs/6409294114#step:5:459
Some users have created actions that can post comment on PR, like:
https://github.com/mshick/add-pr-comment
https://github.com/nyurik/auto_pr_comments_from_forks
But it’s difficult to combine them with boa-dev/criterion-compare-action.
GitHub has introduced a new event type: pull_request_target
, which allows to run workflows from base branch and pass a token with write permission.
GitHub Actions improvements for fork and pull request workflows | The GitHub Blog
It says:
The event runs against the workflow and code from the base of the pull request. This means the workflow is running from a trusted source and is given access to a read/write token as well as secrets enabling the maintainer to safely comment on or label a pull request.
I give this a try.
I first created a PR from a fork repo:
It fails as before.
Then I modify pull_request.yml to use pull_request_target
, then create another PR.
1 | on: |
Now it works well:
I made a PR and it got merged.
https://github.com/casbin/casbin-rs/pull/298
Task 4 casdoor-rust-sdk
This week I take a look at poem as mentor suggested.
Poem has a sub crate poem-openapi
poem/poem-openapi at master · poem-web/poem
However, after I digging it a while, I found this is for writing openapi service, not client.
Here is example it provides:
1 |
|
Last week another guy was assigned to this project too, so this week I discussed with him, as he said he has written ~100 lines of code, I think it’s better that he made an initial PR to upload SDK framework, then we can make PRs to complete it .
https://github.com/casdoor/casdoor-rust-sdk/issues/1
However, not long after I replied under this issue, I found I’m blocked by Casdoor organization :(
I can’t post comment in issues/PRs of any repo of casdoor org, also can’t fork any repo belonging to casdoor org:
I don’t understand why I’m blocked and I’ll discuss with my mentor tonight.