diff --git a/.gitignore b/.gitignore index e498fd3e..6d205842 100644 --- a/.gitignore +++ b/.gitignore @@ -361,6 +361,7 @@ MigrationBackup/ cmake-build/ xcode-build/ cmake-build*/ +build_support/ # pip *.egg-info diff --git a/CMakeLists.txt b/CMakeLists.txt index 159289ca..cf6415be 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,7 +32,7 @@ endif() project( casbin - VERSION 1.44.0 + VERSION 1.53.2 DESCRIPTION "An authorization library that supports access control models like ACL, RBAC, ABAC in C/C++" HOMEPAGE_URL https://github.com/casbin/casbin-cpp LANGUAGES CXX C diff --git a/build_support/clang_format_exclusions.txt b/build_support/clang_format_exclusions.txt deleted file mode 100644 index e69de29b..00000000 diff --git a/build_support/run_clang_format.py b/build_support/run_clang_format.py deleted file mode 100644 index 4a427407..00000000 --- a/build_support/run_clang_format.py +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env python -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# -# Modified from the Apache Arrow project for the Terrier project. - -import argparse -import codecs -import difflib -import fnmatch -import os -import subprocess -import sys - - -def check(arguments, source_dir, style): - formatted_filenames = [] - error = False - format_args = [arguments.clang_format_binary, "--style=" + style] - - for directory, subdirs, filenames in os.walk(source_dir): - fullpaths = (os.path.join(directory, filename) - for filename in filenames) - source_files = [x for x in fullpaths - if x.endswith(".h") or x.endswith(".cpp")] - formatted_filenames.extend( - # Filter out files that match the globs in the globs file - [filename for filename in source_files - if not any((fnmatch.fnmatch(filename, exclude_glob) - for exclude_glob in exclude_globs))]) - - if arguments.fix: - if not arguments.quiet: - # Print out each file on its own line, but run - # clang format once for all of the files - print("\n".join(map(lambda x: "Formatting {}".format(x), - formatted_filenames))) - subprocess.check_call(format_args + - ["-i"] + formatted_filenames) - else: - for filename in formatted_filenames: - if not arguments.quiet: - print("Checking {}".format(filename)) - # - # Due to some incompatibilities between Python 2 and - # Python 3, there are some specific actions we take here - # to make sure the difflib.unified_diff call works. - # - # In Python 2, the call to subprocess.check_output return - # a 'str' type. In Python 3, however, the call returns a - # 'bytes' type unless the 'encoding' argument is - # specified. Unfortunately, the 'encoding' argument is not - # in the Python 2 API. We could do an if/else here based - # on the version of Python we are running, but it's more - # straightforward to read the file in binary and do utf-8 - # conversion. In Python 2, it's just converting string - # types to unicode types, whereas in Python 3 it's - # converting bytes types to utf-8 encoded str types. This - # approach ensures that the arguments to - # difflib.unified_diff are acceptable string types in both - # Python 2 and Python 3. - with open(filename, "rb") as reader: - # Run clang-format and capture its output - formatted = subprocess.check_output( - format_args + [filename]) - formatted = codecs.decode(formatted, "utf-8") - # Read the original file - original = codecs.decode(reader.read(), "utf-8") - # Run the equivalent of diff -u - diff = list(difflib.unified_diff( - original.splitlines(True), - formatted.splitlines(True), - fromfile=filename, - tofile="{} (after clang format)".format( - filename))) - if diff: - print("{} had clang-format style issues".format(filename)) - # Print out the diff to stderr - error = True - sys.stderr.writelines(diff) - return error - - -if __name__ == "__main__": - parser = argparse.ArgumentParser( - description="Runs clang format on all of the source " - "files. If --fix is specified, and compares the output " - "with the existing file, outputting a unifiied diff if " - "there are any necessary changes") - parser.add_argument("clang_format_binary", - help="Path to the clang-format binary") - parser.add_argument("exclude_globs", - help="Filename containing globs for files " - "that should be excluded from the checks") - parser.add_argument("--source_dirs", - help="Comma-separated root directories of the code") - parser.add_argument("--format_style", - help="format style of the code") - parser.add_argument("--fix", default=False, - action="store_true", - help="If specified, will re-format the source " - "code instead of comparing the re-formatted " - "output, defaults to %(default)s") - parser.add_argument("--quiet", default=False, - action="store_true", - help="If specified, only print errors") - - args = parser.parse_args() - - had_err = False - style = args.format_style - exclude_globs = [line.strip() for line in open(args.exclude_globs)] - for source_dir in args.source_dirs.split(','): - if len(source_dir) > 0: - had_err = check(args, source_dir, style) - - sys.exit(1 if had_err else 0) diff --git a/casbin/config/config.cpp b/casbin/config/config.cpp index 6d5b864e..7c4b9495 100644 --- a/casbin/config/config.cpp +++ b/casbin/config/config.cpp @@ -77,9 +77,8 @@ void Config::ParseBuffer(std::istream* buf) { else { std::vector option_val = Split(line, "=", 2); if (option_val.size() != 2) { - char* error = new char; - sprintf(error, "parse the content error : line %d , %s = ? ", line_num, option_val[0].c_str()); - throw IllegalArgumentException(std::string(error)); + std::string error = "parse the content error : line " + std::to_string(line_num) + " , " + option_val[0] + " = ?"; + throw IllegalArgumentException(error); } std::string option = Trim(option_val[0]); std::string value = Trim(option_val[1]); diff --git a/casbin/enforcer_cached.cpp b/casbin/enforcer_cached.cpp index 0bdae56a..d67b79a8 100644 --- a/casbin/enforcer_cached.cpp +++ b/casbin/enforcer_cached.cpp @@ -108,14 +108,14 @@ CachedEnforcer::CachedEnforcer(const CachedEnforcer& ce) this->enableCache = ce.enableCache; } -CachedEnforcer::CachedEnforcer(CachedEnforcer&& ce) +CachedEnforcer::CachedEnforcer(CachedEnforcer&& ce) noexcept : Enforcer(ce) { - this->m = move(ce.m); + this->m = std::move(ce.m); this->enableCache = ce.enableCache; } -void CachedEnforcer::EnableCache(const bool& enableCache) { - this->enableCache = enableCache; +void CachedEnforcer::EnableCache(const bool& shouldEnableCache) { + this->enableCache = shouldEnableCache; } std::pair CachedEnforcer::getCachedResult(const std::string& key) { diff --git a/casbin/enforcer_synced.cpp b/casbin/enforcer_synced.cpp index b09c3313..7fdd0779 100644 --- a/casbin/enforcer_synced.cpp +++ b/casbin/enforcer_synced.cpp @@ -139,7 +139,7 @@ void SyncedEnforcer ::SetWatcher(std::shared_ptr w) { // LoadModel reloads the model from the model CONF file. void SyncedEnforcer ::LoadModel() { - std::unique_lock(policyMutex); + std::unique_lock lock(policyMutex); Enforcer::LoadModel(); } diff --git a/casbin/management_api.cpp b/casbin/management_api.cpp index 039cff6c..2b5f198a 100644 --- a/casbin/management_api.cpp +++ b/casbin/management_api.cpp @@ -144,10 +144,7 @@ bool Enforcer ::AddNamedPolicy(const std::string& p_type, const std::vectoraddPolicy("p", p_type, str_slice); } - std::vector policy; - for (int i = 0; i < params.size(); i++) - policy.push_back(params[i]); - return this->addPolicy("p", p_type, policy); + return this->addPolicy("p", p_type, params); } // AddNamedPolicies adds authorization rules to the current named policy. diff --git a/casbin/persist/adapter.cpp b/casbin/persist/adapter.cpp index 6b518093..5ba63750 100644 --- a/casbin/persist/adapter.cpp +++ b/casbin/persist/adapter.cpp @@ -25,8 +25,8 @@ namespace casbin { // LoadPolicyLine loads a text line as a policy rule to model. -void LoadPolicyLine(std::string line, const std::shared_ptr& model) { - if (line == "" || line.find("#") == 0) +void LoadPolicyLine(const std::string& line, const std::shared_ptr& model) { + if (line.empty() || line.find('#') == 0) return; std::vector tokens = Split(line, ",", -1); diff --git a/casbin/persist/adapter.h b/casbin/persist/adapter.h index f93a3141..cfba6eb1 100644 --- a/casbin/persist/adapter.h +++ b/casbin/persist/adapter.h @@ -25,7 +25,7 @@ namespace casbin { // LoadPolicyLine loads a text line as a policy rule to model. -void LoadPolicyLine(std::string line, const std::shared_ptr& model); +void LoadPolicyLine(const std::string& line, const std::shared_ptr& model); /** * Adapter is the interface for Casbin adapters. @@ -34,6 +34,8 @@ class Adapter { public: bool filtered; + virtual ~Adapter() = default; + /** * LoadPolicy loads all policy rules from the storage. * diff --git a/cmake/modules/Findbenchmark.cmake b/cmake/modules/Findbenchmark.cmake index 78755783..3ac9f8d5 100644 --- a/cmake/modules/Findbenchmark.cmake +++ b/cmake/modules/Findbenchmark.cmake @@ -16,7 +16,9 @@ include(FetchContent) FetchContent_Declare( benchmark - URL https://github.com/google/benchmark/archive/refs/tags/v1.5.5.zip + GIT_REPOSITORY https://github.com/google/benchmark.git + GIT_TAG v1.8.3 + DOWNLOAD_EXTRACT_TIMESTAMP FALSE ) set(BENCHMARK_ENABLE_TESTING OFF) diff --git a/cmake/modules/Findgoogletest.cmake b/cmake/modules/Findgoogletest.cmake index 343913c0..a98df46a 100644 --- a/cmake/modules/Findgoogletest.cmake +++ b/cmake/modules/Findgoogletest.cmake @@ -17,7 +17,8 @@ include(FetchContent) FetchContent_Declare( googletest GIT_REPOSITORY https://github.com/google/googletest.git - GIT_TAG release-1.11.0 + GIT_TAG v1.14.0 + DOWNLOAD_EXTRACT_TIMESTAMP FALSE ) # For Windows: Prevent overriding the parent project's compiler/linker settings diff --git a/cmake/modules/Findjson.cmake b/cmake/modules/Findjson.cmake index 36bbec4e..68788f04 100644 --- a/cmake/modules/Findjson.cmake +++ b/cmake/modules/Findjson.cmake @@ -16,6 +16,11 @@ include(FetchContent) set(JSON_Install ON) -FetchContent_Declare(json URL https://github.com/nlohmann/json/releases/download/v3.11.2/json.tar.xz) +FetchContent_Declare( + json + GIT_REPOSITORY https://github.com/nlohmann/json.git + GIT_TAG v3.11.2 + DOWNLOAD_EXTRACT_TIMESTAMP FALSE +) FetchContent_MakeAvailable(json) diff --git a/cmake/modules/Findpybind11.cmake b/cmake/modules/Findpybind11.cmake index 600f1883..6e98ee62 100644 --- a/cmake/modules/Findpybind11.cmake +++ b/cmake/modules/Findpybind11.cmake @@ -17,7 +17,8 @@ include(FetchContent) FetchContent_Declare( pybind11 GIT_REPOSITORY https://github.com/pybind/pybind11.git - GIT_TAG v2.8.0 + GIT_TAG v2.11.1 + DOWNLOAD_EXTRACT_TIMESTAMP FALSE ) FetchContent_MakeAvailable(pybind11) diff --git a/include/casbin/enforcer_cached.h b/include/casbin/enforcer_cached.h index 56460ca3..59c6fc6c 100644 --- a/include/casbin/enforcer_cached.h +++ b/include/casbin/enforcer_cached.h @@ -30,9 +30,9 @@ class CachedEnforcer : public Enforcer { std::mutex locker; CachedEnforcer(const CachedEnforcer& ce); - CachedEnforcer(CachedEnforcer&& ce); + CachedEnforcer(CachedEnforcer&& ce) noexcept; - void EnableCache(const bool& enableCache); + void EnableCache(const bool& shouldEnableCache); std::pair getCachedResult(const std::string& key); void setCachedResult(const std::string& key, const bool& res); void InvalidateCache(); diff --git a/include/casbin/model/evaluator.h b/include/casbin/model/evaluator.h index 3c605356..70f29921 100644 --- a/include/casbin/model/evaluator.h +++ b/include/casbin/model/evaluator.h @@ -97,7 +97,7 @@ class ExprtkEvaluator : public IEvaluator { float GetFloat() override; - std::string GetString(); + std::string GetString() override; void Clean(AssertionMap& section, bool after_enforce = true) override; diff --git a/include/casbin/persist/adapter.h b/include/casbin/persist/adapter.h index 9e004e48..390577ce 100644 --- a/include/casbin/persist/adapter.h +++ b/include/casbin/persist/adapter.h @@ -25,7 +25,7 @@ namespace casbin { // LoadPolicyLine loads a text line as a policy rule to model. -void LoadPolicyLine(std::string line, const std::shared_ptr& model); +void LoadPolicyLine(const std::string& line, const std::shared_ptr& model); /** * Adapter is the interface for Casbin adapters. @@ -34,6 +34,8 @@ class Adapter { public: bool filtered; + virtual ~Adapter() = default; + /** * LoadPolicy loads all policy rules from the storage. * diff --git a/tests/benchmarks/model_b.cpp b/tests/benchmarks/model_b.cpp index 469f3cb4..c8803a81 100644 --- a/tests/benchmarks/model_b.cpp +++ b/tests/benchmarks/model_b.cpp @@ -58,33 +58,30 @@ static void BenchmarkRBACModel(benchmark::State& state) { BENCHMARK(BenchmarkRBACModel); static void BenchmarkRBACModelSizesSmall(benchmark::State& state) { - // 100, 10, 1000 - int num_roles = 100, num_resources = 10, num_users = 1000; + int num_roles = 100, num_resources = 10, num_users = 1000; casbin::Enforcer e(rbac_model_path, "", false); - for (int i = 0; i < num_roles; ++i) e.AddPolicy({"group-has-a-very-long-name-" + std::to_string(i), "data-has-a-very-long-name-" + std::to_string(i % num_resources), "read"}); - - for (int i = 0; i < num_users; ++i) { - e.AddGroupingPolicy({"user-has-a-very-long-name-" + std::to_string(i), "group-has-a-very-long-name-" + std::to_string(i % num_roles)}); - } - - int num_request = 17; - std::vector requests(num_request); - - for (int i = 0; i < num_request; ++i) { - int id_user = num_users / num_request * i, - id_role = id_user / num_roles, - id_resource = id_role % num_resources; - if (i&2 == 0) - id_resource = (id_resource + 1) % num_resources; - - requests[i] = {"user-has-a-very-long-name-" + std::to_string(id_user), "data-has-a-very-long-name-" + std::to_string(id_resource), "read"}; - } - - for (auto _ : state) - for (auto& req: requests) - e.Enforce(req); + for (int i = 0; i < num_roles; ++i) + e.AddPolicy({ + "group-has-a-very-long-name-" + std::to_string(i), + "data-has-a-very-long-name-" + std::to_string(i % num_resources), + "read" + }); + + for (int i = 0; i < num_users; ++i) + e.AddGroupingPolicy({ + "user-has-a-very-long-name-" + std::to_string(i), + "group-has-a-very-long-name-" + std::to_string(i % num_roles) + }); + + int itr = 0; + for (auto _ : state) + e.Enforce({ + "user-has-a-very-long-name-" + std::to_string(itr % num_users), + "data-has-a-very-long-name-" + std::to_string(itr % num_resources), + "read" + }), ++itr; } BENCHMARK(BenchmarkRBACModelSizesSmall);