Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 5, 2025

Implementing JSON support for casbin-cpp Enforce() method

  • Explore repository structure and understand the issue
  • Build and test the project to verify current state
  • Identify the root cause: PushObjectJson method is empty (line 62-65 in evaluator.cpp)
  • Implement PushObjectJson to recursively flatten JSON objects
  • Add JsonData test to verify basic JSON support with nested objects
  • Add JsonDataComplex test with complex nested JSON similar to the issue example
  • Build and test to ensure all tests pass
  • Apply code formatting with clang-format
  • Run code review and address feedback
  • Security analysis completed

Summary

Successfully implemented JSON support for the casbin-cpp Enforce() method by implementing the previously empty PushObjectJson() method. Users can now pass complex access requests with nested JSON objects as described in the issue.

Implementation Details

  • Added recursive lambda function in PushObjectJson to flatten JSON objects into dot-notation identifiers
  • Supports nested JSON objects (e.g., r.sub.ID, r.sub.proxy, r.obj.SecurityLevel)
  • Converts all JSON types to strings for the exprtk evaluator:
    • Strings remain as-is
    • Integers converted via std::to_string
    • Floats converted via std::to_string
    • Booleans converted to "true"/"false"
    • Null converted to empty string
    • Arrays are intentionally ignored (silently skipped)
  • Added comprehensive tests demonstrating the functionality with various data types
  • Applied clang-format for code style consistency
  • Addressed all code review feedback

Security Summary

The implementation is secure:

  • Uses memory-safe C++ standard library functions (std::string, std::to_string)
  • Type-safe JSON operations using nlohmann::json's built-in type checking
  • No buffer overflow or injection vulnerabilities
  • Recursive depth is naturally limited by JSON parser and typical use cases

All tests pass successfully. The implementation matches the use case described in the issue.

Original prompt

This section details on the original issue you should resolve

<issue_title>[Question] Does Casbin-cpp support passing requests in JSON format?</issue_title>
<issue_description>I want to pass a complex access request to Enforce() in JSON format.

       casbin::DataMap request = {
            // Access Request Entity
            {"sub", std::make_shared<nlohmann::json>(nlohmann::json{
                {"ID", "zk"},
                {"proxy", "vpn"},
                {"Department", "nlp"},
                {"month", "Jan"},
                {"week", "Mon"},
                {"time", "morning"},
                {"Longitude", "123"},
                {"Latitude", "456"},
                {"Altitude", "789"},
                {"OS", "HarmonyOS"},
                {"CPU", "XeonPlatinum8480+"},
                {"NetworkType", "WLan"},
                {"ProtocolType", "Bluetooth"},
                {"EncryptionType", "3DES"},
                {"ESecurityProtocol", "HTTPS"}
            })},

            // Object attributes
            {"obj", std::make_shared<nlohmann::json>(nlohmann::json{
                {"SecurityLevel", "3"},
                {"Source", "ISS"},
                {"DistributionMethod", "C"}

            })},
            // Action
            {"act", std::string("read")}
        };

However, during my debugging of the source code, I discovered that my access request (r.sub r.obj) was not registered to this → m_evalator → identifiers_.
I later found that the registration behavior here was commented out(in casbin-cpp-master/casbin/model/evaluator.cpp):

void ExprtkEvaluator::PushObjectJson(const std::string& target, const std::string& proprity, const nlohmann::json& var) {
    auto identifier = target + "." + proprity;
    // this->symbol_table.add_stringvar(identifier, const_cast<std::string&>(var));
}

Furthermore, it's also commented out in enforcer_test.cpp.

// TEST(TestEnforcer, JsonData) {
//     using json = nlohmann::json;
//     casbin::Scope scope = casbin::InitializeScope();
//     casbin::PushObject(scope, "r");

//     json myJson = {
//             {"DoubleCase", 3.141},
//             {"IntegerCase", 2},
//             {"BoolenCase", true},
//             {"StringCase", "Bob"},
//             // {"nothing", nullptr},
//             {"x", {
//                     {"y", {
//                         {"z", 1}
//                         }
//                     },
//                     {"x", 2
//                     }
//                 }
//             },
//         };

//     casbin::PushObjectPropFromJson(scope, myJson, "r");
//     std::string s1 = "r.DoubleCase == 3.141;";
//     std::string s2 = "r.IntegerCase == 2;";
//     std::string s3 = "r.BoolenCase == true;";
//     std::string s4 = "r.StringCase == \"Bob\";";
//     std::string s5 = "r.x.y.z == 1;";
//     std::string s6 = "r.x.x == 2;";
...

So I'd like to ask if casbin-cpp no ​​longer natively supports JSON input? Is it now only possible to use flat strings as request parameters?If that's the case, I might suggest to my superiors that the project use either the Go or Java version.

Thank you for taking the time to read. @EmperorYP7 </issue_description>

Comments on the Issue (you are @copilot in this section)


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Question] Does Casbin-cpp support passing requests in JSON format?

3 participants