From dfe331f379238dfe97b7e4fc9a6e103c98ef4124 Mon Sep 17 00:00:00 2001 From: chennian Date: Tue, 7 Jun 2022 22:34:58 +0800 Subject: [PATCH 1/7] Signed-off-by:chennian Signed-off-by: chennian --- BUILD.gn | 1 + bundle.json | 1 + interfaces/innerkits/privacy/test/BUILD.gn | 54 ++ .../test/unittest/src/privacy_kit_test.cpp | 594 ++++++++++++++++++ .../test/unittest/src/privacy_kit_test.h | 64 ++ .../privacy/test/unittest/src/to_string.cpp | 61 ++ .../privacy/test/unittest/src/to_string.h | 35 ++ ohos.build | 3 +- services/accesstokenmanager/BUILD.gn | 2 + .../service/accesstoken_manager_service.cpp | 11 +- services/privacymanager/BUILD.gn | 14 + .../privacymanager/include/common/constant.h | 40 ++ .../privacymanager/include/common/time_util.h | 30 + .../privacymanager/include/common/to_string.h | 36 ++ .../include/database/data_translator.h | 37 ++ .../include/database/sqlite_storage.h | 85 +++ ...on_permission_used_record_callback_proxy.h | 40 ++ .../on_permission_used_record_callback_stub.h | 38 ++ .../include/record/permission_record.h | 41 ++ .../record/permission_record_manager.h | 67 ++ .../record/permission_record_repository.h | 39 ++ .../include/record/permission_visitor.h | 42 ++ .../record/permission_visitor_repository.h | 39 ++ .../privacymanager/src/common/constant.cpp | 85 +++ .../privacymanager/src/common/time_util.cpp | 29 + .../privacymanager/src/common/to_string.cpp | 97 +++ .../src/database/data_translator.cpp | 109 ++++ .../src/database/sqlite_storage.cpp | 379 +++++++++++ ..._permission_used_record_callback_proxy.cpp | 71 +++ ...n_permission_used_record_callback_stub.cpp | 65 ++ .../src/record/permission_record.cpp | 45 ++ .../src/record/permission_record_manager.cpp | 417 ++++++++++++ .../record/permission_record_repository.cpp | 74 +++ .../src/record/permission_visitor.cpp | 42 ++ .../record/permission_visitor_repository.cpp | 87 +++ .../src/service/privacy_manager_service.cpp | 12 +- .../add_permission_used_record_test.cpp | 55 ++ .../add_permission_used_record_test.h | 37 ++ 38 files changed, 2972 insertions(+), 6 deletions(-) create mode 100644 interfaces/innerkits/privacy/test/BUILD.gn create mode 100644 interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.cpp create mode 100644 interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.h create mode 100644 interfaces/innerkits/privacy/test/unittest/src/to_string.cpp create mode 100644 interfaces/innerkits/privacy/test/unittest/src/to_string.h create mode 100644 services/privacymanager/include/common/time_util.h create mode 100644 services/privacymanager/include/common/to_string.h create mode 100644 services/privacymanager/include/database/data_translator.h create mode 100644 services/privacymanager/include/database/sqlite_storage.h create mode 100644 services/privacymanager/include/record/on_permission_used_record_callback_proxy.h create mode 100644 services/privacymanager/include/record/on_permission_used_record_callback_stub.h create mode 100644 services/privacymanager/include/record/permission_record.h create mode 100644 services/privacymanager/include/record/permission_record_manager.h create mode 100644 services/privacymanager/include/record/permission_record_repository.h create mode 100644 services/privacymanager/include/record/permission_visitor.h create mode 100644 services/privacymanager/include/record/permission_visitor_repository.h create mode 100644 services/privacymanager/src/common/constant.cpp create mode 100644 services/privacymanager/src/common/time_util.cpp create mode 100644 services/privacymanager/src/common/to_string.cpp create mode 100644 services/privacymanager/src/database/data_translator.cpp create mode 100644 services/privacymanager/src/database/sqlite_storage.cpp create mode 100644 services/privacymanager/src/record/on_permission_used_record_callback_proxy.cpp create mode 100644 services/privacymanager/src/record/on_permission_used_record_callback_stub.cpp create mode 100644 services/privacymanager/src/record/permission_record.cpp create mode 100644 services/privacymanager/src/record/permission_record_manager.cpp create mode 100644 services/privacymanager/src/record/permission_record_repository.cpp create mode 100644 services/privacymanager/src/record/permission_visitor.cpp create mode 100644 services/privacymanager/src/record/permission_visitor_repository.cpp create mode 100644 services/privacymanager/test/add_permission_used_record_test/add_permission_used_record_test.cpp create mode 100644 services/privacymanager/test/add_permission_used_record_test/add_permission_used_record_test.h diff --git a/BUILD.gn b/BUILD.gn index c48606cd3..7d1454cd1 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -58,6 +58,7 @@ group("accesstoken_build_module_test") { "//base/security/access_token/interfaces/innerkits/accesstoken/test:unittest", "//base/security/access_token/interfaces/innerkits/nativetoken/test:unittest", "//base/security/access_token/interfaces/innerkits/token_setproc/test:unittest", + "//base/security/access_token/interfaces/innerkits/privacy/test:unittest", "//base/security/access_token/services/accesstokenmanager/test:unittest", ] } diff --git a/bundle.json b/bundle.json index 7bd645199..6b780f3b8 100644 --- a/bundle.json +++ b/bundle.json @@ -89,6 +89,7 @@ "//base/security/access_token:accesstoken_build_module_test", "//base/security/access_token/interfaces/innerkits/accesstoken/test:unittest", "//base/security/access_token/interfaces/innerkits/nativetoken/test:unittest", + "//base/security/access_token/interfaces/innerkits/privacy/test:unittest", "//base/security/access_token/interfaces/innerkits/token_setproc/test:unittest", "//base/security/access_token/interfaces/kits/accesstoken/test/benchmarktest:benchmarktest", "//base/security/access_token/test/fuzztest/access_token:fuzztest" diff --git a/interfaces/innerkits/privacy/test/BUILD.gn b/interfaces/innerkits/privacy/test/BUILD.gn new file mode 100644 index 000000000..b6b8ffe33 --- /dev/null +++ b/interfaces/innerkits/privacy/test/BUILD.gn @@ -0,0 +1,54 @@ +# Copyright (c) 2021-2022 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("//build/test.gni") + +ohos_unittest("libprivacy_sdk_test") { + subsystem_name = "security" + part_name = "access_token" + module_out_path = part_name + "/" + part_name + + include_dirs = [ + "//utils/native/base/include", + "//third_party/googletest/include", + "//base/security/access_token/interfaces/innerkits/accesstoken/include", + "//base/security/access_token/interfaces/innerkits/nativetoken/include", + "//base/security/access_token/interfaces/innerkits/privacy/include", + "//base/security/access_token/services/privacymanager/include/record", + ] + + sources = [ + "unittest/src/privacy_kit_test.cpp", + "unittest/src/to_string.cpp", + ] + + cflags_cc = [ "-DHILOG_ENABLE" ] + + deps = [ + "//base/security/access_token/interfaces/innerkits/accesstoken:libaccesstoken_sdk", + "//base/security/access_token/interfaces/innerkits/nativetoken:libnativetoken", + "//base/security/access_token/interfaces/innerkits/privacy:libprivacy_sdk", + "//base/security/access_token/services/privacymanager:privacy_manager_service", + "//utils/native/base:utils", + ] + external_deps = [ + "ipc:ipc_core", + "samgr_standard:samgr_proxy", + "startup_l2:syspara", + ] +} + +group("unittest") { + testonly = true + deps = [ ":libprivacy_sdk_test" ] +} diff --git a/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.cpp b/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.cpp new file mode 100644 index 000000000..01c2fe34a --- /dev/null +++ b/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.cpp @@ -0,0 +1,594 @@ +/* + * Copyright (c) 2022 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 "privacy_kit_test.h" + +#include "accesstoken_kit.h" +#include "nativetoken_kit.h" +#include "parameter.h" +#include "privacy_kit.h" +#include "to_string.h" + +using namespace testing::ext; +using namespace OHOS::Security::AccessToken; + +const static int32_t RET_NO_ERROR = 0; +const static int32_t RET_ERROR = -1; + +HapPolicyParams g_PolicyPramsA = { + .apl = APL_NORMAL, + .domain = "test.domain.A", +}; + +HapInfoParams g_InfoParmsA = { + .userID = 1, + .bundleName = "ohos.privacy_test.bundleA", + .instIndex = 0, + .appIDDesc = "privacy_test.bundleA" +}; + +HapPolicyParams g_PolicyPramsB = { + .apl = APL_NORMAL, + .domain = "test.domain.B", +}; + +HapInfoParams g_InfoParmsB = { + .userID = 1, + .bundleName = "ohos.privacy_test.bundleB", + .instIndex = 0, + .appIDDesc = "privacy_test.bundleB" +}; + +void PrivacyKitTest::SetUpTestCase() +{} + +void PrivacyKitTest::TearDownTestCase() +{ +} + +void PrivacyKitTest::SetUp() +{ + AccessTokenKit::AllocHapToken(g_InfoParmsA, g_PolicyPramsA); + AccessTokenKit::AllocHapToken(g_InfoParmsB, g_PolicyPramsB); +} + +void PrivacyKitTest::TearDown() +{ + AccessTokenID tokenId = AccessTokenKit::GetHapTokenID(g_InfoParmsA.userID, + g_InfoParmsA.bundleName, + g_InfoParmsA.instIndex); + AccessTokenKit::DeleteToken(tokenId); + + tokenId = AccessTokenKit::GetHapTokenID(g_InfoParmsB.userID, + g_InfoParmsB.bundleName, + g_InfoParmsB.instIndex); + AccessTokenKit::DeleteToken(tokenId); +} + +std::string PrivacyKitTest::GetLocalDeviceUdid() +{ + const int32_t DEVICE_UUID_LENGTH = 65; + char udid[DEVICE_UUID_LENGTH] = {0}; + GetDevUdid(udid, DEVICE_UUID_LENGTH); + return udid; +} + +void PrivacyKitTest::BuildQueryRequest(AccessTokenID tokenId, const std::string deviceId, const std::string& bundleName, + const std::vector permissionList, PermissionUsedRequest& request) +{ + request.tokenId = tokenId; + request.isRemote = false; + request.deviceId = deviceId; + request.bundleName = bundleName; + request.permissionList = permissionList; + request.beginTimeMillis = 0; + request.endTimeMillis = 0; + request.flag = FLAG_PERMISSION_USAGE_SUMMARY; +} + +void PrivacyKitTest::CheckPermissionUsedResult(const PermissionUsedRequest& request, const PermissionUsedResult& result, + int32_t permRecordSize, int32_t totalSuccessCount, int32_t totalFailCount) +{ + int32_t successCount = 0; + int32_t failCount = 0; + ASSERT_EQ(request.tokenId, result.bundleRecords[0].tokenId); + ASSERT_EQ(request.isRemote, result.bundleRecords[0].isRemote); + ASSERT_EQ(request.deviceId, result.bundleRecords[0].deviceId); + ASSERT_EQ(request.bundleName, result.bundleRecords[0].bundleName); + ASSERT_EQ(permRecordSize, result.bundleRecords[0].permissionRecords.size()); + for (int32_t i = 0; i < permRecordSize; i++) { + successCount += result.bundleRecords[0].permissionRecords[i].accessCount; + failCount += result.bundleRecords[0].permissionRecords[i].rejectCount; + } + ASSERT_EQ(totalSuccessCount, successCount); + ASSERT_EQ(totalFailCount, failCount); +} + +/** + * @tc.name: AddPermissionUsedRecord001 + * @tc.desc: cannot AddPermissionUsedRecord with illegal tokenId and permission. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(PrivacyKitTest, AddPermissionUsedRecord001, TestSize.Level1) +{ + int32_t successCount = 1; + int32_t failCount = 0; + AccessTokenID tokenId = AccessTokenKit::GetHapTokenID(g_InfoParmsA.userID, + g_InfoParmsA.bundleName, + g_InfoParmsA.instIndex); + ASSERT_NE(0, tokenId); + ASSERT_EQ(RET_ERROR, PrivacyKit::AddPermissionUsedRecord(0, "ohos.permission.READ_CONTACTS", successCount, failCount)); + ASSERT_EQ(RET_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "", successCount, failCount)); + ASSERT_EQ(RET_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.READ_CONTACTS", -1, failCount)); + + PermissionUsedRequest request; + PermissionUsedResult result; + std::vector permissionList; + BuildQueryRequest(tokenId, GetLocalDeviceUdid(), g_InfoParmsA.bundleName, permissionList, request); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetPermissionUsedRecords(request, result)); + ASSERT_EQ(0, result.bundleRecords.size()); +} + +/** + * @tc.name: AddPermissionUsedRecord002 + * @tc.desc: cannot AddPermissionUsedRecord with invalid tokenId and permission. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(PrivacyKitTest, AddPermissionUsedRecord002, TestSize.Level1) +{ + int32_t successCount = 1; + int32_t failCount = 0; + AccessTokenID tokenId = AccessTokenKit::GetHapTokenID(g_InfoParmsA.userID, + g_InfoParmsA.bundleName, + g_InfoParmsA.instIndex); + ASSERT_NE(0, tokenId); + + ASSERT_EQ(RET_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.test", successCount, failCount)); + ASSERT_EQ(RET_ERROR, PrivacyKit::AddPermissionUsedRecord(123, "ohos.permission.CAMERA", successCount, failCount)); + ASSERT_EQ(RET_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.READ_CONTACTS", 0, 0)); + + PermissionUsedRequest request; + PermissionUsedResult result; + std::vector permissionList; + BuildQueryRequest(123, "", "", permissionList, request); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetPermissionUsedRecords(request, result)); + ASSERT_EQ(0, result.bundleRecords.size()); + + BuildQueryRequest(tokenId, GetLocalDeviceUdid(), g_InfoParmsA.bundleName, permissionList, request); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetPermissionUsedRecords(request, result)); + ASSERT_EQ(0, result.bundleRecords.size()); +} + +/** + * @tc.name: AddPermissionUsedRecord003 + * @tc.desc: cannot AddPermissionUsedRecord with native tokenId. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(PrivacyKitTest, AddPermissionUsedRecord003, TestSize.Level1) +{ + const char **dcaps = new const char *[2]; + dcaps[0] = "AT_CAP"; + dcaps[1] = "ST_CAP"; + uint64_t tokenId; + const char **acls = new const char *[2]; + acls[0] = "ohos.permission.test1"; + acls[1] = "ohos.permission.test2"; + const char **perms = new const char *[2]; + perms[0] = "ohos.permission.test1"; + perms[1] = "ohos.permission.test2"; + NativeTokenInfoParams infoInstance = { + .dcapsNum = 2, + .permsNum = 2, + .aclsNum = 2, + .dcaps = dcaps, + .perms = perms, + .acls = acls, + .processName = "GetAccessTokenId008", + .aplStr = "system_core", + }; + tokenId = GetAccessTokenId(&infoInstance); + ASSERT_NE(tokenId, 0); + + delete[] perms; + delete[] dcaps; + delete[] acls; + + int32_t successCount = 1; + int32_t failCount = 0; + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.READ_CONTACTS", successCount, failCount)); + + PermissionUsedRequest request; + PermissionUsedResult result; + std::vector permissionList; + BuildQueryRequest(tokenId, "", "", permissionList, request); + + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetPermissionUsedRecords(request, result)); + ASSERT_EQ(0, result.bundleRecords.size()); +} + +/** + * @tc.name: AddPermissionUsedRecord004 + * @tc.desc: AddPermissionUsedRecord user_grant permission. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(PrivacyKitTest, AddPermissionUsedRecord004, TestSize.Level1) +{ + int32_t count_0 = 0; + int32_t count_1 = 1; + AccessTokenID tokenId = AccessTokenKit::GetHapTokenID(g_InfoParmsA.userID, + g_InfoParmsA.bundleName, + g_InfoParmsA.instIndex); + ASSERT_NE(0, tokenId); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.CAMERA", count_1, count_0)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.WRITE_CONTACTS", count_0, count_1)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.LOCATION", count_1, count_1)); + + PermissionUsedRequest request; + PermissionUsedResult result; + std::vector permissionList; + BuildQueryRequest(tokenId, GetLocalDeviceUdid(), g_InfoParmsA.bundleName, permissionList, request); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetPermissionUsedRecords(request, result)); + + ASSERT_EQ(1, result.bundleRecords.size()); + CheckPermissionUsedResult(request, result, 3, 2, 2); +} + +/** + * @tc.name: AddPermissionUsedRecord005 + * @tc.desc: AddPermissionUsedRecord user_grant permission. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(PrivacyKitTest, AddPermissionUsedRecord005, TestSize.Level1) +{ + int32_t count_0 = 0; + int32_t count_1 = 1; + AccessTokenID tokenId1 = AccessTokenKit::GetHapTokenID(g_InfoParmsA.userID, + g_InfoParmsA.bundleName, + g_InfoParmsA.instIndex); + ASSERT_NE(0, tokenId1); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId1, "ohos.permission.CAMERA", count_1, count_0)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId1, "ohos.permission.LOCATION", count_0, count_1)); + + AccessTokenID tokenId2 = AccessTokenKit::GetHapTokenID(g_InfoParmsB.userID, + g_InfoParmsB.bundleName, + g_InfoParmsB.instIndex); + ASSERT_NE(0, tokenId2); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId2, "ohos.permission.CAMERA", count_0, count_1)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId2, "ohos.permission.LOCATION", count_1, count_0)); + + + PermissionUsedRequest request; + PermissionUsedResult result; + std::vector permissionList; + BuildQueryRequest(tokenId1, GetLocalDeviceUdid(), g_InfoParmsA.bundleName, permissionList, request); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetPermissionUsedRecords(request, result)); + + ASSERT_EQ(1, result.bundleRecords.size()); + CheckPermissionUsedResult(request, result, 2, 1, 1); + + BuildQueryRequest(tokenId2, GetLocalDeviceUdid(), g_InfoParmsB.bundleName, permissionList, request); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetPermissionUsedRecords(request, result)); + + ASSERT_EQ(1, result.bundleRecords.size()); + CheckPermissionUsedResult(request, result, 2, 1, 1); +} + +/** + * @tc.name: AddPermissionUsedRecord006 + * @tc.desc: AddPermissionUsedRecord permission combine records. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(PrivacyKitTest, AddPermissionUsedRecord006, TestSize.Level1) +{ + int32_t count_0 = 0; + int32_t count_1 = 1; + AccessTokenID tokenId = AccessTokenKit::GetHapTokenID(g_InfoParmsA.userID, + g_InfoParmsA.bundleName, + g_InfoParmsA.instIndex); + ASSERT_NE(0, tokenId); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.CAMERA", count_1, count_0)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.CAMERA", count_1, count_0)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.CAMERA", count_1, count_0)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.CAMERA", count_1, count_0)); + + PermissionUsedRequest request; + PermissionUsedResult result; + std::vector permissionList; + BuildQueryRequest(tokenId, GetLocalDeviceUdid(), g_InfoParmsA.bundleName, permissionList, request); + request.flag = FLAG_PERMISSION_USAGE_DETAIL; + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetPermissionUsedRecords(request, result)); + + ASSERT_EQ(1, result.bundleRecords.size()); + ASSERT_EQ(1, result.bundleRecords[0].permissionRecords.size()); + ASSERT_EQ(1, result.bundleRecords[0].permissionRecords[0].accessRecords.size()); + CheckPermissionUsedResult(request, result, 1, 4, 0); + + sleep(61); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.CAMERA", count_1, count_0)); + + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetPermissionUsedRecords(request, result)); + + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetPermissionUsedRecords(request, result)); + ASSERT_EQ(1, result.bundleRecords.size()); + ASSERT_EQ(1, result.bundleRecords[0].permissionRecords.size()); + ASSERT_EQ(2, result.bundleRecords[0].permissionRecords[0].accessRecords.size()); + CheckPermissionUsedResult(request, result, 1, 5, 0); +} + +/** + * @tc.name: RemovePermissionUsedRecords001 + * @tc.desc: cannot RemovePermissionUsedRecords with illegal tokenId and deviceID. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(PrivacyKitTest, RemovePermissionUsedRecords001, TestSize.Level1) +{ + ASSERT_EQ(RET_ERROR, PrivacyKit::RemovePermissionUsedRecords(0, "")); +} + +/** + * @tc.name: RemovePermissionUsedRecords002 + * @tc.desc: RemovePermissionUsedRecords with invalid tokenId and deviceID. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(PrivacyKitTest, RemovePermissionUsedRecords002, TestSize.Level1) +{ + int32_t successCount = 1; + int32_t failCount = 0; + AccessTokenID tokenId = AccessTokenKit::GetHapTokenID(g_InfoParmsA.userID, + g_InfoParmsA.bundleName, + g_InfoParmsA.instIndex); + ASSERT_NE(0, tokenId); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.CAMERA", successCount, failCount)); + PermissionUsedRequest request; + PermissionUsedResult result; + std::vector permissionList; + BuildQueryRequest(tokenId, GetLocalDeviceUdid(), g_InfoParmsA.bundleName, permissionList, request); + + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::RemovePermissionUsedRecords(tokenId, "invalid_device")); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetPermissionUsedRecords(request, result)); + ASSERT_EQ(1, result.bundleRecords.size()); + + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::RemovePermissionUsedRecords(123, GetLocalDeviceUdid())); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetPermissionUsedRecords(request, result)); + ASSERT_EQ(1, result.bundleRecords.size()); +} + +/** + * @tc.name: RemovePermissionUsedRecords003 + * @tc.desc: RemovePermissionUsedRecords with valid tokenId and deviceID. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(PrivacyKitTest, RemovePermissionUsedRecords003, TestSize.Level1) +{ + int32_t successCount = 1; + int32_t failCount = 0; + AccessTokenID tokenId = AccessTokenKit::GetHapTokenID(g_InfoParmsA.userID, + g_InfoParmsA.bundleName, + g_InfoParmsA.instIndex); + ASSERT_NE(0, tokenId); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.CAMERA", successCount, failCount)); + PermissionUsedRequest request; + PermissionUsedResult result; + std::vector permissionList; + BuildQueryRequest(tokenId, GetLocalDeviceUdid(), g_InfoParmsA.bundleName, permissionList, request); + + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::RemovePermissionUsedRecords(tokenId, "")); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetPermissionUsedRecords(request, result)); + ASSERT_EQ(0, result.bundleRecords.size()); +} + +/** + * @tc.name: GetPermissionUsedRecords001 + * @tc.desc: cannot GetPermissionUsedRecords with invalid query time. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(PrivacyKitTest, GetPermissionUsedRecords001, TestSize.Level1) +{ + int32_t successCount = 1; + int32_t failCount = 0; + AccessTokenID tokenId = AccessTokenKit::GetHapTokenID(g_InfoParmsA.userID, + g_InfoParmsA.bundleName, + g_InfoParmsA.instIndex); + ASSERT_NE(0, tokenId); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.MICROPHONE", successCount, failCount)); + PermissionUsedRequest request; + PermissionUsedResult result; + std::vector permissionList; + BuildQueryRequest(tokenId, GetLocalDeviceUdid(), g_InfoParmsA.bundleName, permissionList, request); + request.beginTimeMillis = -1; + request.endTimeMillis = -1; + ASSERT_EQ(RET_ERROR, PrivacyKit::GetPermissionUsedRecords(request, result)); + + request.beginTimeMillis = 3; + request.endTimeMillis = 1; + ASSERT_EQ(RET_ERROR, PrivacyKit::GetPermissionUsedRecords(request, result)); +} + +/** + * @tc.name: GetPermissionUsedRecords002 + * @tc.desc: cannot GetPermissionUsedRecords with valid query time. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(PrivacyKitTest, GetPermissionUsedRecords002, TestSize.Level1) +{ + int32_t successCount = 1; + int32_t failCount = 0; + AccessTokenID tokenId = AccessTokenKit::GetHapTokenID(g_InfoParmsA.userID, + g_InfoParmsA.bundleName, + g_InfoParmsA.instIndex); + ASSERT_NE(0, tokenId); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.MICROPHONE", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.CAMERA", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.READ_CALENDAR", successCount, failCount)); + + PermissionUsedRequest request; + PermissionUsedResult result; + std::vector permissionList; + // query by tokenId + BuildQueryRequest(tokenId, "", "", permissionList, request); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetPermissionUsedRecords(request, result)); + ASSERT_EQ(1, result.bundleRecords.size()); + request.deviceId = GetLocalDeviceUdid(); + request.bundleName = g_InfoParmsA.bundleName; + CheckPermissionUsedResult(request, result, 3, 3, 0); + + // query by deviceId and bundle Name + BuildQueryRequest(0, GetLocalDeviceUdid(), g_InfoParmsA.bundleName, permissionList, request); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetPermissionUsedRecords(request, result)); + ASSERT_EQ(1, result.bundleRecords.size()); + request.tokenId = tokenId; + CheckPermissionUsedResult(request, result, 3, 3, 0); + + // query by unmatched tokenId, deviceId and bundle Name + BuildQueryRequest(123, GetLocalDeviceUdid(), g_InfoParmsA.bundleName, permissionList, request); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetPermissionUsedRecords(request, result)); + ASSERT_EQ(0, result.bundleRecords.size()); + + // query by unmatched tokenId, deviceId and bundle Name + BuildQueryRequest(tokenId, "local device", g_InfoParmsA.bundleName, permissionList, request); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetPermissionUsedRecords(request, result)); + ASSERT_EQ(0, result.bundleRecords.size()); + + // query by unmatched tokenId, deviceId and bundle Name + BuildQueryRequest(tokenId, GetLocalDeviceUdid(), "bundleA", permissionList, request); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetPermissionUsedRecords(request, result)); + ASSERT_EQ(0, result.bundleRecords.size()); +} + +/** + * @tc.name: GetPermissionUsedRecords003 + * @tc.desc: cannot GetPermissionUsedRecords with valid query time. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(PrivacyKitTest, GetPermissionUsedRecords003, TestSize.Level1) +{ + int32_t successCount = 1; + int32_t failCount = 0; + AccessTokenID tokenId = AccessTokenKit::GetHapTokenID(g_InfoParmsA.userID, + g_InfoParmsA.bundleName, + g_InfoParmsA.instIndex); + ASSERT_NE(0, tokenId); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.MICROPHONE", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.MICROPHONE", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.MICROPHONE", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.MICROPHONE", successCount, failCount)); + + PermissionUsedRequest request; + PermissionUsedResult result; + std::vector permissionList; + BuildQueryRequest(tokenId, GetLocalDeviceUdid(), g_InfoParmsA.bundleName, permissionList, request); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetPermissionUsedRecords(request, result)); + ASSERT_EQ(1, result.bundleRecords.size()); + CheckPermissionUsedResult(request, result, 1, 4, 0); + + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.CAMERA", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.READ_CALENDAR", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.WRITE_CALENDAR", successCount, failCount)); + + BuildQueryRequest(tokenId, GetLocalDeviceUdid(), g_InfoParmsA.bundleName, permissionList, request); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetPermissionUsedRecords(request, result)); + ASSERT_EQ(1, result.bundleRecords.size()); + CheckPermissionUsedResult(request, result, 4, 7, 0); +} + +/** + * @tc.name: GetPermissionUsedRecords004 + * @tc.desc: cannot GetPermissionUsedRecords with valid query time. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(PrivacyKitTest, GetPermissionUsedRecords004, TestSize.Level1) +{ + int32_t successCount = 1; + int32_t failCount = 0; + AccessTokenID tokenId1 = AccessTokenKit::GetHapTokenID(g_InfoParmsA.userID, + g_InfoParmsA.bundleName, + g_InfoParmsA.instIndex); + AccessTokenID tokenId2 = AccessTokenKit::GetHapTokenID(g_InfoParmsB.userID, + g_InfoParmsB.bundleName, + g_InfoParmsB.instIndex); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId1, "ohos.permission.CAMERA", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId1, "ohos.permission.READ_CALENDAR", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId2, "ohos.permission.CAMERA", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId2, "ohos.permission.READ_CALENDAR", successCount, failCount)); + + PermissionUsedRequest request; + PermissionUsedResult result; + std::vector permissionList; + BuildQueryRequest(0, GetLocalDeviceUdid(), "", permissionList, request); + + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetPermissionUsedRecords(request, result)); + if (result.bundleRecords.size() < 2) { + ASSERT_EQ(RET_NO_ERROR, RET_ERROR); + } +} + +/** + * @tc.name: GetPermissionUsedRecordsAsync001 + * @tc.desc: cannot GetPermissionUsedRecordsAsync with invalid query time. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(PrivacyKitTest, GetPermissionUsedRecordsAsync001, TestSize.Level1) +{ + int32_t successCount = 1; + int32_t failCount = 0; + std::string permission = "ohos.permission.CAMERA"; + AccessTokenID tokenID = AccessTokenKit::GetHapTokenID(g_InfoParmsA.userID, + g_InfoParmsA.bundleName, + g_InfoParmsA.instIndex); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenID, permission, successCount, failCount)); + PermissionUsedRequest request; + std::vector permissionList; + BuildQueryRequest(tokenID, GetLocalDeviceUdid(), "", permissionList, request); + request.beginTimeMillis = -1; + request.endTimeMillis = -1; + OHOS::sptr callback(new TestCallBack()); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetPermissionUsedRecords(request, callback)); +} + +/** + * @tc.name: GetPermissionUsedRecordsAsync002 + * @tc.desc: cannot GetPermissionUsedRecordsAsync with valid query time. + * @tc.type: FUNC + * @tc.require:Issue Number + */ +HWTEST_F(PrivacyKitTest, GetPermissionUsedRecordsAsync002, TestSize.Level1) +{ + int32_t successCount = 1; + int32_t failCount = 0; + std::string permission = "ohos.permission.CAMERA"; + AccessTokenID tokenID = AccessTokenKit::GetHapTokenID(g_InfoParmsA.userID, + g_InfoParmsA.bundleName, + g_InfoParmsA.instIndex); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenID, permission, successCount, failCount)); + PermissionUsedRequest request; + std::vector permissionList; + BuildQueryRequest(tokenID, GetLocalDeviceUdid(), "", permissionList, request); + OHOS::sptr callback(new TestCallBack()); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetPermissionUsedRecords(request, callback)); +} \ No newline at end of file diff --git a/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.h b/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.h new file mode 100644 index 000000000..74d67f34f --- /dev/null +++ b/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2021-2022 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 PRIVACY_KIT_TEST_H +#define PRIVACY_KIT_TEST_H + +#include +#include + +#include "on_permission_used_record_callback_stub.h" +#include "permission_used_request.h" +#include "permission_used_result.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +static const uint32_t TEST_TOKENID_INVALID = 0; +static const uint32_t TEST_VALID_TOKENID_A = 1; +static const uint32_t TEST_VALID_TOKENID_B = 2; +static const std::string TEST_EMPTY_DEVICEID = ""; +static const std::string TEST_PERMISSION_INVALID = ""; + +class PrivacyKitTest : public testing::Test { +public: + static void SetUpTestCase(); + + static void TearDownTestCase(); + + void SetUp(); + + void TearDown(); + + class TestCallBack : public OnPermissionUsedRecordCallbackStub { + public: + TestCallBack() = default; + virtual ~TestCallBack() = default; + + void OnQueried(ErrCode code, PermissionUsedResult& result) + { + GTEST_LOG_(INFO) << "TestCallBack, code :" << code << ", bundleSize :" << result.bundleRecords.size(); + } + }; + std::string GetLocalDeviceUdid(); + void BuildQueryRequest(AccessTokenID tokenId, const std::string deviceId, const std::string& bundleName, + const std::vector permissionList, PermissionUsedRequest& request); + void CheckPermissionUsedResult(const PermissionUsedRequest& request, const PermissionUsedResult& result, + int32_t permRecordSize, int32_t totalSuccessCount, int32_t totalFailCount); +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // PRIVACY_KIT_TEST_H diff --git a/interfaces/innerkits/privacy/test/unittest/src/to_string.cpp b/interfaces/innerkits/privacy/test/unittest/src/to_string.cpp new file mode 100644 index 000000000..c9f30da23 --- /dev/null +++ b/interfaces/innerkits/privacy/test/unittest/src/to_string.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2022 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 "to_string.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +void ToString::PermissionUsedRecordToString(const PermissionUsedRecord& permissionRecord, std::string& infos) +{ + infos.append(R"( "permissionRecords": [)"); + infos.append("\n"); + + infos.append(R"( "permissionName": ")" + permissionRecord.permissionName + R"(")" + ",\n"); + infos.append(R"( "accessCount": ")" + std::to_string(permissionRecord.accessCount) + R"(")" + ",\n"); + infos.append(R"( "rejectCount": )" + std::to_string(permissionRecord.rejectCount) + ",\n"); + infos.append(R"( "lastAccessTime": )" + std::to_string(permissionRecord.lastAccessTime) + ",\n"); + infos.append(R"( "lastRejectTime": )" + std::to_string(permissionRecord.lastRejectTime) + ",\n"); + infos.append(R"( "lastAccessDuration": )" + std::to_string(permissionRecord.lastAccessDuration) + ",\n"); + infos.append(" ],\n"); +} + +void ToString::BundleUsedRecordToString(const BundleUsedRecord& bundleRecord, std::string& infos) +{ + infos.append(R"({)"); + infos.append("\n"); + infos.append(R"( "bundleName": )" + bundleRecord.bundleName + ",\n"); + infos.append(R"( "deviceId": )" + bundleRecord.deviceId + ",\n"); + + for (auto perm : bundleRecord.permissionRecords) { + ToString::PermissionUsedRecordToString(perm, infos); + } + + infos.append("}"); +} + +void ToString::PermissionUsedResultToString(const PermissionUsedResult& result, std::string& infos) +{ + infos.append(R"("beginTimeMillis": )" + std::to_string(result.beginTimeMillis) + ",\n"); + infos.append(R"("endTimeMillis": )" + std::to_string(result.endTimeMillis) + ",\n"); + + for (auto res : result.bundleRecords) { + ToString::BundleUsedRecordToString(res, infos); + } + infos.append("\n"); +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/innerkits/privacy/test/unittest/src/to_string.h b/interfaces/innerkits/privacy/test/unittest/src/to_string.h new file mode 100644 index 000000000..3d96c712d --- /dev/null +++ b/interfaces/innerkits/privacy/test/unittest/src/to_string.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021-2022 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 TO_STRING_H +#define TO_STRING_H + +#include +#include "permission_used_request.h" +#include "permission_used_result.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class ToString { +public: + static void PermissionUsedRecordToString(const PermissionUsedRecord& permissionRecord, std::string& infos); + static void BundleUsedRecordToString(const BundleUsedRecord& bundleRecord, std::string& infos); + static void PermissionUsedResultToString(const PermissionUsedResult& result, std::string& infos); +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // TO_STRING_H diff --git a/ohos.build b/ohos.build index 67d710d1d..9bb34ca00 100644 --- a/ohos.build +++ b/ohos.build @@ -53,7 +53,8 @@ "//base/security/access_token:accesstoken_build_module_test", "//base/security/access_token/interfaces/innerkits/accesstoken/test:unittest", "//base/security/access_token/interfaces/innerkits/nativetoken/test:unittest", - "//base/security/access_token/interfaces/innerkits/token_setproc/test:unittest" + "//base/security/access_token/interfaces/innerkits/token_setproc/test:unittest", + "//base/security/access_token/interfaces/innerkits/privacy/test:unittest" ] } } diff --git a/services/accesstokenmanager/BUILD.gn b/services/accesstokenmanager/BUILD.gn index a2095d564..136d70f60 100644 --- a/services/accesstokenmanager/BUILD.gn +++ b/services/accesstokenmanager/BUILD.gn @@ -37,6 +37,7 @@ ohos_shared_library("accesstoken_manager_service") { "//base/security/access_token/frameworks/common/include", "//base/security/access_token/frameworks/tokensync/include", "//base/security/access_token/interfaces/innerkits/accesstoken/include", + "//base/security/access_token/interfaces/innerkits/privacy/include", "//base/security/access_token/interfaces/innerkits/tokensync/src", "//base/security/access_token/services/tokensyncmanager/include/common", "//foundation/distributedhardware/devicemanager/interfaces/inner_kits/native_cpp/include", @@ -67,6 +68,7 @@ ohos_shared_library("accesstoken_manager_service") { "//base/security/access_token/frameworks/accesstoken:accesstoken_communication_adapter_cxx", "//base/security/access_token/frameworks/common:accesstoken_common_cxx", "//base/security/access_token/frameworks/database:accesstoken_database_cxx", + "//base/security/access_token/interfaces/innerkits/privacy:libprivacy_sdk", "//base/security/access_token/services/accesstokenmanager:access_token.rc", "//third_party/sqlite:sqlite", "//utils/native/base:utils", diff --git a/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp b/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp index 8f885455c..8c69021be 100644 --- a/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp +++ b/services/accesstokenmanager/main/cpp/src/service/accesstoken_manager_service.cpp @@ -29,6 +29,7 @@ #include "native_token_receptor.h" #include "permission_list_state.h" #include "permission_manager.h" +#include "privacy_kit.h" namespace OHOS { namespace Security { @@ -86,7 +87,13 @@ int AccessTokenManagerService::VerifyAccessToken(AccessTokenID tokenID, const st { ACCESSTOKEN_LOG_INFO(LABEL, "called, tokenID: 0x%{public}x, permissionName: %{public}s", tokenID, permissionName.c_str()); - return PermissionManager::GetInstance().VerifyAccessToken(tokenID, permissionName); + int isGranted = PermissionManager::GetInstance().VerifyAccessToken(tokenID, permissionName); + if (isGranted != PERMISSION_GRANTED) { + PrivacyKit::AddPermissionUsedRecord(tokenID, permissionName, 0, 1); + } else { + PrivacyKit::AddPermissionUsedRecord(tokenID, permissionName, 1, 0); + } + return isGranted; } int AccessTokenManagerService::VerifyNativeToken(AccessTokenID tokenID, const std::string& permissionName) @@ -194,6 +201,7 @@ int AccessTokenManagerService::ClearUserGrantedPermissionState(AccessTokenID tok ACCESSTOKEN_LOG_INFO(LABEL, "called, tokenID: 0x%{public}x", tokenID); PermissionManager::GetInstance().ClearUserGrantedPermissionState(tokenID); AccessTokenInfoManager::GetInstance().RefreshTokenInfoIfNeeded(); + PrivacyKit::RemovePermissionUsedRecords(tokenID, ""); return RET_SUCCESS; } @@ -214,6 +222,7 @@ AccessTokenIDEx AccessTokenManagerService::AllocHapToken(const HapInfoParcel& in int AccessTokenManagerService::DeleteToken(AccessTokenID tokenID) { ACCESSTOKEN_LOG_INFO(LABEL, "called, tokenID: 0x%{public}x", tokenID); + PrivacyKit::RemovePermissionUsedRecords(tokenID, ""); // only support hap token deletion return AccessTokenInfoManager::GetInstance().RemoveHapTokenInfo(tokenID); } diff --git a/services/privacymanager/BUILD.gn b/services/privacymanager/BUILD.gn index 900f65e01..6567a05e2 100644 --- a/services/privacymanager/BUILD.gn +++ b/services/privacymanager/BUILD.gn @@ -19,6 +19,8 @@ ohos_shared_library("privacy_manager_service") { include_dirs = [ "include/common", + "include/database", + "include/record", "include/service", "//base/security/access_token/frameworks/privacy/include", "//base/security/access_token/frameworks/common/include", @@ -29,6 +31,18 @@ ohos_shared_library("privacy_manager_service") { ] sources = [ + "src/common/constant.cpp", + "src/common/time_util.cpp", + "src/common/to_string.cpp", + "src/database/data_translator.cpp", + "src/database/sqlite_storage.cpp", + "src/record/on_permission_used_record_callback_proxy.cpp", + "src/record/on_permission_used_record_callback_stub.cpp", + "src/record/permission_record_manager.cpp", + "src/record/permission_record_repository.cpp", + "src/record/permission_record.cpp", + "src/record/permission_visitor_repository.cpp", + "src/record/permission_visitor.cpp", "src/service/privacy_manager_service.cpp", "src/service/privacy_manager_stub.cpp", ] diff --git a/services/privacymanager/include/common/constant.h b/services/privacymanager/include/common/constant.h index 768179065..c754282d5 100644 --- a/services/privacymanager/include/common/constant.h +++ b/services/privacymanager/include/common/constant.h @@ -24,10 +24,50 @@ namespace Security { namespace AccessToken { class Constant { public: + enum OpCode { + OP_ANSWER_CALL = 0, + OP_READ_CALENDAR = 1, + OP_WRITE_CALENDAR = 2, + OP_SEND_MESSAGES = 3, + OP_WRITE_CALL_LOG = 4, + OP_READ_CALL_LOG = 5, + OP_READ_CELL_MESSAGES = 6, + OP_MICROPHONE = 7, + OP_RECEIVE_WAP_MESSAGES = 8, + OP_RECEIVE_SMS = 9, + OP_RECEIVE_MMS = 10, + OP_READ_MESSAGES = 11, + OP_READ_CONTACTS = 12, + OP_WRITE_CONTACTS = 13, + OP_LOCATION_IN_BACKGROUND = 14, + OP_LOCATION = 15, + OP_MEDIA_LOCATION = 16, + OP_CAMERA = 17, + OP_READ_MEDIA = 18, + OP_WRITE_MEDIA = 19, + OP_ACTIVITY_MOTION = 20, + OP_READ_HEALTH_DATA = 21, + OP_MANAGE_VOICEMAIL = 22, + OP_DISTRIBUTED_DATASYNC = 23, + }; + enum ErrorCode { FAILURE = -1, SUCCESS = 0, }; + + const static int32_t MAX_TOTAL_RECORD = 10000; + const static int32_t MAX_DETAIL_RECORD = 10; + const static int32_t RECORD_DELETE_TIME = 30 * 86400; + const static int32_t PRECISE = 60; + const static int32_t LATEST_RECORD_TIME = 7 * 86400; + + const static std::map PERMISSION_OPCODE_MAP; +public: + static bool TransferPermissionToOpcode(const std::string& permissionName, int32_t& opCode); + static bool TransferOpcodeToPermission(int32_t opCode, std::string& permissionName); + + static std::string GetLocalDeviceUdid(); }; } // namespace AccessToken } // namespace Security diff --git a/services/privacymanager/include/common/time_util.h b/services/privacymanager/include/common/time_util.h new file mode 100644 index 000000000..3bb25b773 --- /dev/null +++ b/services/privacymanager/include/common/time_util.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021-2022 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 TIME_UTIL_H +#define TIME_UTIL_H +#include +namespace OHOS { +namespace Security { +namespace AccessToken { +class TimeUtil { +public: + static int64_t GetCurrentTimestamp(); +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS + +#endif // TIME_UTIL_H diff --git a/services/privacymanager/include/common/to_string.h b/services/privacymanager/include/common/to_string.h new file mode 100644 index 000000000..3a1575745 --- /dev/null +++ b/services/privacymanager/include/common/to_string.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021-2022 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 TO_STRING_H +#define TO_STRING_H + +#include +#include "permission_used_request.h" +#include "permission_used_result.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class ToString { +public: + static void DetailUsedRecordToString(bool isAccessDetail, const std::vector& detailRecord, std::string& infos); + static void PermissionUsedRecordToString(const std::vector& permissionRecords, std::string& infos); + static void BundleUsedRecordToString(const BundleUsedRecord& bundleRecord, std::string& infos); + static void PermissionUsedResultToString(const PermissionUsedResult& result, std::string& infos); +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // TO_STRING_H diff --git a/services/privacymanager/include/database/data_translator.h b/services/privacymanager/include/database/data_translator.h new file mode 100644 index 000000000..c84df10b1 --- /dev/null +++ b/services/privacymanager/include/database/data_translator.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021-2022 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 DATA_TRANSLATOR_H +#define DATA_TRANSLATOR_H + +#include + +#include "permission_used_request.h" +#include "permission_used_result.h" +#include "generic_values.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class DataTranslator final { +public: + static int32_t TranslationIntoGenericValues(const PermissionUsedRequest& request, GenericValues& visitorGenericValues, + GenericValues& andGenericValues, GenericValues& orGenericValues); + static int32_t TranslationGenericValuesIntoPermissionUsedRecord(const GenericValues& inGenericValues, PermissionUsedRecord& permissionRecord); +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // DATA_TRANSLATOR_H diff --git a/services/privacymanager/include/database/sqlite_storage.h b/services/privacymanager/include/database/sqlite_storage.h new file mode 100644 index 000000000..3b7b25359 --- /dev/null +++ b/services/privacymanager/include/database/sqlite_storage.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021-2022 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 SQL_STORAGE_H +#define SQL_STORAGE_H + +#include "generic_values.h" +#include "sqlite_helper.h" + +#include "nocopyable.h" +#include "rwlock.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +struct SqliteTable { +public: + std::string tableName_; + std::vector tableColumnNames_; +}; +class SqliteStorage : public SqliteHelper { +public: + enum DataType { + PERMISSION_VISITOR = 0, + PERMISSION_RECORD, + }; + enum ExecuteResult { FAILURE = -1, SUCCESS }; + static SqliteStorage& GetInstance(); + + ~SqliteStorage() override; + + int32_t Add(const DataType type, const std::vector& values); + int32_t Remove(const DataType type, const GenericValues& conditions); + int32_t Find(const DataType type, std::vector& results); + int32_t FindByConditions(const DataType type, const GenericValues& andConditions, + const GenericValues& orConditions, std::vector& results); + int32_t Modify(const DataType type, const GenericValues& modifyValues, const GenericValues& conditions); + int32_t RefreshAll(const DataType type, const std::vector& values); + + void OnCreate() override; + void OnUpdate() override; + +private: + SqliteStorage(); + DISALLOW_COPY_AND_MOVE(SqliteStorage); + + std::map dataTypeToSqlTable_; + OHOS::Utils::RWLock rwLock_; + + int32_t CreatePermissionVisitorTable() const; + int32_t CreatePermissionRecordTable() const; + + std::string CreateInsertPrepareSqlCmd(const DataType type) const; + std::string CreateDeletePrepareSqlCmd( + const DataType type, const std::vector& columnNames = std::vector()) const; + std::string CreateSelectPrepareSqlCmd(const DataType type) const; + std::string CreateSelectByConditionPrepareSqlCmd(const DataType type, + const std::vector& andColumns, const std::vector& orColumns) const; + std::string CreateUpdatePrepareSqlCmd(const DataType type, const std::vector& modifyColumns, + const std::vector& conditionColumns) const; + +private: + inline static const std::string PERMISSION_VISITOR_TABLE = "permission_visitor_table"; + inline static const std::string PERMISSION_RECORD_TABLE = "permission_record_table"; + inline static const std::string DATABASE_NAME = "permission_used_record.db"; + inline static const std::string DATABASE_PATH = "/data/system/access_token/"; + static const int32_t DATABASE_VERSION = 1; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS + +#endif // SQL_STORAGE_H diff --git a/services/privacymanager/include/record/on_permission_used_record_callback_proxy.h b/services/privacymanager/include/record/on_permission_used_record_callback_proxy.h new file mode 100644 index 000000000..4706e333d --- /dev/null +++ b/services/privacymanager/include/record/on_permission_used_record_callback_proxy.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2021-2022 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 ON_PERMISSION_USED_RECORD_CALLBACK_PROXY_H +#define ON_PERMISSION_USED_RECORD_CALLBACK_PROXY_H + + +#include "on_permission_used_record_callback.h" + +#include "iremote_proxy.h" +#include "nocopyable.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class OnPermissionUsedRecordCallbackProxy : public IRemoteProxy { +public: + explicit OnPermissionUsedRecordCallbackProxy(const sptr& impl); + ~OnPermissionUsedRecordCallbackProxy() override; + + virtual void OnQueried(ErrCode code, PermissionUsedResult& result) override; +private: + static inline BrokerDelegator delegator_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // ON_PERMISSION_USED_RECORD_CALLBACK_PROXY_H diff --git a/services/privacymanager/include/record/on_permission_used_record_callback_stub.h b/services/privacymanager/include/record/on_permission_used_record_callback_stub.h new file mode 100644 index 000000000..9dbae35ca --- /dev/null +++ b/services/privacymanager/include/record/on_permission_used_record_callback_stub.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021-2022 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 ON_PERMISSION_USED_RECORD_CALLBACK_STUB_H +#define ON_PERMISSION_USED_RECORD_CALLBACK_STUB_H + + +#include "on_permission_used_record_callback.h" + +#include "iremote_stub.h" +#include "nocopyable.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class OnPermissionUsedRecordCallbackStub : public IRemoteStub { +public: + OnPermissionUsedRecordCallbackStub() = default; + virtual ~OnPermissionUsedRecordCallbackStub() = default; + + int32_t OnRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) override; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // ON_PERMISSION_USED_RECORD_CALLBACK_STUB_H diff --git a/services/privacymanager/include/record/permission_record.h b/services/privacymanager/include/record/permission_record.h new file mode 100644 index 000000000..80013b1ee --- /dev/null +++ b/services/privacymanager/include/record/permission_record.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021-2022 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 PERMISSION_RECORD_H +#define PERMISSION_RECORD_H + +#include "generic_values.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +struct PermissionRecord { + int32_t visitorId = 0; + int32_t opCode = 0; + int32_t status = 0; + int64_t timestamp = 0L; + int64_t accessDuration = 0L; + int32_t accessCount = 0; + int32_t rejectCount = 0; + + PermissionRecord() = default; + + static void TranslationIntoGenericValues(const PermissionRecord& record, GenericValues& values); + static void TranslationIntoPermissionRecord(const GenericValues& values, PermissionRecord& record); +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // PERMISSION_RECORD_H diff --git a/services/privacymanager/include/record/permission_record_manager.h b/services/privacymanager/include/record/permission_record_manager.h new file mode 100644 index 000000000..65bd351bd --- /dev/null +++ b/services/privacymanager/include/record/permission_record_manager.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2021-2022 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 PERMISSION_RECORD_MANAGER_H +#define PERMISSION_RECORD_MANAGER_H + +#include +#include + +#include "access_token.h" +#include "on_permission_used_record_callback.h" +#include "permission_record.h" +#include "permission_used_request.h" +#include "permission_used_result.h" +#include "permission_visitor.h" + +#include "rwlock.h" +#include "nocopyable.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class PermissionRecordManager final { +public: + static PermissionRecordManager& GetInstance(); + virtual ~PermissionRecordManager(); + + void Init(); + int32_t AddPermissionUsedRecord(AccessTokenID tokenID, const std::string& permissionName, int32_t successCount, int32_t failCount); + void RemovePermissionUsedRecords(AccessTokenID tokenID, const std::string& deviceID); + int32_t GetPermissionUsedRecords(const PermissionUsedRequest& request, PermissionUsedResult& result); + int32_t GetPermissionUsedRecordsAsync(const PermissionUsedRequest& request, const sptr& callback); + std::string DumpRecordInfo(const std::string& bundleName, const std::string& permissionName); + +private: + PermissionRecordManager(); + DISALLOW_COPY_AND_MOVE(PermissionRecordManager); + + bool AddVisitor(AccessTokenID tokenID, int32_t& visitorId); + bool GetPermissionVisitor(AccessTokenID tokenID, PermissionVisitor& visitor); + bool AddRecord(int32_t visitorId, const std::string& permissionName, int32_t successCount, int32_t failCount); + bool GetPermissionsRecord(int32_t visitorId, const std::string& permissionName, int32_t successCount, int32_t failCount, PermissionRecord& record); + + int32_t DeletePermissionRecord(int32_t days); + bool GetRecordsFromDB(const PermissionUsedRequest& request, PermissionUsedResult& result); + bool GetRecords(int32_t flag, std::vector recordValues, BundleUsedRecord& bundleRecord, PermissionUsedResult& result); + void UpdateRecords(int32_t flag, const PermissionUsedRecord& inBundleRecord, PermissionUsedRecord& outBundleRecord); + + bool IsLocalDevice(const std::string& deviceId); + OHOS::Utils::RWLock rwLock_; +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // PERMISSION_RECORD_MANAGER_H diff --git a/services/privacymanager/include/record/permission_record_repository.h b/services/privacymanager/include/record/permission_record_repository.h new file mode 100644 index 000000000..909a88af2 --- /dev/null +++ b/services/privacymanager/include/record/permission_record_repository.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021-2022 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 PERMISSION_RECORD_REPOSITORY_H +#define PERMISSION_RECORD_REPOSITORY_H + +#include +#include "generic_values.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class PermissionRecordRepository final { +public: + virtual ~PermissionRecordRepository(); + PermissionRecordRepository(); + + static PermissionRecordRepository& GetInstance(); + + bool AddRecordValues(const std::vector& recordValues); + bool FindRecordValues(const GenericValues& andConditionValues, const GenericValues& orConditionValues, std::vector& recordValues); + bool RemoveRecordValues(const GenericValues& conditionValues); +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // PERMISSION_RECORD_REPOSITORY_H diff --git a/services/privacymanager/include/record/permission_visitor.h b/services/privacymanager/include/record/permission_visitor.h new file mode 100644 index 000000000..95b225d8f --- /dev/null +++ b/services/privacymanager/include/record/permission_visitor.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021-2022 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 PERMISSION_VISITOR_H +#define PERMISSION_VISITOR_H + +#include +#include "access_token.h" +#include "generic_values.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +struct PermissionVisitor { + int32_t id = -1; + AccessTokenID tokenId = 0; + bool isRemoteDevice = false; + std::string deviceId; + int32_t userId; + std::string bundleName; + + PermissionVisitor() = default; + + static void TranslationIntoGenericValues(const PermissionVisitor& visitor, GenericValues& values); + static void TranslationIntoPermissionVisitor(const GenericValues& values, PermissionVisitor& visitor); +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // PERMISSION_VISITOR_H diff --git a/services/privacymanager/include/record/permission_visitor_repository.h b/services/privacymanager/include/record/permission_visitor_repository.h new file mode 100644 index 000000000..e50fc6907 --- /dev/null +++ b/services/privacymanager/include/record/permission_visitor_repository.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021-2022 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 PERMISSION_VISITOR_REPOSITORY_H +#define PERMISSION_VISITOR_REPOSITORY_H + +#include +#include "generic_values.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +class PermissionVisitorRepository final { +public: + virtual ~PermissionVisitorRepository(); + PermissionVisitorRepository(); + + static PermissionVisitorRepository& GetInstance(); + + bool AddVisitorValues(const GenericValues& visitorValues); + bool FindVisitorValues(const GenericValues& andConditionValues, const GenericValues& orConditionValues, std::vector& visitorValues); + bool RemoveVisitorValues(const GenericValues& conditionValues); +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // PERMISSION_VISITOR_REPOSITORY_H diff --git a/services/privacymanager/src/common/constant.cpp b/services/privacymanager/src/common/constant.cpp new file mode 100644 index 000000000..67c8e5c56 --- /dev/null +++ b/services/privacymanager/src/common/constant.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021-2022 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 "constant.h" +#include "parameter.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +const std::map Constant::PERMISSION_OPCODE_MAP = { + std::map::value_type("ohos.permission.ANSWER_CALL", Constant::OP_ANSWER_CALL), + std::map::value_type("ohos.permission.READ_CALENDAR", Constant::OP_READ_CALENDAR), + std::map::value_type("ohos.permission.WRITE_CALENDAR", Constant::OP_WRITE_CALENDAR), + std::map::value_type("ohos.permission.SEND_MESSAGES", Constant::OP_SEND_MESSAGES), + std::map::value_type("ohos.permission.WRITE_CALL_LOG", Constant::OP_WRITE_CALL_LOG), + std::map::value_type("ohos.permission.READ_CALL_LOG", Constant::OP_READ_CALL_LOG), + std::map::value_type("ohos.permission.READ_CELL_MESSAGES", Constant::OP_READ_CELL_MESSAGES), + std::map::value_type("ohos.permission.MICROPHONE", Constant::OP_MICROPHONE), + std::map::value_type("ohos.permission.RECEIVE_WAP_MESSAGES", Constant::OP_RECEIVE_WAP_MESSAGES), + std::map::value_type("ohos.permission.RECEIVE_SMS", Constant::OP_RECEIVE_SMS), + std::map::value_type("ohos.permission.RECEIVE_MMS", Constant::OP_RECEIVE_MMS), + std::map::value_type("ohos.permission.READ_MESSAGES", Constant::OP_READ_MESSAGES), + std::map::value_type("ohos.permission.READ_CONTACTS", Constant::OP_READ_CONTACTS), + std::map::value_type("ohos.permission.WRITE_CONTACTS", Constant::OP_WRITE_CONTACTS), + std::map::value_type("ohos.permission.LOCATION_IN_BACKGROUND", Constant::OP_LOCATION_IN_BACKGROUND), + std::map::value_type("ohos.permission.LOCATION", Constant::OP_LOCATION), + std::map::value_type("ohos.permission.MEDIA_LOCATION", Constant::OP_MEDIA_LOCATION), + std::map::value_type("ohos.permission.CAMERA", Constant::OP_CAMERA), + std::map::value_type("ohos.permission.READ_MEDIA", Constant::OP_READ_MEDIA), + std::map::value_type("ohos.permission.WRITE_MEDIA", Constant::OP_WRITE_MEDIA), + std::map::value_type("ohos.permission.ACTIVITY_MOTION", Constant::OP_ACTIVITY_MOTION), + std::map::value_type("ohos.permission.READ_HEALTH_DATA", Constant::OP_READ_HEALTH_DATA), + std::map::value_type("ohos.permission.MANAGE_VOICEMAIL", Constant::OP_MANAGE_VOICEMAIL), + std::map::value_type("ohos.permission.DISTRIBUTED_DATASYNC", Constant::OP_DISTRIBUTED_DATASYNC), +}; + +bool Constant::TransferPermissionToOpcode(const std::string& permissionName, int32_t& opCode) +{ + if (PERMISSION_OPCODE_MAP.count(permissionName) == 0) { + return false; + } + opCode = PERMISSION_OPCODE_MAP.at(permissionName); + return true; +} + +bool Constant::TransferOpcodeToPermission(int32_t opCode, std::string& permissionName) +{ + auto iter = std::find_if(PERMISSION_OPCODE_MAP.begin(), PERMISSION_OPCODE_MAP.end(), + [opCode](const std::map::value_type item) { + return item.second == opCode; + }); + if (iter == PERMISSION_OPCODE_MAP.end()) { + return false; + } + permissionName = iter->first; + return true; +} + +std::string Constant::GetLocalDeviceUdid() +{ + static std::string localDeviceId; + if (!localDeviceId.empty()) { + return localDeviceId; + } + const int32_t DEVICE_UUID_LENGTH = 65; + char udid[DEVICE_UUID_LENGTH] = {0}; + GetDevUdid(udid, DEVICE_UUID_LENGTH); + localDeviceId = udid; + return localDeviceId; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS \ No newline at end of file diff --git a/services/privacymanager/src/common/time_util.cpp b/services/privacymanager/src/common/time_util.cpp new file mode 100644 index 000000000..3859d15b3 --- /dev/null +++ b/services/privacymanager/src/common/time_util.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2021-2022 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 "time_util.h" +#include + +namespace OHOS { +namespace Security { +namespace AccessToken { +int64_t TimeUtil::GetCurrentTimestamp() +{ + const time_t timestamp = time(NULL); + return timestamp; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/privacymanager/src/common/to_string.cpp b/services/privacymanager/src/common/to_string.cpp new file mode 100644 index 000000000..5ddf15c47 --- /dev/null +++ b/services/privacymanager/src/common/to_string.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2022 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 "to_string.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +void ToString::DetailUsedRecordToString(bool isAccessDetail, const std::vector& detailRecord, std::string& infos) +{ + if (isAccessDetail) { + infos.append(R"( "accessRecords": [)"); + } else { + infos.append(R"( "rejectRecords": [)"); + } + infos.append("\n"); + for (auto detail : detailRecord) { + infos.append(" {"); + infos.append("\n"); + infos.append(R"( "status": ")" + std::to_string(detail.status) + R"(")" + ",\n"); + infos.append(R"( "timestamp": ")" + std::to_string(detail.timestamp) + R"(")" + ",\n"); + infos.append(R"( "duration": )" + std::to_string(detail.accessDuration) + ",\n"); + infos.append(" },"); + infos.append("\n"); + } + + infos.append(" ]"); + infos.append("\n"); +} + +void ToString::PermissionUsedRecordToString(const std::vector& permissionRecords, std::string& infos) +{ + infos.append(R"( "permissionRecords": [)"); + infos.append("\n"); + + for (auto perm : permissionRecords) { + infos.append(" {"); + infos.append("\n"); + infos.append(R"( "permissionName": ")" + perm.permissionName + R"(")" + ",\n"); + infos.append(R"( "accessCount": ")" + std::to_string(perm.accessCount) + R"(")" + ",\n"); + infos.append(R"( "rejectCount": )" + std::to_string(perm.rejectCount) + ",\n"); + infos.append(R"( "lastAccessTime": )" + std::to_string(perm.lastAccessTime) + ",\n"); + infos.append(R"( "lastRejectTime": )" + std::to_string(perm.lastRejectTime) + ",\n"); + infos.append(R"( "lastAccessDuration": )" + std::to_string(perm.lastAccessDuration) + ",\n"); + ToString::DetailUsedRecordToString(true, perm.accessRecords, infos); + ToString::DetailUsedRecordToString(false, perm.rejectRecords, infos); + infos.append(" },"); + infos.append("\n"); + } + + + infos.append(" ]"); + infos.append("\n"); +} + +void ToString::BundleUsedRecordToString(const BundleUsedRecord& bundleRecord, std::string& infos) +{ + infos.append("{"); + infos.append("\n"); + infos.append(R"( "tokenId": )" + std::to_string(bundleRecord.tokenId) + ",\n"); + infos.append(R"( "isRemote": )" + std::to_string(bundleRecord.isRemote) + ",\n"); + infos.append(R"( "bundleName": )" + bundleRecord.bundleName + ",\n"); + infos.append(R"( "deviceId": )" + bundleRecord.deviceId + ",\n"); + + ToString::PermissionUsedRecordToString(bundleRecord.permissionRecords, infos); + + infos.append("}"); + infos.append("\n"); +} + +void ToString::PermissionUsedResultToString(const PermissionUsedResult& result, std::string& infos) +{ + if (result.bundleRecords.size() == 0) { + return; + } + infos.append(R"("beginTime": )" + std::to_string(result.beginTimeMillis) + ",\n"); + infos.append(R"("endTime": )" + std::to_string(result.endTimeMillis) + ",\n"); + + for (auto res : result.bundleRecords) { + ToString::BundleUsedRecordToString(res, infos); + } +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS \ No newline at end of file diff --git a/services/privacymanager/src/database/data_translator.cpp b/services/privacymanager/src/database/data_translator.cpp new file mode 100644 index 000000000..db65a0a6a --- /dev/null +++ b/services/privacymanager/src/database/data_translator.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2021-2022 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 "data_translator.h" + +#include "constant.h" +#include "field_const.h" +#include "time_util.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +int32_t DataTranslator::TranslationIntoGenericValues(const PermissionUsedRequest& request, GenericValues& visitorGenericValues, + GenericValues& andGenericValues, GenericValues& orGenericValues) +{ + int64_t begin = request.beginTimeMillis; + int64_t end = request.endTimeMillis; + if ((begin < 0) || (end < 0) || (begin > end)) { + return Constant::FAILURE; + } + + if (begin == 0 && end == 0) { + int64_t beginTime = TimeUtil::GetCurrentTimestamp() - Constant::LATEST_RECORD_TIME; + begin = (beginTime < 0) ? 0 : beginTime; + end = TimeUtil::GetCurrentTimestamp(); + } + + if (begin != 0) { + andGenericValues.Put(FIELD_TIMESTAMP_BEGIN, begin); + } + if (end != 0) { + andGenericValues.Put(FIELD_TIMESTAMP_END, end); + } + + if (!request.deviceId.empty()) { + visitorGenericValues.Put(FIELD_DEVICE_ID, request.deviceId); + } + if (!request.bundleName.empty()) { + visitorGenericValues.Put(FIELD_BUNDLE_NAME, request.bundleName); + } + + if (request.tokenId != 0) { + visitorGenericValues.Put(FIELD_TOKEN_ID, (int32_t)request.tokenId); + } + + for (auto perm : request.permissionList) { + int32_t opCode; + if (Constant::TransferPermissionToOpcode(perm, opCode)) { + orGenericValues.Put(FIELD_OP_CODE, opCode); + } + } + return Constant::SUCCESS; +} + +int32_t DataTranslator::TranslationGenericValuesIntoPermissionUsedRecord(const GenericValues& inGenericValues, + PermissionUsedRecord& permissionRecord) +{ + std::string permission; + int32_t opCode = inGenericValues.GetInt(FIELD_OP_CODE); + if (!Constant::TransferOpcodeToPermission(opCode, permission)) { + return Constant::FAILURE; + } + + int64_t timestamp = inGenericValues.GetInt64(FIELD_TIMESTAMP); + permissionRecord.permissionName = permission; + + if (inGenericValues.GetInt(FIELD_ACCESS_COUNT) != 0) { + permissionRecord.accessCount = inGenericValues.GetInt(FIELD_ACCESS_COUNT); + permissionRecord.lastAccessTime = timestamp; + permissionRecord.lastAccessDuration = inGenericValues.GetInt64(FIELD_ACCESS_DURATION); + } + + if (inGenericValues.GetInt(FIELD_REJECT_COUNT) != 0) { + permissionRecord.rejectCount = inGenericValues.GetInt(FIELD_REJECT_COUNT); + permissionRecord.lastRejectTime = timestamp; + } + + if (inGenericValues.GetInt(FIELD_FLAG) == 0) { + return Constant::SUCCESS; + } + + UsedRecordDetail detail; + detail.status = inGenericValues.GetInt(FIELD_STATUS); + if (permissionRecord.lastAccessTime > 0) { + detail.timestamp = permissionRecord.lastAccessTime; + detail.accessDuration = inGenericValues.GetInt64(FIELD_ACCESS_DURATION); + permissionRecord.accessRecords.emplace_back(detail); + } + if (permissionRecord.lastRejectTime > 0) { + detail.timestamp = permissionRecord.lastAccessTime; + permissionRecord.rejectRecords.emplace_back(detail); + } + return Constant::SUCCESS; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS \ No newline at end of file diff --git a/services/privacymanager/src/database/sqlite_storage.cpp b/services/privacymanager/src/database/sqlite_storage.cpp new file mode 100644 index 000000000..c79614265 --- /dev/null +++ b/services/privacymanager/src/database/sqlite_storage.cpp @@ -0,0 +1,379 @@ +/* + * Copyright (c) 2021-2022 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 "sqlite_storage.h" + +#include "accesstoken_log.h" +#include "field_const.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { + LOG_CORE, SECURITY_DOMAIN_PRIVACY, "PrivacySqliteStorage" +}; +} + +SqliteStorage& SqliteStorage::GetInstance() +{ + static SqliteStorage instance; + return instance; +} + +SqliteStorage::~SqliteStorage() +{ + Close(); +} + +void SqliteStorage::OnCreate() +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called.", __func__); + CreatePermissionVisitorTable(); + CreatePermissionRecordTable(); +} + +void SqliteStorage::OnUpdate() +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called.", __func__); +} + +SqliteStorage::SqliteStorage() : SqliteHelper(DATABASE_NAME, DATABASE_PATH, DATABASE_VERSION) +{ + SqliteTable permissionVisorTable; + permissionVisorTable.tableName_ = PERMISSION_VISITOR_TABLE; + permissionVisorTable.tableColumnNames_ = { + FIELD_ID, + FIELD_TOKEN_ID, + FIELD_IS_REMOTE_DEVICE, + FIELD_DEVICE_ID, + FIELD_USER_ID, + FIELD_BUNDLE_NAME + }; + + SqliteTable permissionRecordTable; + permissionRecordTable.tableName_ = PERMISSION_RECORD_TABLE; + permissionRecordTable.tableColumnNames_ = { + FIELD_VISITOR_ID, + FIELD_OP_CODE, + FIELD_STATUS, + FIELD_TIMESTAMP, + FIELD_ACCESS_DURATION, + FIELD_ACCESS_COUNT, + FIELD_REJECT_COUNT + }; + + dataTypeToSqlTable_ = { + {PERMISSION_VISITOR, permissionVisorTable}, + {PERMISSION_RECORD, permissionRecordTable}, + }; + Open(); +} + +int32_t SqliteStorage::Add(const DataType type, const std::vector& values) +{ + OHOS::Utils::UniqueWriteGuard lock(this->rwLock_); + std::string prepareSql = CreateInsertPrepareSqlCmd(type); + auto statement = Prepare(prepareSql); + BeginTransaction(); + bool isExecuteSuccessfully = true; + for (auto value : values) { + std::vector columnNames = value.GetAllKeys(); + for (auto columnName : columnNames) { + statement.Bind(columnName, value.Get(columnName)); + } + int32_t ret = statement.Step(); + if (ret != Statement::State::DONE) { + ACCESSTOKEN_LOG_ERROR(LABEL, "failed, errorMsg: %{public}s", SpitError().c_str()); + isExecuteSuccessfully = false; + } + statement.Reset(); + } + if (!isExecuteSuccessfully) { + ACCESSTOKEN_LOG_ERROR(LABEL, "rollback transaction."); + RollbackTransaction(); + return FAILURE; + } + ACCESSTOKEN_LOG_DEBUG(LABEL, "commit transaction."); + CommitTransaction(); + return SUCCESS; +} + +int32_t SqliteStorage::Remove(const DataType type, const GenericValues& conditions) +{ + OHOS::Utils::UniqueWriteGuard lock(this->rwLock_); + std::vector columnNames = conditions.GetAllKeys(); + std::string prepareSql = CreateDeletePrepareSqlCmd(type, columnNames); + auto statement = Prepare(prepareSql); + for (auto columnName : columnNames) { + statement.Bind(columnName, conditions.Get(columnName)); + } + int32_t ret = statement.Step(); + return (ret == Statement::State::DONE) ? SUCCESS : FAILURE; +} + +int32_t SqliteStorage::Modify(const DataType type, const GenericValues& modifyValues, const GenericValues& conditions) +{ + OHOS::Utils::UniqueWriteGuard lock(this->rwLock_); + std::vector modifyColumns = modifyValues.GetAllKeys(); + std::vector conditionColumns = conditions.GetAllKeys(); + std::string prepareSql = CreateUpdatePrepareSqlCmd(type, modifyColumns, conditionColumns); + auto statement = Prepare(prepareSql); + for (auto columnName : modifyColumns) { + statement.Bind(columnName, modifyValues.Get(columnName)); + } + for (auto columnName : conditionColumns) { + statement.Bind(columnName, conditions.Get(columnName)); + } + int32_t ret = statement.Step(); + return (ret == Statement::State::DONE) ? SUCCESS : FAILURE; +} + +int32_t SqliteStorage::Find(const DataType type, std::vector& results) +{ + OHOS::Utils::UniqueWriteGuard lock(this->rwLock_); + std::string prepareSql = CreateSelectPrepareSqlCmd(type); + auto statement = Prepare(prepareSql); + while (statement.Step() == Statement::State::ROW) { + int32_t columnCount = statement.GetColumnCount(); + GenericValues value; + for (int32_t i = 0; i < columnCount; i++) { + if (statement.GetColumnName(i) == FIELD_TIMESTAMP || statement.GetColumnName(i) == FIELD_ACCESS_DURATION) { + value.Put(statement.GetColumnName(i), statement.GetValue(i, true)); + } else { + value.Put(statement.GetColumnName(i), statement.GetValue(i, false)); + } + } + results.emplace_back(value); + } + return SUCCESS; +} + +int32_t SqliteStorage::FindByConditions(const DataType type, const GenericValues& andConditions, + const GenericValues& orConditions, std::vector& results) +{ + OHOS::Utils::UniqueWriteGuard lock(this->rwLock_); + std::vector andColumns = andConditions.GetAllKeys(); + std::vector orColumns = orConditions.GetAllKeys(); + std::string prepareSql = CreateSelectByConditionPrepareSqlCmd(type, andColumns, orColumns); + auto statement = Prepare(prepareSql); + + for (auto columnName : andColumns) { + statement.Bind(columnName, andConditions.Get(columnName)); + } + for (auto columnName : orColumns) { + statement.Bind(columnName, orConditions.Get(columnName)); + } + + while (statement.Step() == Statement::State::ROW) { + int32_t columnCount = statement.GetColumnCount(); + GenericValues value; + for (int32_t i = 0; i < columnCount; i++) { + if (statement.GetColumnName(i) == FIELD_TIMESTAMP || statement.GetColumnName(i) == FIELD_ACCESS_DURATION) { + value.Put(statement.GetColumnName(i), statement.GetValue(i, true)); + } else { + value.Put(statement.GetColumnName(i), statement.GetValue(i, false)); + } + } + results.emplace_back(value); + } + return SUCCESS; +} + +int32_t SqliteStorage::RefreshAll(const DataType type, const std::vector& values) +{ + OHOS::Utils::UniqueWriteGuard lock(this->rwLock_); + std::string deleteSql = CreateDeletePrepareSqlCmd(type); + std::string insertSql = CreateInsertPrepareSqlCmd(type); + auto deleteStatement = Prepare(deleteSql); + auto insertStatement = Prepare(insertSql); + BeginTransaction(); + bool canCommit = deleteStatement.Step() == Statement::State::DONE; + for (auto value : values) { + std::vector columnNames = value.GetAllKeys(); + for (auto columnName : columnNames) { + insertStatement.Bind(columnName, value.Get(columnName)); + } + int32_t ret = insertStatement.Step(); + if (ret != Statement::State::DONE) { + ACCESSTOKEN_LOG_ERROR( + LABEL, "insert failed, errorMsg: %{public}s", SpitError().c_str()); + canCommit = false; + } + insertStatement.Reset(); + } + if (!canCommit) { + ACCESSTOKEN_LOG_ERROR(LABEL, "rollback transaction."); + RollbackTransaction(); + return FAILURE; + } + ACCESSTOKEN_LOG_INFO(LABEL, "commit transaction."); + CommitTransaction(); + return SUCCESS; +} + +std::string SqliteStorage::CreateInsertPrepareSqlCmd(const DataType type) const +{ + auto it = dataTypeToSqlTable_.find(type); + if (it == dataTypeToSqlTable_.end()) { + return std::string(); + } + std::string sql = "insert into " + it->second.tableName_ + " values("; + int32_t i = 1; + for (const auto& columnName : it->second.tableColumnNames_) { + sql.append(":" + columnName); + if (i < (int32_t) it->second.tableColumnNames_.size()) { + sql.append(","); + } + i += 1; + } + sql.append(")"); + return sql; +} + +std::string SqliteStorage::CreateDeletePrepareSqlCmd( + const DataType type, const std::vector& columnNames) const +{ + auto it = dataTypeToSqlTable_.find(type); + if (it == dataTypeToSqlTable_.end()) { + return std::string(); + } + std::string sql = "delete from " + it->second.tableName_ + " where 1 = 1"; + for (auto columnName : columnNames) { + sql.append(" and "); + sql.append(columnName + "=:" + columnName); + } + return sql; +} + +std::string SqliteStorage::CreateUpdatePrepareSqlCmd(const DataType type, const std::vector& modifyColumns, + const std::vector& conditionColumns) const +{ + if (modifyColumns.empty()) { + return std::string(); + } + + auto it = dataTypeToSqlTable_.find(type); + if (it == dataTypeToSqlTable_.end()) { + return std::string(); + } + + std::string sql = "update " + it->second.tableName_ + " set "; + int32_t i = 1; + for (const auto& columnName : modifyColumns) { + sql.append(columnName + "=:" + columnName); + if (i < (int32_t) modifyColumns.size()) { + sql.append(","); + } + i += 1; + } + + if (!conditionColumns.empty()) { + sql.append(" where 1 = 1"); + for (const auto& columnName : conditionColumns) { + sql.append(" and "); + sql.append(columnName + "=:" + columnName); + } + } + return sql; +} + +std::string SqliteStorage::CreateSelectPrepareSqlCmd(const DataType type) const +{ + auto it = dataTypeToSqlTable_.find(type); + if (it == dataTypeToSqlTable_.end()) { + return std::string(); + } + std::string sql = "select * from " + it->second.tableName_; + return sql; +} + +std::string SqliteStorage::CreateSelectByConditionPrepareSqlCmd(const DataType type, + const std::vector& andColumns, const std::vector& orColumns) const +{ + auto it = dataTypeToSqlTable_.find(type); + if (it == dataTypeToSqlTable_.end()) { + return std::string(); + } + + std::string sql = "select * from " + it->second.tableName_ + " where 1 = 1"; + for (const auto& andColName : andColumns) { + if (andColName == FIELD_TIMESTAMP_BEGIN) { + sql.append(" and "); + sql.append(FIELD_TIMESTAMP + " >=:" + andColName); + } else if (andColName == FIELD_TIMESTAMP_END) { + sql.append(" and "); + sql.append(FIELD_TIMESTAMP + " <=:" + andColName); + } else { + sql.append(" and "); + sql.append(andColName + "=:" + andColName); + } + } + if (orColumns.size() > 0) { + sql.append(" and ("); + for (const auto& orColName : orColumns) { + if (orColName.find(FIELD_OP_CODE) != std::string::npos) { + sql.append(FIELD_OP_CODE + " =:" + orColName); + sql.append(" or "); + } + } + sql.append("0)"); + } + return sql; +} + +int32_t SqliteStorage::CreatePermissionVisitorTable() const +{ + auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_VISITOR); + if (it == dataTypeToSqlTable_.end()) { + return FAILURE; + } + std::string sql = "create table if not exists "; + sql.append(it->second.tableName_ + " (") + .append(FIELD_ID + " integer PRIMARY KEY autoincrement not null,") + .append(FIELD_TOKEN_ID + " integer not null,") + .append(FIELD_IS_REMOTE_DEVICE + " integer not null,") + .append(FIELD_DEVICE_ID + " text not null,") + .append(FIELD_USER_ID + " integer not null,") + .append(FIELD_BUNDLE_NAME + " text not null") + .append(")"); + return ExecuteSql(sql); +} + +int32_t SqliteStorage::CreatePermissionRecordTable() const +{ + auto it = dataTypeToSqlTable_.find(DataType::PERMISSION_RECORD); + if (it == dataTypeToSqlTable_.end()) { + return FAILURE; + } + std::string sql = "create table if not exists "; + sql.append(it->second.tableName_ + " (") + .append(FIELD_VISITOR_ID + " integer not null,") + .append(FIELD_OP_CODE + " integer not null,") + .append(FIELD_STATUS + " integer not null,") + .append(FIELD_TIMESTAMP + " integer not null,") + .append(FIELD_ACCESS_DURATION + " integer not null,") + .append(FIELD_ACCESS_COUNT + " integer not null,") + .append(FIELD_REJECT_COUNT + " integer not null,") + .append("primary key(" + FIELD_VISITOR_ID) + .append("," + FIELD_OP_CODE) + .append("," + FIELD_STATUS) + .append("," + FIELD_TIMESTAMP) + .append("))"); + return ExecuteSql(sql); +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/privacymanager/src/record/on_permission_used_record_callback_proxy.cpp b/services/privacymanager/src/record/on_permission_used_record_callback_proxy.cpp new file mode 100644 index 000000000..e0974b25d --- /dev/null +++ b/services/privacymanager/src/record/on_permission_used_record_callback_proxy.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2021-2022 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 "on_permission_used_record_callback_proxy.h" + +#include "accesstoken_log.h" +#include "permission_used_result_parcel.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { + LOG_CORE, SECURITY_DOMAIN_PRIVACY, "OnPermissionUsedRecordCallbackProxy" +}; +} + +OnPermissionUsedRecordCallbackProxy::OnPermissionUsedRecordCallbackProxy(const sptr& impl) + : IRemoteProxy(impl) { +} + +OnPermissionUsedRecordCallbackProxy::~OnPermissionUsedRecordCallbackProxy() +{} + +void OnPermissionUsedRecordCallbackProxy::OnQueried(ErrCode code, PermissionUsedResult& result) +{ + MessageParcel data; + data.WriteInterfaceToken(OnPermissionUsedRecordCallback::GetDescriptor()); + if (!data.WriteInt32(code)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to WriteParcelable(code)"); + return; + } + + PermissionUsedResultParcel resultParcel; + resultParcel.result = result; + if (!data.WriteParcelable(&resultParcel)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to WriteParcelable(result)"); + return; + } + + MessageParcel reply; + MessageOption option(MessageOption::TF_SYNC); + sptr remote = Remote(); + if (remote == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "remote service null."); + return; + } + int32_t requestResult = remote->SendRequest( + static_cast(OnPermissionUsedRecordCallback::ON_QUERIED), data, reply, option); + if (requestResult != NO_ERROR) { + ACCESSTOKEN_LOG_ERROR(LABEL, "send request fail, result: %{public}d", requestResult); + return; + } + + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s SendRequest success", __func__); +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/privacymanager/src/record/on_permission_used_record_callback_stub.cpp b/services/privacymanager/src/record/on_permission_used_record_callback_stub.cpp new file mode 100644 index 000000000..a691970ce --- /dev/null +++ b/services/privacymanager/src/record/on_permission_used_record_callback_stub.cpp @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2021-2022 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 "on_permission_used_record_callback_stub.h" + +#include "accesstoken_log.h" +#include "constant.h" +#include "permission_used_result_parcel.h" +#include "constant.h" +#include "string_ex.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { + LOG_CORE, SECURITY_DOMAIN_PRIVACY, "OnPermissionUsedRecordCallbackStub" +}; +} + +int32_t OnPermissionUsedRecordCallbackStub::OnRemoteRequest( + uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s called, code: 0x%{public}x", __func__, code); + std::u16string descriptor = data.ReadInterfaceToken(); + if (descriptor != OnPermissionUsedRecordCallback::GetDescriptor()) { + ACCESSTOKEN_LOG_ERROR(LABEL, "get unexpect descriptor: %{public}s", Str16ToStr8(descriptor).c_str()); + return Constant::FAILURE; + } + + int32_t msgCode = static_cast(code); + if (msgCode == OnPermissionUsedRecordCallback::ON_QUERIED) { + ErrCode errCode = data.ReadInt32(); + PermissionUsedResult result; + if (errCode != NO_ERROR) { + OnQueried(errCode, result); + return Constant::FAILURE; + } + sptr resultSptr = data.ReadParcelable(); + if (resultSptr == nullptr) { + ACCESSTOKEN_LOG_ERROR(LABEL, "ReadParcelable fail"); + return Constant::FAILURE; + } + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s errCode: %{public}d", __func__, errCode); + OnQueried(errCode, resultSptr->result); + } else { + return IPCObjectStub::OnRemoteRequest(code, data, reply, option); + } + return NO_ERROR; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/privacymanager/src/record/permission_record.cpp b/services/privacymanager/src/record/permission_record.cpp new file mode 100644 index 000000000..34ef629a9 --- /dev/null +++ b/services/privacymanager/src/record/permission_record.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2021-2022 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 "permission_record.h" +#include "field_const.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +void PermissionRecord::TranslationIntoGenericValues(const PermissionRecord& record, GenericValues& values) +{ + values.Put(FIELD_VISITOR_ID, record.visitorId); + values.Put(FIELD_OP_CODE, record.opCode); + values.Put(FIELD_STATUS, record.status); + values.Put(FIELD_TIMESTAMP, record.timestamp); + values.Put(FIELD_ACCESS_DURATION, record.accessDuration); + values.Put(FIELD_ACCESS_COUNT, record.accessCount); + values.Put(FIELD_REJECT_COUNT, record.rejectCount); +} + +void PermissionRecord::TranslationIntoPermissionRecord(const GenericValues& values, PermissionRecord& record) +{ + record.visitorId = values.GetInt(FIELD_VISITOR_ID); + record.opCode = values.GetInt(FIELD_OP_CODE); + record.status = values.GetInt(FIELD_STATUS); + record.timestamp = values.GetInt64(FIELD_TIMESTAMP); + record.accessDuration = values.GetInt64(FIELD_ACCESS_DURATION); + record.accessCount = values.GetInt(FIELD_ACCESS_COUNT); + record.rejectCount = values.GetInt(FIELD_REJECT_COUNT); +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS \ No newline at end of file diff --git a/services/privacymanager/src/record/permission_record_manager.cpp b/services/privacymanager/src/record/permission_record_manager.cpp new file mode 100644 index 000000000..5863784d8 --- /dev/null +++ b/services/privacymanager/src/record/permission_record_manager.cpp @@ -0,0 +1,417 @@ +/* + * Copyright (c) 2021-2022 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 "permission_record_manager.h" + +#include "accesstoken_kit.h" +#include "accesstoken_log.h" +#include "constant.h" +#include "data_translator.h" +#include "field_const.h" +#include "permission_record_repository.h" +#include "permission_visitor_repository.h" +#include "time_util.h" +#include "to_string.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { + LOG_CORE, SECURITY_DOMAIN_PRIVACY, "PermissionRecordManager" +}; +} +PermissionRecordManager& PermissionRecordManager::GetInstance() +{ + static PermissionRecordManager instance; + return instance; +} + +PermissionRecordManager::PermissionRecordManager() +{ +} + +PermissionRecordManager::~PermissionRecordManager() +{ +} + +bool PermissionRecordManager::AddVisitor(AccessTokenID tokenID, int32_t& visitorId) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s called", __func__); + PermissionVisitor visitor; + if (!GetPermissionVisitor(tokenID, visitor)) { + return false; + } + + GenericValues visitorValues; + GenericValues nullValues; + std::vector resultValues; + PermissionVisitor::TranslationIntoGenericValues(visitor, visitorValues); + if (!PermissionVisitorRepository::GetInstance().FindVisitorValues(visitorValues, nullValues, resultValues)) { + return false; + } + if (resultValues.empty()) { + if (!PermissionVisitorRepository::GetInstance().AddVisitorValues(visitorValues)) { + return false; + } + if (!PermissionVisitorRepository::GetInstance().FindVisitorValues(visitorValues, nullValues, resultValues)) { + return false; + } + } + PermissionVisitor::TranslationIntoPermissionVisitor(resultValues[0], visitor); + visitorId = visitor.id; + return true; +} + +bool PermissionRecordManager::GetPermissionVisitor(AccessTokenID tokenID, PermissionVisitor& visitor) +{ + HapTokenInfo tokenInfo; + if (AccessTokenKit::GetHapTokenInfo(tokenID, tokenInfo) != Constant::SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s GetHapTokenInfo fail", __func__); + return false; + } + visitor.isRemoteDevice = true; + visitor.userId = tokenInfo.userID; + visitor.bundleName = tokenInfo.bundleName; + if (IsLocalDevice(tokenInfo.deviceID)) { + visitor.deviceId = Constant::GetLocalDeviceUdid(); + visitor.isRemoteDevice = false; + visitor.tokenId = tokenID; + } + return true; +} + +bool PermissionRecordManager::AddRecord(int32_t visitorId, const std::string& permissionName, int32_t successCount, int32_t failCount) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s called", __func__); + PermissionRecord record; + if (!GetPermissionsRecord(visitorId, permissionName, successCount, failCount, record)) { + return false; + } + + GenericValues nullValues; + GenericValues recordValues; + std::vector insertValues; + std::vector findValues; + PermissionRecord::TranslationIntoGenericValues(record, recordValues); + + int64_t insertTimestamp = record.timestamp; + int64_t insertAccessDuration = record.accessDuration; + int32_t insertAccessCount = record.accessCount; + int32_t insertRejectCount = record.rejectCount; + recordValues.Remove(FIELD_TIMESTAMP); + recordValues.Remove(FIELD_ACCESS_DURATION); + recordValues.Remove(FIELD_ACCESS_COUNT); + recordValues.Remove(FIELD_REJECT_COUNT); + if (!PermissionRecordRepository::GetInstance().FindRecordValues(recordValues, nullValues, findValues)) { + return false; + } + + recordValues.Put(FIELD_TIMESTAMP, insertTimestamp); + recordValues.Put(FIELD_ACCESS_DURATION, insertAccessDuration); + recordValues.Put(FIELD_ACCESS_COUNT, insertAccessCount); + recordValues.Put(FIELD_REJECT_COUNT, insertRejectCount); + for (auto rec : findValues) { + if (insertTimestamp - rec.GetInt64(FIELD_TIMESTAMP) < Constant::PRECISE) { + insertAccessDuration += rec.GetInt64(FIELD_ACCESS_DURATION); + insertAccessCount += rec.GetInt(FIELD_ACCESS_COUNT); + insertRejectCount += rec.GetInt(FIELD_REJECT_COUNT); + recordValues.Remove(FIELD_ACCESS_DURATION); + recordValues.Remove(FIELD_ACCESS_COUNT); + recordValues.Remove(FIELD_REJECT_COUNT); + + recordValues.Put(FIELD_ACCESS_DURATION, insertAccessDuration); + recordValues.Put(FIELD_ACCESS_COUNT, insertAccessCount); + recordValues.Put(FIELD_REJECT_COUNT, insertRejectCount); + + if (!PermissionRecordRepository::GetInstance().RemoveRecordValues(rec)) { + return false; + } + break; + } + } + insertValues.emplace_back(recordValues); + return PermissionRecordRepository::GetInstance().AddRecordValues(insertValues); +} + +bool PermissionRecordManager::GetPermissionsRecord(int32_t visitorId, const std::string& permissionName, + int32_t successCount, int32_t failCount, PermissionRecord& record) +{ + int32_t opCode; + if (!Constant::TransferPermissionToOpcode(permissionName, opCode)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s TransferPermissionToOpcode fail", __func__); + return false; + } + if (successCount == 0 && failCount == 0) { + ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s successCount and failCount are both zero", __func__); + return false; + } + record.visitorId = visitorId; + record.accessCount = successCount; + record.rejectCount = failCount; + record.opCode = opCode; + record.status = 0; // get isForeground by uid lockscreen + record.timestamp = TimeUtil::GetCurrentTimestamp(); + record.accessDuration = 0; + return true; +} + +int32_t PermissionRecordManager::AddPermissionUsedRecord(AccessTokenID tokenID, const std::string& permissionName, + int32_t successCount, int32_t failCount) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s called, tokenId: %{public}x, permissionName: %{public}s", __func__, tokenID, permissionName.c_str()); + auto deleteRecordsTask = [this]() { + ACCESSTOKEN_LOG_DEBUG(LABEL, "DeletePermissionRecord task called"); + DeletePermissionRecord(Constant::RECORD_DELETE_TIME); + }; + std::thread deleteRecordsThread(deleteRecordsTask); + deleteRecordsThread.detach(); + + if (AccessTokenKit::GetTokenTypeFlag(tokenID) != TOKEN_HAP) { + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s Invalid token type", __func__); + return Constant::SUCCESS; + } + + int32_t visitorId; + if (!AddVisitor(tokenID, visitorId)) { + return Constant::FAILURE; + } + if (!AddRecord(visitorId, permissionName, successCount, failCount)) { + return Constant::FAILURE; + } + return Constant::SUCCESS; +} + +void PermissionRecordManager::RemovePermissionUsedRecords(AccessTokenID tokenID, const std::string& deviceID) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s called, tokenId: %{public}x", __func__, tokenID); + auto deleteRecordsTask = [this]() { + ACCESSTOKEN_LOG_DEBUG(LABEL, "DeletePermissionRecord task called"); + DeletePermissionRecord(Constant::RECORD_DELETE_TIME); + }; + std::thread deleteRecordsThread(deleteRecordsTask); + deleteRecordsThread.detach(); + + PermissionVisitor visitor; + if (!GetPermissionVisitor(tokenID, visitor) && deviceID.empty()) { + return; + } + if (!deviceID.empty()) { + visitor.deviceId = deviceID; + } + + GenericValues nullValues; + GenericValues visitorValues; + std::vector findVisitorValues; + PermissionVisitor::TranslationIntoGenericValues(visitor, visitorValues); + if (!PermissionVisitorRepository::GetInstance().FindVisitorValues(visitorValues, nullValues, findVisitorValues)) { + return; + } + + for (auto visitor : findVisitorValues) { + GenericValues record; + record.Put(FIELD_VISITOR_ID, visitor.GetInt(FIELD_ID)); + PermissionRecordRepository::GetInstance().RemoveRecordValues(record); + } + PermissionVisitorRepository::GetInstance().RemoveVisitorValues(visitorValues); +} + +int32_t PermissionRecordManager::GetPermissionUsedRecords(const PermissionUsedRequest& request, PermissionUsedResult& result) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s called", __func__); + auto deleteRecordsTask = [this]() { + ACCESSTOKEN_LOG_DEBUG(LABEL, "DeletePermissionRecord task called"); + DeletePermissionRecord(Constant::RECORD_DELETE_TIME); + }; + std::thread deleteRecordsThread(deleteRecordsTask); + deleteRecordsThread.detach(); + + if (!GetRecordsFromDB(request, result)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "Failed to GetRecordsFromDB"); + return Constant::FAILURE; + } + return Constant::SUCCESS; +} + +int32_t PermissionRecordManager::GetPermissionUsedRecordsAsync(const PermissionUsedRequest& request, const sptr& callback) +{ + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s called", __func__); + auto task = [request, callback]() { + ACCESSTOKEN_LOG_INFO(LABEL, "GetPermissionUsedRecordsAsync task called"); + PermissionUsedResult result; + int32_t ret = PermissionRecordManager::GetInstance().GetPermissionUsedRecords(request, result); + callback->OnQueried(ret, result); + }; + std::thread recordThread(task); + recordThread.detach(); + return Constant::SUCCESS; +} + +bool PermissionRecordManager::GetRecordsFromDB(const PermissionUsedRequest& request, PermissionUsedResult& result) +{ + GenericValues visitorValues; + GenericValues andConditionValues; + GenericValues orConditionValues; + if (DataTranslator::TranslationIntoGenericValues(request, visitorValues, andConditionValues, + orConditionValues) != Constant::SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s: query time is invalid", __func__); + return false; + } + + GenericValues nullValues; + std::vector findVisitorValues; + if (!PermissionVisitorRepository::GetInstance().FindVisitorValues(visitorValues, nullValues, findVisitorValues)) { + return false; + } + if (findVisitorValues.empty()) { + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s: no visitor", __func__); + return true; + } + + for (auto visitor : findVisitorValues) { + andConditionValues.Put(FIELD_VISITOR_ID, visitor.GetInt(FIELD_ID)); + std::vector findRecordsValues; + BundleUsedRecord bundleRecord; + if (!PermissionRecordRepository::GetInstance().FindRecordValues(andConditionValues, orConditionValues, findRecordsValues)) { + return false; + } + andConditionValues.Remove(FIELD_VISITOR_ID); + bundleRecord.tokenId = visitor.GetInt(FIELD_TOKEN_ID); + bundleRecord.isRemote = visitor.GetInt(FIELD_IS_REMOTE_DEVICE); + bundleRecord.deviceId = visitor.GetString(FIELD_DEVICE_ID); + bundleRecord.bundleName = visitor.GetString(FIELD_BUNDLE_NAME); + + if (findRecordsValues.size() != 0) { + if (!GetRecords(request.flag, findRecordsValues, bundleRecord, result)) { + return false; + } + } + + if (bundleRecord.permissionRecords.size() != 0) { + result.bundleRecords.emplace_back(bundleRecord); + } + } + return true; +} + +bool PermissionRecordManager::GetRecords(int32_t flag, std::vector recordValues, BundleUsedRecord& bundleRecord, PermissionUsedResult& result) +{ + std::vector permissionRecords; + for (auto record : recordValues) { + PermissionUsedRecord tmpPermissionRecord; + int64_t timestamp = record.GetInt64(FIELD_TIMESTAMP); + result.beginTimeMillis = ((result.beginTimeMillis == 0) || (timestamp < result.beginTimeMillis)) ? + timestamp : result.beginTimeMillis; + result.endTimeMillis = (timestamp > result.endTimeMillis) ? timestamp : result.endTimeMillis; + + record.Put(FIELD_FLAG, flag); + if (DataTranslator::TranslationGenericValuesIntoPermissionUsedRecord(record, tmpPermissionRecord) != Constant::SUCCESS) { + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s: failed to transform permission to opcode", __func__); + continue; + } + + auto iter = std::find_if(permissionRecords.begin(), permissionRecords.end(), [tmpPermissionRecord](const PermissionUsedRecord& rec) { + return tmpPermissionRecord.permissionName == rec.permissionName; + }); + if (iter != permissionRecords.end()) { + UpdateRecords(flag, tmpPermissionRecord, *iter); + } else { + permissionRecords.emplace_back(tmpPermissionRecord); + } + } + bundleRecord.permissionRecords = permissionRecords; + return true; +} + +void PermissionRecordManager::UpdateRecords(int32_t flag, const PermissionUsedRecord& inBundleRecord, PermissionUsedRecord& outBundleRecord) +{ + outBundleRecord.accessCount += inBundleRecord.accessCount; + outBundleRecord.rejectCount += inBundleRecord.rejectCount; + if (inBundleRecord.lastAccessTime > outBundleRecord.lastAccessTime) { + outBundleRecord.lastAccessTime = inBundleRecord.lastAccessTime; + outBundleRecord.lastAccessDuration = inBundleRecord.lastAccessDuration; + } + outBundleRecord.lastRejectTime = (inBundleRecord.lastRejectTime > outBundleRecord.lastRejectTime) ? + inBundleRecord.lastRejectTime : outBundleRecord.lastRejectTime; + + if (flag == 0) { + return; + } + if (inBundleRecord.lastAccessTime > 0 && outBundleRecord.accessRecords.size() < Constant::MAX_DETAIL_RECORD) { + outBundleRecord.accessRecords.emplace_back(inBundleRecord.accessRecords[0]); + } + if (inBundleRecord.lastRejectTime > 0 && outBundleRecord.rejectRecords.size() < Constant::MAX_DETAIL_RECORD) { + outBundleRecord.rejectRecords.emplace_back(inBundleRecord.rejectRecords[0]); + } +} + +int32_t PermissionRecordManager::DeletePermissionRecord(int32_t days) +{ + GenericValues nullValues; + std::vector deleteRecordValues; + if (!PermissionRecordRepository::GetInstance().FindRecordValues(nullValues, nullValues, deleteRecordValues)) { + return Constant::FAILURE; + } + + int32_t recordNum = 0; + for (auto record : deleteRecordValues) { + recordNum++; + if ((TimeUtil::GetCurrentTimestamp() - record.GetInt64(FIELD_TIMESTAMP)) > days || + recordNum > Constant::MAX_TOTAL_RECORD) { + PermissionRecordRepository::GetInstance().RemoveRecordValues(record); + } + } + return Constant::SUCCESS; +} + +std::string PermissionRecordManager::DumpRecordInfo(const std::string& bundleName, const std::string& permissionName) +{ + ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s called, bundleName=%{public}s, permissionName=%{public}s", + __func__, bundleName.c_str(), permissionName.c_str()); + PermissionUsedRequest request; + request.bundleName = bundleName; + request.flag = FLAG_PERMISSION_USAGE_DETAIL; + request.permissionList.emplace_back(permissionName); + + PermissionUsedResult result; + if (!GetRecordsFromDB(request, result)) { + ACCESSTOKEN_LOG_ERROR(LABEL, "failed to GetRecordsFromDB"); + return ""; + } + + if (result.bundleRecords.size() == 0) { + ACCESSTOKEN_LOG_INFO(LABEL, "result.bundleRecords.size() = 0"); + return ""; + } + std::string dumpInfo; + ToString::PermissionUsedResultToString(result, dumpInfo); + return dumpInfo; +} + +bool PermissionRecordManager::IsLocalDevice(const std::string& deviceId) +{ + if (deviceId == "0") { // local + return true; + } + return false; +} + +void PermissionRecordManager::Init() +{ +} + +} // namespace AccessToken +} // namespace Security +} // namespace OHOS diff --git a/services/privacymanager/src/record/permission_record_repository.cpp b/services/privacymanager/src/record/permission_record_repository.cpp new file mode 100644 index 000000000..e6d00b70a --- /dev/null +++ b/services/privacymanager/src/record/permission_record_repository.cpp @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2021-2022 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 "permission_record_repository.h" + +#include "accesstoken_log.h" +#include "sqlite_storage.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { + LOG_CORE, SECURITY_DOMAIN_PRIVACY, "PermissionRecordRepository" +}; +} + +PermissionRecordRepository& PermissionRecordRepository::GetInstance() +{ + static PermissionRecordRepository instance; + return instance; +} + +PermissionRecordRepository::PermissionRecordRepository() +{ +} + +PermissionRecordRepository::~PermissionRecordRepository() +{ +} + +bool PermissionRecordRepository::AddRecordValues(const std::vector& recordValues) +{ + if (SqliteStorage::GetInstance().Add(SqliteStorage::PERMISSION_RECORD, recordValues) != SqliteStorage::SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s PERMISSION_VISITOR table add fail", __func__); + return false; + } + return true; +} + +bool PermissionRecordRepository::FindRecordValues(const GenericValues& andConditionValues, + const GenericValues& orConditionValues, std::vector& recordValues) +{ + if (SqliteStorage::GetInstance().FindByConditions(SqliteStorage::PERMISSION_RECORD, andConditionValues, + orConditionValues, recordValues) != SqliteStorage::SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s PERMISSION_VISITOR table find fail", __func__); + return false; + } + return true; +} + +bool PermissionRecordRepository::RemoveRecordValues(const GenericValues& conditionValues) +{ + if (SqliteStorage::GetInstance().Remove(SqliteStorage::PERMISSION_RECORD, conditionValues) != SqliteStorage::SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s PERMISSION_VISITOR table add fail", __func__); + return false; + } + return true; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS \ No newline at end of file diff --git a/services/privacymanager/src/record/permission_visitor.cpp b/services/privacymanager/src/record/permission_visitor.cpp new file mode 100644 index 000000000..6e875174e --- /dev/null +++ b/services/privacymanager/src/record/permission_visitor.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2021-2022 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 "permission_visitor.h" +#include "field_const.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +void PermissionVisitor::TranslationIntoGenericValues(const PermissionVisitor& visitor, GenericValues& values) +{ + values.Put(FIELD_TOKEN_ID, (int32_t)visitor.tokenId); + values.Put(FIELD_IS_REMOTE_DEVICE, visitor.isRemoteDevice ? 1 : 0); + values.Put(FIELD_DEVICE_ID, visitor.deviceId); + values.Put(FIELD_USER_ID, visitor.userId); + values.Put(FIELD_BUNDLE_NAME, visitor.bundleName); +} + +void PermissionVisitor::TranslationIntoPermissionVisitor(const GenericValues& values, PermissionVisitor& visitor) +{ + visitor.id = values.GetInt(FIELD_ID); + visitor.tokenId = values.GetInt(FIELD_TOKEN_ID); + visitor.isRemoteDevice = values.GetInt(FIELD_IS_REMOTE_DEVICE); + visitor.deviceId = values.GetString(FIELD_DEVICE_ID); + visitor.userId = values.GetInt(FIELD_USER_ID); + visitor.bundleName = values.GetString(FIELD_BUNDLE_NAME); +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS \ No newline at end of file diff --git a/services/privacymanager/src/record/permission_visitor_repository.cpp b/services/privacymanager/src/record/permission_visitor_repository.cpp new file mode 100644 index 000000000..3d1c2f484 --- /dev/null +++ b/services/privacymanager/src/record/permission_visitor_repository.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2021-2022 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 "permission_visitor_repository.h" + +#include "accesstoken_log.h" +#include "sqlite_storage.h" + +namespace OHOS { +namespace Security { +namespace AccessToken { +namespace { +static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { + LOG_CORE, SECURITY_DOMAIN_PRIVACY, "PermissionVisitorRepository" +}; +} + +PermissionVisitorRepository& PermissionVisitorRepository::GetInstance() +{ + static PermissionVisitorRepository instance; + return instance; +} + +PermissionVisitorRepository::PermissionVisitorRepository() +{ +} + +PermissionVisitorRepository::~PermissionVisitorRepository() +{ +} + +bool PermissionVisitorRepository::AddVisitorValues(const GenericValues& visitorValues) +{ + GenericValues nullValues; + std::vector insertValues; + std::vector resultValues; + if (SqliteStorage::GetInstance().FindByConditions(SqliteStorage::PERMISSION_VISITOR, visitorValues, + nullValues, resultValues) != SqliteStorage::SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s PERMISSION_VISITOR table find fail", __func__); + return false; + } + if (!resultValues.empty()) { + return true; + } + + insertValues.emplace_back(visitorValues); + if (SqliteStorage::GetInstance().Add(SqliteStorage::PERMISSION_VISITOR, insertValues) != SqliteStorage::SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s PERMISSION_VISITOR table add fail", __func__); + return false; + } + return true; +} + +bool PermissionVisitorRepository::FindVisitorValues( + const GenericValues& andValues, const GenericValues& orValues, std::vector& visitorValues) +{ + if (SqliteStorage::GetInstance().FindByConditions(SqliteStorage::PERMISSION_VISITOR, andValues, + orValues, visitorValues) != SqliteStorage::SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s PERMISSION_VISITOR table find fail", __func__); + return false; + } + return true; +} + +bool PermissionVisitorRepository::RemoveVisitorValues(const GenericValues& conditionValues) +{ + if (SqliteStorage::GetInstance().Remove(SqliteStorage::PERMISSION_VISITOR, conditionValues) != SqliteStorage::SUCCESS) { + ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s PERMISSION_VISITOR table remove fail", __func__); + return false; + } + return true; +} +} // namespace AccessToken +} // namespace Security +} // namespace OHOS \ No newline at end of file diff --git a/services/privacymanager/src/service/privacy_manager_service.cpp b/services/privacymanager/src/service/privacy_manager_service.cpp index 55811491e..a0542fccb 100644 --- a/services/privacymanager/src/service/privacy_manager_service.cpp +++ b/services/privacymanager/src/service/privacy_manager_service.cpp @@ -18,6 +18,7 @@ #include "accesstoken_log.h" #include "constant.h" #include "ipc_skeleton.h" +#include "permission_record_manager.h" namespace OHOS { namespace Security { @@ -73,7 +74,7 @@ int32_t PrivacyManagerService::AddPermissionUsedRecord( { ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s called, tokenID: 0x%{public}x, permission: %{public}s", __func__, tokenID, permissionName.c_str()); - return Constant::SUCCESS; + return PermissionRecordManager::GetInstance().AddPermissionUsedRecord(tokenID, permissionName, successCount, failCount); } int32_t PrivacyManagerService::StartUsingPermission(AccessTokenID tokenID, const std::string& permissionName) @@ -93,6 +94,7 @@ int32_t PrivacyManagerService::StopUsingPermission(AccessTokenID tokenID, const int32_t PrivacyManagerService::RemovePermissionUsedRecords(AccessTokenID tokenID, const std::string& deviceID) { ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s called", __func__); + PermissionRecordManager::GetInstance().RemovePermissionUsedRecords(tokenID, deviceID); return Constant::SUCCESS; } @@ -101,20 +103,22 @@ int32_t PrivacyManagerService::GetPermissionUsedRecords( { ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s called", __func__); PermissionUsedResult permissionRecord; - return Constant::SUCCESS; + int32_t ret = PermissionRecordManager::GetInstance().GetPermissionUsedRecords(request.request, permissionRecord); + result.result = permissionRecord; + return ret; } int32_t PrivacyManagerService::GetPermissionUsedRecords( const PermissionUsedRequestParcel& request, const sptr& callback) { ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s called", __func__); - return Constant::SUCCESS; + return PermissionRecordManager::GetInstance().GetPermissionUsedRecordsAsync(request.request, callback); } std::string PrivacyManagerService::DumpRecordInfo(const std::string& bundleName, const std::string& permissionName) { ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s called", __func__); - return ""; + return PermissionRecordManager::GetInstance().DumpRecordInfo(bundleName, permissionName); } bool PrivacyManagerService::Initialize() const diff --git a/services/privacymanager/test/add_permission_used_record_test/add_permission_used_record_test.cpp b/services/privacymanager/test/add_permission_used_record_test/add_permission_used_record_test.cpp new file mode 100644 index 000000000..c139fe2ab --- /dev/null +++ b/services/privacymanager/test/add_permission_used_record_test/add_permission_used_record_test.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2022 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 "add_permission_used_record_test.h" + +using namespace testing::ext; +using namespace OHOS::Security::AccessToken; + +void AddPermissionUsedRecordTest::SetUpTestCase() +{} + +void AddPermissionUsedRecordTest::TearDownTestCase() +{ +} + +void AddPermissionUsedRecordTest::SetUp() +{ +} + +void AddPermissionUsedRecordTest::TearDown() +{ +} + +/** + * @tc.name: AddPermissionUsedRecord_001 + * @tc.desc: cannot AddPermissionUsedRecord with invalid tokenID and permission. + * @tc.type: FUNC + * @tc.require:AR000GK6TD===== + */ +HWTEST_F(AddPermissionUsedRecordTest, AddPermissionUsedRecord_001, TestSize.Level1) +{ + int32_t successCount = 1; + int32_t fasilCount = 0; + std::string permission = "ohon.permission.READ_CONTACTS"; + AccessTokenID tokenID = AccessTokenKit::GetHapTokenID(g_InfoParmsA.userID, + g_InfoParmsA.bundleName, + g_InfoParmsA.instIndex); + int32_t ret = PrivacyKit::AddPermissionUsedRecord(0, permission, successCount, fasilCount); + ASSERT_EQ(RET_FAILED, ret); + + ret = PrivacyKit::AddPermissionUsedRecord(tokenID, "", successCount, fasilCount); + ASSERT_EQ(RET_FAILED, ret); +} diff --git a/services/privacymanager/test/add_permission_used_record_test/add_permission_used_record_test.h b/services/privacymanager/test/add_permission_used_record_test/add_permission_used_record_test.h new file mode 100644 index 000000000..69a973b6c --- /dev/null +++ b/services/privacymanager/test/add_permission_used_record_test/add_permission_used_record_test.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021-2022 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 ADD_PERMISSION_USED_RECORD_TEST_H +#define ADD_PERMISSION_USED_RECORD_TEST_H + +#include + +namespace OHOS { +namespace Security { +namespace AccessToken { +class AddPermissionUsedRecordTest : public testing::Test { +public: + static void SetUpTestCase(); + + static void TearDownTestCase(); + + void SetUp(); + + void TearDown(); +}; +} // namespace AccessToken +} // namespace Security +} // namespace OHOS +#endif // ADD_PERMISSION_USED_RECORD_TEST_H -- Gitee From 0daa18c381beb0fd25b6382815b88397177c66c7 Mon Sep 17 00:00:00 2001 From: chennian Date: Tue, 7 Jun 2022 23:00:28 +0800 Subject: [PATCH 2/7] Signed-off-by:chennian Signed-off-by: chennian --- interfaces/innerkits/privacy/test/BUILD.gn | 1 - .../privacy/test/unittest/src/privacy_kit_test.cpp | 6 +++++- .../privacy/test/unittest/src/privacy_kit_test.h | 6 ------ services/privacymanager/include/common/to_string.h | 6 ++++-- .../privacymanager/include/database/data_translator.h | 7 ++++--- .../privacymanager/include/database/sqlite_storage.h | 2 +- .../include/record/permission_record_repository.h | 3 ++- .../include/record/permission_visitor_repository.h | 3 ++- services/privacymanager/src/common/constant.cpp | 6 ++++-- services/privacymanager/src/common/time_util.cpp | 2 +- services/privacymanager/src/common/to_string.cpp | 9 +++++---- .../privacymanager/src/database/data_translator.cpp | 2 +- .../src/record/permission_record_repository.cpp | 11 ++++++----- .../src/record/permission_visitor_repository.cpp | 3 ++- 14 files changed, 37 insertions(+), 30 deletions(-) diff --git a/interfaces/innerkits/privacy/test/BUILD.gn b/interfaces/innerkits/privacy/test/BUILD.gn index b6b8ffe33..4f740cd7d 100644 --- a/interfaces/innerkits/privacy/test/BUILD.gn +++ b/interfaces/innerkits/privacy/test/BUILD.gn @@ -29,7 +29,6 @@ ohos_unittest("libprivacy_sdk_test") { sources = [ "unittest/src/privacy_kit_test.cpp", - "unittest/src/to_string.cpp", ] cflags_cc = [ "-DHILOG_ENABLE" ] diff --git a/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.cpp b/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.cpp index 01c2fe34a..2ffa8214a 100644 --- a/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.cpp +++ b/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.cpp @@ -19,13 +19,17 @@ #include "nativetoken_kit.h" #include "parameter.h" #include "privacy_kit.h" -#include "to_string.h" using namespace testing::ext; using namespace OHOS::Security::AccessToken; const static int32_t RET_NO_ERROR = 0; const static int32_t RET_ERROR = -1; +static const uint32_t TEST_TOKENID_INVALID = 0; +static const uint32_t TEST_VALID_TOKENID_A = 1; +static const uint32_t TEST_VALID_TOKENID_B = 2; +static const std::string TEST_EMPTY_DEVICEID = ""; +static const std::string TEST_PERMISSION_INVALID = ""; HapPolicyParams g_PolicyPramsA = { .apl = APL_NORMAL, diff --git a/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.h b/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.h index 74d67f34f..8e3cc94ab 100644 --- a/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.h +++ b/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.h @@ -26,12 +26,6 @@ namespace OHOS { namespace Security { namespace AccessToken { -static const uint32_t TEST_TOKENID_INVALID = 0; -static const uint32_t TEST_VALID_TOKENID_A = 1; -static const uint32_t TEST_VALID_TOKENID_B = 2; -static const std::string TEST_EMPTY_DEVICEID = ""; -static const std::string TEST_PERMISSION_INVALID = ""; - class PrivacyKitTest : public testing::Test { public: static void SetUpTestCase(); diff --git a/services/privacymanager/include/common/to_string.h b/services/privacymanager/include/common/to_string.h index 3a1575745..97c14eda9 100644 --- a/services/privacymanager/include/common/to_string.h +++ b/services/privacymanager/include/common/to_string.h @@ -25,8 +25,10 @@ namespace Security { namespace AccessToken { class ToString { public: - static void DetailUsedRecordToString(bool isAccessDetail, const std::vector& detailRecord, std::string& infos); - static void PermissionUsedRecordToString(const std::vector& permissionRecords, std::string& infos); + static void DetailUsedRecordToString( + bool isAccessDetail, const std::vector& detailRecord, std::string& infos); + static void PermissionUsedRecordToString( + const std::vector& permissionRecords, std::string& infos); static void BundleUsedRecordToString(const BundleUsedRecord& bundleRecord, std::string& infos); static void PermissionUsedResultToString(const PermissionUsedResult& result, std::string& infos); }; diff --git a/services/privacymanager/include/database/data_translator.h b/services/privacymanager/include/database/data_translator.h index c84df10b1..e1775cd62 100644 --- a/services/privacymanager/include/database/data_translator.h +++ b/services/privacymanager/include/database/data_translator.h @@ -27,9 +27,10 @@ namespace Security { namespace AccessToken { class DataTranslator final { public: - static int32_t TranslationIntoGenericValues(const PermissionUsedRequest& request, GenericValues& visitorGenericValues, - GenericValues& andGenericValues, GenericValues& orGenericValues); - static int32_t TranslationGenericValuesIntoPermissionUsedRecord(const GenericValues& inGenericValues, PermissionUsedRecord& permissionRecord); + static int32_t TranslationIntoGenericValues(const PermissionUsedRequest& request, + GenericValues& visitorGenericValues, GenericValues& andGenericValues, GenericValues& orGenericValues); + static int32_t TranslationGenericValuesIntoPermissionUsedRecord( + const GenericValues& inGenericValues, PermissionUsedRecord& permissionRecord); }; } // namespace AccessToken } // namespace Security diff --git a/services/privacymanager/include/database/sqlite_storage.h b/services/privacymanager/include/database/sqlite_storage.h index 3b7b25359..bdd8dbf2a 100644 --- a/services/privacymanager/include/database/sqlite_storage.h +++ b/services/privacymanager/include/database/sqlite_storage.h @@ -66,7 +66,7 @@ private: std::string CreateDeletePrepareSqlCmd( const DataType type, const std::vector& columnNames = std::vector()) const; std::string CreateSelectPrepareSqlCmd(const DataType type) const; - std::string CreateSelectByConditionPrepareSqlCmd(const DataType type, + std::string CreateSelectByConditionPrepareSqlCmd(const DataType type, const std::vector& andColumns, const std::vector& orColumns) const; std::string CreateUpdatePrepareSqlCmd(const DataType type, const std::vector& modifyColumns, const std::vector& conditionColumns) const; diff --git a/services/privacymanager/include/record/permission_record_repository.h b/services/privacymanager/include/record/permission_record_repository.h index 909a88af2..f99a37a6a 100644 --- a/services/privacymanager/include/record/permission_record_repository.h +++ b/services/privacymanager/include/record/permission_record_repository.h @@ -30,7 +30,8 @@ public: static PermissionRecordRepository& GetInstance(); bool AddRecordValues(const std::vector& recordValues); - bool FindRecordValues(const GenericValues& andConditionValues, const GenericValues& orConditionValues, std::vector& recordValues); + bool FindRecordValues(const GenericValues& andConditionValues, + const GenericValues& orConditionValues, std::vector& recordValues); bool RemoveRecordValues(const GenericValues& conditionValues); }; } // namespace AccessToken diff --git a/services/privacymanager/include/record/permission_visitor_repository.h b/services/privacymanager/include/record/permission_visitor_repository.h index e50fc6907..a0322d4e4 100644 --- a/services/privacymanager/include/record/permission_visitor_repository.h +++ b/services/privacymanager/include/record/permission_visitor_repository.h @@ -30,7 +30,8 @@ public: static PermissionVisitorRepository& GetInstance(); bool AddVisitorValues(const GenericValues& visitorValues); - bool FindVisitorValues(const GenericValues& andConditionValues, const GenericValues& orConditionValues, std::vector& visitorValues); + bool FindVisitorValues(const GenericValues& andConditionValues, + const GenericValues& orConditionValues, std::vector& visitorValues); bool RemoveVisitorValues(const GenericValues& conditionValues); }; } // namespace AccessToken diff --git a/services/privacymanager/src/common/constant.cpp b/services/privacymanager/src/common/constant.cpp index 67c8e5c56..94934531d 100644 --- a/services/privacymanager/src/common/constant.cpp +++ b/services/privacymanager/src/common/constant.cpp @@ -34,7 +34,8 @@ const std::map Constant::PERMISSION_OPCODE_MAP = { std::map::value_type("ohos.permission.READ_MESSAGES", Constant::OP_READ_MESSAGES), std::map::value_type("ohos.permission.READ_CONTACTS", Constant::OP_READ_CONTACTS), std::map::value_type("ohos.permission.WRITE_CONTACTS", Constant::OP_WRITE_CONTACTS), - std::map::value_type("ohos.permission.LOCATION_IN_BACKGROUND", Constant::OP_LOCATION_IN_BACKGROUND), + std::map::value_type( + "ohos.permission.LOCATION_IN_BACKGROUND", Constant::OP_LOCATION_IN_BACKGROUND), std::map::value_type("ohos.permission.LOCATION", Constant::OP_LOCATION), std::map::value_type("ohos.permission.MEDIA_LOCATION", Constant::OP_MEDIA_LOCATION), std::map::value_type("ohos.permission.CAMERA", Constant::OP_CAMERA), @@ -43,7 +44,8 @@ const std::map Constant::PERMISSION_OPCODE_MAP = { std::map::value_type("ohos.permission.ACTIVITY_MOTION", Constant::OP_ACTIVITY_MOTION), std::map::value_type("ohos.permission.READ_HEALTH_DATA", Constant::OP_READ_HEALTH_DATA), std::map::value_type("ohos.permission.MANAGE_VOICEMAIL", Constant::OP_MANAGE_VOICEMAIL), - std::map::value_type("ohos.permission.DISTRIBUTED_DATASYNC", Constant::OP_DISTRIBUTED_DATASYNC), + std::map::value_type( + "ohos.permission.DISTRIBUTED_DATASYNC", Constant::OP_DISTRIBUTED_DATASYNC), }; bool Constant::TransferPermissionToOpcode(const std::string& permissionName, int32_t& opCode) diff --git a/services/privacymanager/src/common/time_util.cpp b/services/privacymanager/src/common/time_util.cpp index 3859d15b3..18feb6fa7 100644 --- a/services/privacymanager/src/common/time_util.cpp +++ b/services/privacymanager/src/common/time_util.cpp @@ -14,7 +14,7 @@ */ #include "time_util.h" -#include +#include namespace OHOS { namespace Security { diff --git a/services/privacymanager/src/common/to_string.cpp b/services/privacymanager/src/common/to_string.cpp index 5ddf15c47..99cece8a6 100644 --- a/services/privacymanager/src/common/to_string.cpp +++ b/services/privacymanager/src/common/to_string.cpp @@ -18,7 +18,8 @@ namespace OHOS { namespace Security { namespace AccessToken { -void ToString::DetailUsedRecordToString(bool isAccessDetail, const std::vector& detailRecord, std::string& infos) +void ToString::DetailUsedRecordToString( + bool isAccessDetail, const std::vector& detailRecord, std::string& infos) { if (isAccessDetail) { infos.append(R"( "accessRecords": [)"); @@ -40,7 +41,8 @@ void ToString::DetailUsedRecordToString(bool isAccessDetail, const std::vector& permissionRecords, std::string& infos) +void ToString::PermissionUsedRecordToString( + const std::vector& permissionRecords, std::string& infos) { infos.append(R"( "permissionRecords": [)"); infos.append("\n"); @@ -59,8 +61,7 @@ void ToString::PermissionUsedRecordToString(const std::vector& recordValues) { if (SqliteStorage::GetInstance().FindByConditions(SqliteStorage::PERMISSION_RECORD, andConditionValues, orConditionValues, recordValues) != SqliteStorage::SUCCESS) { ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s PERMISSION_VISITOR table find fail", __func__); - return false; + return false; } return true; } bool PermissionRecordRepository::RemoveRecordValues(const GenericValues& conditionValues) { - if (SqliteStorage::GetInstance().Remove(SqliteStorage::PERMISSION_RECORD, conditionValues) != SqliteStorage::SUCCESS) { + if (SqliteStorage::GetInstance().Remove(SqliteStorage::PERMISSION_RECORD, conditionValues) + != SqliteStorage::SUCCESS) { ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s PERMISSION_VISITOR table add fail", __func__); - return false; + return false; } return true; } diff --git a/services/privacymanager/src/record/permission_visitor_repository.cpp b/services/privacymanager/src/record/permission_visitor_repository.cpp index 3d1c2f484..34544eee1 100644 --- a/services/privacymanager/src/record/permission_visitor_repository.cpp +++ b/services/privacymanager/src/record/permission_visitor_repository.cpp @@ -76,7 +76,8 @@ bool PermissionVisitorRepository::FindVisitorValues( bool PermissionVisitorRepository::RemoveVisitorValues(const GenericValues& conditionValues) { - if (SqliteStorage::GetInstance().Remove(SqliteStorage::PERMISSION_VISITOR, conditionValues) != SqliteStorage::SUCCESS) { + if (SqliteStorage::GetInstance().Remove(SqliteStorage::PERMISSION_VISITOR, conditionValues) + != SqliteStorage::SUCCESS) { ACCESSTOKEN_LOG_ERROR(LABEL, "%{public}s PERMISSION_VISITOR table remove fail", __func__); return false; } -- Gitee From 7f75a6a320d7ad0cbd2ca974486bdb87f177e15c Mon Sep 17 00:00:00 2001 From: chennian Date: Tue, 7 Jun 2022 23:03:07 +0800 Subject: [PATCH 3/7] Signed-off-by:chennian Signed-off-by: chennian --- BUILD.gn | 2 +- interfaces/innerkits/privacy/test/BUILD.gn | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/BUILD.gn b/BUILD.gn index 7d1454cd1..d52623233 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -57,8 +57,8 @@ group("accesstoken_build_module_test") { deps += [ "//base/security/access_token/interfaces/innerkits/accesstoken/test:unittest", "//base/security/access_token/interfaces/innerkits/nativetoken/test:unittest", - "//base/security/access_token/interfaces/innerkits/token_setproc/test:unittest", "//base/security/access_token/interfaces/innerkits/privacy/test:unittest", + "//base/security/access_token/interfaces/innerkits/token_setproc/test:unittest", "//base/security/access_token/services/accesstokenmanager/test:unittest", ] } diff --git a/interfaces/innerkits/privacy/test/BUILD.gn b/interfaces/innerkits/privacy/test/BUILD.gn index 4f740cd7d..e4afdc821 100644 --- a/interfaces/innerkits/privacy/test/BUILD.gn +++ b/interfaces/innerkits/privacy/test/BUILD.gn @@ -27,9 +27,7 @@ ohos_unittest("libprivacy_sdk_test") { "//base/security/access_token/services/privacymanager/include/record", ] - sources = [ - "unittest/src/privacy_kit_test.cpp", - ] + sources = [ "unittest/src/privacy_kit_test.cpp" ] cflags_cc = [ "-DHILOG_ENABLE" ] -- Gitee From c8cd90a71499b726f21a45155675f7b4bb843f88 Mon Sep 17 00:00:00 2001 From: chennian Date: Tue, 7 Jun 2022 23:15:00 +0800 Subject: [PATCH 4/7] Signed-off-by:chennian Signed-off-by: chennian --- .../test/unittest/src/privacy_kit_test.cpp | 72 ++++++++++++------- .../test/unittest/src/privacy_kit_test.h | 2 +- .../src/database/data_translator.cpp | 4 +- .../src/record/permission_record_manager.cpp | 28 +++++--- .../src/service/privacy_manager_service.cpp | 3 +- 5 files changed, 71 insertions(+), 38 deletions(-) diff --git a/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.cpp b/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.cpp index 2ffa8214a..1b87e6394 100644 --- a/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.cpp +++ b/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.cpp @@ -134,9 +134,11 @@ HWTEST_F(PrivacyKitTest, AddPermissionUsedRecord001, TestSize.Level1) g_InfoParmsA.bundleName, g_InfoParmsA.instIndex); ASSERT_NE(0, tokenId); - ASSERT_EQ(RET_ERROR, PrivacyKit::AddPermissionUsedRecord(0, "ohos.permission.READ_CONTACTS", successCount, failCount)); + ASSERT_EQ(RET_ERROR, PrivacyKit::AddPermissionUsedRecord( + 0, "ohos.permission.READ_CONTACTS", successCount, failCount)); ASSERT_EQ(RET_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "", successCount, failCount)); - ASSERT_EQ(RET_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.READ_CONTACTS", -1, failCount)); + ASSERT_EQ(RET_ERROR, PrivacyKit::AddPermissionUsedRecord( + tokenId, "ohos.permission.READ_CONTACTS", -1, failCount)); PermissionUsedRequest request; PermissionUsedResult result; @@ -161,7 +163,8 @@ HWTEST_F(PrivacyKitTest, AddPermissionUsedRecord002, TestSize.Level1) g_InfoParmsA.instIndex); ASSERT_NE(0, tokenId); - ASSERT_EQ(RET_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.test", successCount, failCount)); + ASSERT_EQ(RET_ERROR, PrivacyKit::AddPermissionUsedRecord( + tokenId, "ohos.permission.test", successCount, failCount)); ASSERT_EQ(RET_ERROR, PrivacyKit::AddPermissionUsedRecord(123, "ohos.permission.CAMERA", successCount, failCount)); ASSERT_EQ(RET_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.READ_CONTACTS", 0, 0)); @@ -214,7 +217,8 @@ HWTEST_F(PrivacyKitTest, AddPermissionUsedRecord003, TestSize.Level1) int32_t successCount = 1; int32_t failCount = 0; - ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.READ_CONTACTS", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord( + tokenId, "ohos.permission.READ_CONTACTS", successCount, failCount)); PermissionUsedRequest request; PermissionUsedResult result; @@ -240,7 +244,8 @@ HWTEST_F(PrivacyKitTest, AddPermissionUsedRecord004, TestSize.Level1) g_InfoParmsA.instIndex); ASSERT_NE(0, tokenId); ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.CAMERA", count_1, count_0)); - ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.WRITE_CONTACTS", count_0, count_1)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord( + tokenId, "ohos.permission.WRITE_CONTACTS", count_0, count_1)); ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.LOCATION", count_1, count_1)); PermissionUsedRequest request; @@ -268,14 +273,16 @@ HWTEST_F(PrivacyKitTest, AddPermissionUsedRecord005, TestSize.Level1) g_InfoParmsA.instIndex); ASSERT_NE(0, tokenId1); ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId1, "ohos.permission.CAMERA", count_1, count_0)); - ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId1, "ohos.permission.LOCATION", count_0, count_1)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord( + tokenId1, "ohos.permission.LOCATION", count_0, count_1)); AccessTokenID tokenId2 = AccessTokenKit::GetHapTokenID(g_InfoParmsB.userID, g_InfoParmsB.bundleName, g_InfoParmsB.instIndex); ASSERT_NE(0, tokenId2); ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId2, "ohos.permission.CAMERA", count_0, count_1)); - ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId2, "ohos.permission.LOCATION", count_1, count_0)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord( + tokenId2, "ohos.permission.LOCATION", count_1, count_0)); PermissionUsedRequest request; @@ -362,7 +369,8 @@ HWTEST_F(PrivacyKitTest, RemovePermissionUsedRecords002, TestSize.Level1) g_InfoParmsA.bundleName, g_InfoParmsA.instIndex); ASSERT_NE(0, tokenId); - ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.CAMERA", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord( + tokenId, "ohos.permission.CAMERA", successCount, failCount)); PermissionUsedRequest request; PermissionUsedResult result; std::vector permissionList; @@ -391,7 +399,8 @@ HWTEST_F(PrivacyKitTest, RemovePermissionUsedRecords003, TestSize.Level1) g_InfoParmsA.bundleName, g_InfoParmsA.instIndex); ASSERT_NE(0, tokenId); - ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.CAMERA", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord( + tokenId, "ohos.permission.CAMERA", successCount, failCount)); PermissionUsedRequest request; PermissionUsedResult result; std::vector permissionList; @@ -416,7 +425,8 @@ HWTEST_F(PrivacyKitTest, GetPermissionUsedRecords001, TestSize.Level1) g_InfoParmsA.bundleName, g_InfoParmsA.instIndex); ASSERT_NE(0, tokenId); - ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.MICROPHONE", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord( + tokenId, "ohos.permission.MICROPHONE", successCount, failCount)); PermissionUsedRequest request; PermissionUsedResult result; std::vector permissionList; @@ -444,9 +454,12 @@ HWTEST_F(PrivacyKitTest, GetPermissionUsedRecords002, TestSize.Level1) g_InfoParmsA.bundleName, g_InfoParmsA.instIndex); ASSERT_NE(0, tokenId); - ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.MICROPHONE", successCount, failCount)); - ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.CAMERA", successCount, failCount)); - ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.READ_CALENDAR", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord( + tokenId, "ohos.permission.MICROPHONE", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord( + tokenId, "ohos.permission.CAMERA", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord( + tokenId, "ohos.permission.READ_CALENDAR", successCount, failCount)); PermissionUsedRequest request; PermissionUsedResult result; @@ -496,10 +509,14 @@ HWTEST_F(PrivacyKitTest, GetPermissionUsedRecords003, TestSize.Level1) g_InfoParmsA.bundleName, g_InfoParmsA.instIndex); ASSERT_NE(0, tokenId); - ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.MICROPHONE", successCount, failCount)); - ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.MICROPHONE", successCount, failCount)); - ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.MICROPHONE", successCount, failCount)); - ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.MICROPHONE", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord( + tokenId, "ohos.permission.MICROPHONE", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord( + tokenId, "ohos.permission.MICROPHONE", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord( + tokenId, "ohos.permission.MICROPHONE", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord( + tokenId, "ohos.permission.MICROPHONE", successCount, failCount)); PermissionUsedRequest request; PermissionUsedResult result; @@ -509,9 +526,12 @@ HWTEST_F(PrivacyKitTest, GetPermissionUsedRecords003, TestSize.Level1) ASSERT_EQ(1, result.bundleRecords.size()); CheckPermissionUsedResult(request, result, 1, 4, 0); - ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.CAMERA", successCount, failCount)); - ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.READ_CALENDAR", successCount, failCount)); - ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId, "ohos.permission.WRITE_CALENDAR", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord( + tokenId, "ohos.permission.CAMERA", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord( + tokenId, "ohos.permission.READ_CALENDAR", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord( + tokenId, "ohos.permission.WRITE_CALENDAR", successCount, failCount)); BuildQueryRequest(tokenId, GetLocalDeviceUdid(), g_InfoParmsA.bundleName, permissionList, request); ASSERT_EQ(RET_NO_ERROR, PrivacyKit::GetPermissionUsedRecords(request, result)); @@ -535,10 +555,14 @@ HWTEST_F(PrivacyKitTest, GetPermissionUsedRecords004, TestSize.Level1) AccessTokenID tokenId2 = AccessTokenKit::GetHapTokenID(g_InfoParmsB.userID, g_InfoParmsB.bundleName, g_InfoParmsB.instIndex); - ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId1, "ohos.permission.CAMERA", successCount, failCount)); - ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId1, "ohos.permission.READ_CALENDAR", successCount, failCount)); - ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId2, "ohos.permission.CAMERA", successCount, failCount)); - ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord(tokenId2, "ohos.permission.READ_CALENDAR", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord( + tokenId1, "ohos.permission.CAMERA", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord( + tokenId1, "ohos.permission.READ_CALENDAR", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord( + tokenId2, "ohos.permission.CAMERA", successCount, failCount)); + ASSERT_EQ(RET_NO_ERROR, PrivacyKit::AddPermissionUsedRecord( + tokenId2, "ohos.permission.READ_CALENDAR", successCount, failCount)); PermissionUsedRequest request; PermissionUsedResult result; diff --git a/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.h b/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.h index 8e3cc94ab..f36a4a7b8 100644 --- a/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.h +++ b/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.h @@ -17,7 +17,7 @@ #define PRIVACY_KIT_TEST_H #include -#include +#include #include "on_permission_used_record_callback_stub.h" #include "permission_used_request.h" diff --git a/services/privacymanager/src/database/data_translator.cpp b/services/privacymanager/src/database/data_translator.cpp index bfec0eceb..c07056595 100644 --- a/services/privacymanager/src/database/data_translator.cpp +++ b/services/privacymanager/src/database/data_translator.cpp @@ -22,8 +22,8 @@ namespace OHOS { namespace Security { namespace AccessToken { -int32_t DataTranslator::TranslationIntoGenericValues(const PermissionUsedRequest& request, GenericValues& visitorGenericValues, - GenericValues& andGenericValues, GenericValues& orGenericValues) +int32_t DataTranslator::TranslationIntoGenericValues(const PermissionUsedRequest& request, + GenericValues& visitorGenericValues, GenericValues& andGenericValues, GenericValues& orGenericValues) { int64_t begin = request.beginTimeMillis; int64_t end = request.endTimeMillis; diff --git a/services/privacymanager/src/record/permission_record_manager.cpp b/services/privacymanager/src/record/permission_record_manager.cpp index 5863784d8..07d0f30a5 100644 --- a/services/privacymanager/src/record/permission_record_manager.cpp +++ b/services/privacymanager/src/record/permission_record_manager.cpp @@ -93,7 +93,8 @@ bool PermissionRecordManager::GetPermissionVisitor(AccessTokenID tokenID, Permis return true; } -bool PermissionRecordManager::AddRecord(int32_t visitorId, const std::string& permissionName, int32_t successCount, int32_t failCount) +bool PermissionRecordManager::AddRecord( + int32_t visitorId, const std::string& permissionName, int32_t successCount, int32_t failCount) { ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s called", __func__); PermissionRecord record; @@ -171,7 +172,8 @@ bool PermissionRecordManager::GetPermissionsRecord(int32_t visitorId, const std: int32_t PermissionRecordManager::AddPermissionUsedRecord(AccessTokenID tokenID, const std::string& permissionName, int32_t successCount, int32_t failCount) { - ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s called, tokenId: %{public}x, permissionName: %{public}s", __func__, tokenID, permissionName.c_str()); + ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s called, tokenId: %{public}x, permissionName: %{public}s", __func__, + tokenID, permissionName.c_str()); auto deleteRecordsTask = [this]() { ACCESSTOKEN_LOG_DEBUG(LABEL, "DeletePermissionRecord task called"); DeletePermissionRecord(Constant::RECORD_DELETE_TIME); @@ -228,7 +230,8 @@ void PermissionRecordManager::RemovePermissionUsedRecords(AccessTokenID tokenID, PermissionVisitorRepository::GetInstance().RemoveVisitorValues(visitorValues); } -int32_t PermissionRecordManager::GetPermissionUsedRecords(const PermissionUsedRequest& request, PermissionUsedResult& result) +int32_t PermissionRecordManager::GetPermissionUsedRecords( + const PermissionUsedRequest& request, PermissionUsedResult& result) { ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s called", __func__); auto deleteRecordsTask = [this]() { @@ -245,7 +248,8 @@ int32_t PermissionRecordManager::GetPermissionUsedRecords(const PermissionUsedRe return Constant::SUCCESS; } -int32_t PermissionRecordManager::GetPermissionUsedRecordsAsync(const PermissionUsedRequest& request, const sptr& callback) +int32_t PermissionRecordManager::GetPermissionUsedRecordsAsync( + const PermissionUsedRequest& request, const sptr& callback) { ACCESSTOKEN_LOG_DEBUG(LABEL, "%{public}s called", __func__); auto task = [request, callback]() { @@ -284,7 +288,8 @@ bool PermissionRecordManager::GetRecordsFromDB(const PermissionUsedRequest& requ andConditionValues.Put(FIELD_VISITOR_ID, visitor.GetInt(FIELD_ID)); std::vector findRecordsValues; BundleUsedRecord bundleRecord; - if (!PermissionRecordRepository::GetInstance().FindRecordValues(andConditionValues, orConditionValues, findRecordsValues)) { + if (!PermissionRecordRepository::GetInstance().FindRecordValues( + andConditionValues, orConditionValues, findRecordsValues)) { return false; } andConditionValues.Remove(FIELD_VISITOR_ID); @@ -306,7 +311,8 @@ bool PermissionRecordManager::GetRecordsFromDB(const PermissionUsedRequest& requ return true; } -bool PermissionRecordManager::GetRecords(int32_t flag, std::vector recordValues, BundleUsedRecord& bundleRecord, PermissionUsedResult& result) +bool PermissionRecordManager::GetRecords( + int32_t flag, std::vector recordValues, BundleUsedRecord& bundleRecord, PermissionUsedResult& result) { std::vector permissionRecords; for (auto record : recordValues) { @@ -317,12 +323,14 @@ bool PermissionRecordManager::GetRecords(int32_t flag, std::vector result.endTimeMillis) ? timestamp : result.endTimeMillis; record.Put(FIELD_FLAG, flag); - if (DataTranslator::TranslationGenericValuesIntoPermissionUsedRecord(record, tmpPermissionRecord) != Constant::SUCCESS) { + if (DataTranslator::TranslationGenericValuesIntoPermissionUsedRecord(record, tmpPermissionRecord) + != Constant::SUCCESS) { ACCESSTOKEN_LOG_INFO(LABEL, "%{public}s: failed to transform permission to opcode", __func__); continue; } - auto iter = std::find_if(permissionRecords.begin(), permissionRecords.end(), [tmpPermissionRecord](const PermissionUsedRecord& rec) { + auto iter = std::find_if(permissionRecords.begin(), permissionRecords.end(), + [tmpPermissionRecord](const PermissionUsedRecord& rec) { return tmpPermissionRecord.permissionName == rec.permissionName; }); if (iter != permissionRecords.end()) { @@ -335,7 +343,8 @@ bool PermissionRecordManager::GetRecords(int32_t flag, std::vector Date: Tue, 7 Jun 2022 23:16:37 +0800 Subject: [PATCH 5/7] Signed-off-by:chennian Signed-off-by: chennian --- services/privacymanager/BUILD.gn | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/privacymanager/BUILD.gn b/services/privacymanager/BUILD.gn index 6567a05e2..5225ac30e 100644 --- a/services/privacymanager/BUILD.gn +++ b/services/privacymanager/BUILD.gn @@ -38,11 +38,11 @@ ohos_shared_library("privacy_manager_service") { "src/database/sqlite_storage.cpp", "src/record/on_permission_used_record_callback_proxy.cpp", "src/record/on_permission_used_record_callback_stub.cpp", + "src/record/permission_record.cpp", "src/record/permission_record_manager.cpp", "src/record/permission_record_repository.cpp", - "src/record/permission_record.cpp", - "src/record/permission_visitor_repository.cpp", "src/record/permission_visitor.cpp", + "src/record/permission_visitor_repository.cpp", "src/service/privacy_manager_service.cpp", "src/service/privacy_manager_stub.cpp", ] -- Gitee From b56d97de55ca921b3c7eefb25761be4eab5b9831 Mon Sep 17 00:00:00 2001 From: chennian Date: Tue, 7 Jun 2022 23:23:52 +0800 Subject: [PATCH 6/7] Signed-off-by:chennian Signed-off-by: chennian --- .../privacy/test/unittest/src/privacy_kit_test.cpp | 8 ++++---- .../include/record/permission_record_manager.h | 12 ++++++++---- services/privacymanager/src/common/constant.cpp | 3 ++- .../privacymanager/src/database/sqlite_storage.cpp | 2 +- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.cpp b/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.cpp index 1b87e6394..72e5e44fa 100644 --- a/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.cpp +++ b/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.cpp @@ -31,24 +31,24 @@ static const uint32_t TEST_VALID_TOKENID_B = 2; static const std::string TEST_EMPTY_DEVICEID = ""; static const std::string TEST_PERMISSION_INVALID = ""; -HapPolicyParams g_PolicyPramsA = { +static HapPolicyParams g_PolicyPramsA = { .apl = APL_NORMAL, .domain = "test.domain.A", }; -HapInfoParams g_InfoParmsA = { +static HapInfoParams g_InfoParmsA = { .userID = 1, .bundleName = "ohos.privacy_test.bundleA", .instIndex = 0, .appIDDesc = "privacy_test.bundleA" }; -HapPolicyParams g_PolicyPramsB = { +static HapPolicyParams g_PolicyPramsB = { .apl = APL_NORMAL, .domain = "test.domain.B", }; -HapInfoParams g_InfoParmsB = { +static HapInfoParams g_InfoParmsB = { .userID = 1, .bundleName = "ohos.privacy_test.bundleB", .instIndex = 0, diff --git a/services/privacymanager/include/record/permission_record_manager.h b/services/privacymanager/include/record/permission_record_manager.h index 65bd351bd..1663d167b 100644 --- a/services/privacymanager/include/record/permission_record_manager.h +++ b/services/privacymanager/include/record/permission_record_manager.h @@ -38,10 +38,12 @@ public: virtual ~PermissionRecordManager(); void Init(); - int32_t AddPermissionUsedRecord(AccessTokenID tokenID, const std::string& permissionName, int32_t successCount, int32_t failCount); + int32_t AddPermissionUsedRecord( + AccessTokenID tokenID, const std::string& permissionName, int32_t successCount, int32_t failCount); void RemovePermissionUsedRecords(AccessTokenID tokenID, const std::string& deviceID); int32_t GetPermissionUsedRecords(const PermissionUsedRequest& request, PermissionUsedResult& result); - int32_t GetPermissionUsedRecordsAsync(const PermissionUsedRequest& request, const sptr& callback); + int32_t GetPermissionUsedRecordsAsync( + const PermissionUsedRequest& request, const sptr& callback); std::string DumpRecordInfo(const std::string& bundleName, const std::string& permissionName); private: @@ -51,11 +53,13 @@ private: bool AddVisitor(AccessTokenID tokenID, int32_t& visitorId); bool GetPermissionVisitor(AccessTokenID tokenID, PermissionVisitor& visitor); bool AddRecord(int32_t visitorId, const std::string& permissionName, int32_t successCount, int32_t failCount); - bool GetPermissionsRecord(int32_t visitorId, const std::string& permissionName, int32_t successCount, int32_t failCount, PermissionRecord& record); + bool GetPermissionsRecord(int32_t visitorId, const std::string& permissionName, + int32_t successCount, int32_t failCount, PermissionRecord& record); int32_t DeletePermissionRecord(int32_t days); bool GetRecordsFromDB(const PermissionUsedRequest& request, PermissionUsedResult& result); - bool GetRecords(int32_t flag, std::vector recordValues, BundleUsedRecord& bundleRecord, PermissionUsedResult& result); + bool GetRecords(int32_t flag, std::vector recordValues, + BundleUsedRecord& bundleRecord, PermissionUsedResult& result); void UpdateRecords(int32_t flag, const PermissionUsedRecord& inBundleRecord, PermissionUsedRecord& outBundleRecord); bool IsLocalDevice(const std::string& deviceId); diff --git a/services/privacymanager/src/common/constant.cpp b/services/privacymanager/src/common/constant.cpp index 94934531d..f0aab8648 100644 --- a/services/privacymanager/src/common/constant.cpp +++ b/services/privacymanager/src/common/constant.cpp @@ -28,7 +28,8 @@ const std::map Constant::PERMISSION_OPCODE_MAP = { std::map::value_type("ohos.permission.READ_CALL_LOG", Constant::OP_READ_CALL_LOG), std::map::value_type("ohos.permission.READ_CELL_MESSAGES", Constant::OP_READ_CELL_MESSAGES), std::map::value_type("ohos.permission.MICROPHONE", Constant::OP_MICROPHONE), - std::map::value_type("ohos.permission.RECEIVE_WAP_MESSAGES", Constant::OP_RECEIVE_WAP_MESSAGES), + std::map::value_type( + "ohos.permission.RECEIVE_WAP_MESSAGES", Constant::OP_RECEIVE_WAP_MESSAGES), std::map::value_type("ohos.permission.RECEIVE_SMS", Constant::OP_RECEIVE_SMS), std::map::value_type("ohos.permission.RECEIVE_MMS", Constant::OP_RECEIVE_MMS), std::map::value_type("ohos.permission.READ_MESSAGES", Constant::OP_READ_MESSAGES), diff --git a/services/privacymanager/src/database/sqlite_storage.cpp b/services/privacymanager/src/database/sqlite_storage.cpp index c79614265..a14712f04 100644 --- a/services/privacymanager/src/database/sqlite_storage.cpp +++ b/services/privacymanager/src/database/sqlite_storage.cpp @@ -300,7 +300,7 @@ std::string SqliteStorage::CreateSelectPrepareSqlCmd(const DataType type) const return sql; } -std::string SqliteStorage::CreateSelectByConditionPrepareSqlCmd(const DataType type, +std::string SqliteStorage::CreateSelectByConditionPrepareSqlCmd(const DataType type, const std::vector& andColumns, const std::vector& orColumns) const { auto it = dataTypeToSqlTable_.find(type); -- Gitee From 6a67c5aa4deafea98a32e791e59c2e46beb41a9a Mon Sep 17 00:00:00 2001 From: chennian Date: Wed, 8 Jun 2022 08:18:40 +0800 Subject: [PATCH 7/7] Signed-off-by:chennian Signed-off-by: chennian --- .../innerkits/privacy/test/unittest/src/privacy_kit_test.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.cpp b/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.cpp index 72e5e44fa..50651173f 100644 --- a/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.cpp +++ b/interfaces/innerkits/privacy/test/unittest/src/privacy_kit_test.cpp @@ -25,11 +25,6 @@ using namespace OHOS::Security::AccessToken; const static int32_t RET_NO_ERROR = 0; const static int32_t RET_ERROR = -1; -static const uint32_t TEST_TOKENID_INVALID = 0; -static const uint32_t TEST_VALID_TOKENID_A = 1; -static const uint32_t TEST_VALID_TOKENID_B = 2; -static const std::string TEST_EMPTY_DEVICEID = ""; -static const std::string TEST_PERMISSION_INVALID = ""; static HapPolicyParams g_PolicyPramsA = { .apl = APL_NORMAL, -- Gitee