From a3b028c81d8bdd1c3c9695a99b698afd9a965119 Mon Sep 17 00:00:00 2001 From: nianyuu Date: Thu, 7 Aug 2025 16:32:15 +0800 Subject: [PATCH] support to get decPaths map Signed-off-by: nianyuu --- BUILD.gn | 1 + bundle.json | 9 ++ interfaces/innerkits/dec_util/BUILD.gn | 43 +++++ .../innerkits/dec_util/include/dec_api.h | 32 ++++ interfaces/innerkits/dec_util/src/dec_api.cpp | 148 ++++++++++++++++++ test/BUILD.gn | 1 + test/unittest/dec_util_test/BUILD.gn | 50 ++++++ test/unittest/dec_util_test/dec_util_test.cpp | 64 ++++++++ 8 files changed, 348 insertions(+) create mode 100644 interfaces/innerkits/dec_util/BUILD.gn create mode 100644 interfaces/innerkits/dec_util/include/dec_api.h create mode 100644 interfaces/innerkits/dec_util/src/dec_api.cpp create mode 100644 test/unittest/dec_util_test/BUILD.gn create mode 100644 test/unittest/dec_util_test/dec_util_test.cpp diff --git a/BUILD.gn b/BUILD.gn index fc79436f..84894ac9 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -83,6 +83,7 @@ group("appspawn_all") { deps += [ "modules/common:appspawn_common" ] deps += [ "modules/sysevent:event_reporter" ] deps += [ "${appspawn_innerkits_path}/client:appspawn_client" ] + deps += [ "${appspawn_innerkits_path}/dec_util:appspawn_dec_util" ] deps += [ "${appspawn_path}/modules/module_engine:libappspawn_module_engine", "${appspawn_path}/modules/module_engine:libappspawn_stub_empty", diff --git a/bundle.json b/bundle.json index 6582a611..c72c2116 100644 --- a/bundle.json +++ b/bundle.json @@ -109,6 +109,15 @@ ] }, "name": "//base/startup/appspawn/interfaces/innerkits/hnp:hnpapi" + }, + { + "header": { + "header_base": "//base/startup/appspawn/interfaces/innerkits/dec_util/include/", + "header_files": [ + "dec_api.h" + ] + }, + "name": "//base/startup/appspawn/interfaces/innerkits/dec_util:appspawn_dec_util" } ], "test": [ diff --git a/interfaces/innerkits/dec_util/BUILD.gn b/interfaces/innerkits/dec_util/BUILD.gn new file mode 100644 index 00000000..e47cd626 --- /dev/null +++ b/interfaces/innerkits/dec_util/BUILD.gn @@ -0,0 +1,43 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed 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. +import("//base/startup/appspawn/appspawn.gni") +import("//build/ohos.gni") + +if (!defined(ohos_lite)) { + config("exported_header_files") { + visibility = [ ":*" ] + include_dirs = [ + "${appspawn_path}/interfaces/innerkits/dec_util/include", + ] + } + + ohos_shared_library("appspawn_dec_util") { + include_dirs = [ "${appspawn_path}/interfaces/innerkits/dec_util/include" ] + sources = [ "${appspawn_path}/interfaces/innerkits/dec_util/src/dec_api.cpp" ] + + public_configs = [ ":exported_header_files" ] + external_deps = [ + "cJSON:cjson", + "config_policy:configpolicy_util", + "hilog:libhilog", + ] + deps = [ "${appspawn_path}/util:libappspawn_util" ] + install_enable = true + subsystem_name = "${subsystem_name}" + part_name = "${part_name}" + } +} else { + group("appspawn_dec_util") { + deps = [] + } +} diff --git a/interfaces/innerkits/dec_util/include/dec_api.h b/interfaces/innerkits/dec_util/include/dec_api.h new file mode 100644 index 00000000..d6fd80c7 --- /dev/null +++ b/interfaces/innerkits/dec_util/include/dec_api.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed 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. + */ + +#ifndef DEC_API_H +#define DEC_API_H + +#include +#include +#include + +/** + * @brief Get decPaths map from sandbox json config file + * + * @param void + * + * @return A map where the key is a permission string and the value is a vector of corresponding decPaths + */ +std::map> GetDecPathMap(void); + +#endif diff --git a/interfaces/innerkits/dec_util/src/dec_api.cpp b/interfaces/innerkits/dec_util/src/dec_api.cpp new file mode 100644 index 00000000..dd649316 --- /dev/null +++ b/interfaces/innerkits/dec_util/src/dec_api.cpp @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed 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. + */ + +#include "appspawn_utils.h" +#include "cJSON.h" +#include "config_policy_utils.h" +#include "dec_api.h" +#include "hilog/log.h" +#include "json_utils.h" + +static std::vector InitDecConfig(void) +{ + std::vector sandboxConfig = {}; + CfgFiles *files = GetCfgFiles("etc/sandbox"); + for (int i = 0; (files != nullptr) && (i < MAX_CFG_POLICY_DIRS_CNT); ++i) { + if (files->paths[i] == nullptr) { + continue; + } + std::string path = files->paths[i]; + std::string appPath = path + "/appdata-sandbox.json"; + APPSPAWN_LOGV("Init sandbox dec config %{public}s", appPath.c_str()); + cJSON *config = GetJsonObjFromFile(appPath.c_str()); + APPSPAWN_CHECK((config != nullptr && cJSON_IsObject(config)), continue, + "Failed to init sandbox dec config %{public}s", appPath.c_str()); + sandboxConfig.push_back(config); + } + FreeCfgFiles(files); + return sandboxConfig; +} + +static void DestroyDecConfig(std::vector &sandboxConfig) +{ + for (auto& config : sandboxConfig) { + APPSPAWN_CHECK_ONLY_EXPER(config != nullptr, continue); + cJSON_Delete(config); + config = nullptr; + } + sandboxConfig.clear(); +} + +static std::string ConvertDecPath(std::string path) +{ + std::vector> replacements = { + {"", "currentUser"}, + {"", "com.ohos.dlpmanager"} + }; + + for (const auto& [from, to] : replacements) { + size_t pos = 0; + while ((pos = path.find(from, pos)) != std::string::npos) { + path.replace(pos, from.length(), to); + pos += to.length(); + } + } + return path; +} + +static void AddDecPathsByPermission(std::map> &decMap, + const std::string permission, const cJSON *permItem) +{ + cJSON *mountPoints = cJSON_GetObjectItemCaseSensitive(permItem, "mount-paths"); + APPSPAWN_CHECK(mountPoints != nullptr && cJSON_IsArray(mountPoints), return, + "Don't get mountPoints json from permission"); + + std::vector decPaths = {}; + int arraySize = cJSON_GetArraySize(mountPoints); + for (int i = 0; i < arraySize; ++i) { + cJSON *mntPoint = cJSON_GetArrayItem(mountPoints, i); + APPSPAWN_CHECK(mntPoint != nullptr && cJSON_IsObject(mntPoint), continue, + "Don't get mntPoint json from mountPoints"); + + cJSON *decPathJson = cJSON_GetObjectItemCaseSensitive(mntPoint, "dec-paths"); + if (decPathJson == nullptr || !cJSON_IsArray(decPathJson)) { + APPSPAWN_LOGV("Don't get decPath json from mntPoint"); + continue; + } + + int count = cJSON_GetArraySize(decPathJson); + for (int j = 0; j < count; ++j) { + cJSON *item = cJSON_GetArrayItem(decPathJson, j); + APPSPAWN_CHECK(item != nullptr && cJSON_IsString(item), continue, "Don't get decPath item"); + const char *strValue = cJSON_GetStringValue(item); + APPSPAWN_CHECK_ONLY_EXPER(strValue != nullptr, continue); + + std::string decPath = ConvertDecPath(strValue); + APPSPAWN_LOGI("Get decPath %{public}s from %{public}s", decPath.c_str(), permission.c_str()); + decPaths.push_back(decPath); + } + } + + if (!decPaths.empty()) { + auto it = decMap.find(permission); + if (it == decMap.end()) { + decMap[permission] = decPaths; + } else { + for (const auto& path : decPaths) { + it->second.push_back(path); + } + } + } +} + +static void ProcessConfig(const cJSON *config, std::map> &decMap) +{ + cJSON *permission = cJSON_GetObjectItemCaseSensitive(config, "permission"); + APPSPAWN_CHECK(permission != nullptr && cJSON_IsArray(permission), return, + "Don't get permission json from config"); + + int arraySize = cJSON_GetArraySize(permission); + for (int i = 0; i < arraySize; ++i) { + cJSON *item = cJSON_GetArrayItem(permission, i); + cJSON *permissionChild = item->child; + while (permissionChild != nullptr && cJSON_IsArray(permissionChild)) { + cJSON *permItem = cJSON_GetArrayItem(permissionChild, 0); + APPSPAWN_CHECK(permItem != nullptr && cJSON_IsObject(permItem), permissionChild = permissionChild->next; + continue, "Don't get permission item"); + APPSPAWN_LOGV("AddDecPathsByPermission %{public}s", permissionChild->string); + AddDecPathsByPermission(decMap, permissionChild->string, permItem); + permissionChild = permissionChild->next; + } + } +} + +std::map> GetDecPathMap(void) +{ + std::vector sandboxConfig = InitDecConfig(); + APPSPAWN_CHECK(!sandboxConfig.empty(), return {}, "Sandbox dec config is empty"); + + std::map> decMap = {}; + for (auto& config : sandboxConfig) { + ProcessConfig(config, decMap); + } + + DestroyDecConfig(sandboxConfig); + return decMap; +} diff --git a/test/BUILD.gn b/test/BUILD.gn index bfb189b8..7e399ae1 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -34,6 +34,7 @@ group("unittest") { deps += [ "unittest/single_test/hnp_installer:hnp_installer_test" ] deps += [ "unittest/devicedebug_test:DevicedebugTest" ] deps += [ "unittest/app_spawn_hisysevent_test:AppSpawn_HisysEvent_ut" ] + deps += [ "unittest/dec_util_test:DecUtilTest" ] } else { testonly = true deps = [ "unittest/app_spawn_lite_test:unittest" ] diff --git a/test/unittest/dec_util_test/BUILD.gn b/test/unittest/dec_util_test/BUILD.gn new file mode 100644 index 00000000..08bb86fd --- /dev/null +++ b/test/unittest/dec_util_test/BUILD.gn @@ -0,0 +1,50 @@ +# Copyright (c) 2025 Huawei Device Co., Ltd. +# Licensed 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. +import("//base/startup/appspawn/appspawn.gni") +import("//build/test.gni") + +if (!defined(ohos_lite)) { + ohos_unittest("DecUtilTest") { + module_out_path = "appspawn/appspawn" + cflags = [ + "-Wno-implicit-fallthrough", + "-Wno-unused-function", + "-Dprivate=public", + "-Dprotected=public", + ] + + cflags_cc = [ + "-Wno-implicit-fallthrough", + "-fexceptions", + ] + + include_dirs = [ + "${appspawn_path}/interfaces/innerkits/dec_util/include", + ] + + sources = [ + "${appspawn_path}/interfaces/innerkits/dec_util/src/dec_api.cpp", + "dec_util_test.cpp", + ] + + defines = [ "APPSPAWN_TEST" ] + + deps = [ "${appspawn_path}/util:libappspawn_util" ] + + external_deps = [ + "cJSON:cjson", + "config_policy:configpolicy_util", + "hilog:libhilog", + ] + } +} diff --git a/test/unittest/dec_util_test/dec_util_test.cpp b/test/unittest/dec_util_test/dec_util_test.cpp new file mode 100644 index 00000000..925a1785 --- /dev/null +++ b/test/unittest/dec_util_test/dec_util_test.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed 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. + */ + +#include +#include + +#include "appspawn_utils.h" +#include "dec_api.h" + +using namespace testing; +using namespace testing::ext; + +namespace OHOS { +class DecUtilTest : public testing::Test { +public: + static void SetUpTestCase() {} + static void TearDownTestCase() {} + void SetUp() + { + const TestInfo *info = UnitTest::GetInstance()->current_test_info(); + GTEST_LOG_(INFO) << info->test_suite_name() << "." << info->name() << " start"; + APPSPAWN_LOGI("%{public}s.%{public}s start", info->test_suite_name(), info->name()); + } + void TearDown() + { + const TestInfo *info = UnitTest::GetInstance()->current_test_info(); + GTEST_LOG_(INFO) << info->test_suite_name() << "." << info->name() << " end"; + APPSPAWN_LOGI("%{public}s.%{public}s end", info->test_suite_name(), info->name()); + } +}; + +/** +* @tc.name: App_Spawn_DecUtil_GetDecPathMap_Success +* @tc.desc: Verify get decPaths map succeed +* +*/ +HWTEST_F(DecUtilTest, App_Spawn_DecUtil_GetDecPathMap_Success, TestSize.Level0) +{ + std::map> decMap = GetDecPathMap(); + + for (const auto& pair : decMap) { + const std::string& key = pair.first; + const std::vector& values = pair.second; + APPSPAWN_LOGI("permission %{public}s", key.c_str()); + for (const std::string& value : values) { + APPSPAWN_LOGI("decPath %{public}s", value.c_str()); + } + } + + EXPECT_GT(decMap.size(), 0); +} +} -- Gitee