diff --git a/services/distributeddataservice/service/cloud/cloud_service_impl.cpp b/services/distributeddataservice/service/cloud/cloud_service_impl.cpp index 3179ab11376288d127fe3f4e7c81c42f98aaa90b..afb534d925cf270ebcaa86e65f37ecf6a94df221 100644 --- a/services/distributeddataservice/service/cloud/cloud_service_impl.cpp +++ b/services/distributeddataservice/service/cloud/cloud_service_impl.cpp @@ -1602,7 +1602,7 @@ CloudServiceImpl::HapInfo CloudServiceImpl::GetHapInfo(uint32_t tokenId) { if (AccessTokenKit::GetTokenTypeFlag(tokenId) != TOKEN_HAP) { ZLOGE("TokenType is not TOKEN_HAP, tokenId:0x%{public}x", tokenId); - return { 0, 0, ""}; + return { INVALID_USER_ID, -1, "" }; } HapTokenInfo tokenInfo; int errCode = AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo); diff --git a/services/distributeddataservice/service/object/BUILD.gn b/services/distributeddataservice/service/object/BUILD.gn index b5bba90befa02cfc57ac579e272d1f9ac8a0f8e0..c39250f9f66d1602489dd07bf9bdf253491f4467 100644 --- a/services/distributeddataservice/service/object/BUILD.gn +++ b/services/distributeddataservice/service/object/BUILD.gn @@ -21,6 +21,7 @@ config("object_public_config") { "${data_service_path}/service/matrix/include", "${data_service_path}/adapter/include/communicator", "${data_service_path}/adapter/include/utils", + "${data_service_path}/service/permission/include", ] } diff --git a/services/distributeddataservice/service/object/include/object_service_impl.h b/services/distributeddataservice/service/object/include/object_service_impl.h index 98f0fcd616966ccde0ad575a327a4d0fbf01c540..7d14b70b2dcbc3b649fc4ef843bf6e366bed8a61 100644 --- a/services/distributeddataservice/service/object/include/object_service_impl.h +++ b/services/distributeddataservice/service/object/include/object_service_impl.h @@ -73,6 +73,7 @@ private: void RegisterHandler(); int32_t SaveMetaData(StoreMetaData& saveMeta); void UpdateMetaData(); + int32_t PermissionCheck(const std::string &bundleName, const std::string &sessionId, uint32_t tokenId); static Factory factory_; std::shared_ptr executors_; diff --git a/services/distributeddataservice/service/object/src/object_service_impl.cpp b/services/distributeddataservice/service/object/src/object_service_impl.cpp index ff6d5ee3af5e31e993f6ab2e0808f161c010aaba..4cc7bfc0980f88faef2bdd847643292c2a5c3dcf 100644 --- a/services/distributeddataservice/service/object/src/object_service_impl.cpp +++ b/services/distributeddataservice/service/object/src/object_service_impl.cpp @@ -33,6 +33,7 @@ #include "metadata/store_meta_data.h" #include "object_asset_loader.h" #include "object_dms_handler.h" +#include "permission_validator.h" #include "snapshot/bind_event.h" #include "store/auto_cache.h" #include "utils/anonymous.h" @@ -62,6 +63,24 @@ ObjectServiceImpl::Factory::~Factory() { } +int32_t ObjectServiceImpl::PermissionCheck(const std::string &bundleName, const std::string &sessionId, + uint32_t tokenId) +{ + bool isContinue = false; + int32_t status = IsContinue(isContinue); + if (status != OBJECT_SUCCESS) { + ZLOGE("object continue failed %{public}d, bundleName:%{public}s", status, bundleName.c_str()); + return status; + } + // check permission + if (!isContinue && !DistributedKv::PermissionValidator::GetInstance().CheckSyncPermission(tokenId)) { + ZLOGE("object permission denied, isContinue:%{public}d, bundleName:%{public}s, sessionId:%{public}s,", + isContinue, bundleName.c_str(), Anonymous::Change(sessionId).c_str()); + return OBJECT_PERMISSION_DENIED; + } + return OBJECT_SUCCESS; +} + int32_t ObjectServiceImpl::ObjectStoreSave(const std::string &bundleName, const std::string &sessionId, const std::string &deviceId, const std::map> &data, sptr callback) @@ -74,6 +93,11 @@ int32_t ObjectServiceImpl::ObjectStoreSave(const std::string &bundleName, const if (status != OBJECT_SUCCESS) { return status; } + status = PermissionCheck(bundleName, sessionId, tokenId); + if (status != OBJECT_SUCCESS) { + ZLOGE("Save permission check fail %{public}d, bundleName:%{public}s,", status, bundleName.c_str()); + return status; + } status = ObjectStoreManager::GetInstance().Save(bundleName, sessionId, data, deviceId, callback); if (status != OBJECT_SUCCESS) { ZLOGE("save fail %{public}d", status); @@ -229,6 +253,11 @@ int32_t ObjectServiceImpl::ObjectStoreRevokeSave( if (status != OBJECT_SUCCESS) { return status; } + status = PermissionCheck(bundleName, sessionId, tokenId); + if (status != OBJECT_SUCCESS) { + ZLOGE("RevokeSave permission check fail %{public}d, bundleName:%{public}s,", status, bundleName.c_str()); + return status; + } status = ObjectStoreManager::GetInstance().RevokeSave(bundleName, sessionId, callback); if (status != OBJECT_SUCCESS) { ZLOGE("revoke save fail %{public}d", status); @@ -246,6 +275,11 @@ int32_t ObjectServiceImpl::ObjectStoreRetrieve( if (status != OBJECT_SUCCESS) { return status; } + status = PermissionCheck(bundleName, sessionId, tokenId); + if (status != OBJECT_SUCCESS) { + ZLOGE("retrieve permission check fail %{public}d, bundleName:%{public}s,", status, bundleName.c_str()); + return status; + } status = ObjectStoreManager::GetInstance().Retrieve(bundleName, sessionId, callback, tokenId); if (status != OBJECT_SUCCESS) { ZLOGE("retrieve fail %{public}d", status); diff --git a/services/distributeddataservice/service/test/BUILD.gn b/services/distributeddataservice/service/test/BUILD.gn index 1f6ecbcfdfb96958d59b23c6e105f906d9608ef1..08ac99f0eb5b20730f8d8a1795f9fbdc2dddf86f 100644 --- a/services/distributeddataservice/service/test/BUILD.gn +++ b/services/distributeddataservice/service/test/BUILD.gn @@ -969,6 +969,7 @@ ohos_unittest("ObjectManagerMockTest") { "../object/src/object_types_utils.cpp", "mock/access_token_mock.cpp", "mock/account_delegate_mock.cpp", + "mock/checker_mock.cpp", "mock/device_manager_adapter_mock.cpp", "mock/kv_store_nb_delegate_mock.cpp", "object_manager_mock_test.cpp", diff --git a/services/distributeddataservice/service/test/object_manager_mock_test.cpp b/services/distributeddataservice/service/test/object_manager_mock_test.cpp index 58835654a7d72331f08ae1a09b6a5613da98577e..ead794bac6a25d82f7dbed8944851fe80a76b53c 100644 --- a/services/distributeddataservice/service/test/object_manager_mock_test.cpp +++ b/services/distributeddataservice/service/test/object_manager_mock_test.cpp @@ -17,15 +17,18 @@ #include #include +#include "accesstoken_kit.h" #include "device_manager_adapter_mock.h" #include "device_matrix_mock.h" #include "gtest/gtest.h" #include "mock/access_token_mock.h" #include "mock/account_delegate_mock.h" +#include "mock/checker_mock.h" #include "mock/distributed_file_daemon_manager_mock.h" #include "mock/meta_data_manager_mock.h" #include "object_manager.h" #include "object_service_impl.h" +#include "token_setproc.h" using namespace OHOS::DistributedObject; @@ -40,6 +43,7 @@ using OnComplete = OHOS::DistributedData::MetaDataManager::OnComplete; namespace OHOS::Test { namespace DistributedDataTest { +static constexpr const int32_t TEST_FLAG_CALL_TWO = 2; class ObjectManagerMockTest : public testing::Test { public: static void SetUpTestCase(void) @@ -96,7 +100,9 @@ protected: std::string sessionId_ = "123"; OHOS::ObjectStore::AssetBindInfo assetBindInfo_; AssetValue assetValue_; + static CheckerMock checkerMock_; }; +CheckerMock ObjectManagerMockTest::checkerMock_; /** * @tc.name: IsNeedMetaSync001 @@ -191,7 +197,7 @@ HWTEST_F(ObjectManagerMockTest, IsNeedMetaSync003, TestSize.Level0) HWTEST_F(ObjectManagerMockTest, SyncOnStore001, TestSize.Level0) { // 2 means that the GetUserByToken interface will be called twice - EXPECT_CALL(*accountDelegateMock, GetUserByToken(_)).Times(2).WillRepeatedly(Return(0)); + EXPECT_CALL(*accountDelegateMock, GetUserByToken(_)).Times(TEST_FLAG_CALL_TWO).WillRepeatedly(Return(0)); auto &manager = ObjectStoreManager::GetInstance(); std::function &results)> func; func = [](const std::map &results) { return results; }; @@ -510,7 +516,7 @@ HWTEST_F(ObjectManagerMockTest, IsContinue002, TestSize.Level1) std::shared_ptr objectServiceImpl = std::make_shared(); bool isContinue = false; EXPECT_CALL(*accTokenMock, GetTokenTypeFlag(_)) - .Times(2) + .Times(TEST_FLAG_CALL_TWO) .WillRepeatedly(Return(ATokenTypeEnum::TOKEN_HAP)); EXPECT_CALL(*accTokenMock, GetHapTokenInfo(_, _)) .Times(1) @@ -518,5 +524,159 @@ HWTEST_F(ObjectManagerMockTest, IsContinue002, TestSize.Level1) auto ret = objectServiceImpl->IsContinue(isContinue); EXPECT_EQ(ret, DistributedObject::OBJECT_SUCCESS); } + +/** +* @tc.name: PermissionCheck001 +* @tc.desc: Test ObjectStoreSave function when PermissionCheck is not in continue and have sync permission. +* @tc.type: FUNC +*/ +HWTEST_F(ObjectManagerMockTest, PermissionCheck001, TestSize.Level1) +{ + std::string bundleName = "com.examples.test"; + std::string sessionId = "sessionId"; + std::string deviceId = "deviceId"; + std::map> data; + sptr callback; + std::vector checkers = {"SystemChecker"}; + CheckerManager::GetInstance().LoadCheckers(checkers); + EXPECT_CALL(*accTokenMock, GetTokenTypeFlag(_)) + .Times(1) + .WillRepeatedly(Return(ATokenTypeEnum::TOKEN_HAP)); + EXPECT_CALL(*accTokenMock, GetHapTokenInfo(_, _)) + .Times(1) + .WillRepeatedly(Return(0)); + EXPECT_CALL(*accTokenMock, VerifyAccessToken(_, _)) + .Times(1) + .WillRepeatedly(Return(TypePermissionState::PERMISSION_GRANTED)); + std::shared_ptr objectServiceImpl = std::make_shared(); + int32_t ret = objectServiceImpl->ObjectStoreSave(bundleName, sessionId, deviceId, data, callback); + EXPECT_EQ(ret, DistributedKv::INVALID_ARGUMENT); +} + +/** +* @tc.name: PermissionCheck002 +* @tc.desc: Test ObjectStoreSave function when PermissionCheck is not in continue and TokenType is not TOKEN_HAP. +* @tc.type: FUNC +*/ +HWTEST_F(ObjectManagerMockTest, PermissionCheck002, TestSize.Level1) +{ + std::string bundleName = "com.examples.test"; + std::string sessionId = "sessionId"; + std::string deviceId = "deviceId"; + std::map> data; + sptr callback; + std::vector checkers = {"SystemChecker"}; + CheckerManager::GetInstance().LoadCheckers(checkers); + EXPECT_CALL(*accTokenMock, GetTokenTypeFlag(_)) + .Times(1) + .WillOnce(Return(ATokenTypeEnum::TOKEN_NATIVE)); + std::shared_ptr objectServiceImpl = std::make_shared(); + int32_t ret = objectServiceImpl->ObjectStoreSave(bundleName, sessionId, deviceId, data, callback); + EXPECT_EQ(ret, OBJECT_INNER_ERROR); +} + +/** +* @tc.name: PermissionCheck003 +* @tc.desc: Test ObjectStoreRevokeSave function when PermissionCheck is not in continue and have sync permission. +* @tc.type: FUNC +*/ +HWTEST_F(ObjectManagerMockTest, PermissionCheck003, TestSize.Level1) +{ + std::string bundleName = "com.examples.test"; + std::string sessionId = "sessionId"; + sptr callback; + std::vector checkers = {"SystemChecker"}; + CheckerManager::GetInstance().LoadCheckers(checkers); + EXPECT_CALL(*accTokenMock, GetTokenTypeFlag(_)) + .Times(1) + .WillRepeatedly(Return(ATokenTypeEnum::TOKEN_HAP)); + EXPECT_CALL(*accTokenMock, GetHapTokenInfo(_, _)) + .Times(1) + .WillRepeatedly(Return(0)); + EXPECT_CALL(*accTokenMock, VerifyAccessToken(_, _)) + .Times(1) + .WillRepeatedly(Return(TypePermissionState::PERMISSION_GRANTED)); + std::shared_ptr objectServiceImpl = std::make_shared(); + int32_t ret = objectServiceImpl->ObjectStoreRevokeSave(bundleName, sessionId, callback); + EXPECT_EQ(ret, DistributedKv::INVALID_ARGUMENT); +} + +/** +* @tc.name: PermissionCheck004 +* @tc.desc: Test ObjectStoreRevokeSave function when PermissionCheck is not in continue and not sync permission. +* @tc.type: FUNC +*/ +HWTEST_F(ObjectManagerMockTest, PermissionCheck004, TestSize.Level1) +{ + std::string bundleName = "com.examples.test"; + std::string sessionId = "sessionId"; + sptr callback; + std::vector checkers = {"SystemChecker"}; + CheckerManager::GetInstance().LoadCheckers(checkers); + EXPECT_CALL(*accTokenMock, GetTokenTypeFlag(_)) + .Times(1) + .WillRepeatedly(Return(ATokenTypeEnum::TOKEN_HAP)); + EXPECT_CALL(*accTokenMock, GetHapTokenInfo(_, _)) + .Times(1) + .WillRepeatedly(Return(0)); + EXPECT_CALL(*accTokenMock, VerifyAccessToken(_, _)) + .Times(1) + .WillRepeatedly(Return(TypePermissionState::PERMISSION_DENIED)); + std::shared_ptr objectServiceImpl = std::make_shared(); + int32_t ret = objectServiceImpl->ObjectStoreRevokeSave(bundleName, sessionId, callback); + EXPECT_EQ(ret, OBJECT_PERMISSION_DENIED); +} + +/** +* @tc.name: PermissionCheck005 +* @tc.desc: Test ObjectStoreRetrieve function when PermissionCheck is not in continue and have sync permission. +* @tc.type: FUNC +*/ +HWTEST_F(ObjectManagerMockTest, PermissionCheck005, TestSize.Level1) +{ + std::string bundleName = "com.examples.test"; + std::string sessionId = "sessionId"; + sptr callback; + std::vector checkers = {"SystemChecker"}; + CheckerManager::GetInstance().LoadCheckers(checkers); + EXPECT_CALL(*accTokenMock, GetTokenTypeFlag(_)) + .Times(1) + .WillRepeatedly(Return(ATokenTypeEnum::TOKEN_HAP)); + EXPECT_CALL(*accTokenMock, GetHapTokenInfo(_, _)) + .Times(1) + .WillRepeatedly(Return(0)); + EXPECT_CALL(*accTokenMock, VerifyAccessToken(_, _)) + .Times(1) + .WillRepeatedly(Return(TypePermissionState::PERMISSION_GRANTED)); + std::shared_ptr objectServiceImpl = std::make_shared(); + int32_t ret = objectServiceImpl->ObjectStoreRetrieve(bundleName, sessionId, callback); + EXPECT_EQ(ret, DistributedKv::INVALID_ARGUMENT); +} + +/** +* @tc.name: PermissionCheck006 +* @tc.desc: Test ObjectStoreRetrieve function when PermissionCheck is not in continue and not sync permission. +* @tc.type: FUNC +*/ +HWTEST_F(ObjectManagerMockTest, PermissionCheck006, TestSize.Level1) +{ + std::string bundleName = "com.examples.test"; + std::string sessionId = "sessionId"; + sptr callback; + std::vector checkers = {"SystemChecker"}; + CheckerManager::GetInstance().LoadCheckers(checkers); + EXPECT_CALL(*accTokenMock, GetTokenTypeFlag(_)) + .Times(1) + .WillRepeatedly(Return(ATokenTypeEnum::TOKEN_HAP)); + EXPECT_CALL(*accTokenMock, GetHapTokenInfo(_, _)) + .Times(1) + .WillRepeatedly(Return(0)); + EXPECT_CALL(*accTokenMock, VerifyAccessToken(_, _)) + .Times(1) + .WillRepeatedly(Return(TypePermissionState::PERMISSION_DENIED)); + std::shared_ptr objectServiceImpl = std::make_shared(); + int32_t ret = objectServiceImpl->ObjectStoreRetrieve(bundleName, sessionId, callback); + EXPECT_EQ(ret, OBJECT_PERMISSION_DENIED); +} }; // namespace DistributedDataTest } // namespace OHOS::Test \ No newline at end of file