diff --git a/services/distributeddataservice/service/rdb/rdb_service_impl.cpp b/services/distributeddataservice/service/rdb/rdb_service_impl.cpp index d0ffa6fe5cb78f3208d0ff916afc2fe58d6d699d..cf23627a68ba4fe1db480ecc2bef14a1015d812a 100644 --- a/services/distributeddataservice/service/rdb/rdb_service_impl.cpp +++ b/services/distributeddataservice/service/rdb/rdb_service_impl.cpp @@ -1749,11 +1749,11 @@ int32_t RdbServiceImpl::VerifyPromiseInfo(const RdbSyncerParam ¶m) auto isCreated = MetaDataManager::GetInstance().LoadMeta(meta.GetKeyLocal(), localMeta, true); if (!isCreated) { ZLOGE("Store not exist. bundleName:%{public}s, storeName:%{public}s", meta.bundleName.c_str(), - meta.storeId.c_str()); + meta.GetStoreAlias().c_str()); return RDB_ERROR; } ATokenTypeEnum type = AccessTokenKit::GetTokenType(tokenId); - if (type == ATokenTypeEnum::TOKEN_NATIVE) { + if (type == ATokenTypeEnum::TOKEN_NATIVE || type == ATokenTypeEnum::TOKEN_SHELL) { auto tokenIdRet = std::find(localMeta.promiseInfo.tokenIds.begin(), localMeta.promiseInfo.tokenIds.end(), tokenId); auto uidRet = std::find(localMeta.promiseInfo.uids.begin(), localMeta.promiseInfo.uids.end(), uid); @@ -1765,15 +1765,18 @@ int32_t RdbServiceImpl::VerifyPromiseInfo(const RdbSyncerParam ¶m) !isPromise) { return RDB_ERROR; } - } - if (type == ATokenTypeEnum::TOKEN_HAP) { - for (const auto& permissionName : localMeta.promiseInfo.permissionNames) { + } else if (type == ATokenTypeEnum::TOKEN_HAP) { + for (const auto &permissionName : localMeta.promiseInfo.permissionNames) { if (PermitDelegate::VerifyPermission(permissionName, tokenId)) { return RDB_OK; } } ZLOGE("Permission denied! tokenId:0x%{public}x", tokenId); return RDB_ERROR; + } else { + ZLOGE("invalid type! bundleName:%{public}s, storeName:%{public}s, token_type is %{public}d.", + meta.bundleName.c_str(), meta.GetStoreAlias().c_str(), type); + return RDB_ERROR; } return RDB_OK; } diff --git a/services/distributeddataservice/service/test/BUILD.gn b/services/distributeddataservice/service/test/BUILD.gn index 142b4921164a156f29d8ad5aa3e98dfda8eab50c..d69c2976a517b0f4b397397c1b5ca00eff25a733 100644 --- a/services/distributeddataservice/service/test/BUILD.gn +++ b/services/distributeddataservice/service/test/BUILD.gn @@ -616,6 +616,74 @@ ohos_unittest("RdbServiceImplTest") { ] } +ohos_unittest("RdbServiceImplTokenTest") { + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } + module_out_path = module_output_path + sources = [ + "mock/access_token_mock.cpp", + "mock/checker_mock.cpp", + "mock/db_change_data_mock.cpp", + "mock/db_store_mock.cpp", + "rdb_service_impl_token_test.cpp", + ] + + include_dirs = [ + "${data_service_path}/adapter/include/communicator", + "${data_service_path}/framework/include/eventcenter", + "${data_service_path}/service/test/mock", + ] + + defines = [ + "TEST_ON_DEVICE", + "OPENSSL_SUPPRESS_DEPRECATED", + ] + cflags = [ + "-Werror", + "-Dprotected=public", + "-Wno-multichar", + "-Wno-c99-designator", + "-fno-access-control", # Ignore Private Member Access Control + ] + + external_deps = [ + "ability_base:base", + "ability_base:want", + "access_token:libaccesstoken_sdk", + "access_token:libnativetoken", + "access_token:libtokenid_sdk", + "bundle_framework:appexecfwk_base", + "bundle_framework:appexecfwk_core", + "c_utils:utils", + "data_share:datashare_common", + "data_share:datashare_consumer", + "device_manager:devicemanagersdk", + "dsoftbus:softbus_client", + "googletest:gmock_main", + "googletest:gtest_main", + "hicollie:libhicollie", + "hilog:libhilog", + "hisysevent:libhisysevent", + "huks:libhukssdk", + "ipc:ipc_core", + "kv_store:datamgr_common", + "kv_store:distributeddata_inner", + "kv_store:distributeddb", + "relational_store:native_rdb", + "resource_management:global_resmgr", + ] + + deps = [ + "${data_service_path}/adapter/utils:distributeddata_utils", + "${data_service_path}/framework:distributeddatasvcfwk", + "${data_service_path}/service:distributeddatasvc", + "${data_service_path}/service/rdb:distributeddata_rdb", + ] +} + ohos_unittest("ObjectAssetLoaderTest") { module_out_path = module_output_path sources = [ @@ -1991,6 +2059,7 @@ group("unittest") { deps += [ ":RdbResultSetImplTest", ":RdbServiceImplTest", + ":RdbServiceImplTokenTest", ":RdbServiceTest", ] } diff --git a/services/distributeddataservice/service/test/mock/access_token_mock.cpp b/services/distributeddataservice/service/test/mock/access_token_mock.cpp index 2d80d5263eece63ade5d2c96262040d4b43c5def..c0fe454a66674a2997c086ccba971fe1af022243 100644 --- a/services/distributeddataservice/service/test/mock/access_token_mock.cpp +++ b/services/distributeddataservice/service/test/mock/access_token_mock.cpp @@ -22,6 +22,14 @@ ATokenTypeEnum AccessTokenKit::GetTokenTypeFlag(AccessTokenID tokenID) return BAccessTokenKit::accessTokenkit->GetTokenTypeFlag(tokenID); } +ATokenTypeEnum AccessTokenKit::GetTokenType(AccessTokenID tokenID) +{ + if (BAccessTokenKit::accessTokenkit == nullptr) { + return ATokenTypeEnum::TOKEN_INVALID; + } + return BAccessTokenKit::accessTokenkit->GetTokenType(tokenID); +} + int AccessTokenKit::GetHapTokenInfo(AccessTokenID tokenID, HapTokenInfo& hapTokenInfoRes) { return BAccessTokenKit::accessTokenkit->GetHapTokenInfo(tokenID, hapTokenInfoRes); diff --git a/services/distributeddataservice/service/test/mock/access_token_mock.h b/services/distributeddataservice/service/test/mock/access_token_mock.h index 110dde08e624007cf6b03e8ea0bbdf3167f5b36c..e02b6d0d408bf3a3db3e495dfffac47240e60c17 100644 --- a/services/distributeddataservice/service/test/mock/access_token_mock.h +++ b/services/distributeddataservice/service/test/mock/access_token_mock.h @@ -25,6 +25,7 @@ namespace AccessToken { class BAccessTokenKit { public: virtual ATokenTypeEnum GetTokenTypeFlag(AccessTokenID) = 0; + virtual ATokenTypeEnum GetTokenType(AccessTokenID) = 0; virtual int GetHapTokenInfo(AccessTokenID, HapTokenInfo&) = 0; virtual int GetNativeTokenInfo(AccessTokenID, NativeTokenInfo&) = 0; virtual int VerifyAccessToken(AccessTokenID, const std::string&) = 0; @@ -37,6 +38,7 @@ private: class AccessTokenKitMock : public BAccessTokenKit { public: MOCK_METHOD(ATokenTypeEnum, GetTokenTypeFlag, (AccessTokenID)); + MOCK_METHOD(ATokenTypeEnum, GetTokenType, (AccessTokenID)); MOCK_METHOD(int, GetHapTokenInfo, (AccessTokenID, HapTokenInfo&)); MOCK_METHOD(int, GetNativeTokenInfo, (AccessTokenID, NativeTokenInfo&)); MOCK_METHOD(int, VerifyAccessToken, (AccessTokenID, const std::string&)); diff --git a/services/distributeddataservice/service/test/rdb_service_impl_token_test.cpp b/services/distributeddataservice/service/test/rdb_service_impl_token_test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..14f8263647ce09ed05bf04573e323c05d037127a --- /dev/null +++ b/services/distributeddataservice/service/test/rdb_service_impl_token_test.cpp @@ -0,0 +1,354 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "account/account_delegate.h" +#include "rdb_service_impl.h" +#include "ipc_skeleton.h" +#include "gmock/gmock.h" +#include "mock/access_token_mock.h" +#include "bootstrap.h" +#include "checker_mock.h" +#include "crypto_manager.h" +#include "device_manager_adapter.h" +#include "device_matrix.h" +#include "metadata/meta_data_manager.h" +#include "metadata/store_meta_data.h" +#include "metadata/store_meta_data_local.h" +#include "mock/db_store_mock.h" +#include "rdb_types.h" +#include "relational_store_manager.h" +#include "gtest/gtest.h" +#include "directory/directory_manager.h" +using namespace OHOS::DistributedRdb; +using namespace OHOS::DistributedData; +using namespace DistributedDB; +using namespace OHOS::Security::AccessToken; +using namespace testing::ext; +using namespace testing; +using namespace std; +using DmAdapter = OHOS::DistributedData::DeviceManagerAdapter; + +namespace OHOS::Test { +namespace DistributedRDBTest { + +static constexpr const char *TEST_BUNDLE = "test_rdb_service_impl_bundleName"; +static constexpr const char *TEST_APPID = "test_rdb_service_impl_appid"; +static constexpr const char *TEST_STORE = "test_rdb_service_impl_store"; + +class RdbServiceImplTokenTest : public testing::Test { +public: + static void SetUpTestCase(void); + static void TearDownTestCase(void); + static void InitMetaData(); + void SetUp(); + void TearDown(); +protected: + static inline std::shared_ptr accTokenMock = nullptr; + static std::shared_ptr dbStoreMock_; + static StoreMetaData metaData_; + static CheckerMock checkerMock_; + static void InitMetaDataManager(); + static void GetRdbSyncerParam(RdbSyncerParam ¶m); +}; +std::shared_ptr RdbServiceImplTokenTest::dbStoreMock_ = std::make_shared(); +StoreMetaData RdbServiceImplTokenTest::metaData_; +CheckerMock RdbServiceImplTokenTest::checkerMock_; + + +void RdbServiceImplTokenTest::InitMetaData() +{ + metaData_.deviceId = DmAdapter::GetInstance().GetLocalDevice().uuid; + metaData_.appId = TEST_APPID; + metaData_.bundleName = TEST_BUNDLE; + metaData_.tokenId = OHOS::IPCSkeleton::GetCallingTokenID(); + metaData_.user = std::to_string(AccountDelegate::GetInstance()->GetUserByToken(metaData_.tokenId)); + metaData_.area = OHOS::DistributedKv::EL1; + metaData_.instanceId = -1; + metaData_.isAutoSync = true; + metaData_.storeType = DistributedRdb::RDB_DEVICE_COLLABORATION; + metaData_.storeId = TEST_STORE; + metaData_.dataDir = DirectoryManager::GetInstance().GetStorePath(metaData_) + "/" + TEST_STORE; +} + +void RdbServiceImplTokenTest::InitMetaDataManager() +{ + MetaDataManager::GetInstance().Initialize(dbStoreMock_, nullptr, ""); + MetaDataManager::GetInstance().SetSyncer([](const auto &, auto) { + DeviceMatrix::GetInstance().OnChanged(DeviceMatrix::META_STORE_MASK); + }); +} + +void RdbServiceImplTokenTest::SetUpTestCase() +{ + accTokenMock = std::make_shared(); + BAccessTokenKit::accessTokenkit = accTokenMock; + size_t max = 12; + size_t min = 5; + auto dmExecutor = std::make_shared(max, min); + DeviceManagerAdapter::GetInstance().Init(dmExecutor); + InitMetaData(); + Bootstrap::GetInstance().LoadCheckers(); + CryptoManager::GetInstance().GenerateRootKey(); +} + +void RdbServiceImplTokenTest::TearDownTestCase() +{ + accTokenMock = nullptr; + BAccessTokenKit::accessTokenkit = nullptr; +} + +void RdbServiceImplTokenTest::SetUp() +{ +} + +void RdbServiceImplTokenTest::TearDown() +{ +} + +void RdbServiceImplTokenTest::GetRdbSyncerParam(RdbSyncerParam ¶m) +{ + param.bundleName_ = metaData_.bundleName; + param.type_ = metaData_.storeType; + param.level_ = metaData_.securityLevel; + param.area_ = metaData_.area; + param.hapName_ = metaData_.bundleName; + param.storeName_ = metaData_.storeId; + param.isEncrypt_ = metaData_.isEncrypt; + param.isSearchable_ = metaData_.isSearchable; + param.haMode_ = metaData_.haMode; + param.asyncDownloadAsset_ = metaData_.asyncDownloadAsset; + param.user_ = metaData_.user; +} + +/** + * @tc.name: VerifyPromiseInfo001 + * @tc.desc: Test VerifyPromiseInfo when tokenId and uid are not in promiseInfo. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zd + */ +HWTEST_F(RdbServiceImplTokenTest, VerifyPromiseInfo001, TestSize.Level0) +{ + EXPECT_CALL(*accTokenMock, GetTokenType(testing::_)) + .WillOnce(testing::Return(ATokenTypeEnum::TOKEN_INVALID)) + .WillRepeatedly(testing::Return(ATokenTypeEnum::TOKEN_INVALID)); + RdbServiceImpl service; + RdbSyncerParam param; + int32_t result = service.VerifyPromiseInfo(param); + + EXPECT_EQ(result, RDB_ERROR); +} + +/** + * @tc.name: VerifyPromiseInfo002 + * @tc.desc: Test VerifyPromiseInfo when tokenId and uid are not in promiseInfo. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zd + */ +HWTEST_F(RdbServiceImplTokenTest, VerifyPromiseInfo002, TestSize.Level0) +{ + InitMetaDataManager(); + StoreMetaDataLocal localMeta; + auto tokenId = IPCSkeleton::GetCallingTokenID(); + localMeta.isAutoSync = true; + localMeta.promiseInfo.tokenIds = {tokenId}; + localMeta.promiseInfo.uids = {}; + localMeta.promiseInfo.permissionNames = {}; + EXPECT_EQ(MetaDataManager::GetInstance().SaveMeta(metaData_.GetKeyLocal(), localMeta, true), true); + + EXPECT_CALL(*accTokenMock, GetTokenType(testing::_)) + .WillOnce(testing::Return(ATokenTypeEnum::TOKEN_INVALID)) + .WillRepeatedly(testing::Return(ATokenTypeEnum::TOKEN_INVALID)); + RdbServiceImpl service; + RdbSyncerParam param; + GetRdbSyncerParam(param); + int32_t result = service.VerifyPromiseInfo(param); + + EXPECT_EQ(result, RDB_ERROR); + EXPECT_EQ(MetaDataManager::GetInstance().DelMeta(metaData_.GetKeyLocal(), true), true); +} + +/** + * @tc.name: VerifyPromiseInfo003 + * @tc.desc: Test VerifyPromiseInfo when tokenId and uid are not in promiseInfo. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zd + */ +HWTEST_F(RdbServiceImplTokenTest, VerifyPromiseInfo003, TestSize.Level0) +{ + StoreMetaDataLocal localMeta; + auto tokenId = IPCSkeleton::GetCallingTokenID(); + localMeta.isAutoSync = true; + localMeta.promiseInfo.tokenIds = {tokenId}; + localMeta.promiseInfo.uids = {}; + localMeta.promiseInfo.permissionNames = {}; + EXPECT_EQ(MetaDataManager::GetInstance().SaveMeta(metaData_.GetKeyLocal(), localMeta, true), true); + + EXPECT_CALL(*accTokenMock, GetTokenType(testing::_)) + .WillOnce(testing::Return(ATokenTypeEnum::TOKEN_SHELL)) + .WillRepeatedly(testing::Return(ATokenTypeEnum::TOKEN_SHELL)); + RdbServiceImpl service; + RdbSyncerParam param; + GetRdbSyncerParam(param); + int32_t result = service.VerifyPromiseInfo(param); + + EXPECT_EQ(result, RDB_OK); + EXPECT_EQ(MetaDataManager::GetInstance().DelMeta(metaData_.GetKeyLocal(), true), true); +} + +/** + * @tc.name: VerifyPromiseInfo004 + * @tc.desc: Test VerifyPromiseInfo when tokenId and uid are not in promiseInfo. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zd + */ +HWTEST_F(RdbServiceImplTokenTest, VerifyPromiseInfo004, TestSize.Level0) +{ + StoreMetaDataLocal localMeta; + localMeta.isAutoSync = true; + localMeta.promiseInfo.tokenIds = {}; + localMeta.promiseInfo.uids = {}; + localMeta.promiseInfo.permissionNames = {}; + EXPECT_EQ(MetaDataManager::GetInstance().SaveMeta(metaData_.GetKeyLocal(), localMeta, true), true); + + EXPECT_CALL(*accTokenMock, GetTokenType(testing::_)) + .WillOnce(testing::Return(ATokenTypeEnum::TOKEN_SHELL)) + .WillRepeatedly(testing::Return(ATokenTypeEnum::TOKEN_SHELL)); + RdbServiceImpl service; + RdbSyncerParam param; + GetRdbSyncerParam(param); + int32_t result = service.VerifyPromiseInfo(param); + + EXPECT_EQ(result, RDB_ERROR); + EXPECT_EQ(MetaDataManager::GetInstance().DelMeta(metaData_.GetKeyLocal(), true), true); +} + +/** + * @tc.name: VerifyPromiseInfo005 + * @tc.desc: Test VerifyPromiseInfo when tokenId and uid are not in promiseInfo. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zd + */ +HWTEST_F(RdbServiceImplTokenTest, VerifyPromiseInfo005, TestSize.Level0) +{ + StoreMetaDataLocal localMeta; + auto tokenId = IPCSkeleton::GetCallingTokenID(); + localMeta.isAutoSync = true; + localMeta.promiseInfo.tokenIds = {tokenId}; + localMeta.promiseInfo.uids = {}; + localMeta.promiseInfo.permissionNames = {}; + EXPECT_EQ(MetaDataManager::GetInstance().SaveMeta(metaData_.GetKeyLocal(), localMeta, true), true); + + EXPECT_CALL(*accTokenMock, GetTokenType(testing::_)) + .WillOnce(testing::Return(ATokenTypeEnum::TOKEN_NATIVE)) + .WillRepeatedly(testing::Return(ATokenTypeEnum::TOKEN_NATIVE)); + RdbServiceImpl service; + RdbSyncerParam param; + GetRdbSyncerParam(param); + int32_t result = service.VerifyPromiseInfo(param); + + EXPECT_EQ(result, RDB_OK); + EXPECT_EQ(MetaDataManager::GetInstance().DelMeta(metaData_.GetKeyLocal(), true), true); +} + +/** + * @tc.name: VerifyPromiseInfo006 + * @tc.desc: Test VerifyPromiseInfo when tokenId and uid are not in promiseInfo. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zd + */ +HWTEST_F(RdbServiceImplTokenTest, VerifyPromiseInfo006, TestSize.Level0) +{ + StoreMetaDataLocal localMeta; + localMeta.isAutoSync = true; + localMeta.promiseInfo.tokenIds = {}; + localMeta.promiseInfo.uids = {}; + localMeta.promiseInfo.permissionNames = {}; + EXPECT_EQ(MetaDataManager::GetInstance().SaveMeta(metaData_.GetKeyLocal(), localMeta, true), true); + + EXPECT_CALL(*accTokenMock, GetTokenType(testing::_)) + .WillOnce(testing::Return(ATokenTypeEnum::TOKEN_NATIVE)) + .WillRepeatedly(testing::Return(ATokenTypeEnum::TOKEN_NATIVE)); + RdbServiceImpl service; + RdbSyncerParam param; + GetRdbSyncerParam(param); + int32_t result = service.VerifyPromiseInfo(param); + + EXPECT_EQ(result, RDB_ERROR); + EXPECT_EQ(MetaDataManager::GetInstance().DelMeta(metaData_.GetKeyLocal(), true), true); +} +/** + * @tc.name: VerifyPromiseInfo007 + * @tc.desc: Test VerifyPromiseInfo when tokenId and uid are not in promiseInfo. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zd + */ +HWTEST_F(RdbServiceImplTokenTest, VerifyPromiseInfo007, TestSize.Level0) +{ + StoreMetaDataLocal localMeta; + auto tokenId = IPCSkeleton::GetCallingTokenID(); + localMeta.isAutoSync = true; + localMeta.promiseInfo.tokenIds = {tokenId}; + localMeta.promiseInfo.uids = {}; + localMeta.promiseInfo.permissionNames = {}; + EXPECT_EQ(MetaDataManager::GetInstance().SaveMeta(metaData_.GetKeyLocal(), localMeta, true), true); + + EXPECT_CALL(*accTokenMock, GetTokenType(testing::_)) + .WillOnce(testing::Return(ATokenTypeEnum::TOKEN_HAP)) + .WillRepeatedly(testing::Return(ATokenTypeEnum::TOKEN_HAP)); + RdbServiceImpl service; + RdbSyncerParam param; + GetRdbSyncerParam(param); + int32_t result = service.VerifyPromiseInfo(param); + + EXPECT_EQ(result, RDB_ERROR); + EXPECT_EQ(MetaDataManager::GetInstance().DelMeta(metaData_.GetKeyLocal(), true), true); +} + +/** + * @tc.name: VerifyPromiseInfo008 + * @tc.desc: Test VerifyPromiseInfo when tokenId and uid are not in promiseInfo. + * @tc.type: FUNC + * @tc.require: + * @tc.author: zd + */ +HWTEST_F(RdbServiceImplTokenTest, VerifyPromiseInfo008, TestSize.Level0) +{ + StoreMetaDataLocal localMeta; + auto tokenId = IPCSkeleton::GetCallingTokenID(); + localMeta.isAutoSync = true; + localMeta.promiseInfo.tokenIds = {tokenId}; + localMeta.promiseInfo.uids = {}; + localMeta.promiseInfo.permissionNames = {TEST_BUNDLE}; + EXPECT_EQ(MetaDataManager::GetInstance().SaveMeta(metaData_.GetKeyLocal(), localMeta, true), true); + + EXPECT_CALL(*accTokenMock, GetTokenType(testing::_)) + .WillOnce(testing::Return(ATokenTypeEnum::TOKEN_HAP)) + .WillRepeatedly(testing::Return(ATokenTypeEnum::TOKEN_HAP)); + RdbServiceImpl service; + RdbSyncerParam param; + GetRdbSyncerParam(param); + int32_t result = service.VerifyPromiseInfo(param); + + EXPECT_EQ(result, RDB_OK); + EXPECT_EQ(MetaDataManager::GetInstance().DelMeta(metaData_.GetKeyLocal(), true), true); +} +} // namespace DistributedRDBTest +} // namespace OHOS::Test \ No newline at end of file