- Name: Yash Pandey (@EmperorYP7)
- Organisation: Casbin
- Project link: https://summerofcode.withgoogle.com/projects/#6057909131149312
- Repository link: https://github.com/casbin/casbin-cpp
- Project Name: Benchmarking, Python bindings and Migrating to CTest for Casbin-CPP
- Project Summary: Casbin is an authorization library that extends its features to implement Access
Control Lists, Role-Based Access Control,
and Attribute-Based Access Control models in various programming languages to its clients. Casbin's Core
Engine is written in GoLang. Casbin-CPP has obvious benefits of speed and efficiency compared to its
implementation in other languages and thus, benchmarking is vital for the project to stand out from the
rest. Python is the most versatile as well as the most used programming language and has huge community
support. Casbin-CPP has the potential to support new PyCasbin to compound the benefits of both languages
through language bindings and extension libraries. Currently, the project uses Microsoft Unit Testing
Framework for C++ for testing and Microsoft’s Azure DevOps pipelines for CI. CTest is truly cross-platform
and can be configured using GitHub Actions for consistent and better CI.
Project Ideas are as follows:
- Modernizing the project with C++17 standard and Google’s benchmarking tool
- Implement Python bindings for Casbin-CPP using pybind11 library
- Implement testing based on CTest and set up workflows for Continuous Integration through GitHub Actions
I've been contributing to Casbin-CPP prior to GSoC period. This is when I got introduced to
the project. I tackled some good first issues and learnt about the codebase.
Major contributions include the implementation of SyncedEnforcer
along with the unit tests. Here are my contributions:
# | Title | Status |
---|---|---|
casbin-cpp#82 | feat: Replaced pragma with include guards | |
casbin-cpp#84 | Python bindings to facilitate PyCasbin-on-CPP | |
casbin-cpp#90 | feat: Added async ticker | |
casbin-cpp#92 | feat: Replaced travis with GitHub Actions | |
casbin-cpp#93 | feat: Added translation unit for synced enforcer | |
casbin-cpp#94 | feat: Added Tests for SyncedEnforcer | |
casbin-cpp#96 | Upgrade to C++17 | |
casbin-cpp#98 | fix: Build on MS Visual Studio |
I utilized this phase to plan out and discuss about my projects with the mentors and also work on the plan ahead. I studied about pybind11 and various ways people implemented it in their projects. I studied about mosquitto, Glewlwyd, and envoy proxy to work out ways to integrate casbin with these projects as per casbin-cpp#100, casbin-cpp#79, and casbin-cpp#50. I planned to work on ABAC support for the project. I tried to clean up the project and get it ready for the bindings and C++17 standardization.
Here's my contributions during this period:
# | Title | Status |
---|---|---|
casdoor#65 | feat: Added captcha | |
casbin-cpp#99 | Configure CMake build system 🏗️ | |
casbin-cpp#101 | feat: Initiate CMake configuration | |
casbin-cpp#103 | feat: Completion of Enforcer API | |
casbin-cpp#104 | fix: Taking in parameters by const reference |
I tried to work on integrating Casbin-CPP with Glewlwyd. It required a bit of planning since Casbin-CPP used C++17 and Glewlwyd, C. The discussion can be found in casbin-cpp#100. The idea was to create a middleware which would let casbin operate on the config file and users given by Glewlwyd.
Meanwhile, I added ABAC support by creating object wrapper using C++17 features. There was some overhead involved with the approach I proposed. I am currently working on getting around it.
I also worked on configuring CTests for the project and changed the testing framework from MS Unit Testing to googletest. This includes setting up CI to test the builds on every platform.
Here are my contributions:
# | Title | Status |
---|---|---|
casbin-cpp#105 | feat: Added ABAC entity wrapper | |
casbin-cpp#106 | feat: Added implementation and tests for UpdatePolicy API |
I successfully shifted the testing framework of casbin-cpp from MS Unit testing to Google Test through CTest. This includes configuring CI for build and test through GitHub Actions. The work is ready to be merged to master.
I discovered that Google Test does not provide thread safe tests and is not configured to handle
multithreaded/distributed workflows which prevents us from testing casbin::SyncedEnforcer
.
What can be done instead is to join the threads before assertions.
To inculcate ABAC features into the existing project, I'll be using std::variant
to store
std::string
or a shared pointer to casbin::ABACData
object. This means a refactoring of the
internal API and inspecting ways to integrate this within casbin::Scope
through duktape.
Here are my contributions:
# | Title | Status |
---|---|---|
casbin-cpp#107 | feat: Initiated CTest setup | |
casbin-cpp#108 | test: Management API, Utility methods and more | |
casbin-cpp#109 | test: Added RBAC, Role Manager and removed MS Unit Tests | |
casbin-cpp#110 | feat: Implemented ABAC in Internal API |
Discussions:
# | Title |
---|---|
casbin-cpp#102 | can casbin-cpp support ABAC? |
casbin-cpp#100 | Integrate with Glewlwyd |
In the upcoming week, I'll be:
- Investigating ways and implementing Code Coverage for the project
- Start configuration for Python bindings
- Find out more about Glewlwyd and integrating the project
This week marked the beginning of benchmarking for casbin-cpp
. This includes configuring build system for
finding Google benchmark tool and fetch it from the web if needed. This means that the project
doesn't need the user to setup/install any dependency explicitly. Also, a CI workflow for benchmarking was
set up.
Since the build system was shifted to CMake, this called for updated documentations.
I continued working on CTest and added all the tests implemented in previous MS Unit Tests. I also tried to come up with an approach to implement ABAC in the internal API. I need a bit of reference from GoLang's implementation for the same.
Here are the PRs I opened this week:
# | Title | Status |
---|---|---|
casbin-cpp#112 | feat: Inherit std::exception |
|
casbin-cpp#113 | chore: Updated docs for build instructions | |
casbin-cpp#114 | feat: Initiated benchmark workflow |
Here are the ones I continued working on this week:
# | Title | Status |
---|---|---|
casbin-cpp#108 | test: Management API, Utility methods and more (Continued) | |
casbin-cpp#109 | test: Added RBAC, Role Manager and removed MS Unit Tests (Continued) | |
casbin-cpp#110 | feat: Implemented ABAC in Internal API (Continued) |
Here are the discussions I took part into:
# | Title |
---|---|
casbin-cpp#41 | Setup code coverage badge |
casbin-cpp#111 | Exceptions should inherit std::exception |
casbin-cpp#102 | can casbin-cpp support ABAC? |
In the upcoming week I plan to:
- Complete benchmarking all functions within the library
- Setup code coverage for the project
- Implement ABAC in the internal API
- Cleaning up the code
I utilized this week to inspect about expression evaluators used in casbin-cpp
as per the conversation
in casbin-cpp#110. This will take me a while to
analyse and implement ABAC in casbin-cpp. I'd also include casbin::ABACData
abstraction into the
internal and management APIs. Evaluators also need to recognise and parse sub_rule
s within policy
and model files.
I benchmarked all the functions which are on par with GoLang's casbin. This revealed that there was a
significant memory leak in the project. The benchmarks also bottlenecked at specific functions including
Enforcer::AddPolicies()
and Enforcer::AddGroupingPolicies()
. The library performed significantly slower
with RBAC workflows than GoLang's casbin.
I also tried to incorporate visual benchmarking within the project. However, it is not intended to be
merged in casbin-cpp:master
. Here's the commit:
https://github.com/EmperorYP7/casbin-cpp/commit/e9923bf37a03eebc03655ccf601bc900488f724c
Here are the PRs I opened this week:
# | Title | Status |
---|---|---|
casbin-cpp#116 | test: Benchmarks for CachedEnforcer |
|
casbin-cpp#118 | test: Benchmarks for ManagementAPI | |
casbin-cpp#120 | test: Benchmarks for Model and RoleManager |
Here are the issues I opened:
# | Title | Status |
---|---|---|
casbin-cpp#117 | Error while using casbin::Enforcer::AddPolicies() | |
casbin-cpp#119 | Memory leakage while using Enforcer::AddPolicy and RBAC workflows |
Next week I'll try to:
- Work on ABAC support for the project
- Set up code-coverage (This will require 3rd party apps from GitHub marketplace)
- Clean up code and fix memory leaks
- Improve the performance of the library.
This week I made modifications to the project to accomodate ABAC workflow into the API. My approach was to declare datatypes intrinsic to casbin. The datatypes declared are as follows:
AttributeValue
: The type of a value of an attributeAttribute
: The type of an attribute containing the name and the value as astd::pair
.AttributeVector
: Vector of attributes.AttributeList
: Initializer list of attributes.AttributeMap
: Unordered map containing name and value of the attributes.Data
: Type of Data for accomodatingABACData
DataVector
: Vector ofcasbin::Data
DataList
: Initializer list ofcasbin::Data
DataMap
: unordered map containing name asstd::string
, andcasbin::Data
In case the data is an ABACData
object, the API generates a casbin::Scope
object named
as per the corresponding token key and feeds in the attributes within that object.
Understanding intrinsic types might be confusing for the user/client at first. I made sure that the type names are intuitive and can easily be grasped by anyone having remote familiarity with ABAC.
I also invested some time in cleaning up the project, i.e. reducing the overall memory footprint by minimizing the number of copies and initializations through const reference, references, initializer lists etc.
Here are the PRs I opened this week:
# | Title | Status |
---|---|---|
casbin-cpp#121 | chore: Cleanup | |
casbin-cpp#122 | feat: Streamlined types |
Here are the PRs I followed up on this week:
# | Title | Status |
---|---|---|
casbin-cpp#110 | feat: Implemented ABAC in Internal API (continued) | |
casbin-cpp#116 | test: Benchmarks for CachedEnforcer (continued) |
|
casbin-cpp#118 | test: Benchmarks for ManagementAPI (continued) | |
casbin-cpp#120 | test: Benchmarks for Model and RoleManager (continued) |
Discussions I took part in:
# | Title | Status |
---|---|---|
casbin-cpp#102 | can casbin-cpp support ABAC and eval()? |
The next week I'll try to:
- Come up with an approach to implement
eval()
- Initiate workflow for Python bindings
- Release the benchmark results on the official site
This week marked the beginning of python bindings. I configured the
build system so that it finds pybind11 if it is installed within PATH.
If it doesn't find it there, CMake fetches the zip file from Github
and place the contents into build/_deps
directory. This means that
the project doesn't require any special dependency to be installed.
I also added a mock python binding which compiled sucessfully.
However, I immediately faced a problem. Pybind11's build configuration enforces it to build with C++11, but the project is made in C++17. I tried to research about it and stumbled upon this documentation section - STL containers in pybind11. I'll try to work upon it in the upcoming week.
I also added the results of the benchmarks in casbin-cpp#118 to casbin's website. There was a discussion as to how the testbed should be selected to showcase the benchmarks. I used Apple M1 as the testbed which apparantly, isn't a popular server environemnt. Here is the discussion casbin-website#255.
The benchmarks revealed that the enforcer is a lot slower than expected. I am investigating into what is the cause of such an underperformance. Reference.
Here are the PRs I opened this week:
# | Title | Status |
---|---|---|
casbin-cpp#125 | chore: Model Cleanup | |
casbin-website#256 | feat: Added benchmarks for Casbin-CPP | |
casbin-cpp#123 | feat: Initiated pybind11 Configuration | |
casbin-cpp#124 | chore: Util cleanup |
These are the discussions I participated in:
# | Title | Status |
---|---|---|
casbin-website#255 | Add the C++ result to our benchmark page (between Go and Lua tabs) | |
casbin-cpp#120 | test: Benchmarks for Model and RoleManager |
The next week I'll try to:
- Develop python bindings for the casbin API
- Fix and clean up
casbin::Enforcer
and the API for better performance - Release the revised benchmark results on the official site
* Dates in DD/MM/YYYY format