From e492b41b41b0e48d2bd1a671a05b1194adf40ca4 Mon Sep 17 00:00:00 2001 From: illybyy Date: Fri, 18 Feb 2022 10:24:54 +0800 Subject: [PATCH] support multi-user & optimize framework Signed-off-by: illybyy --- conf/config.json | 31 +- .../innerkits/distributeddata/include/types.h | 7 + .../distributeddata/include/visibility.h | 12 +- .../adapter/account/BUILD.gn | 3 + .../adapter/account/src/account_delegate.cpp | 2 + .../account/src/account_delegate_impl.cpp | 20 +- .../adapter/account/src/user_delegate.cpp | 164 +++ .../adapter/auth/BUILD.gn | 46 + .../adapter/auth/src/auth_delegate.cpp | 126 +++ .../src/process_communicator_impl.cpp | 36 +- .../include/account/account_delegate.h | 2 + .../adapter/include/account/user_delegate.h | 66 ++ .../adapter/include/account/visibility.h | 13 +- .../adapter/include/auth/auth_delegate.h | 77 ++ .../adapter/include/autils/visibility.h | 6 +- .../adapter/include/broadcaster/visibility.h | 5 +- .../communicator/extend_head_handler.h | 30 + .../communicator/process_communicator_impl.h | 11 + .../adapter/include/dfx/visibility.h | 6 +- .../adapter/include/log/visibility.h | 5 +- services/distributeddataservice/app/BUILD.gn | 8 + .../app/src/backup_handler.cpp | 97 +- .../app/src/backup_handler.h | 30 +- .../app/src/key/key_manager.cpp | 398 ++++++++ .../app/src/key/key_manager.h | 113 +++ .../app/src/kvstore_app_accessor.cpp | 15 +- .../app/src/kvstore_app_manager.cpp | 246 ++--- .../app/src/kvstore_app_manager.h | 63 +- .../app/src/kvstore_base.h | 26 + .../app/src/kvstore_data_service.cpp | 826 +++++++-------- .../app/src/kvstore_data_service.h | 93 +- .../app/src/kvstore_impl.cpp | 40 +- .../app/src/kvstore_impl.h | 10 +- .../app/src/kvstore_meta_manager.cpp | 942 ++++++------------ .../app/src/kvstore_meta_manager.h | 214 +--- .../app/src/kvstore_user_manager.cpp | 55 +- .../app/src/kvstore_user_manager.h | 20 +- .../app/src/kvstore_user_observer.cpp | 38 + .../app/src/kvstore_user_observer.h | 29 + .../session_manager/route_head_handler.cpp | 225 +++++ .../src/session_manager/route_head_handler.h | 77 ++ .../src/session_manager/session_manager.cpp | 92 ++ .../app/src/session_manager/session_manager.h | 58 ++ .../src/session_manager/upgrade_manager.cpp | 49 + .../app/src/session_manager/upgrade_manager.h | 35 + .../app/src/single_kvstore_impl.cpp | 109 +- .../app/src/single_kvstore_impl.h | 17 +- .../app/src/uninstaller/BUILD.gn | 4 + .../app/src/uninstaller/uninstaller_impl.cpp | 9 +- .../app/test/unittest/kvstore_backup_test.cpp | 4 +- .../session_manager/session_manager_test.cpp | 79 ++ .../distributeddataservice/framework/BUILD.gn | 4 + .../include/metadata/capability_meta_data.h | 36 + .../framework/include/metadata/meta_data.h | 20 +- .../include/metadata/secret_key_meta_data.h | 9 +- .../include/metadata/store_meta_data.h | 37 +- .../include/metadata/strategy_meta_data.h | 33 + .../include/metadata/user_meta_data.h | 47 + .../include/serializable/serializable.h | 14 + .../framework/include/utils/constant.h | 14 - .../metadata/capability_meta_data.cpp | 41 + .../framework/metadata/meta_data.cpp | 14 - .../metadata/secret_key_meta_data.cpp | 3 + .../framework/metadata/store_meta_data.cpp | 28 +- .../framework/metadata/strategy_meta_data.cpp | 39 + .../framework/metadata/user_meta_data.cpp | 64 ++ .../framework/test/serializable_test.cpp | 39 +- .../framework/utils/constant.cpp | 17 - .../service/bootstrap/src/bootstrap.cpp | 2 +- .../config/include/model/directory_config.h | 4 +- .../config/src/model/directory_config.cpp | 10 +- .../directory/include/directory_manager.h | 90 +- .../directory/src/directory_manager.cpp | 212 ++-- .../service/rdb/rdb_service_impl.cpp | 2 +- .../service/rdb/rdb_syncer.cpp | 8 +- .../service/test/directory_manager_test.cpp | 62 +- 76 files changed, 3606 insertions(+), 1932 deletions(-) create mode 100644 services/distributeddataservice/adapter/account/src/user_delegate.cpp create mode 100644 services/distributeddataservice/adapter/auth/BUILD.gn create mode 100644 services/distributeddataservice/adapter/auth/src/auth_delegate.cpp create mode 100644 services/distributeddataservice/adapter/include/account/user_delegate.h create mode 100644 services/distributeddataservice/adapter/include/auth/auth_delegate.h create mode 100644 services/distributeddataservice/adapter/include/communicator/extend_head_handler.h create mode 100644 services/distributeddataservice/app/src/key/key_manager.cpp create mode 100644 services/distributeddataservice/app/src/key/key_manager.h create mode 100644 services/distributeddataservice/app/src/kvstore_base.h create mode 100644 services/distributeddataservice/app/src/kvstore_user_observer.cpp create mode 100644 services/distributeddataservice/app/src/kvstore_user_observer.h create mode 100644 services/distributeddataservice/app/src/session_manager/route_head_handler.cpp create mode 100644 services/distributeddataservice/app/src/session_manager/route_head_handler.h create mode 100644 services/distributeddataservice/app/src/session_manager/session_manager.cpp create mode 100644 services/distributeddataservice/app/src/session_manager/session_manager.h create mode 100644 services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp create mode 100644 services/distributeddataservice/app/src/session_manager/upgrade_manager.h create mode 100644 services/distributeddataservice/app/test/unittest/session_manager/session_manager_test.cpp create mode 100644 services/distributeddataservice/framework/include/metadata/capability_meta_data.h create mode 100644 services/distributeddataservice/framework/include/metadata/strategy_meta_data.h create mode 100644 services/distributeddataservice/framework/include/metadata/user_meta_data.h create mode 100644 services/distributeddataservice/framework/metadata/capability_meta_data.cpp create mode 100644 services/distributeddataservice/framework/metadata/strategy_meta_data.cpp create mode 100644 services/distributeddataservice/framework/metadata/user_meta_data.cpp diff --git a/conf/config.json b/conf/config.json index 8b241c7c2..6469381f7 100644 --- a/conf/config.json +++ b/conf/config.json @@ -63,27 +63,28 @@ ] }, "directory": { - "workers": [ - "appWorker", - "serverWorker" - ], - "metaPath": "/data/service/el0/0/database/ddms/metadata/", + "currentStrategyHolder": "caller", "strategy": [ { - "version": "0", - "holder": "ddms", - "path": "/data/{security}/0/mdds/{userId}/{bundleName}", - "metaPath": "/data/misc_de/0/mdds/Meta" + "holder": "ddms_old", + "path": "/data/{security}/0/mdds/{userId}/{bundleName}/", + "backupPath": "/data/{security}/0/mdds/{userId}/backup/", + "keyPath": "/data/misc_de/0/mdds/{userId}/{bundleName}/", + "metaPath": "/data/misc_de/0/mdds/Meta/" }, { - "version": "1", - "holder": "ddms", - "path": "/data/service/{security}/0/database/ddms/{userId}/{bundleName}" + "holder": "ddms_new", + "path": "/data/service/{security}/{userId}/database/ddms/{bundleName}/", + "backupPath": "/data/service/{security}/{userId}/database/ddms/backup/", + "keyPath": "/data/service/{security}/{userId}/database/{bundleName}/", + "metaPath": "/data/service/el1/public/database/distributeddata/meta/" }, { - "version": "2", - "hodler": "caller", - "path": "/data/{type}/{security}/{userId}/{packageName}/database/{bundleName}" + "holder": "caller", + "path": "/data/{type}/{security}/{userId}/database/{bundleName}/", + "backupPath": "/data/{type}/{security}/{userId}/database/{bundleName}/backup/", + "keyPath": "/data/{type}/{security}/{userId}/database/{bundleName}/", + "metaPath": "/data/service/el1/public/database/distributeddata/meta/" } ] } diff --git a/interfaces/innerkits/distributeddata/include/types.h b/interfaces/innerkits/distributeddata/include/types.h index 3fd669735..803ee8017 100755 --- a/interfaces/innerkits/distributeddata/include/types.h +++ b/interfaces/innerkits/distributeddata/include/types.h @@ -82,6 +82,13 @@ struct KvStoreTuple { std::string userId; std::string appId; std::string storeId; + + KvStoreTuple() = default; + KvStoreTuple(std::string userId, std::string appId) : userId(std::move(userId)), appId(std::move(appId)) {} + KvStoreTuple(std::string userId, std::string appId, std::string storeId) : userId(std::move(userId)), appId(std::move(appId)), storeId(std::move(storeId)) {} + bool operator<(const KvStoreTuple &that) const { + return this->userId < that.userId || this->appId < that.appId || this->storeId < that.storeId; + } }; struct AppThreadInfo { diff --git a/interfaces/innerkits/distributeddata/include/visibility.h b/interfaces/innerkits/distributeddata/include/visibility.h index 502eda59b..1438f876c 100644 --- a/interfaces/innerkits/distributeddata/include/visibility.h +++ b/interfaces/innerkits/distributeddata/include/visibility.h @@ -13,10 +13,14 @@ * limitations under the License. */ +#ifndef OHOS_DISTRIBUTED_DATA_INTERFACE_DISTRIBUTEDDATA_INCLUDE_COMMON_VISIBILITY_H +#define OHOS_DISTRIBUTED_DATA_INTERFACE_DISTRIBUTEDDATA_INCLUDE_COMMON_VISIBILITY_H + +#ifndef API_EXPORT +#define API_EXPORT __attribute__((visibility("default"))) +#endif #ifndef KVSTORE_API -#define KVSTORE_API __attribute__ ((visibility ("default"))) +#define KVSTORE_API API_EXPORT #endif -#ifndef API_EXPORT -#define API_EXPORT __attribute__((visibility ("default"))) -#endif \ No newline at end of file +#endif // OHOS_DISTRIBUTED_DATA_INTERFACE_DISTRIBUTEDDATA_INCLUDE_COMMON_VISIBILITY_H \ No newline at end of file diff --git a/services/distributeddataservice/adapter/account/BUILD.gn b/services/distributeddataservice/adapter/account/BUILD.gn index ec49f1aa7..d79136e44 100755 --- a/services/distributeddataservice/adapter/account/BUILD.gn +++ b/services/distributeddataservice/adapter/account/BUILD.gn @@ -16,9 +16,11 @@ ohos_static_library("distributeddata_account_static") { sources = [ "src/account_delegate.cpp", "src/account_delegate_impl.cpp", + "src/user_delegate.cpp", ] include_dirs = [ + "../include/log", "../include/account", "../include/permission", "../include/utils", @@ -50,5 +52,6 @@ ohos_static_library("distributeddata_account_static") { "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core", "os_account_standard:libaccountkits", + "os_account_standard:os_account_innerkits", ] } diff --git a/services/distributeddataservice/adapter/account/src/account_delegate.cpp b/services/distributeddataservice/adapter/account/src/account_delegate.cpp index 17737f1e5..e2734df68 100755 --- a/services/distributeddataservice/adapter/account/src/account_delegate.cpp +++ b/services/distributeddataservice/adapter/account/src/account_delegate.cpp @@ -17,6 +17,8 @@ namespace OHOS { namespace DistributedKv { +const std::string AccountDelegate::MAIN_DEVICE_ACCOUNT_ID = "0"; + AccountDelegate *AccountDelegate::GetInstance() { if (getInstance_ == nullptr) { diff --git a/services/distributeddataservice/adapter/account/src/account_delegate_impl.cpp b/services/distributeddataservice/adapter/account/src/account_delegate_impl.cpp index 4c0dab823..a724c5bfa 100755 --- a/services/distributeddataservice/adapter/account/src/account_delegate_impl.cpp +++ b/services/distributeddataservice/adapter/account/src/account_delegate_impl.cpp @@ -24,6 +24,7 @@ #include #include "constant.h" #include "ohos_account_kits.h" +#include "os_account_manager.h" #include "permission_validator.h" #include "utils/crypto.h" @@ -42,13 +43,7 @@ void EventSubscriber::OnReceiveEvent(const CommonEventData &event) std::string action = want.GetAction(); ZLOGI("Want Action is %s", action.c_str()); - if (action == CommonEventSupport::COMMON_EVENT_HWID_LOGIN) { - accountEventInfo.status = AccountStatus::HARMONY_ACCOUNT_LOGIN; - } else if (action == CommonEventSupport::COMMON_EVENT_HWID_LOGOUT) { - accountEventInfo.status = AccountStatus::HARMONY_ACCOUNT_LOGOUT; - } else if (action == CommonEventSupport::COMMON_EVENT_HWID_TOKEN_INVALID) { - accountEventInfo.status = AccountStatus::HARMONY_ACCOUNT_DELETE; - } else if (action == CommonEventSupport::COMMON_EVENT_USER_REMOVED) { + if (action == CommonEventSupport::COMMON_EVENT_USER_REMOVED) { accountEventInfo.status = AccountStatus::DEVICE_ACCOUNT_DELETE; accountEventInfo.deviceAccountId = std::to_string(want.GetIntParam(CommonEventSupport::COMMON_EVENT_USER_REMOVED, -1)); @@ -93,9 +88,6 @@ void AccountDelegateImpl::SubscribeAccountEvent() { ZLOGI("Subscribe account event listener start."); MatchingSkills matchingSkills; - matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_HWID_LOGIN); - matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_HWID_LOGOUT); - matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_HWID_TOKEN_INVALID); matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_REMOVED); CommonEventSubscribeInfo info(matchingSkills); eventSubscriber_ = std::make_shared(info); @@ -149,7 +141,13 @@ std::string AccountDelegateImpl::GetCurrentAccountId(const std::string &bundleNa std::string AccountDelegateImpl::GetDeviceAccountIdByUID(int32_t uid) const { - return std::to_string(AccountSA::OhosAccountKits::GetInstance().GetDeviceAccountIdByUID(uid)); + int userId = 0; + auto ret = AccountSA::OsAccountManager::GetOsAccountLocalIdFromUid(uid, userId); + if (ret != 0) { + ZLOGE("failed get os account local id from uid, ret:%{public}d", ret); + return {}; + } + return std::to_string(userId); } void AccountDelegateImpl::NotifyAccountChanged(const AccountEventInfo &accountEventInfo) diff --git a/services/distributeddataservice/adapter/account/src/user_delegate.cpp b/services/distributeddataservice/adapter/account/src/user_delegate.cpp new file mode 100644 index 000000000..7a0f3012f --- /dev/null +++ b/services/distributeddataservice/adapter/account/src/user_delegate.cpp @@ -0,0 +1,164 @@ +/* + * 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 "user_delegate.h" + +#define LOG_TAG "UserDelegate" + +#include "communication_provider.h" +#include "log_print.h" +#include "os_account_manager.h" + +namespace OHOS::DistributedData { +using namespace OHOS::AppDistributedKv; +using namespace OHOS::AccountSA; +std::vector UserDelegate::GetAllLocalUserStatus() const +{ + auto deviceInfo = CommunicationProvider::GetInstance().GetLocalDevice(); + if (deviceInfo.deviceId.empty()) { + ZLOGE("failed to get local device id"); + return {}; + } + std::vector accounts; + auto ret = OsAccountManager::QueryAllCreatedOsAccounts(accounts); + if (ret != 0) { + ZLOGE("failed to query os accounts, ret:%{public}d", ret); + return {}; + } + std::vector userStatus; + for (const auto &account : accounts) { + userStatus.emplace_back(account.GetLocalId(), account.GetIsActived()); + } + return userStatus; +} + +std::vector UserDelegate::GetAllRemoteUserStatus(const std::string &deviceId) const +{ + if (deviceId.empty()) { + ZLOGE("error input device id"); + return {}; + } + return deviceUserMap_.Find(deviceId).second; +} + +std::vector UserDelegate::GetActiveUsers() const +{ + auto status = GetAllLocalUserStatus(); + return FilterActiveUsers(status); +} + +std::vector UserDelegate::GetActiveUsers(const std::string &deviceId) const +{ + auto status = GetAllRemoteUserStatus(deviceId); + return FilterActiveUsers(status); +} + +std::vector UserDelegate::FilterActiveUsers(std::vector &status) +{ + std::vector activeUsers; + for (const auto &item : status) { + if (!item.isActive) { + continue; + } + activeUsers.push_back(item.id); + } + return activeUsers; +} + +void UserDelegate::DeleteUsers(const std::string &deviceId) +{ + deviceUserMap_.Erase(deviceId); +} + +void UserDelegate::UpdateUsers(const DistributedData::UserMetaData &userMetaData, bool isLocal = true) +{ + deviceUserMap_[userMetaData.deviceId] = userMetaData.users; + if (!isLocal) { + ZLOGD("notify local user change only"); + return; + } + observerMap_.ForEach([](const std::string &name, const std::shared_ptr &observer) { + observer->OnUserChanged(); + return true; + }); +} + +UserDelegate &UserDelegate::GetInstance() +{ + static UserDelegate instance; + return instance; +} + +void UserDelegate::Init() +{ + osAccountSubscriber_ = std::make_shared(std::shared_ptr(this)); + if (osAccountSubscriber_ == nullptr) { + ZLOGE("failed to create os account subscriber"); + return; + } + auto ret = OsAccountManager::SubscribeOsAccount(osAccountSubscriber_); + ZLOGD("subscribe os account ret:%{public}d", ret); +} + +bool UserDelegate::SubscribeUserEvent(const std::shared_ptr &observer) +{ + if (observer == nullptr || observer->Name().empty() || observerMap_.Contains(observer->Name())) { + ZLOGD("invalid observer"); + return false; + } + return observerMap_.Insert(observer->Name(), observer); +} + +bool UserDelegate::NotifyUserEvent(const UserDelegate::UserEvent &userEvent) +{ + auto deviceInfo = CommunicationProvider::GetInstance().GetLocalDevice(); + if (deviceInfo.deviceId.empty()) { + ZLOGE("failed to get local device id"); + return {}; + } + // update all local user status + UserMetaData userMetaData; + userMetaData.deviceId = deviceInfo.deviceId; + auto localUsers = GetAllLocalUserStatus(); + for (const auto &item : localUsers) { + userMetaData.users.emplace_back(item.id, item.isActive); + } + UpdateUsers(userMetaData); + return true; +} + +UserDelegate::StoreOsAccountSubscriber::StoreOsAccountSubscriber(std::shared_ptr userDelegate) + : userDelegate_(std::move(userDelegate)) +{ +} + +void UserDelegate::StoreOsAccountSubscriber::OnAccountsChanged(const int &id) +{ + OsAccountSubscribeInfo info; + auto ret = GetSubscribeInfo(info); + if (ret != 0) { + ZLOGE("failed to get subscribe info, ret:%{public}d", ret); + return; + } + OS_ACCOUNT_SUBSCRIBE_TYPE type; + ret = info.GetOsAccountSubscribeType(type); + if (ret != 0) { + ZLOGE("failed to get subscribe info, ret:%{public}d", ret); + return; + } + userDelegate_->NotifyUserEvent( + { id, type == OS_ACCOUNT_SUBSCRIBE_TYPE::ACTIVED || type == OS_ACCOUNT_SUBSCRIBE_TYPE::ACTIVATING }); +} +} // namespace OHOS::DistributedData diff --git a/services/distributeddataservice/adapter/auth/BUILD.gn b/services/distributeddataservice/adapter/auth/BUILD.gn new file mode 100644 index 000000000..48f0737c1 --- /dev/null +++ b/services/distributeddataservice/adapter/auth/BUILD.gn @@ -0,0 +1,46 @@ +# 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. +import("//build/ohos.gni") + +ohos_static_library("distributeddata_auth_static") { + sources = [ + "src/auth_delegate.cpp", + ] + + include_dirs = [ + "../include", + "../include/autils", + "../include/communicator", + "../include/log", + "//third_party/json/single_include", + "//utils/native/base/include", + "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/app_distributeddata/include", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/framework/include", + ] + + cflags_cc = [ "-fvisibility=hidden" ] + + remove_configs = [ "//build/config/compiler:no_exceptions" ] + + configs = [ "//build/config/compiler:exceptions" ] + + deps = [ + "//utils/native/base:utils", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/framework:distributeddatasvcfwk", + ] + + external_deps = [ + "hiviewdfx_hilog_native:libhilog", + "deviceauth_standard:deviceauth_sdk", + ] +} diff --git a/services/distributeddataservice/adapter/auth/src/auth_delegate.cpp b/services/distributeddataservice/adapter/auth/src/auth_delegate.cpp new file mode 100644 index 000000000..339e88417 --- /dev/null +++ b/services/distributeddataservice/adapter/auth/src/auth_delegate.cpp @@ -0,0 +1,126 @@ +/* + * 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 "auth/auth_delegate.h" +#define LOG_TAG "AuthDelegate" + +#include "device_auth.h" +#include "device_auth_defines.h" +#include "communication_provider.h" +#include "log_print.h" + +namespace OHOS::DistributedData { + +bool AuthDelegate::CheckAccess( + const int &localUserId, const int &peerUserId, const std::string &peerDeviceId, const std::string &appId) +{ + auto group = GetGroupInfo(localUserId, appId, peerDeviceId); + if (group.groupType < 0) { + ZLOGE("failed to parse group %{public}s)", group.groupId.c_str()); + return false; + } + auto groupManager = GetGmInstance(); + if (groupManager == nullptr || groupManager->checkAccessToGroup == nullptr) { + ZLOGE("failed to get group manager"); + return {}; + } + auto ret = groupManager->checkAccessToGroup(localUserId, appId.c_str(), group.groupId.c_str()); + ZLOGD("check access to group ret:%{public}d", ret); + return ret == HC_SUCCESS; +} + +int32_t AuthDelegate::GetGroupType( + const int &localUserId, const int &peerUserId, const std::string &peerDeviceId, const std::string &appId) +{ + auto group = GetGroupInfo(localUserId, appId, peerDeviceId); + if (group.groupType < GroupType::ALL_GROUP) { + ZLOGE("failed to parse group json(%{public}d)", group.groupType); + } + return group.groupType; +} + +AuthDelegate::RelatedGroup AuthDelegate::GetGroupInfo( + int32_t localUserId, const std::string &appId, const std::string &peerDeviceId) +{ + auto groupManager = GetGmInstance(); + if (groupManager == nullptr || groupManager->getRelatedGroups == nullptr) { + ZLOGE("failed to get group manager"); + return {}; + } + char *groupInfo = nullptr; + uint32_t groupNum = 0; + auto ret = groupManager->getRelatedGroups(localUserId, appId.c_str(), peerDeviceId.c_str(), &groupInfo, &groupNum); + if (groupInfo == nullptr) { + ZLOGE("failed to get related groups, ret:%{public}d", ret); + return {}; + } + std::vector groups; + RelatedGroup::Unmarshall(groupInfo, groups); + free(groupInfo); + + // same account has priority + std::sort(groups.begin(), groups.end(), [](const RelatedGroup &group1, const RelatedGroup &group2){ + return group1.groupType > group2.groupType; + }); + if (!groups.empty()) { + return groups.front(); + } + return {}; +} + +std::vector AuthDelegate::GetTrustedDevicesByType(AUTH_GROUP_TYPE type, int32_t localUserId, const std::string &appId) { + auto groupManager = GetGmInstance(); + if (groupManager == nullptr || groupManager->getRelatedGroups == nullptr || groupManager->getTrustedDevices == nullptr) { + ZLOGE("failed to get group manager"); + return {}; + } + + char *groupsJson = nullptr; + uint32_t groupNum = 0; + auto ret = groupManager->getJoinedGroups(localUserId, appId.c_str(), type, &groupsJson, &groupNum); + if (groupsJson == nullptr) { + ZLOGE("failed to get joined groups, ret:%{public}d", ret); + return {}; + } + std::vector groups; + RelatedGroup::Unmarshall(groupsJson, groups); + free(groupsJson); + + std::vector trustedDevices; + for (const auto &group : groups) { + if (group.groupType != type) { + continue; + } + char *devicesJson = nullptr; + uint32_t devNum = 0; + ret = groupManager->getTrustedDevices(localUserId, appId.c_str(), group.groupId.c_str(), &devicesJson, &devNum); + if (devicesJson == nullptr) { + ZLOGE("failed to get trusted devicesJson, ret:%{public}d", ret); + return {}; + } + std::vector devices; + TrustDevice::Unmarshall(devicesJson, devices); + free(devicesJson); + for (const auto &item : devices) { + auto &provider = AppDistributedKv::CommunicationProvider::GetInstance(); + auto networkId = provider.ToNodeId(item.authId); + auto uuid = provider.GetUuidByNodeId(networkId); + trustedDevices.push_back(uuid); + } + } + + return trustedDevices; +} +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp b/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp index 797a27f76..a115a2c22 100755 --- a/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp +++ b/services/distributeddataservice/adapter/communicator/src/process_communicator_impl.cpp @@ -187,5 +187,37 @@ void ProcessCommunicatorImpl::OnDeviceChanged(const DeviceInfo &info, const Devi devInfo.identifier = info.deviceId; onDeviceChangeHandler_(devInfo, (type == DeviceChangeType::DEVICE_ONLINE)); } -} // namespace AppDistributedKv -} // namespace OHOS + +void ProcessCommunicatorImpl::SetHeaderHandler(const GetExtHeaderHandleFunction &handler) +{ + getExtHeaderHandleFunction_ = handler; +} + +std::shared_ptr ProcessCommunicatorImpl::GetExtendHeaderHandle(const ExtendInfo &info) +{ + if (getExtHeaderHandleFunction_ != nullptr) { + return getExtHeaderHandleFunction_(info); + } + return {}; +} + +DBStatus ProcessCommunicatorImpl::CheckAndGetDataHeadInfo( + const uint8_t *data, uint32_t dataLen, uint32_t &headLen, std::vector &users) +{ + if (getExtHeaderHandleFunction_ == nullptr) { + ZLOGE("header handler creator not registered"); + return DB_ERROR; + } + auto handler = getExtHeaderHandleFunction_({}); + if (handler == nullptr) { + ZLOGE("failed to get header handler"); + return DB_ERROR; + } + auto ret = handler->ParseHeadData(data, dataLen, headLen, users); + if (users.empty()) { + return NO_PERMISSION; + } + return ret ? DBStatus::OK : DBStatus::INVALID_FORMAT; +} +} // namespace AppDistributedKv +} // namespace OHOS diff --git a/services/distributeddataservice/adapter/include/account/account_delegate.h b/services/distributeddataservice/adapter/include/account/account_delegate.h index 617e56f56..9675873f6 100755 --- a/services/distributeddataservice/adapter/include/account/account_delegate.h +++ b/services/distributeddataservice/adapter/include/account/account_delegate.h @@ -53,6 +53,8 @@ public: KVSTORE_API virtual std::string GetDeviceAccountIdByUID(int32_t uid) const = 0; KVSTORE_API virtual void SubscribeAccountEvent() = 0; KVSTORE_API static AccountDelegate *GetInstance(); + const static std::string MAIN_DEVICE_ACCOUNT_ID; + private: using BaseInstance = AccountDelegate *(*)(); static BaseInstance getInstance_; diff --git a/services/distributeddataservice/adapter/include/account/user_delegate.h b/services/distributeddataservice/adapter/include/account/user_delegate.h new file mode 100644 index 000000000..2981e99f0 --- /dev/null +++ b/services/distributeddataservice/adapter/include/account/user_delegate.h @@ -0,0 +1,66 @@ +/* + * 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. + */ + +#ifndef SDB_USER_DELEGATE_H +#define SDB_USER_DELEGATE_H + +#include + +#include "visibility.h" +#include "concurrent_map.h" +#include "metadata/user_meta_data.h" +#include "os_account_manager.h" + +namespace OHOS::DistributedData { +class API_EXPORT UserDelegate { +public: + class StoreOsAccountSubscriber : public AccountSA::OsAccountSubscriber { + public: + StoreOsAccountSubscriber(std::shared_ptr userDelegate); + void OnAccountsChanged(const int &id) override; + + private: + std::shared_ptr userDelegate_; + }; + struct UserEvent { + int id; + bool isActive; + }; + class API_EXPORT Observer { + public: + API_EXPORT virtual void OnUserChanged() = 0; + API_EXPORT virtual std::string Name() = 0; + }; + API_EXPORT static UserDelegate &GetInstance(); + API_EXPORT void Init(); + API_EXPORT std::vector GetAllLocalUserStatus() const; + API_EXPORT std::vector GetAllRemoteUserStatus(const std::string &deviceId) const; + API_EXPORT std::vector GetActiveUsers() const; + API_EXPORT std::vector GetActiveUsers(const std::string &deviceId) const; + API_EXPORT void UpdateUsers(const DistributedData::UserMetaData &userMetaData, bool isLocal); + API_EXPORT void DeleteUsers(const std::string &deviceId); + API_EXPORT bool SubscribeUserEvent(const std::shared_ptr &observer); + +private: + bool NotifyUserEvent(const UserEvent &userEvent); + static std::vector FilterActiveUsers(std::vector &status); + + ConcurrentMap> deviceUserMap_; + ConcurrentMap> observerMap_{}; + std::shared_ptr osAccountSubscriber_; +}; +} // namespace OHOS::DistributedData + +#endif //SDB_USER_DELEGATE_H diff --git a/services/distributeddataservice/adapter/include/account/visibility.h b/services/distributeddataservice/adapter/include/account/visibility.h index 2ffb65244..b4a5c7547 100644 --- a/services/distributeddataservice/adapter/include/account/visibility.h +++ b/services/distributeddataservice/adapter/include/account/visibility.h @@ -13,15 +13,10 @@ * limitations under the License. */ -#ifndef KVSTORE_API -#ifdef _WIN32 - #ifdef DB_DLL_EXPORT - #define KVSTORE_API __declspec(dllexport) - #else - #define KVSTORE_API - #endif -#else - #define KVSTORE_API __attribute__ ((visibility ("default"))) +#ifndef API_EXPORT +#define API_EXPORT __attribute__((visibility("default"))) #endif +#ifndef KVSTORE_API +#define KVSTORE_API API_EXPORT #endif diff --git a/services/distributeddataservice/adapter/include/auth/auth_delegate.h b/services/distributeddataservice/adapter/include/auth/auth_delegate.h new file mode 100644 index 000000000..2541a201b --- /dev/null +++ b/services/distributeddataservice/adapter/include/auth/auth_delegate.h @@ -0,0 +1,77 @@ +/* + * 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. + */ + +#ifndef SDB_AUTH_DELEGATE_H +#define SDB_AUTH_DELEGATE_H + +#include + +#include "serializable/serializable.h" +namespace OHOS::DistributedData { +enum AUTH_GROUP_TYPE { + PEER_TO_PEER_GROUP, + IDENTICAL_ACCOUNT_GROUP +}; +class API_EXPORT AuthDelegate { +public: + API_EXPORT static bool CheckAccess( + const int &localUserId, const int &peerUserId, const std::string &peerDeviceId, const std::string &appId); + API_EXPORT static int32_t GetGroupType( + const int &localUserId, const int &peerUserId, const std::string &peerDeviceId, const std::string &appId); + API_EXPORT static std::vector GetTrustedDevicesByType(AUTH_GROUP_TYPE type, int32_t localUserId, const std::string &appId); +private: + struct RelatedGroup final : public Serializable { + int32_t groupType = -1; + std::string groupId; + RelatedGroup() {}; + ~RelatedGroup() {} + RelatedGroup(const RelatedGroup &) = default; + RelatedGroup &operator=(const RelatedGroup &) = default; + bool Marshal(Serializable::json &node) const override + { + SetValue(node[GET_NAME(groupType)], groupType); + SetValue(node[GET_NAME(groupId)], groupId); + return true; + } + + bool Unmarshal(const Serializable::json &node) override + { + GetValue(node, GET_NAME(groupType), groupType); + GetValue(node, GET_NAME(groupId), groupId); + return true; + } + }; + + struct TrustDevice final : public Serializable { + std::string authId; // udid + TrustDevice() = default; + TrustDevice(const TrustDevice &) = default; + TrustDevice &operator=(const TrustDevice &) = default; + bool Marshal(Serializable::json &node) const override + { + SetValue(node[GET_NAME(authId)], authId); + return true; + } + + bool Unmarshal(const Serializable::json &node) override + { + GetValue(node, GET_NAME(authId), authId); + return true; + } + }; + static RelatedGroup GetGroupInfo(int32_t localUserId, const std::string &appId, const std::string &peerDeviceId); +}; +} // namespace OHOS::DistributedData +#endif //SDB_AUTH_DELEGATE_H diff --git a/services/distributeddataservice/adapter/include/autils/visibility.h b/services/distributeddataservice/adapter/include/autils/visibility.h index 10bc02f92..d084342a8 100644 --- a/services/distributeddataservice/adapter/include/autils/visibility.h +++ b/services/distributeddataservice/adapter/include/autils/visibility.h @@ -12,8 +12,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +#ifndef API_EXPORT +#define API_EXPORT __attribute__((visibility("default"))) +#endif #ifndef KVSTORE_API -#define KVSTORE_API __attribute__ ((visibility ("default"))) +#define KVSTORE_API API_EXPORT #endif diff --git a/services/distributeddataservice/adapter/include/broadcaster/visibility.h b/services/distributeddataservice/adapter/include/broadcaster/visibility.h index 10bc02f92..b4a5c7547 100644 --- a/services/distributeddataservice/adapter/include/broadcaster/visibility.h +++ b/services/distributeddataservice/adapter/include/broadcaster/visibility.h @@ -13,7 +13,10 @@ * limitations under the License. */ +#ifndef API_EXPORT +#define API_EXPORT __attribute__((visibility("default"))) +#endif #ifndef KVSTORE_API -#define KVSTORE_API __attribute__ ((visibility ("default"))) +#define KVSTORE_API API_EXPORT #endif diff --git a/services/distributeddataservice/adapter/include/communicator/extend_head_handler.h b/services/distributeddataservice/adapter/include/communicator/extend_head_handler.h new file mode 100644 index 000000000..d2aef567e --- /dev/null +++ b/services/distributeddataservice/adapter/include/communicator/extend_head_handler.h @@ -0,0 +1,30 @@ +/* + * 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. + */ + +#ifndef SDB_EXTEND_HEAD_HANDLER_H +#define SDB_EXTEND_HEAD_HANDLER_H +#include +#include "iprocess_communicator.h" + +namespace OHOS::DistributedData { +class RouteHeadHandler : public DistributedDB::ExtendHeaderHandle { +public: + DistributedDB::DBStatus GetHeadDataSize(uint32_t &headSize) override = 0; + DistributedDB::DBStatus FillHeadData(uint8_t *data, uint32_t headSize, uint32_t totalLen) override = 0; + + virtual bool ParseHeadData(const uint8_t *data, uint32_t totalLen, uint32_t &headSize, std::vector &users) = 0; +}; +} // namespace OHOS::DistributedData +#endif //SDB_EXTEND_HEAD_HANDLER_H diff --git a/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h b/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h index a4bee389d..851b7fc85 100755 --- a/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h +++ b/services/distributeddataservice/adapter/include/communicator/process_communicator_impl.h @@ -19,6 +19,7 @@ #include #include "iprocess_communicator.h" #include "communication_provider.h" +#include "extend_head_handler.h" namespace OHOS { namespace AppDistributedKv { @@ -30,6 +31,8 @@ public: using OnDeviceChange = DistributedDB::OnDeviceChange; using OnDataReceive = DistributedDB::OnDataReceive; using DeviceInfos = DistributedDB::DeviceInfos; + using GetExtHeaderHandleFunction = std::function(const DistributedDB::ExtendInfo &info)>; + KVSTORE_API ProcessCommunicatorImpl(); KVSTORE_API ~ProcessCommunicatorImpl() override; @@ -45,6 +48,12 @@ public: KVSTORE_API DeviceInfos GetLocalDeviceInfos() override; KVSTORE_API std::vector GetRemoteOnlineDeviceInfosList() override; KVSTORE_API bool IsSameProcessLabelStartedOnPeerDevice(const DeviceInfos &peerDevInfo) override; + + KVSTORE_API void SetHeaderHandler(const GetExtHeaderHandleFunction &handler); + KVSTORE_API std::shared_ptr GetExtendHeaderHandle(const DistributedDB::ExtendInfo &info) override; + KVSTORE_API DBStatus CheckAndGetDataHeadInfo( + const uint8_t *data, uint32_t dataLen, uint32_t &headLen, std::vector &users) override; + private: void OnMessage(const DeviceInfo &info, const uint8_t *ptr, const int size, const PipeInfo &pipeInfo) const override; @@ -53,6 +62,8 @@ private: std::string thisProcessLabel_; OnDeviceChange onDeviceChangeHandler_; OnDataReceive onDataReceiveHandler_; + GetExtHeaderHandleFunction getExtHeaderHandleFunction_; // ext header handler creator + mutable std::mutex onDeviceChangeMutex_; mutable std::mutex onDataReceiveMutex_; diff --git a/services/distributeddataservice/adapter/include/dfx/visibility.h b/services/distributeddataservice/adapter/include/dfx/visibility.h index 10bc02f92..19c057c44 100644 --- a/services/distributeddataservice/adapter/include/dfx/visibility.h +++ b/services/distributeddataservice/adapter/include/dfx/visibility.h @@ -13,7 +13,9 @@ * limitations under the License. */ +#ifndef API_EXPORT +#define API_EXPORT __attribute__((visibility("default"))) +#endif #ifndef KVSTORE_API -#define KVSTORE_API __attribute__ ((visibility ("default"))) +#define KVSTORE_API API_EXPORT #endif - diff --git a/services/distributeddataservice/adapter/include/log/visibility.h b/services/distributeddataservice/adapter/include/log/visibility.h index 10bc02f92..b4a5c7547 100644 --- a/services/distributeddataservice/adapter/include/log/visibility.h +++ b/services/distributeddataservice/adapter/include/log/visibility.h @@ -13,7 +13,10 @@ * limitations under the License. */ +#ifndef API_EXPORT +#define API_EXPORT __attribute__((visibility("default"))) +#endif #ifndef KVSTORE_API -#define KVSTORE_API __attribute__ ((visibility ("default"))) +#define KVSTORE_API API_EXPORT #endif diff --git a/services/distributeddataservice/app/BUILD.gn b/services/distributeddataservice/app/BUILD.gn index b344d3f3d..3105911f4 100755 --- a/services/distributeddataservice/app/BUILD.gn +++ b/services/distributeddataservice/app/BUILD.gn @@ -42,6 +42,8 @@ config("module_private_config") { "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/bootstrap/include", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/config/include", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/directory/include", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/app/src/key", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/app/src/session_manager", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/framework/include", "//foundation/distributeddatamgr/distributeddatamgr/frameworks/innerkitsimpl/rdb/include", "//foundation/distributeddatamgr/distributeddatamgr/frameworks/innerkitsimpl/rdb/src", @@ -78,6 +80,7 @@ ohos_shared_library("distributeddataservice") { "src/device_kvstore_impl.cpp", "src/device_kvstore_observer_impl.cpp", "src/device_kvstore_resultset_impl.cpp", + "src/key/key_manager.cpp", "src/kvstore_account_observer.cpp", "src/kvstore_app_accessor.cpp", "src/kvstore_app_manager.cpp", @@ -89,9 +92,13 @@ ohos_shared_library("distributeddataservice") { "src/kvstore_snapshot_impl.cpp", "src/kvstore_sync_manager.cpp", "src/kvstore_user_manager.cpp", + "src/kvstore_user_observer.cpp", "src/query_helper.cpp", "src/security/security.cpp", "src/security/sensitive.cpp", + "src/session_manager/route_head_handler.cpp", + "src/session_manager/session_manager.cpp", + "src/session_manager/upgrade_manager.cpp", "src/single_kvstore_impl.cpp", ] @@ -131,6 +138,7 @@ ohos_shared_library("distributeddataservice") { "hiviewdfx_hilog_native:libhilog", "huks:libhukssdk", "ipc:ipc_core", + "os_account_standard:os_account_innerkits", "permission_standard:libpermissionsdk_standard", "power_manager_native:powermgr_client", "safwk:system_ability_fwk", diff --git a/services/distributeddataservice/app/src/backup_handler.cpp b/services/distributeddataservice/app/src/backup_handler.cpp index 80202b83e..96874e60b 100755 --- a/services/distributeddataservice/app/src/backup_handler.cpp +++ b/services/distributeddataservice/app/src/backup_handler.cpp @@ -23,6 +23,7 @@ #include "account_delegate.h" #include "battery_info.h" #include "battery_srv_client.h" +#include "directory_manager.h" #include "constant.h" #include "kv_store_delegate_manager.h" #include "kv_scheduler.h" @@ -32,9 +33,10 @@ #include "power_mgr_client.h" #include "time_utils.h" #include "utils/crypto.h" - +#include "metadata/meta_data.h" namespace OHOS::DistributedKv { using json = nlohmann::json; +using namespace OHOS::DistributedData; BackupHandler::BackupHandler(IKvStoreDataService *kvStoreDataService) { @@ -68,7 +70,7 @@ void BackupHandler::BackSchedule() continue; } - KvStoreType type = entry.second.kvStoreMetaData.kvStoreType; + KvStoreType type = static_cast(entry.second.kvStoreMetaData.kvStoreType); if (type == KvStoreType::MULTI_VERSION) { MultiKvStoreBackup(entry.second); } else if (type == KvStoreType::SINGLE_VERSION) { @@ -95,13 +97,11 @@ void BackupHandler::SingleKvStoreBackup(const MetaData &metaData) dbOption.createDirByStoreIdOnly = true; dbOption.secOption = KvStoreAppManager::ConvertSecurity(metaData.kvStoreMetaData.securityLevel); - auto *delegateMgr = new DistributedDB::KvStoreDelegateManager(metaData.kvStoreMetaData.appId, - AccountDelegate::GetInstance()->GetCurrentAccountId(metaData.kvStoreMetaData.bundleName)); + auto *delegateMgr = new DistributedDB::KvStoreDelegateManager( + metaData.kvStoreMetaData.appId, metaData.kvStoreMetaData.deviceAccountId); + std::string storePath = DirectoryManager::GetInstance().GetStorePath(metaData.kvStoreMetaData); + delegateMgr->SetKvStoreConfig({ storePath }); - std::string appDataStoragePath = KvStoreAppManager::GetDataStoragePath(metaData.kvStoreMetaData.deviceAccountId, - metaData.kvStoreMetaData.bundleName, backupPara.pathType); - DistributedDB::KvStoreConfig kvStoreConfig = {appDataStoragePath}; - delegateMgr->SetKvStoreConfig(kvStoreConfig); std::function fun = [&](DistributedDB::DBStatus status, DistributedDB::KvStoreNbDelegate *delegate) { auto del = std::shared_ptr(delegateMgr); @@ -152,12 +152,9 @@ void BackupHandler::MultiKvStoreBackup(const MetaData &metaData) option.createDirByStoreIdOnly = true; auto *delegateMgr = new DistributedDB::KvStoreDelegateManager(metaData.kvStoreMetaData.appId, - AccountDelegate::GetInstance()->GetCurrentAccountId(metaData.kvStoreMetaData.bundleName)); - std::string appDataStoragePath = KvStoreAppManager::GetDataStoragePath(metaData.kvStoreMetaData.deviceAccountId, - metaData.kvStoreMetaData.bundleName, backupPara.pathType); - DistributedDB::KvStoreConfig kvStoreConfig; - kvStoreConfig.dataDir = appDataStoragePath; - delegateMgr->SetKvStoreConfig(kvStoreConfig); + metaData.kvStoreMetaData.deviceAccountId); + std::string storePath = DirectoryManager::GetInstance().GetStorePath(metaData.kvStoreMetaData); + delegateMgr->SetKvStoreConfig({ storePath }); std::function fun = [&](DistributedDB::DBStatus status, DistributedDB::KvStoreDelegate *delegate) { auto del = std::shared_ptr(delegateMgr); @@ -189,31 +186,32 @@ void BackupHandler::MultiKvStoreBackup(const MetaData &metaData) bool BackupHandler::InitBackupPara(const MetaData &metaData, BackupPara &backupPara) { BackupPara backupParameter; - auto pathType = KvStoreAppManager::ConvertPathType( - metaData.kvStoreMetaData.uid, metaData.kvStoreMetaData.bundleName, metaData.kvStoreMetaData.securityLevel); - if (!ForceCreateDirectory(BackupHandler::GetBackupPath(metaData.kvStoreMetaData.deviceAccountId, pathType))) { + std::string backupPath = BackupHandler::GetBackupPath(metaData.kvStoreMetaData); + if (!ForceCreateDirectory(backupPath)) { ZLOGE("MultiKvStoreBackup backup create directory failed."); return false; } DistributedDB::CipherPassword password; - const std::vector &secretKey = metaData.secretKeyMetaData.secretKey; + const std::vector &secretKey = metaData.secretKeyMetaData.sKey; if (password.SetValue(secretKey.data(), secretKey.size()) != DistributedDB::CipherPassword::OK) { ZLOGE("Set secret key value failed. len is (%d)", int32_t(secretKey.size())); return false; } - std::initializer_list backList = {metaData.kvStoreMetaData.userId, "_", + std::initializer_list backList = {metaData.kvStoreMetaData.deviceAccountId, "_", metaData.kvStoreMetaData.appId, "_", metaData.kvStoreMetaData.storeId}; std::string backupName = Constant::Concatenate(backList); std::initializer_list backFullList = { - BackupHandler::GetBackupPath(metaData.kvStoreMetaData.deviceAccountId, pathType), "/", + backupPath, "/", GetHashedBackupName(backupName)}; auto backupFullName = Constant::Concatenate(backFullList); std::initializer_list backNameList = {backupFullName, ".", "backup"}; auto backupBackFullName = Constant::Concatenate(backNameList); - backupParameter.pathType = pathType; + backupParameter.pathType = DirWorker::ConvertPathType(metaData.kvStoreMetaData.uid, + metaData.kvStoreMetaData.bundleName, + metaData.kvStoreMetaData.securityLevel); backupParameter.password = password; backupParameter.backupFullName = backupFullName; backupParameter.backupBackFullName = backupBackFullName; @@ -229,27 +227,22 @@ bool BackupHandler::SingleKvStoreRecover(MetaData &metaData, DistributedDB::KvSt ZLOGE("SingleKvStoreRecover failed, delegate is null."); return false; } - auto pathType = KvStoreAppManager::ConvertPathType( - metaData.kvStoreMetaData.uid, metaData.kvStoreMetaData.bundleName, metaData.kvStoreMetaData.securityLevel); - if (!BackupHandler::FileExists(BackupHandler::GetBackupPath(metaData.kvStoreMetaData.deviceAccountId, pathType))) { + std::string backupPath = BackupHandler::GetBackupPath(metaData.kvStoreMetaData); + if (!BackupHandler::FileExists(backupPath)) { ZLOGE("SingleKvStoreRecover failed, backupDir_ file is not exist."); return false; } DistributedDB::CipherPassword password; - const std::vector &secretKey = metaData.secretKeyMetaData.secretKey; + const std::vector &secretKey = metaData.secretKeyMetaData.sKey; if (password.SetValue(secretKey.data(), secretKey.size()) != DistributedDB::CipherPassword::OK) { ZLOGE("Set secret key failed."); return false; } - std::string backupName = Constant::Concatenate( - {metaData.kvStoreMetaData.userId, "_", metaData.kvStoreMetaData.appId, "_", - metaData.kvStoreMetaData.storeId}); - auto backupFullName = Constant::Concatenate({ - BackupHandler::GetBackupPath(metaData.kvStoreMetaData.deviceAccountId, pathType), "/", - GetHashedBackupName(backupName) - }); + std::string backupName = Constant::Concatenate({ metaData.kvStoreMetaData.deviceAccountId, "_", + metaData.kvStoreMetaData.appId, "_", metaData.kvStoreMetaData.storeId }); + auto backupFullName = Constant::Concatenate({ backupPath, "/", GetHashedBackupName(backupName) }); DistributedDB::DBStatus dbStatus = delegate->Import(backupFullName, password); if (dbStatus == DistributedDB::DBStatus::OK) { ZLOGI("SingleKvStoreRecover success."); @@ -259,36 +252,30 @@ bool BackupHandler::SingleKvStoreRecover(MetaData &metaData, DistributedDB::KvSt return false; } -bool BackupHandler::MultiKvStoreRecover(MetaData &metaData, - DistributedDB::KvStoreDelegate *delegate) +bool BackupHandler::MultiKvStoreRecover(MetaData &metaData, DistributedDB::KvStoreDelegate *delegate) { ZLOGI("start."); if (delegate == nullptr) { ZLOGE("MultiKvStoreRecover failed, delegate is null."); return false; } - auto pathType = KvStoreAppManager::ConvertPathType( - metaData.kvStoreMetaData.uid, metaData.kvStoreMetaData.bundleName, metaData.kvStoreMetaData.securityLevel); - if (!BackupHandler::FileExists(BackupHandler::GetBackupPath(metaData.kvStoreMetaData.deviceAccountId, pathType))) { + if (!BackupHandler::FileExists(BackupHandler::GetBackupPath(metaData.kvStoreMetaData))) { ZLOGE("MultiKvStoreRecover failed, backupDir_ file is not exist."); return false; } ZLOGI("MultiKvStoreRecover start."); DistributedDB::CipherPassword password; - const std::vector &secretKey = metaData.secretKeyMetaData.secretKey; + const std::vector &secretKey = metaData.secretKeyMetaData.sKey; if (password.SetValue(secretKey.data(), secretKey.size()) != DistributedDB::CipherPassword::OK) { ZLOGE("Set secret key failed."); return false; } - std::string backupName = Constant::Concatenate( - {metaData.kvStoreMetaData.userId, "_", metaData.kvStoreMetaData.appId, "_", - metaData.kvStoreMetaData.storeId}); - auto backupFullName = Constant::Concatenate({ - BackupHandler::GetBackupPath(metaData.kvStoreMetaData.deviceAccountId, pathType), "/", - GetHashedBackupName(backupName) - }); + std::string backupName = Constant::Concatenate({ metaData.kvStoreMetaData.deviceAccountId, "_", + metaData.kvStoreMetaData.appId, "_", metaData.kvStoreMetaData.storeId }); + auto backupFullName = Constant::Concatenate( + { BackupHandler::GetBackupPath(metaData.kvStoreMetaData), "/", GetHashedBackupName(backupName) }); DistributedDB::DBStatus dbStatus = delegate->Import(backupFullName, password); if (dbStatus == DistributedDB::DBStatus::OK) { ZLOGI("MultiKvStoreRecover success."); @@ -298,25 +285,9 @@ bool BackupHandler::MultiKvStoreRecover(MetaData &metaData, return false; } -std::string BackupHandler::backupDirCe_; -std::string BackupHandler::backupDirDe_; -const std::string &BackupHandler::GetBackupPath(const std::string &deviceAccountId, int pathType) +std::string BackupHandler::GetBackupPath(const StoreMetaData &metaData) { - if (pathType == KvStoreAppManager::PATH_DE) { - if (backupDirDe_.empty()) { - backupDirDe_ = Constant::Concatenate({ Constant::ROOT_PATH_DE, "/", Constant::SERVICE_NAME, "/", - deviceAccountId, "/", Constant::GetDefaultHarmonyAccountName(), - "/", "backup" }); - } - return backupDirDe_; - } else { - if (backupDirCe_.empty()) { - backupDirCe_ = Constant::Concatenate({ Constant::ROOT_PATH_CE, "/", Constant::SERVICE_NAME, "/", - deviceAccountId, "/", Constant::GetDefaultHarmonyAccountName(), - "/", "backup" }); - } - return backupDirCe_; - } + return DirectoryManager::GetInstance().GetStoreBackupPath(metaData); } bool BackupHandler::RenameFile(const std::string &oldPath, const std::string &newPath) diff --git a/services/distributeddataservice/app/src/backup_handler.h b/services/distributeddataservice/app/src/backup_handler.h index a8f71aec5..f4653e421 100755 --- a/services/distributeddataservice/app/src/backup_handler.h +++ b/services/distributeddataservice/app/src/backup_handler.h @@ -16,13 +16,16 @@ #ifndef DISTRIBUTEDDATAMGR_BACKUP_HANDLER_H #define DISTRIBUTEDDATAMGR_BACKUP_HANDLER_H -#include "kv_store_nb_delegate.h" -#include "kv_store_delegate.h" -#include "types.h" -#include "kv_scheduler.h" -#include "kvstore_meta_manager.h" #include "ikvstore_data_service.h" +#include "kv_scheduler.h" +#include "kv_store_delegate.h" +#include "kv_store_nb_delegate.h" #include "kvstore_app_manager.h" +#include "kvstore_meta_manager.h" +#include "metadata/meta_data.h" +#include "metadata/store_meta_data.h" +#include "types.h" +#include "directory_manager.h" namespace OHOS::DistributedKv { class BackupHandler { @@ -31,29 +34,26 @@ public: BackupHandler(); ~BackupHandler(); void BackSchedule(); - void SingleKvStoreBackup(const MetaData &metaData); - void MultiKvStoreBackup(const MetaData &metaData); - bool SingleKvStoreRecover(MetaData &metaData, DistributedDB::KvStoreNbDelegate *delegate); - bool MultiKvStoreRecover(MetaData &metaData, DistributedDB::KvStoreDelegate *delegate); + void SingleKvStoreBackup(const DistributedData::MetaData &metaData); + void MultiKvStoreBackup(const DistributedData::MetaData &metaData); + bool SingleKvStoreRecover(DistributedData::MetaData &metaData, DistributedDB::KvStoreNbDelegate *delegate); + bool MultiKvStoreRecover(DistributedData::MetaData &metaData, DistributedDB::KvStoreDelegate *delegate); - static const std::string &GetBackupPath(const std::string &deviceAccountId, int pathType); + static std::string GetBackupPath(const DistributedData::StoreMetaData &metaData); static bool RenameFile(const std::string &oldPath, const std::string &newPath); static bool RemoveFile(const std::string &path); static bool FileExists(const std::string &path); static std::string GetHashedBackupName(const std::string &bundleName); struct BackupPara { - KvStoreAppManager::PathType pathType; + DistributedData::PathType pathType; DistributedDB::CipherPassword password; std::string backupFullName; std::string backupBackFullName; }; private: bool CheckNeedBackup(); - bool InitBackupPara(const MetaData &metaData, BackupPara &backupPara); - - static std::string backupDirCe_; - static std::string backupDirDe_; + bool InitBackupPara(const DistributedData::MetaData &metaData, BackupPara &backupPara); KvScheduler scheduler_ {}; int64_t backupSuccessTime_ = 0; diff --git a/services/distributeddataservice/app/src/key/key_manager.cpp b/services/distributeddataservice/app/src/key/key_manager.cpp new file mode 100644 index 000000000..4232c413a --- /dev/null +++ b/services/distributeddataservice/app/src/key/key_manager.cpp @@ -0,0 +1,398 @@ +/* + * Copyright (c) 2021 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. + */ +#define LOG_TAG "KeyManager" +#include "key_manager.h" + +#include +#include +#include + +#include "directory_ex.h" +#include "directory_manager.h" +#include "directory_utils.h" +#include "file_ex.h" +#include "hks_api.h" +#include "hks_param.h" +#include "kvstore_meta_manager.h" +#include "log_print.h" + +namespace OHOS::DistributedData { +using namespace std::chrono; +using json = nlohmann::json; +using namespace DistributedKv; + +std::vector KeyManager::vecRootKeyAlias_ = std::vector(ROOT_KEY_ALIAS, ROOT_KEY_ALIAS + strlen(ROOT_KEY_ALIAS)); +std::vector KeyManager::vecNonce_ = std::vector(HKS_BLOB_TYPE_NONCE, HKS_BLOB_TYPE_NONCE + strlen(HKS_BLOB_TYPE_NONCE)); +std::vector KeyManager::vecAad_ = std::vector(HKS_BLOB_TYPE_AAD, HKS_BLOB_TYPE_AAD + strlen(HKS_BLOB_TYPE_AAD)); +Status KeyManager::GenerateRootKey() +{ + ZLOGI("GenerateRootKey."); + struct HksBlob rootKeyName = { static_cast(vecRootKeyAlias_.size()), &(vecRootKeyAlias_[0]) }; + struct HksParamSet *paramSet = nullptr; + int32_t ret = HksInitParamSet(¶mSet); + if (ret != HKS_SUCCESS) { + ZLOGE("HksInitParamSet() failed with error %{public}d", ret); + return Status::ERROR; + } + + struct HksParam genKeyParams[] = { + { .tag = HKS_TAG_ALGORITHM, { .uint32Param = HKS_ALG_AES } }, + { .tag = HKS_TAG_KEY_SIZE, { .uint32Param = HKS_AES_KEY_SIZE_256 } }, + { .tag = HKS_TAG_PURPOSE, { .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT } }, + { .tag = HKS_TAG_DIGEST, { .uint32Param = 0 } }, + { .tag = HKS_TAG_PADDING, { .uint32Param = HKS_PADDING_NONE } }, + { .tag = HKS_TAG_BLOCK_MODE, { .uint32Param = HKS_MODE_GCM } }, + }; + + ret = HksAddParams(paramSet, genKeyParams, sizeof(genKeyParams) / sizeof(genKeyParams[0])); + if (ret != HKS_SUCCESS) { + ZLOGE("HksAddParams failed with error %{public}d", ret); + HksFreeParamSet(¶mSet); + return Status::ERROR; + } + + ret = HksBuildParamSet(¶mSet); + if (ret != HKS_SUCCESS) { + ZLOGE("HksBuildParamSet failed with error %{public}d", ret); + HksFreeParamSet(¶mSet); + return Status::ERROR; + } + + ret = HksGenerateKey(&rootKeyName, paramSet, nullptr); + if (ret != HKS_SUCCESS) { + ZLOGE("HksGenerateKey failed with error %{public}d", ret); + HksFreeParamSet(¶mSet); + return Status::ERROR; + } + HksFreeParamSet(¶mSet); + + DistributedDB::Key dbKey = + std::vector(ROOT_KEY_GENERATED, ROOT_KEY_GENERATED + sizeof(ROOT_KEY_GENERATED)); + DistributedDB::Value dbValue{ ROOT_KEY_ALIAS, ROOT_KEY_ALIAS + strlen(ROOT_KEY_ALIAS) }; + auto dbRet = KvStoreMetaManager::GetInstance().CheckUpdateServiceMeta(dbKey, UPDATE_LOCAL, dbValue); + if (dbRet != Status::SUCCESS) { + ZLOGE("CheckUpdateServiceMeta failed."); + return dbRet; + } + + ZLOGI("GenerateRootKey Succeed."); + return Status::SUCCESS; +} + +Status KeyManager::CheckRootKeyExist() +{ + ZLOGI("GenerateRootKey."); + DistributedDB::Key dbKey = + std::vector(ROOT_KEY_GENERATED, ROOT_KEY_GENERATED + strlen(ROOT_KEY_GENERATED)); + DistributedDB::Value dbValue; + auto ret = KvStoreMetaManager::GetInstance().CheckUpdateServiceMeta(dbKey, CHECK_EXIST_LOCAL, dbValue); + if (ret == Status::SUCCESS) { + ZLOGI("root key exist."); + return Status::SUCCESS; + } + return Status::ERROR; +} +SecretKey KeyManager::GetSecretKey(const StoreMetaData &meta, const std::string &key, Status &status) +{ + SecretKey secretKey; + auto metaSecretKey = KvStoreMetaManager::GetMetaKey(meta.deviceAccountId, "default", meta.appId, meta.storeId, + key); + std::string keyName = (meta.kvStoreType == MULTI_VERSION) ? KvStoreImpl::KeyName() : SingleKvStoreImpl::KeyName(); + auto secretKeyFile = GetSecretSingleKeyFile(meta); + status = GetSecretKeyFromMeta(metaSecretKey, secretKey); + ZLOGI("Getting secret key"); + if (status != Status::SUCCESS) { + ZLOGI("recover from file!"); + status = RecoverSecretKeyFromFile(secretKeyFile, metaSecretKey, secretKey); + } + if (status != Status::SUCCESS) { + secretKey.data = Crypto::Random(32); // 32 is key length + WriteSecretKeyToFile(secretKeyFile, secretKey.data); + status = WriteSecretKeyToMeta(metaSecretKey, secretKey.data); + } else if (secretKey.IsEmpty()) { + ZLOGW("recover failed"); + status = Status::CRYPT_ERROR; + } + return secretKey; +} +Status KeyManager::GetSecretKeyFromMeta(const std::vector &metaSecretKey, SecretKey &key) +{ + const DistributedDB::Key &dbKey = metaSecretKey; + DistributedDB::Value dbValue; + auto dbStatus = KvStoreMetaManager::GetInstance().CheckUpdateServiceMeta(dbKey, CHECK_EXIST_LOCAL, dbValue); + if (dbStatus != Status::SUCCESS) { + return Status::DB_ERROR; + } + SecretKeyMetaData sKeyValue; + if (sKeyValue.Unmarshall({ dbValue.begin(), dbValue.end() })) { + ZLOGE("parse json error"); + return Status::ERROR; + } + auto createTime = TransferByteArrayToType(sKeyValue.time); + DecryptWorkKey(sKeyValue.sKey, key.data); + system_clock::time_point createTimeChrono = system_clock::from_time_t(createTime); + key.outdated = ((createTimeChrono + hours(HOURS_PER_YEAR)) < system_clock::now()); // secretKey valid for 1 year. + return Status::SUCCESS; +} + +std::vector KeyManager::EncryptWorkKey(const std::vector &key) +{ + struct HksBlob blobAad = { static_cast(vecAad_.size()), &(vecAad_[0]) }; + struct HksBlob blobNonce = { static_cast(vecNonce_.size()), &(vecNonce_[0]) }; + struct HksBlob rootKeyName = { static_cast(vecRootKeyAlias_.size()), &(vecRootKeyAlias_[0]) }; + struct HksBlob plainKey = { static_cast(key.size()), const_cast(&(key[0])) }; + uint8_t cipherBuf[256] = { 0 }; + struct HksBlob encryptedKey = { sizeof(cipherBuf), cipherBuf }; + std::vector encryptedKeyVec; + struct HksParamSet *encryptParamSet = nullptr; + int32_t ret = HksInitParamSet(&encryptParamSet); + if (ret != HKS_SUCCESS) { + ZLOGE("HksInitParamSet() failed with error %{public}d", ret); + return {}; + } + struct HksParam encryptParams[] = { + { .tag = HKS_TAG_ALGORITHM, { .uint32Param = HKS_ALG_AES } }, + { .tag = HKS_TAG_PURPOSE, { .uint32Param = HKS_KEY_PURPOSE_ENCRYPT } }, + { .tag = HKS_TAG_DIGEST, { .uint32Param = 0 } }, + { .tag = HKS_TAG_BLOCK_MODE, { .uint32Param = HKS_MODE_GCM } }, + { .tag = HKS_TAG_PADDING, { .uint32Param = HKS_PADDING_NONE } }, + { .tag = HKS_TAG_NONCE, { .blob = blobNonce } }, + { .tag = HKS_TAG_ASSOCIATED_DATA, { .blob = blobAad } }, + }; + ret = HksAddParams(encryptParamSet, encryptParams, sizeof(encryptParams) / sizeof(encryptParams[0])); + if (ret != HKS_SUCCESS) { + ZLOGE("HksAddParams failed with error %{public}d", ret); + HksFreeParamSet(&encryptParamSet); + return {}; + } + + ret = HksBuildParamSet(&encryptParamSet); + if (ret != HKS_SUCCESS) { + ZLOGE("HksBuildParamSet failed with error %{public}d", ret); + HksFreeParamSet(&encryptParamSet); + return {}; + } + + ret = HksEncrypt(&rootKeyName, encryptParamSet, &plainKey, &encryptedKey); + if (ret != HKS_SUCCESS) { + ZLOGE("HksEncrypt failed with error %{public}d", ret); + HksFreeParamSet(&encryptParamSet); + return {}; + } + (void)HksFreeParamSet(&encryptParamSet); + + for (uint32_t i = 0; i < encryptedKey.size; i++) { + encryptedKeyVec.push_back(encryptedKey.data[i]); + } + return encryptedKeyVec; +} +bool KeyManager::DecryptWorkKey(const std::vector &encryptedKey, std::vector &key) +{ + struct HksBlob blobAad = { static_cast(vecAad_.size()), &(vecAad_[0]) }; + struct HksBlob blobNonce = { static_cast(vecNonce_.size()), &(vecNonce_[0]) }; + struct HksBlob rootKeyName = { static_cast(vecRootKeyAlias_.size()), &(vecRootKeyAlias_[0]) }; + struct HksBlob encryptedKeyBlob = { static_cast(encryptedKey.size()), + const_cast(&(encryptedKey[0])) }; + uint8_t plainBuf[256] = { 0 }; + struct HksBlob plainKeyBlob = { sizeof(plainBuf), plainBuf }; + struct HksParamSet *decryptParamSet = nullptr; + int32_t ret = HksInitParamSet(&decryptParamSet); + if (ret != HKS_SUCCESS) { + ZLOGE("HksInitParamSet() failed with error %{public}d", ret); + return false; + } + struct HksParam decryptParams[] = { + { .tag = HKS_TAG_ALGORITHM, { .uint32Param = HKS_ALG_AES } }, + { .tag = HKS_TAG_PURPOSE, { .uint32Param = HKS_KEY_PURPOSE_DECRYPT } }, + { .tag = HKS_TAG_DIGEST, { .uint32Param = 0 } }, + { .tag = HKS_TAG_BLOCK_MODE, { .uint32Param = HKS_MODE_GCM } }, + { .tag = HKS_TAG_PADDING, { .uint32Param = HKS_PADDING_NONE } }, + { .tag = HKS_TAG_NONCE, { .blob = blobNonce } }, + { .tag = HKS_TAG_ASSOCIATED_DATA, { .blob = blobAad } }, + }; + ret = HksAddParams(decryptParamSet, decryptParams, sizeof(decryptParams) / sizeof(decryptParams[0])); + if (ret != HKS_SUCCESS) { + ZLOGE("HksAddParams failed with error %{public}d", ret); + HksFreeParamSet(&decryptParamSet); + return false; + } + + ret = HksBuildParamSet(&decryptParamSet); + if (ret != HKS_SUCCESS) { + ZLOGE("HksBuildParamSet failed with error %{public}d", ret); + HksFreeParamSet(&decryptParamSet); + return false; + } + + ret = HksDecrypt(&rootKeyName, decryptParamSet, &encryptedKeyBlob, &plainKeyBlob); + if (ret != HKS_SUCCESS) { + ZLOGW("HksDecrypt failed with error %{public}d", ret); + HksFreeParamSet(&decryptParamSet); + return false; + } + (void)HksFreeParamSet(&decryptParamSet); + + for (uint32_t i = 0; i < plainKeyBlob.size; i++) { + key.push_back(plainKeyBlob.data[i]); + } + return true; +} +Status KeyManager::WriteSecretKeyToMeta(const std::vector &metaKey, const std::vector &key) +{ + ZLOGD("start"); + SecretKeyMetaData secretKey; + secretKey.kvStoreType = KvStoreType::DEVICE_COLLABORATION; + secretKey.time = TransferTypeToByteArray(system_clock::to_time_t(system_clock::now())); + secretKey.sKey = EncryptWorkKey(key); + if (secretKey.sKey.empty()) { + ZLOGE("encrypt work key error."); + return Status::CRYPT_ERROR; + } + + auto valueStr = to_string(secretKey.Marshall()); + std::vector metaValue = { valueStr.begin(), valueStr.end() }; + auto status = KvStoreMetaManager::GetInstance().CheckUpdateServiceMeta(metaKey, UPDATE_LOCAL, metaValue); + if (status != Status::SUCCESS) { + ZLOGE("end with %d", static_cast(status)); + return Status::DB_ERROR; + } + ZLOGD("normal end"); + return Status::SUCCESS; +} + +Status KeyManager::WriteSecretKeyToFile(const std::string &secretKeyFile, const std::vector &key) +{ + ZLOGD("start"); + std::vector secretKey = EncryptWorkKey(key); + if (secretKey.empty()) { + ZLOGW("encrypt work key error."); + return Status::CRYPT_ERROR; + } + std::string dbDir = secretKeyFile.substr(0, secretKeyFile.find_last_of('/')); + if (!ForceCreateDirectory(dbDir)) { + return Status::ERROR; + } + + std::vector secretKeyInByte = + TransferTypeToByteArray(system_clock::to_time_t(system_clock::now())); + std::vector secretKeyInChar; + secretKeyInChar.insert(secretKeyInChar.end(), secretKeyInByte.begin(), secretKeyInByte.end()); + secretKeyInChar.insert(secretKeyInChar.end(), secretKey.begin(), secretKey.end()); + if (SaveBufferToFile(secretKeyFile, secretKeyInChar)) { + ZLOGD("normal end"); + return Status::SUCCESS; + } + ZLOGW("failure end"); + return Status::ERROR; +} +Status KeyManager::RemoveSecretKey(const StoreMetaData &meta) +{ + Status status = Status::SUCCESS; + auto &metaManager = KvStoreMetaManager::GetInstance(); + + DistributedDB::Key secretDbKey = + KvStoreMetaManager::GetMetaKey(meta.deviceAccountId, "default", meta.bundleName, meta.storeId, "KEY"); + DistributedDB::Key secretSingleDbKey = + KvStoreMetaManager::GetMetaKey(meta.deviceAccountId, "default", meta.bundleName, meta.storeId, "SINGLE_KEY"); + auto dbStatus = metaManager.CheckUpdateServiceMeta(secretDbKey, DELETE_LOCAL); + if (dbStatus != Status::SUCCESS) { + ZLOGE("delete secretDbKey fail Status %d", static_cast(dbStatus)); + status = Status::DB_ERROR; + } + dbStatus = metaManager.CheckUpdateServiceMeta(secretSingleDbKey, DELETE_LOCAL); + if (dbStatus != Status::SUCCESS) { + ZLOGE("delete secretSingleDbKey fail Status %d", static_cast(dbStatus)); + status = Status::DB_ERROR; + } + + std::string secretKeyFile = GetSecretKeyFile(meta); + bool rmFile = RemoveFile(secretKeyFile); + if (!rmFile) { + ZLOGW("remove secretKeyFile fail."); + status = Status::DB_ERROR; + } + secretKeyFile = GetSecretSingleKeyFile(meta); + rmFile = RemoveFile(secretKeyFile); + if (!rmFile) { + ZLOGW("remove secretKeyFile Single fail."); + status = Status::DB_ERROR; + } + return status; +} + +Status KeyManager::RecoverSecretKeyFromFile( + const std::string &secretKeyFile, const std::vector &metaSecretKey, SecretKey &securityKey) +{ + std::vector fileBuffer; + if (!LoadBufferFromFile(secretKeyFile, fileBuffer)) { + return Status::ERROR; + } + if (fileBuffer.size() < sizeof(time_t) / sizeof(uint8_t) + KEY_SIZE) { + return Status::ERROR; + } + std::vector timeVec; + auto iter = fileBuffer.begin(); + for (int i = 0; i < static_cast(sizeof(time_t) / sizeof(uint8_t)); i++) { + timeVec.push_back(*iter); + iter++; + } + time_t createTime = TransferByteArrayToType(timeVec); + SecretKeyMetaData secretKey; + secretKey.sKey.insert(secretKey.sKey.end(), iter, fileBuffer.end()); + if (!DecryptWorkKey(secretKey.sKey, securityKey.data)) { + return Status::ERROR; + } + system_clock::time_point createTimeChrono = system_clock::from_time_t(createTime); + securityKey.outdated = + ((createTimeChrono + hours(HOURS_PER_YEAR)) < system_clock::now()); // secretKey valid for 1 year. + + secretKey.time = TransferTypeToByteArray(createTime); + secretKey.kvStoreType = KvStoreType::DEVICE_COLLABORATION; + + auto valueStr = to_string(secretKey.Marshall()); + std::vector metaSecretValue = { valueStr.begin(), valueStr.end() }; + auto dbStatus = + KvStoreMetaManager::GetInstance().CheckUpdateServiceMeta(metaSecretKey, UPDATE_LOCAL, metaSecretValue); + if (dbStatus != Status::SUCCESS) { + ZLOGE("put work key failed."); + return Status::DB_ERROR; + } + return Status::SUCCESS; +} + +std::string KeyManager::GetSecretKeyFile(const StoreMetaData &meta) +{ + std::string hashedStoreId; + DistributedDB::DBStatus result = DistributedDB::KvStoreDelegateManager::GetDatabaseDir(meta.storeId, hashedStoreId); + if (DistributedDB::OK != result) { + ZLOGE("get data base directory by kvstore store id failed, result = %d.", result); + return ""; + } + auto keyDir = DirectoryManager::GetInstance().GetStoreKeyPath(meta); + return keyDir + hashedStoreId + ".mul.key"; +} + +std::string KeyManager::GetSecretSingleKeyFile(const StoreMetaData &meta) +{ + std::string hashedStoreId; + DistributedDB::DBStatus result = DistributedDB::KvStoreDelegateManager::GetDatabaseDir(meta.storeId, hashedStoreId); + if (DistributedDB::OK != result) { + ZLOGE("get data base directory by kvstore store id failed, result = %d.", result); + return ""; + } + auto keyDir = DirectoryManager::GetInstance().GetStoreKeyPath(meta); + return keyDir + hashedStoreId + ".sig.key"; +} +} // namespace OHOS::DistributedKv diff --git a/services/distributeddataservice/app/src/key/key_manager.h b/services/distributeddataservice/app/src/key/key_manager.h new file mode 100644 index 000000000..c6657f2f5 --- /dev/null +++ b/services/distributeddataservice/app/src/key/key_manager.h @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2021 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 SDB_KEYMANAGER_H +#define SDB_KEYMANAGER_H + +#include + +#include "utils/crypto.h" +#include "kvstore_meta_manager.h" +#include "metadata/secret_key_meta_data.h" +#include "metadata/store_meta_data.h" +#include "types.h" + +namespace OHOS::DistributedData { +struct SecretKey { + std::vector data; + bool outdated = false; + SecretKey() = default; + SecretKey(const SecretKey &key) = delete; + SecretKey &operator=(const SecretKey &key) = delete; + SecretKey(std::vector &&key) noexcept : data(std::move(key)) + { + } + SecretKey(SecretKey &&key) noexcept + { + operator=(std::move(key)); + } + SecretKey &operator=(SecretKey &&key) noexcept + { + if (this == &key) { + return *this; + } + data = key.data; + return *this; + } + + ~SecretKey() + { + data.assign(data.size(), 0); + } + bool IsEmpty() const + { + return data.empty(); + } +}; + +class KeyManager { +public: + explicit KeyManager(); + static DistributedKv::Status GenerateRootKey(); + + static DistributedKv::Status CheckRootKeyExist(); + static SecretKey GetSecretKey(const DistributedData::StoreMetaData &meta, const std::string &key, DistributedKv::Status &status); + static DistributedKv::Status GetSecretKeyFromMeta(const std::vector &metaSecretKey, SecretKey &key); + static std::vector EncryptWorkKey(const std::vector &key); + + static bool DecryptWorkKey(const std::vector &encryptedKey, std::vector &key); + + static DistributedKv::Status WriteSecretKeyToMeta(const std::vector &metaKey, const std::vector &key); + + static DistributedKv::Status WriteSecretKeyToFile(const std::string &secretKeyFile, const std::vector &key); + + static DistributedKv::Status RemoveSecretKey(const DistributedData::StoreMetaData &meta); + + static DistributedKv::Status RecoverSecretKeyFromFile( + const std::string &secretKeyFile, const std::vector &metaSecretKey, SecretKey &securityKey); + + template + static void ReKey(const StoreMetaData &meta, sptr &store) + { + std::vector key = Crypto::Random(KEY_SIZE); + auto metaKey = KvStoreMetaManager::GetMetaKey( + meta.deviceAccountId, "default", meta.bundleName, meta.storeId, store->GetName()); + WriteSecretKeyToMeta(metaKey, key); + Status status = store->ReKey(key); + if (status == Status::SUCCESS) { + WriteSecretKeyToFile(GetSecretKeyFile(meta), key); + } + key.assign(key.size(), 0); + } + + + static std::string GetSecretKeyFile(const DistributedData::StoreMetaData &meta); + + static std::string GetSecretSingleKeyFile(const DistributedData::StoreMetaData &meta); + +private: + static std::vector vecRootKeyAlias_; + static std::vector vecNonce_; + static std::vector vecAad_; + + static constexpr const char *HKS_BLOB_TYPE_NONCE = "Z5s0Bo571KoqwIi6"; + static constexpr const char *HKS_BLOB_TYPE_AAD = "distributeddata"; + static constexpr const char *ROOT_KEY_ALIAS = "distributed_db_root_key"; + static constexpr const char *ROOT_KEY_GENERATED = "RootKeyGenerated"; + static constexpr int HOURS_PER_YEAR = (24 * 365); + static constexpr int KEY_SIZE = 32; +}; +} // namespace OHOS::DistributedKv + +#endif //SDB_KEYMANAGER_H diff --git a/services/distributeddataservice/app/src/kvstore_app_accessor.cpp b/services/distributeddataservice/app/src/kvstore_app_accessor.cpp index 40af4e48d..de7bc9648 100755 --- a/services/distributeddataservice/app/src/kvstore_app_accessor.cpp +++ b/services/distributeddataservice/app/src/kvstore_app_accessor.cpp @@ -19,13 +19,16 @@ #include #include #include "broadcast_sender.h" +#include "directory_manager.h" #include "kv_store_delegate_manager.h" #include "kvstore_app_manager.h" #include "kvstore_meta_manager.h" #include "log_print.h" #include "permission_validator.h" +#include "metadata/store_meta_data.h" namespace OHOS::DistributedKv { +using namespace OHOS::DistributedData; KvStoreAppAccessor::~KvStoreAppAccessor() { ZLOGD("destructor."); @@ -67,25 +70,21 @@ void KvStoreAppAccessor::EnableKvStoreAutoLaunch() std::map entries; if (KvStoreMetaManager::GetInstance().GetFullMetaData(entries)) { for (auto &meta : entries) { - KvStoreMetaData &metaData = meta.second.kvStoreMetaData; + StoreMetaData &metaData = meta.second.kvStoreMetaData; ZLOGI("meta appId:%s", metaData.appId.c_str()); if (!PermissionValidator::IsAutoLaunchEnabled(metaData.appId)) { continue; } DistributedDB::CipherPassword password; - const std::vector &secretKey = meta.second.secretKeyMetaData.secretKey; + const std::vector &secretKey = meta.second.secretKeyMetaData.sKey; if (password.SetValue(secretKey.data(), secretKey.size()) != DistributedDB::CipherPassword::OK) { ZLOGE("Get secret key failed."); return; } - auto pathType = - KvStoreAppManager::ConvertPathType(metaData.uid, metaData.bundleName, metaData.securityLevel); - std::string appPath = KvStoreAppManager::GetDataStoragePath( - metaData.deviceAccountId, metaData.bundleName, pathType); DistributedDB::AutoLaunchOption dbLaunchOption; dbLaunchOption.createIfNecessary = true; dbLaunchOption.createDirByStoreIdOnly = true; - dbLaunchOption.dataDir = Constant::Concatenate({appPath, "/", metaData.bundleName}); + dbLaunchOption.dataDir = DirectoryManager::GetInstance().GetStorePath(metaData); dbLaunchOption.observer = nullptr; if (password.GetSize() > 0) { dbLaunchOption.isEncryptedDb = true; @@ -109,7 +108,7 @@ void KvStoreAppAccessor::OnCallback(const std::string &userId, const std::string { ZLOGI("start"); if (status == DistributedDB::AutoLaunchStatus::WRITE_OPENED) { - KvStoreMetaData kvStoreMetaData; + StoreMetaData kvStoreMetaData; if (KvStoreMetaManager::GetInstance().GetKvStoreMetaDataByAppId(appId, kvStoreMetaData)) { BroadcastSender::GetInstance()->SendEvent({userId, kvStoreMetaData.bundleName, storeId}); ZLOGW("AppId:%s is opened, bundle:%s.", appId.c_str(), kvStoreMetaData.bundleName.c_str()); diff --git a/services/distributeddataservice/app/src/kvstore_app_manager.cpp b/services/distributeddataservice/app/src/kvstore_app_manager.cpp index f5ba2b2b7..d3a775ab5 100755 --- a/services/distributeddataservice/app/src/kvstore_app_manager.cpp +++ b/services/distributeddataservice/app/src/kvstore_app_manager.cpp @@ -24,29 +24,30 @@ #include "account_delegate.h" #include "broadcast_sender.h" #include "checker/checker_manager.h" -#include "constant.h" +#include "utils/constant.h" #include "directory_utils.h" +#include "directory_manager.h" #include "device_kvstore_impl.h" #include "ikvstore.h" #include "kv_store_delegate.h" #include "kvstore_app_accessor.h" +#include "kvstore_meta_manager.h" #include "kvstore_utils.h" #include "log_print.h" #include "process_communicator_impl.h" #include "permission_validator.h" #include "reporter.h" +#include "route_head_handler.h" #include "types.h" namespace OHOS { namespace DistributedKv { -using namespace OHOS::DistributedData; +using namespace DistributedData; KvStoreAppManager::KvStoreAppManager(const std::string &bundleName, pid_t uid) : bundleName_(bundleName), uid_(uid), flowCtrl_(BURST_CAPACITY, SUSTAINED_CAPACITY) { ZLOGI("begin."); - deviceAccountId_ = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid); - GetDelegateManager(PATH_DE); - GetDelegateManager(PATH_CE); + userId_ = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid); } KvStoreAppManager::~KvStoreAppManager() @@ -67,7 +68,7 @@ KvStoreAppManager::~KvStoreAppManager() Status KvStoreAppManager::ConvertErrorStatus(DistributedDB::DBStatus dbStatus, bool createIfMissing) { if (dbStatus != DistributedDB::DBStatus::OK) { - ZLOGE("delegate return error: %d.", static_cast(dbStatus)); + ZLOGE("delegate return error: %{public}d.", static_cast(dbStatus)); switch (dbStatus) { case DistributedDB::DBStatus::INVALID_PASSWD_OR_CORRUPTED_DB: return Status::CRYPT_ERROR; @@ -91,16 +92,15 @@ Status KvStoreAppManager::ConvertErrorStatus(DistributedDB::DBStatus dbStatus, b } return Status::SUCCESS; } - -Status KvStoreAppManager::GetKvStore(const Options &options, const std::string &appId, const std::string &storeId, - const std::vector &cipherKey, sptr &kvStore) +Status KvStoreAppManager::GetKvStore(const Options &options, const StoreMetaData &storeMeta, const std::vector &cipherKey, + sptr &kvStore) { ZLOGI("begin"); kvStore = nullptr; - PathType type = ConvertPathType(uid_, bundleName_, options.securityLevel); - auto *delegateManager = GetDelegateManager(type); + PathType type = DirWorker::ConvertPathType(uid_, bundleName_, options.securityLevel); + auto *delegateManager = GetDelegateManager(type, storeMeta); if (delegateManager == nullptr) { - ZLOGE("delegateManagers[%d] is nullptr.", type); + ZLOGE("delegateManagers[%{public}d] is nullptr.", type); return Status::ILLEGAL_STATE; } @@ -110,16 +110,16 @@ Status KvStoreAppManager::GetKvStore(const Options &options, const std::string & } std::lock_guard lg(storeMutex_); - auto it = stores_[type].find(storeId); + auto it = stores_[type].find(storeMeta.storeId); if (it != stores_[type].end()) { kvStore = it->second; - ZLOGI("find store in map refcount: %d.", kvStore->GetSptrRefCount()); + ZLOGI("find store in map refcount: %{public}d.", kvStore->GetSptrRefCount()); kvStore->IncreaseOpenCount(); return Status::SUCCESS; } if ((GetTotalKvStoreNum()) >= static_cast(Constant::MAX_OPEN_KVSTORES)) { - ZLOGE("limit %d KvStores can be opened.", Constant::MAX_OPEN_KVSTORES); + ZLOGE("limit %{public}d KvStores can be opened.", Constant::MAX_OPEN_KVSTORES); return Status::ERROR; } @@ -132,26 +132,26 @@ Status KvStoreAppManager::GetKvStore(const Options &options, const std::string & DistributedDB::KvStoreDelegate *storeDelegate = nullptr; DistributedDB::DBStatus dbStatusTmp; - delegateManager->GetKvStore(storeId, dbOption, + delegateManager->GetKvStore(storeMeta.storeId, dbOption, [&storeDelegate, &dbStatusTmp](DistributedDB::DBStatus dbStatus, DistributedDB::KvStoreDelegate *delegate) { storeDelegate = delegate; dbStatusTmp = dbStatus; }); if (storeDelegate == nullptr) { - ZLOGE("storeDelegate is nullptr, status:%d.", static_cast(dbStatusTmp)); + ZLOGE("storeDelegate is nullptr, status:%{public}d.", static_cast(dbStatusTmp)); return ConvertErrorStatus(dbStatusTmp, options.createIfMissing); } ZLOGD("get delegate"); - kvStore = new (std::nothrow)KvStoreImpl(options, deviceAccountId_, bundleName_, - appId, storeId, GetDbDir(options), storeDelegate); + kvStore = new (std::nothrow)KvStoreImpl(options, userId_, bundleName_, + storeMeta.bundleName, storeMeta.storeId, GetDbDir(storeMeta), storeDelegate); if (kvStore == nullptr) { delegateManager->CloseKvStore(storeDelegate); kvStore = nullptr; return Status::ERROR; } - auto result = stores_[type].emplace(storeId, kvStore); + auto result = stores_[type].emplace(storeMeta.storeId, kvStore); if (!result.second) { ZLOGE("emplace failed."); delegateManager->CloseKvStore(storeDelegate); @@ -159,19 +159,19 @@ Status KvStoreAppManager::GetKvStore(const Options &options, const std::string & return Status::ERROR; } - ZLOGD("after emplace refcount: %d", kvStore->GetSptrRefCount()); + ZLOGD("after emplace refcount: %{public}d", kvStore->GetSptrRefCount()); return Status::SUCCESS; } -Status KvStoreAppManager::GetKvStore(const Options &options, const std::string &appId, const std::string &storeId, +Status KvStoreAppManager::GetKvStore(const Options &options, const StoreMetaData &storeMeta, const std::vector &cipherKey, sptr &kvStore) { ZLOGI("begin"); kvStore = nullptr; - PathType type = ConvertPathType(uid_, bundleName_, options.securityLevel); - auto *delegateManager = GetDelegateManager(type); + PathType type = DirWorker::ConvertPathType(uid_, bundleName_, options.securityLevel); + auto *delegateManager = GetDelegateManager(type, storeMeta); if (delegateManager == nullptr) { - ZLOGE("delegateManagers[%d] is nullptr.", type); + ZLOGE("delegateManagers[%{public}d] is nullptr.", type); return Status::ILLEGAL_STATE; } @@ -180,16 +180,16 @@ Status KvStoreAppManager::GetKvStore(const Options &options, const std::string & return Status::EXCEED_MAX_ACCESS_RATE; } std::lock_guard lg(storeMutex_); - auto it = singleStores_[type].find(storeId); + auto it = singleStores_[type].find(storeMeta.storeId); if (it != singleStores_[type].end()) { kvStore = it->second; - ZLOGI("find store in map refcount: %d.", kvStore->GetSptrRefCount()); + ZLOGI("find store in map refcount: %{public}d.", kvStore->GetSptrRefCount()); kvStore->IncreaseOpenCount(); return Status::SUCCESS; } if ((GetTotalKvStoreNum()) >= static_cast(Constant::MAX_OPEN_KVSTORES)) { - ZLOGE("limit %d KvStores can be opened.", Constant::MAX_OPEN_KVSTORES); + ZLOGE("limit %{public}d KvStores can be opened.", Constant::MAX_OPEN_KVSTORES); return Status::ERROR; } @@ -202,7 +202,7 @@ Status KvStoreAppManager::GetKvStore(const Options &options, const std::string & DistributedDB::KvStoreNbDelegate *storeDelegate = nullptr; DistributedDB::DBStatus dbStatusTmp; - delegateManager->GetKvStore(storeId, dbOption, + delegateManager->GetKvStore(storeMeta.storeId, dbOption, [&](DistributedDB::DBStatus dbStatus, DistributedDB::KvStoreNbDelegate *kvStoreDelegate) { storeDelegate = kvStoreDelegate; dbStatusTmp = dbStatus; @@ -212,24 +212,24 @@ Status KvStoreAppManager::GetKvStore(const Options &options, const std::string & ZLOGE("storeDelegate is nullptr."); return ConvertErrorStatus(dbStatusTmp, options.createIfMissing); } - std::string kvStorePath = GetDbDir(options); + std::string kvStorePath = GetDbDir(storeMeta); switch (options.kvStoreType) { case KvStoreType::DEVICE_COLLABORATION: kvStore = new (std::nothrow) DeviceKvStoreImpl( - options, deviceAccountId_, bundleName_, storeId, trueAppId_, kvStorePath, storeDelegate); + options, userId_, bundleName_, storeMeta.storeId, trueAppId_, kvStorePath, storeDelegate); break; default: kvStore = new (std::nothrow) SingleKvStoreImpl( - options, deviceAccountId_, bundleName_, storeId, trueAppId_, kvStorePath, storeDelegate); + options, userId_, bundleName_, storeMeta.storeId, trueAppId_, kvStorePath, storeDelegate); break; } if (kvStore == nullptr) { ZLOGE("store is nullptr."); delegateManager->CloseKvStore(storeDelegate); - kvStore = nullptr; return Status::ERROR; } - auto result = singleStores_[type].emplace(storeId, kvStore); + kvStore->SetCompatibleIdentify(); + auto result = singleStores_[type].emplace(storeMeta.storeId, kvStore); if (!result.second) { ZLOGE("emplace failed."); delegateManager->CloseKvStore(storeDelegate); @@ -237,13 +237,13 @@ Status KvStoreAppManager::GetKvStore(const Options &options, const std::string & return Status::ERROR; } - ZLOGI("after emplace refcount: %d autoSync: %d", kvStore->GetSptrRefCount(), static_cast(options.autoSync)); + ZLOGI("after emplace refcount: %{public}d autoSync: %{public}d", kvStore->GetSptrRefCount(), static_cast(options.autoSync)); if (options.autoSync) { bool autoSync = true; DistributedDB::PragmaData data = static_cast(&autoSync); auto pragmaStatus = storeDelegate->Pragma(DistributedDB::PragmaCmd::AUTO_SYNC, data); if (pragmaStatus != DistributedDB::DBStatus::OK) { - ZLOGE("pragmaStatus: %d", static_cast(pragmaStatus)); + ZLOGE("pragmaStatus: %{public}d", static_cast(pragmaStatus)); } } @@ -252,12 +252,12 @@ Status KvStoreAppManager::GetKvStore(const Options &options, const std::string & dbOption.createDirByStoreIdOnly, kvStorePath, nullptr }; launchOption.secOption = ConvertSecurity(options.securityLevel); - AppAccessorParam accessorParam = {Constant::DEFAULT_GROUP_ID, trueAppId_, storeId, launchOption}; + AppAccessorParam accessorParam = {Constant::DEFAULT_GROUP_ID, trueAppId_, storeMeta.storeId, launchOption}; KvStoreAppAccessor::GetInstance().EnableKvStoreAutoLaunch(accessorParam); return Status::SUCCESS; } -Status KvStoreAppManager::CloseKvStore(const std::string &storeId) +Status KvStoreAppManager::CloseKvStore(const StoreMetaData &storeMeta) { ZLOGI("CloseKvStore"); if (!flowCtrl_.IsTokenEnough()) { @@ -265,12 +265,12 @@ Status KvStoreAppManager::CloseKvStore(const std::string &storeId) return Status::EXCEED_MAX_ACCESS_RATE; } std::lock_guard lg(storeMutex_); - Status status = CloseKvStore(storeId, PATH_DE); + Status status = CloseKvStore(PATH_DE, storeMeta); if (status != Status::STORE_NOT_OPEN) { return status; } - status = CloseKvStore(storeId, PATH_CE); + status = CloseKvStore(PATH_CE, storeMeta); if (status != Status::STORE_NOT_OPEN) { return status; } @@ -279,7 +279,7 @@ Status KvStoreAppManager::CloseKvStore(const std::string &storeId) return Status::STORE_NOT_OPEN; } -Status KvStoreAppManager::CloseAllKvStore() +Status KvStoreAppManager::CloseAllKvStore(const DistributedData::StoreMetaData &storeMeta) { ZLOGI("begin."); std::lock_guard lg(storeMutex_); @@ -287,28 +287,28 @@ Status KvStoreAppManager::CloseAllKvStore() return Status::STORE_NOT_OPEN; } - ZLOGI("close %zu KvStores.", GetTotalKvStoreNum()); - Status status = CloseAllKvStore(PATH_DE); + ZLOGI("close %{public}zu KvStores.", GetTotalKvStoreNum()); + Status status = CloseAllKvStore(PATH_DE, storeMeta); if (status == Status::DB_ERROR) { return status; } - status = CloseAllKvStore(PATH_CE); + status = CloseAllKvStore(PATH_CE, storeMeta); if (status == Status::DB_ERROR) { return status; } return Status::SUCCESS; } -Status KvStoreAppManager::DeleteKvStore(const std::string &storeId) +Status KvStoreAppManager::DeleteKvStore(const StoreMetaData &storeMeta) { - ZLOGI("%s", storeId.c_str()); + ZLOGI("%{public}s", storeMeta.storeId.c_str()); if (!flowCtrl_.IsTokenEnough()) { ZLOGE("flow control denied"); return Status::EXCEED_MAX_ACCESS_RATE; } - Status statusDE = DeleteKvStore(storeId, PATH_DE); - Status statusCE = DeleteKvStore(storeId, PATH_CE); + Status statusDE = DeleteKvStore(storeMeta, PATH_DE); + Status statusCE = DeleteKvStore(storeMeta, PATH_CE); if (statusDE == Status::SUCCESS || statusCE == Status::SUCCESS) { return Status::SUCCESS; } @@ -317,23 +317,25 @@ Status KvStoreAppManager::DeleteKvStore(const std::string &storeId) return Status::DB_ERROR; } -Status KvStoreAppManager::DeleteAllKvStore() +Status KvStoreAppManager::DeleteAllKvStore(const std::string &appId) { ZLOGI("begin."); std::lock_guard lg(storeMutex_); if (GetTotalKvStoreNum() == 0) { return Status::STORE_NOT_OPEN; } - ZLOGI("delete %d KvStores.", int32_t(GetTotalKvStoreNum())); + ZLOGI("delete %{public}d KvStores.", int32_t(GetTotalKvStoreNum())); - Status status = DeleteAllKvStore(PATH_DE); + Status status = Status::SUCCESS; + auto storeMeta = KvStoreMetaManager::BuildStoreMeta({}, { appId }, {}, {}, status); // todo: tobedone + status = DeleteAllKvStore(PATH_DE, storeMeta); if (status != Status::SUCCESS) { - ZLOGE("path de delegate delete error: %d.", static_cast(status)); + ZLOGE("path de delegate delete error: %{public}d.", static_cast(status)); return Status::DB_ERROR; } - status = DeleteAllKvStore(PATH_CE); + status = DeleteAllKvStore(PATH_CE, storeMeta); if (status != Status::SUCCESS) { - ZLOGE("path ce delegate delete error: %d.", static_cast(status)); + ZLOGE("path ce delegate delete error: %{public}d.", static_cast(status)); return Status::DB_ERROR; } return Status::SUCCESS; @@ -348,10 +350,10 @@ Status KvStoreAppManager::MigrateAllKvStore(const std::string &harmonyAccountId) std::lock_guard lg(storeMutex_); // update userid in kvstore tuple map of permission adapter. - KvStoreTuple srcKvStoreTuple {userId_, bundleName_}; + KvStoreTuple srcKvStoreTuple { accountId_, bundleName_}; KvStoreTuple dstKvStoreTuple {harmonyAccountId, bundleName_}; PermissionValidator::UpdateKvStoreTupleMap(srcKvStoreTuple, dstKvStoreTuple); - userId_ = harmonyAccountId; + accountId_ = harmonyAccountId; ZLOGI("path de migration begin."); Status statusDE = MigrateAllKvStore(harmonyAccountId, PATH_DE); ZLOGI("path ce migration begin."); @@ -389,6 +391,7 @@ Status KvStoreAppManager::InitNbDbOption(const Options &options, const std::vect return Status::DB_ERROR; } + dbOption.syncDualTupleMode = true; // tuple of (appid+storeid) dbOption.createIfNecessary = options.createIfMissing; dbOption.isEncryptedDb = options.encrypt; if (options.encrypt) { @@ -411,44 +414,25 @@ Status KvStoreAppManager::InitNbDbOption(const Options &options, const std::vect return Status::SUCCESS; } -std::string KvStoreAppManager::GetDbDir(const Options &options) const +std::string KvStoreAppManager::GetDbDir(const StoreMetaData &storeMeta) const { - return GetDataStoragePath(deviceAccountId_, bundleName_, ConvertPathType(uid_, bundleName_, options.securityLevel)); + return DirectoryManager::GetInstance().GetStorePath(storeMeta); } -KvStoreAppManager::PathType KvStoreAppManager::ConvertPathType(int32_t uid, const std::string &bundleName, - int securityLevel) -{ - switch (securityLevel) { - case S0: // fallthrough - case S1: - return PATH_DE; - case S2: // fallthrough - case S3_EX: // fallthrough - case S3: // fallthrough - case S4: // fallthrough - return PATH_CE; - default: - break; - } - auto *checker = CheckerManager::GetInstance().GetChecker("SystemChecker"); - if (checker == nullptr || !checker->IsValid(uid, bundleName)) { - return PATH_CE; - } - return PATH_DE; -} - -DistributedDB::KvStoreDelegateManager *KvStoreAppManager::GetDelegateManager(PathType type) +DistributedDB::KvStoreDelegateManager *KvStoreAppManager::GetDelegateManager( + PathType type, const DistributedData::StoreMetaData &storeMeta) { std::lock_guard guard(delegateMutex_); if (delegateManagers_[type] != nullptr) { return delegateManagers_[type]; } - std::string directory = GetDataStoragePath(deviceAccountId_, bundleName_, type); + StoreMetaData tmpMeta = storeMeta; + tmpMeta.securityLevel = (type == DistributedData::PATH_DE ? S0 : S4); // todo: improve + std::string directory = DirectoryManager::GetInstance().GetStorePath(tmpMeta); bool ret = ForceCreateDirectory(directory); if (!ret) { - ZLOGE("create directory[%s] failed, errstr=[%d].", directory.c_str(), errno); + ZLOGE("create directory[%{public}s] failed, errstr=[%{public}d].", directory.c_str(), errno); return nullptr; } // change mode for directories to 0755, and for files to 0600. @@ -462,11 +446,10 @@ DistributedDB::KvStoreDelegateManager *KvStoreAppManager::GetDelegateManager(Pat return nullptr; } - userId_ = AccountDelegate::GetInstance()->GetCurrentAccountId(bundleName_); - ZLOGD("accountId: %s bundleName: %s", KvStoreUtils::ToBeAnonymous(userId_).c_str(), bundleName_.c_str()); + ZLOGD("userId: %{public}s bundleName: %{public}s", userId_.c_str(), bundleName_.c_str()); delegateManagers_[type] = new (std::nothrow) DistributedDB::KvStoreDelegateManager(trueAppId_, userId_); if (delegateManagers_[type] == nullptr) { - ZLOGE("delegateManagers_[%d] is nullptr.", type); + ZLOGE("delegateManagers_[%{public}d] is nullptr.", type); return nullptr; } @@ -474,8 +457,9 @@ DistributedDB::KvStoreDelegateManager *KvStoreAppManager::GetDelegateManager(Pat kvStoreConfig.dataDir = directory; delegateManagers_[type]->SetKvStoreConfig(kvStoreConfig); auto communicator = std::make_shared(); + communicator->SetHeaderHandler(RouteHeadHandlerImpl::GetInstance); auto result = DistributedDB::KvStoreDelegateManager::SetProcessCommunicator(communicator); - ZLOGI("app set communicator result:%d.", static_cast(result)); + ZLOGI("app set communicator result:%{public}d.", static_cast(result)); return delegateManagers_[type]; } @@ -488,15 +472,15 @@ DistributedDB::KvStoreDelegateManager *KvStoreAppManager::SwitchDelegateManager( return oldDelegateManager; } -Status KvStoreAppManager::CloseKvStore(const std::string &storeId, PathType type) +Status KvStoreAppManager::CloseKvStore(PathType type, const StoreMetaData &storeMeta) { - auto *delegateManager = GetDelegateManager(type); + auto *delegateManager = GetDelegateManager(type, storeMeta); if (delegateManager == nullptr) { - ZLOGE("delegateManager[%d] is null.", type); + ZLOGE("delegateManager[%{public}d] is null.", type); return Status::ILLEGAL_STATE; } - auto it = stores_[type].find(storeId); + auto it = stores_[type].find(storeMeta.storeId); if (it != stores_[type].end()) { ZLOGD("find store and close delegate."); InnerStatus status = it->second->Close(delegateManager); @@ -507,11 +491,11 @@ Status KvStoreAppManager::CloseKvStore(const std::string &storeId, PathType type if (status == InnerStatus::DECREASE_REFCOUNT) { return Status::SUCCESS; } - ZLOGE("delegate close error: %d.", static_cast(status)); + ZLOGE("delegate close error: %{public}d.", static_cast(status)); return Status::DB_ERROR; } - auto itSingle = singleStores_[type].find(storeId); + auto itSingle = singleStores_[type].find(storeMeta.storeId); if (itSingle != singleStores_[type].end()) { ZLOGD("find single store and close delegate."); InnerStatus status = itSingle->second->Close(delegateManager); @@ -522,27 +506,27 @@ Status KvStoreAppManager::CloseKvStore(const std::string &storeId, PathType type if (status == InnerStatus::DECREASE_REFCOUNT) { return Status::SUCCESS; } - ZLOGE("delegate close error: %d.", static_cast(status)); + ZLOGE("delegate close error: %{public}d.", static_cast(status)); return Status::DB_ERROR; } return Status::STORE_NOT_OPEN; } -Status KvStoreAppManager::CloseAllKvStore(PathType type) +Status KvStoreAppManager::CloseAllKvStore(PathType type, const StoreMetaData &storeMeta) { - auto *delegateManager = GetDelegateManager(type); + auto *delegateManager = GetDelegateManager(type, storeMeta); if (delegateManager == nullptr) { - ZLOGE("delegateManager[%d] is null.", type); + ZLOGE("delegateManager[%{public}d] is null.", type); return Status::ILLEGAL_STATE; } for (auto it = stores_[type].begin(); it != stores_[type].end(); it = stores_[type].erase(it)) { KvStoreImpl *currentStore = it->second.GetRefPtr(); - ZLOGI("close kvstore, refcount %d.", it->second->GetSptrRefCount()); + ZLOGI("close kvstore, refcount %{public}d.", it->second->GetSptrRefCount()); Status status = currentStore->ForceClose(delegateManager); if (status != Status::SUCCESS) { - ZLOGE("delegate close error: %d.", static_cast(status)); + ZLOGE("delegate close error: %{public}d.", static_cast(status)); return Status::DB_ERROR; } } @@ -550,10 +534,10 @@ Status KvStoreAppManager::CloseAllKvStore(PathType type) for (auto it = singleStores_[type].begin(); it != singleStores_[type].end(); it = singleStores_[type].erase(it)) { SingleKvStoreImpl *currentStore = it->second.GetRefPtr(); - ZLOGI("close kvstore, refcount %d.", it->second->GetSptrRefCount()); + ZLOGI("close kvstore, refcount %{public}d.", it->second->GetSptrRefCount()); Status status = currentStore->ForceClose(delegateManager); if (status != Status::SUCCESS) { - ZLOGE("delegate close error: %d.", static_cast(status)); + ZLOGE("delegate close error: %{public}d.", static_cast(status)); return Status::DB_ERROR; } } @@ -561,15 +545,15 @@ Status KvStoreAppManager::CloseAllKvStore(PathType type) return Status::SUCCESS; } -Status KvStoreAppManager::DeleteKvStore(const std::string &storeId, PathType type) +Status KvStoreAppManager::DeleteKvStore(const StoreMetaData &storeMeta, PathType type) { - auto *delegateManager = GetDelegateManager(type); + auto *delegateManager = GetDelegateManager(type, storeMeta); if (delegateManager == nullptr) { - ZLOGE("delegateManager[%d] is null.", type); + ZLOGE("delegateManager[%{public}d] is null.", type); return Status::ILLEGAL_STATE; } std::lock_guard lg(storeMutex_); - auto it = stores_[type].find(storeId); + auto it = stores_[type].find(storeMeta.storeId); if (it != stores_[type].end()) { Status status = it->second->ForceClose(delegateManager); if (status != Status::SUCCESS) { @@ -578,7 +562,7 @@ Status KvStoreAppManager::DeleteKvStore(const std::string &storeId, PathType typ stores_[type].erase(it); } - auto itSingle = singleStores_[type].find(storeId); + auto itSingle = singleStores_[type].find(storeMeta.storeId); if (itSingle != singleStores_[type].end()) { Status status = itSingle->second->ForceClose(delegateManager); if (status != Status::SUCCESS) { @@ -587,7 +571,7 @@ Status KvStoreAppManager::DeleteKvStore(const std::string &storeId, PathType typ singleStores_[type].erase(itSingle); } - DistributedDB::DBStatus status = delegateManager->DeleteKvStore(storeId); + DistributedDB::DBStatus status = delegateManager->DeleteKvStore(storeMeta.storeId); if (singleStores_[type].empty() && stores_[type].empty()) { SwitchDelegateManager(type, nullptr); delete delegateManager; @@ -595,11 +579,11 @@ Status KvStoreAppManager::DeleteKvStore(const std::string &storeId, PathType typ return (status != DistributedDB::DBStatus::OK) ? Status::DB_ERROR : Status::SUCCESS; } -Status KvStoreAppManager::DeleteAllKvStore(PathType type) +Status KvStoreAppManager::DeleteAllKvStore(PathType type, const StoreMetaData &storeMeta) { - auto *delegateManager = GetDelegateManager(type); + auto *delegateManager = GetDelegateManager(type, storeMeta); if (delegateManager == nullptr) { - ZLOGE("delegateManager[%d] is null.", type); + ZLOGE("delegateManager[%{public}d] is null.", type); return Status::ILLEGAL_STATE; } @@ -608,14 +592,14 @@ Status KvStoreAppManager::DeleteAllKvStore(PathType type) KvStoreImpl *currentStore = it->second.GetRefPtr(); Status status = currentStore->ForceClose(delegateManager); if (status != Status::SUCCESS) { - ZLOGE("delegate delete close failed error: %d.", static_cast(status)); + ZLOGE("delegate delete close failed error: %{public}d.", static_cast(status)); return Status::DB_ERROR; } - ZLOGI("delete kvstore, refcount %d.", it->second->GetSptrRefCount()); + ZLOGI("delete kvstore, refcount %{public}d.", it->second->GetSptrRefCount()); DistributedDB::DBStatus dbStatus = delegateManager->DeleteKvStore(storeId); if (dbStatus != DistributedDB::DBStatus::OK) { - ZLOGE("delegate delete error: %d.", static_cast(dbStatus)); + ZLOGE("delegate delete error: %{public}d.", static_cast(dbStatus)); return Status::DB_ERROR; } } @@ -626,14 +610,14 @@ Status KvStoreAppManager::DeleteAllKvStore(PathType type) SingleKvStoreImpl *currentStore = it->second.GetRefPtr(); Status status = currentStore->ForceClose(delegateManager); if (status != Status::SUCCESS) { - ZLOGE("delegate delete close failed error: %d.", static_cast(status)); + ZLOGE("delegate delete close failed error: %{public}d.", static_cast(status)); return Status::DB_ERROR; } - ZLOGI("close kvstore, refcount %d.", it->second->GetSptrRefCount()); + ZLOGI("close kvstore, refcount %{public}d.", it->second->GetSptrRefCount()); DistributedDB::DBStatus dbStatus = delegateManager->DeleteKvStore(storeId); if (dbStatus != DistributedDB::DBStatus::OK) { - ZLOGE("delegate delete error: %d.", static_cast(dbStatus)); + ZLOGE("delegate delete error: %{public}d.", static_cast(dbStatus)); return Status::DB_ERROR; } } @@ -645,13 +629,13 @@ Status KvStoreAppManager::DeleteAllKvStore(PathType type) Status KvStoreAppManager::MigrateAllKvStore(const std::string &harmonyAccountId, PathType type) { - auto *delegateManager = GetDelegateManager(type); + auto *delegateManager = GetDelegateManager(type, {}); //todo: if (delegateManager == nullptr) { ZLOGE("delegateManager is nullptr."); return Status::ILLEGAL_STATE; } - std::string dirPath = GetDataStoragePath(deviceAccountId_, bundleName_, type); + std::string dirPath = GetDataStoragePath(userId_, bundleName_, type); DistributedDB::KvStoreDelegateManager *newDelegateManager = nullptr; Status status = Status::SUCCESS; ZLOGI("KvStore migration begin."); @@ -659,7 +643,7 @@ Status KvStoreAppManager::MigrateAllKvStore(const std::string &harmonyAccountId, sptr impl = it.second; if (impl->MigrateKvStore(harmonyAccountId, dirPath, delegateManager, newDelegateManager) != Status::SUCCESS) { status = Status::MIGRATION_KVSTORE_FAILED; - ZLOGE("migrate kvstore for appId-%s failed.", bundleName_.c_str()); + ZLOGE("migrate kvstore for appId-%{public}s failed.", bundleName_.c_str()); // skip this failed, continue to migrate other kvstore. } } @@ -669,7 +653,7 @@ Status KvStoreAppManager::MigrateAllKvStore(const std::string &harmonyAccountId, sptr impl = it.second; if (impl->MigrateKvStore(harmonyAccountId, dirPath, delegateManager, newDelegateManager) != Status::SUCCESS) { status = Status::MIGRATION_KVSTORE_FAILED; - ZLOGE("migrate single kvstore for appId-%s failed.", bundleName_.c_str()); + ZLOGE("migrate single kvstore for appId-%{public}s failed.", bundleName_.c_str()); // skip this failed, continue to migrate other kvstore. } } @@ -718,8 +702,8 @@ DistributedDB::SecurityOption KvStoreAppManager::ConvertSecurity(int securityLev void KvStoreAppManager::Dump(int fd) const { const std::string prefix(8, ' '); - std::string dePath = GetDataStoragePath(deviceAccountId_, bundleName_, PATH_DE); - std::string cePath = GetDataStoragePath(deviceAccountId_, bundleName_, PATH_CE); + std::string dePath = GetDataStoragePath(userId_, bundleName_, PATH_DE); + std::string cePath = GetDataStoragePath(userId_, bundleName_, PATH_CE); size_t singleStoreNum = singleStores_[PATH_DE].size() + singleStores_[PATH_CE].size(); dprintf(fd, "%s----------------------------------------------------------\n", prefix.c_str()); dprintf(fd, "%sAppID : %s\n", prefix.c_str(), trueAppId_.c_str()); @@ -733,5 +717,23 @@ void KvStoreAppManager::Dump(int fd) const } } } + +bool KvStoreAppManager::IsStoreOpened(const std::string &storeId) const +{ + return (!singleStores_[PATH_DE].empty() && singleStores_->find(storeId) != singleStores_->end()) + || (!singleStores_[PATH_CE].empty() && singleStores_->find(storeId) != singleStores_->end()); +} + +void KvStoreAppManager::SetCompatibleIdentify(const std::string &deviceId) const +{ + for (const auto &storeType : singleStores_) { + for (const auto &item : storeType) { + if (item.second == nullptr) { + continue; + } + item.second->SetCompatibleIdentify(deviceId); + } + } +} } // namespace DistributedKv } // namespace OHOS diff --git a/services/distributeddataservice/app/src/kvstore_app_manager.h b/services/distributeddataservice/app/src/kvstore_app_manager.h index ca356d949..18ed57d38 100755 --- a/services/distributeddataservice/app/src/kvstore_app_manager.h +++ b/services/distributeddataservice/app/src/kvstore_app_manager.h @@ -19,41 +19,37 @@ #include #include #include + +#include "directory_manager.h" #include "flowctrl_manager/kvstore_flowctrl_manager.h" #include "kv_store_delegate_manager.h" -#include "kvstore_impl.h" -#include "types.h" -#include "single_kvstore_impl.h" #include "kv_store_nb_delegate.h" +#include "kvstore_impl.h" #include "nocopyable.h" +#include "single_kvstore_impl.h" +#include "types.h" namespace OHOS { namespace DistributedKv { class KvStoreAppManager { public: - enum PathType { - PATH_DE, - PATH_CE, - PATH_TYPE_MAX - }; - KvStoreAppManager(const std::string &bundleName, pid_t uid); virtual ~KvStoreAppManager(); - Status GetKvStore(const Options &options, const std::string &appId, const std::string &storeId, - const std::vector &cipherKey, sptr &kvStore); + Status GetKvStore(const Options &options, const DistributedData::StoreMetaData &storeMeta, + const std::vector &cipherKey, sptr &kvStore); - Status GetKvStore(const Options &options, const std::string &appId, const std::string &storeId, - const std::vector &cipherKey, sptr &kvStore); + Status GetKvStore(const Options &options, const DistributedData::StoreMetaData &storeMeta, + const std::vector &cipherKey, sptr &kvStore); - Status CloseKvStore(const std::string &storeId); + Status CloseKvStore(const DistributedData::StoreMetaData &storeMeta); - Status CloseAllKvStore(); + Status CloseAllKvStore(const DistributedData::StoreMetaData &storeMeta); - Status DeleteKvStore(const std::string &storeId); + Status DeleteKvStore(const DistributedData::StoreMetaData &storeMeta); - Status DeleteAllKvStore(); + Status DeleteAllKvStore(const std::string &appId); Status MigrateAllKvStore(const std::string &harmonyAccountId); @@ -64,38 +60,39 @@ public: DistributedDB::KvStoreNbDelegate::Option &dbOption); static std::string GetDataStoragePath(const std::string &userId, const std::string &bundleName, - PathType type); + DistributedData::PathType type); - static PathType ConvertPathType(int32_t uid, const std::string &bundleName, int securityLevel); - - std::string GetDbDir(const Options &options) const; + std::string GetDbDir(const DistributedData::StoreMetaData &storeMeta) const; void Dump(int fd) const; static DistributedDB::SecurityOption ConvertSecurity(int securityLevel); size_t GetTotalKvStoreNum() const; + + bool IsStoreOpened(const std::string &storeId) const; + void SetCompatibleIdentify(const std::string &deviceId) const; private: DISALLOW_COPY_AND_MOVE(KvStoreAppManager); Status ConvertErrorStatus(DistributedDB::DBStatus dbStatus, bool createIfMissing); - DistributedDB::KvStoreDelegateManager *GetDelegateManager(PathType type); - DistributedDB::KvStoreDelegateManager *SwitchDelegateManager(PathType type, + DistributedDB::KvStoreDelegateManager *GetDelegateManager(DistributedData::PathType type, const DistributedData::StoreMetaData &storeMeta); + DistributedDB::KvStoreDelegateManager *SwitchDelegateManager(DistributedData::PathType type, DistributedDB::KvStoreDelegateManager *delegateManager); - Status CloseKvStore(const std::string &storeId, PathType type); - Status CloseAllKvStore(PathType type); - Status DeleteKvStore(const std::string &storeId, PathType type); - Status DeleteAllKvStore(PathType type); - Status MigrateAllKvStore(const std::string &harmonyAccountId, PathType type); + Status CloseKvStore(DistributedData::PathType type, const DistributedData::StoreMetaData &storeMeta); + Status CloseAllKvStore(DistributedData::PathType type, const DistributedData::StoreMetaData &storeMeta); + Status DeleteKvStore(const DistributedData::StoreMetaData &storeMeta, DistributedData::PathType type); + Status DeleteAllKvStore(DistributedData::PathType type, const DistributedData::StoreMetaData &storeMeta); + Status MigrateAllKvStore(const std::string &harmonyAccountId, DistributedData::PathType type); std::mutex storeMutex_ {}; - std::map> stores_[PATH_TYPE_MAX] {}; - std::map> singleStores_[PATH_TYPE_MAX] {}; - std::string userId_ {}; + std::map> stores_[DistributedData::PATH_TYPE_MAX] {}; + std::map> singleStores_[DistributedData::PATH_TYPE_MAX] {}; + std::string accountId_{}; std::string bundleName_ {}; - std::string deviceAccountId_ {}; + std::string userId_{}; std::string trueAppId_ {}; pid_t uid_; std::mutex delegateMutex_ {}; - DistributedDB::KvStoreDelegateManager *delegateManagers_[PATH_TYPE_MAX] {nullptr, nullptr}; + DistributedDB::KvStoreDelegateManager *delegateManagers_[DistributedData::PATH_TYPE_MAX] {nullptr, nullptr}; KvStoreFlowCtrlManager flowCtrl_; static inline const int BURST_CAPACITY = 50; static inline const int SUSTAINED_CAPACITY = 500; diff --git a/services/distributeddataservice/app/src/kvstore_base.h b/services/distributeddataservice/app/src/kvstore_base.h new file mode 100644 index 000000000..f2301c14b --- /dev/null +++ b/services/distributeddataservice/app/src/kvstore_base.h @@ -0,0 +1,26 @@ +/* +* 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. +*/ + +#ifndef SDB_KVSTOREBASE_H +#define SDB_KVSTOREBASE_H +namespace OHOS { +namespace DistributedKv { +class KvStoreBase { +public: + virtual std::string GetName() const = 0; +}; +} +}// namespace OHOS +#endif//SDB_KVSTOREBASE_H diff --git a/services/distributeddataservice/app/src/kvstore_data_service.cpp b/services/distributeddataservice/app/src/kvstore_data_service.cpp index 41ee80e4a..7a2689701 100644 --- a/services/distributeddataservice/app/src/kvstore_data_service.cpp +++ b/services/distributeddataservice/app/src/kvstore_data_service.cpp @@ -21,9 +21,11 @@ #include #include #include + #include #include +#include "auth/auth_delegate.h" #include "auto_launch_export.h" #include "bootstrap.h" #include "checker/checker_manager.h" @@ -37,6 +39,7 @@ #include "kvstore_account_observer.h" #include "kvstore_app_accessor.h" #include "kvstore_meta_manager.h" +#include "kvstore_user_observer.h" #include "kvstore_utils.h" #include "log_print.h" #include "permission/permission.h" @@ -45,9 +48,11 @@ #include "process_communicator_impl.h" #include "rdb_service_impl.h" #include "reporter.h" +#include "route_head_handler.h" #include "system_ability_definition.h" #include "uninstaller/uninstaller.h" #include "utils/block_integer.h" +#include "user_delegate.h" #include "utils/crypto.h" namespace OHOS::DistributedKv { @@ -58,9 +63,6 @@ using namespace OHOS::DistributedData; using KvStoreDelegateManager = DistributedDB::KvStoreDelegateManager; REGISTER_SYSTEM_ABILITY_BY_ID(KvStoreDataService, DISTRIBUTED_KV_DATA_SERVICE_ABILITY_ID, true); - -constexpr size_t MAX_APP_ID_LENGTH = 256; - KvStoreDataService::KvStoreDataService(bool runOnCreate) : SystemAbility(runOnCreate), accountMutex_(), @@ -90,23 +92,43 @@ KvStoreDataService::~KvStoreDataService() void KvStoreDataService::Initialize() { ZLOGI("begin."); + UserDelegate::GetInstance().Init(); #ifndef UT_TEST KvStoreDelegateManager::SetProcessLabel(Bootstrap::GetInstance().GetProcessLabel(), "default"); #endif - InitSecurityAdapter(); KvStoreMetaManager::GetInstance().InitMetaParameter(); - std::thread th = std::thread([]() { + std::thread th = std::thread([this]() { auto communicator = std::make_shared(); + communicator->SetHeaderHandler(RouteHeadHandlerImpl::GetInstance); auto ret = KvStoreDelegateManager::SetProcessCommunicator(communicator); - ZLOGI("set communicator ret:%d.", static_cast(ret)); - if (KvStoreMetaManager::GetInstance().CheckRootKeyExist() == Status::SUCCESS) { + ZLOGI("set communicator ret:%{public}d.", static_cast(ret)); + ret = DistributedDB::KvStoreDelegateManager::SetSyncActivationCheckCallback( + [this](const std::string &userId, const std::string &appId, const std::string &storeId) { + ZLOGD("get sync enable, user:%{public}s, app:%{public}s, store:%{public}s", userId.c_str(), + appId.c_str(), storeId.c_str()); + std::vector users = UserDelegate::GetInstance().GetAllLocalUserStatus(); + bool isStoreOpened = false; + for (const auto &user : users) { + if (userId == std::to_string(user.id) && !user.isActive) { + ZLOGD("the user %{public}s is not active", userId.c_str()); + return false; + } + if (IsStoreOpened(std::to_string(user.id), appId, storeId)) { + isStoreOpened = true; + } + } + ZLOGD("the store already opened ? %{public}d", isStoreOpened); + return !isStoreOpened; + }); + ZLOGI("set sync activation check callback ret:%{public}d.", static_cast(ret)); + if (KeyManager::CheckRootKeyExist() == Status::SUCCESS) { return; } constexpr int RETRY_MAX_TIMES = 100; int retryCount = 0; constexpr int RETRY_TIME_INTERVAL_MILLISECOND = 1 * 1000 * 1000; // retry after 1 second while (retryCount < RETRY_MAX_TIMES) { - if (KvStoreMetaManager::GetInstance().GenerateRootKey() == Status::SUCCESS) { + if (KeyManager::GenerateRootKey() == Status::SUCCESS) { ZLOGI("GenerateRootKey success."); break; } @@ -117,104 +139,46 @@ void KvStoreDataService::Initialize() }); th.detach(); - accountEventObserver_ = std::make_shared(*this); - AccountDelegate::GetInstance()->Subscribe(accountEventObserver_); + AccountDelegate::GetInstance()->Subscribe(std::make_shared(*this)); + UserDelegate::GetInstance().SubscribeUserEvent(std::make_shared()); + AppDistributedKv::CommunicationProvider::MakeCommunicationProvider()->StartWatchDeviceChange(this, {}); } -Status KvStoreDataService::GetKvStore(const Options &options, const AppId &appId, const StoreId &storeId, - std::function)> callback) +template +Status KvStoreDataService::GetIKvStore(const Options &options, const AppId &appId, const StoreId &storeId, + std::function)> callback) { ZLOGI("begin."); - DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); - if (!appId.IsValid() || !storeId.IsValid() || options.kvStoreType != KvStoreType::MULTI_VERSION) { - ZLOGE("invalid argument type."); - return Status::INVALID_ARGUMENT; - } KVSTORE_ACCOUNT_EVENT_PROCESSING_CHECKER(Status::SYSTEM_ACCOUNT_EVENT_PROCESSING); - KvStoreParam param; - param.bundleName = appId.appId; - param.storeId = storeId.storeId; const int32_t uid = IPCSkeleton::GetCallingUid(); - param.trueAppId = CheckerManager::GetInstance().GetAppId(appId.appId, uid); - if (param.trueAppId.empty()) { - ZLOGW("appId:%{public}s, uid:%{public}d, PERMISSION_DENIED", appId.appId.c_str(), uid); - return Status::PERMISSION_DENIED; - } - - param.userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid); - SecretKeyPara keyPara; - Status status = KvStoreDataService::GetSecretKey(options, param, keyPara); - if (status != Status::SUCCESS) { - callback(nullptr); - return status; - } - - auto it = deviceAccountMap_.find(param.userId); - if (it == deviceAccountMap_.end()) { - auto result = deviceAccountMap_.emplace(std::piecewise_construct, - std::forward_as_tuple(param.userId), std::forward_as_tuple(param.userId)); - if (!result.second) { - ZLOGE("emplace failed."); - FaultMsg msg = {FaultType::RUNTIME_FAULT, "user", __FUNCTION__, Fault::RF_GET_DB}; - Reporter::GetInstance()->ServiceFault()->Report(msg); + Status status = Status::INVALID_ARGUMENT; + StoreMetaData storeMeta = KvStoreMetaManager::GetInstance().GetStoreMeta(uid, appId, storeId, status); + if (status == Status::KEY_NOT_FOUND) { + storeMeta = KvStoreMetaManager::BuildStoreMeta(options, appId, storeId, uid, status); + if (status != Status::SUCCESS) { + ZLOGI("get meta data failed."); callback(nullptr); - return Status::ERROR; + return status; } - it = result.first; - } - - sptr store; - param.status = (it->second).GetKvStore(options, param.bundleName, param.storeId, uid, keyPara.secretKey, store); - if (keyPara.outdated) { - KvStoreMetaManager::GetInstance().ReKey(param.userId, param.bundleName, param.storeId, - KvStoreAppManager::ConvertPathType(param.uid, param.bundleName, options.securityLevel), store); - } - - ZLOGD("get kvstore return status:%d, userId:[%s], bundleName:[%s].", - param.status, KvStoreUtils::ToBeAnonymous(param.userId).c_str(), appId.appId.c_str()); - if (param.status == Status::SUCCESS) { - callback(std::move(store)); - return UpdateMetaData(options, param, keyPara.metaKey, it->second); + } else { + callback(nullptr); + return status; } - param.status = GetKvStoreFailDo(options, param, keyPara, it->second, store); - callback(std::move(store)); - return param.status; -} - -Status KvStoreDataService::GetSingleKvStore(const Options &options, const AppId &appId, const StoreId &storeId, - std::function)> callback) -{ - DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); - ZLOGI("begin."); - if (!appId.IsValid() || !storeId.IsValid() || !options.IsValidType() - || options.kvStoreType == KvStoreType::MULTI_VERSION) { - ZLOGE("invalid argument type."); + if (!CheckOptions(options, storeMeta)) { + ZLOGE("encrypt type or kvStore type is not the same"); return Status::INVALID_ARGUMENT; } - - KVSTORE_ACCOUNT_EVENT_PROCESSING_CHECKER(Status::SYSTEM_ACCOUNT_EVENT_PROCESSING); - KvStoreParam param; - param.bundleName = appId.appId; - param.storeId = storeId.storeId; - const int32_t uid = IPCSkeleton::GetCallingUid(); - param.trueAppId = CheckerManager::GetInstance().GetAppId(appId.appId, uid); - if (param.trueAppId.empty()) { - ZLOGW("appId:%{public}s, uid:%{public}d, PERMISSION_DENIED", appId.appId.c_str(), uid); - return Status::PERMISSION_DENIED; - } - - param.userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid); - SecretKeyPara keyPara; - Status status = KvStoreDataService::GetSecretKey(options, param, keyPara); + sptr store; + SecretKey secretKey = KeyManager::GetSecretKey(storeMeta, store->KeyName(), status); if (status != Status::SUCCESS) { callback(nullptr); return status; } - auto it = deviceAccountMap_.find(param.userId); + auto it = deviceAccountMap_.find(storeMeta.userId); if (it == deviceAccountMap_.end()) { auto result = deviceAccountMap_.emplace(std::piecewise_construct, - std::forward_as_tuple(param.userId), std::forward_as_tuple(param.userId)); + std::forward_as_tuple(storeMeta.userId), std::forward_as_tuple(storeMeta.userId)); if (!result.second) { ZLOGE("emplace failed."); callback(nullptr); @@ -222,237 +186,81 @@ Status KvStoreDataService::GetSingleKvStore(const Options &options, const AppId } it = result.first; } - sptr store; - param.status = (it->second).GetKvStore(options, param.bundleName, param.storeId, uid, keyPara.secretKey, store); - if (keyPara.outdated) { - KvStoreMetaManager::GetInstance().ReKey(param.userId, param.bundleName, param.storeId, - KvStoreAppManager::ConvertPathType(param.uid, param.bundleName, options.securityLevel), store); + status = (it->second).GetKvStore(storeMeta, options, secretKey.data, store); + if (secretKey.outdated) { + KeyManager::ReKey(storeMeta, store); } - if (param.status == Status::SUCCESS) { + ZLOGD("get kvstore return status:%{public}d, userId:[%{public}s], bundleName:[%{public}s].", status, storeMeta.userId.c_str(), + appId.appId.c_str()); + if (status == Status::SUCCESS) { callback(std::move(store)); - return UpdateMetaData(options, param, keyPara.metaKey, it->second); + return KvStoreMetaManager::GetInstance().UpdateKvStoreMeta(storeMeta); } - param.status = GetSingleKvStoreFailDo(options, param, keyPara, it->second, store); + status = GetKvStoreFailDo(options, storeMeta, secretKey, it->second, store, status); callback(std::move(store)); - return param.status; + return status; } -Status KvStoreDataService::GetSecretKey(const Options &options, const KvStoreParam &kvParas, - SecretKeyPara &secretKeyParas) +Status KvStoreDataService::GetKvStore(const Options &options, const AppId &appId, const StoreId &storeId, + std::function)> callback) { - std::string bundleName = kvParas.bundleName; - std::string storeIdTmp = kvParas.storeId; - std::lock_guard lg(accountMutex_); - auto metaKey = KvStoreMetaManager::GetMetaKey(kvParas.userId, "default", bundleName, storeIdTmp); - if (!CheckOptions(options, metaKey)) { - ZLOGE("encrypt type or kvStore type is not the same"); + DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); + if (options.kvStoreType != KvStoreType::MULTI_VERSION) { return Status::INVALID_ARGUMENT; } - std::vector secretKey; - std::unique_ptr, void (*)(std::vector *)> cleanGuard( - &secretKey, [](std::vector *ptr) { ptr->assign(ptr->size(), 0); }); - - std::vector metaSecretKey; - std::string secretKeyFile; - if (options.kvStoreType == KvStoreType::MULTI_VERSION) { - metaSecretKey = KvStoreMetaManager::GetMetaKey(kvParas.userId, "default", bundleName, storeIdTmp, "KEY"); - secretKeyFile = KvStoreMetaManager::GetSecretKeyFile(kvParas.userId, bundleName, storeIdTmp, - KvStoreAppManager::ConvertPathType(kvParas.uid, bundleName, options.securityLevel)); - } else { - metaSecretKey = KvStoreMetaManager::GetMetaKey(kvParas.userId, "default", bundleName, storeIdTmp, "SINGLE_KEY"); - secretKeyFile = KvStoreMetaManager::GetSecretSingleKeyFile(kvParas.userId, bundleName, storeIdTmp, - KvStoreAppManager::ConvertPathType(kvParas.uid, bundleName, options.securityLevel)); - } - - bool outdated = false; - Status alreadyCreated = KvStoreMetaManager::GetInstance().CheckUpdateServiceMeta(metaSecretKey, CHECK_EXIST_LOCAL); - if (options.encrypt) { - ZLOGI("Getting secret key"); - Status recStatus = RecoverSecretKey(alreadyCreated, outdated, metaSecretKey, secretKey, secretKeyFile); - if (recStatus != Status::SUCCESS) { - return recStatus; - } - } else { - if (alreadyCreated == Status::SUCCESS || FileExists(secretKeyFile)) { - ZLOGW("try to get an encrypted store with false option encrypt parameter"); - return Status::CRYPT_ERROR; - } - } - - SecretKeyPara kvStoreSecretKey; - kvStoreSecretKey.metaKey = metaKey; - kvStoreSecretKey.secretKey = secretKey; - kvStoreSecretKey.metaSecretKey = metaSecretKey; - kvStoreSecretKey.secretKeyFile = secretKeyFile; - kvStoreSecretKey.alreadyCreated = alreadyCreated; - kvStoreSecretKey.outdated = outdated; - secretKeyParas = kvStoreSecretKey; - - return Status::SUCCESS; -} - -Status KvStoreDataService::RecoverSecretKey(const Status &alreadyCreated, bool &outdated, - const std::vector &metaSecretKey, std::vector &secretKey, const std::string &secretKeyFile) -{ - if (alreadyCreated != Status::SUCCESS) { - KvStoreMetaManager::GetInstance().RecoverSecretKeyFromFile( - secretKeyFile, metaSecretKey, secretKey, outdated); - if (secretKey.empty()) { - ZLOGI("new secret key"); - secretKey = Crypto::Random(32); // 32 is key length - KvStoreMetaManager::GetInstance().WriteSecretKeyToMeta(metaSecretKey, secretKey); - KvStoreMetaManager::GetInstance().WriteSecretKeyToFile(secretKeyFile, secretKey); - } - } else { - KvStoreMetaManager::GetInstance().GetSecretKeyFromMeta(metaSecretKey, secretKey, outdated); - if (secretKey.empty()) { - ZLOGW("get secret key from meta failed, try to recover"); - KvStoreMetaManager::GetInstance().RecoverSecretKeyFromFile( - secretKeyFile, metaSecretKey, secretKey, outdated); - } - if (secretKey.empty()) { - ZLOGW("recover failed"); - return Status::CRYPT_ERROR; - } - KvStoreMetaManager::GetInstance().WriteSecretKeyToFile(secretKeyFile, secretKey); - } - return Status::SUCCESS; -} - -Status KvStoreDataService::UpdateMetaData(const Options &options, const KvStoreParam &kvParas, - const std::vector &metaKey, KvStoreUserManager &kvStoreUserManager) -{ - KvStoreMetaData metaData; - metaData.appId = kvParas.trueAppId; - metaData.appType = "harmony"; - metaData.bundleName = kvParas.bundleName; - metaData.deviceAccountId = kvParas.userId; - metaData.deviceId = DeviceKvStoreImpl::GetLocalDeviceId(); - metaData.isAutoSync = options.autoSync; - metaData.isBackup = options.backup; - metaData.isEncrypt = options.encrypt; - metaData.kvStoreType = options.kvStoreType; - metaData.schema = options.schema; - metaData.storeId = kvParas.storeId; - metaData.userId = AccountDelegate::GetInstance()->GetCurrentAccountId(kvParas.bundleName); - metaData.uid = IPCSkeleton::GetCallingUid(); - metaData.version = STORE_VERSION; - metaData.securityLevel = options.securityLevel; - metaData.dataDir = kvStoreUserManager.GetDbDir(kvParas.bundleName, options); - - std::string jsonStr = metaData.Marshal(); - std::vector jsonVec(jsonStr.begin(), jsonStr.end()); - return KvStoreMetaManager::GetInstance().CheckUpdateServiceMeta(metaKey, UPDATE, jsonVec); + return GetIKvStore(options, appId, storeId, callback); } -Status KvStoreDataService::GetKvStoreFailDo(const Options &options, const KvStoreParam &kvParas, - SecretKeyPara &secKeyParas, KvStoreUserManager &kvUserManager, sptr &store) +Status KvStoreDataService::GetSingleKvStore(const Options &options, const AppId &appId, const StoreId &storeId, + std::function)> callback) { - Status statusTmp = kvParas.status; - Status getKvStoreStatus = statusTmp; - int32_t path = KvStoreAppManager::ConvertPathType(kvParas.uid, kvParas.bundleName, options.securityLevel); - ZLOGW("getKvStore failed with status %d", static_cast(getKvStoreStatus)); - if (getKvStoreStatus == Status::CRYPT_ERROR && options.encrypt) { - if (secKeyParas.alreadyCreated != Status::SUCCESS) { - // create encrypted store failed, remove secret key - KvStoreMetaManager::GetInstance().RemoveSecretKey(kvParas.uid, kvParas.bundleName, kvParas.storeId); - return Status::ERROR; - } - // get existing encrypted store failed, retry with key stored in file - Status status = KvStoreMetaManager::GetInstance().RecoverSecretKeyFromFile( - secKeyParas.secretKeyFile, secKeyParas.metaSecretKey, secKeyParas.secretKey, secKeyParas.outdated); - if (status != Status::SUCCESS) { - store = nullptr; - return Status::CRYPT_ERROR; - } - // here callback is called twice - statusTmp = kvUserManager.GetKvStore( - options, kvParas.bundleName, kvParas.storeId, kvParas.uid, secKeyParas.secretKey, store); - if (secKeyParas.outdated) { - KvStoreMetaManager::GetInstance().ReKey(kvParas.userId, kvParas.bundleName, kvParas.storeId, path, store); - } - } - - // if kvstore damaged and no backup file, then return DB_ERROR - if (statusTmp != Status::SUCCESS && getKvStoreStatus == Status::CRYPT_ERROR) { - // if backup file not exist, dont need recover - if (!CheckBackupFileExist(kvParas.userId, kvParas.bundleName, kvParas.storeId, path)) { - return Status::CRYPT_ERROR; - } - // remove damaged database - if (DeleteKvStoreOnly(kvParas.storeId, kvParas.userId, kvParas.bundleName) != Status::SUCCESS) { - ZLOGE("DeleteKvStoreOnly failed."); - return Status::DB_ERROR; - } - // recover database - return RecoverKvStore(options, kvParas.bundleName, kvParas.storeId, secKeyParas.secretKey, store); + DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); + if (options.kvStoreType != KvStoreType::SINGLE_VERSION && options.kvStoreType != KvStoreType::DEVICE_COLLABORATION) { + return Status::INVALID_ARGUMENT; } - return statusTmp; + return GetIKvStore(options, appId, storeId, callback); } -Status KvStoreDataService::GetSingleKvStoreFailDo(const Options &options, const KvStoreParam &kvParas, - SecretKeyPara &secKeyParas, KvStoreUserManager &kvUserManager, sptr &kvStore) +template +Status KvStoreDataService::GetKvStoreFailDo(const Options &options, const StoreMetaData &storeMeta, SecretKey &secKey, + KvStoreUserManager &kvUserManager, sptr &kvStore, Status getKvStoreStatus) { - Status statusTmp = kvParas.status; - Status getKvStoreStatus = statusTmp; - int32_t path = KvStoreAppManager::ConvertPathType(kvParas.uid, kvParas.bundleName, options.securityLevel); - ZLOGW("getKvStore failed with status %d", static_cast(getKvStoreStatus)); + Status statusTmp = getKvStoreStatus; + ZLOGW("getKvStore failed with status %{public}d", static_cast(getKvStoreStatus)); if (getKvStoreStatus == Status::CRYPT_ERROR && options.encrypt) { - if (secKeyParas.alreadyCreated != Status::SUCCESS) { + if (!secKey.IsEmpty()) { // create encrypted store failed, remove secret key - KvStoreMetaManager::GetInstance().RemoveSecretKey(kvParas.uid, kvParas.bundleName, kvParas.storeId); + KeyManager::RemoveSecretKey(storeMeta); return Status::ERROR; } - // get existing encrypted store failed, retry with key stored in file - Status status = KvStoreMetaManager::GetInstance().RecoverSecretKeyFromFile( - secKeyParas.secretKeyFile, secKeyParas.metaSecretKey, secKeyParas.secretKey, secKeyParas.outdated); - if (status != Status::SUCCESS) { - kvStore = nullptr; - return Status::CRYPT_ERROR; - } // here callback is called twice - statusTmp = kvUserManager.GetKvStore( - options, kvParas.bundleName, kvParas.storeId, kvParas.uid, secKeyParas.secretKey, kvStore); - if (secKeyParas.outdated) { - KvStoreMetaManager::GetInstance().ReKey(kvParas.userId, kvParas.bundleName, kvParas.storeId, path, kvStore); - } + statusTmp = kvUserManager.GetKvStore(storeMeta, options, secKey.data, kvStore); } // if kvstore damaged and no backup file, then return DB_ERROR if (statusTmp != Status::SUCCESS && getKvStoreStatus == Status::CRYPT_ERROR) { // if backup file not exist, dont need recover - if (!CheckBackupFileExist(kvParas.userId, kvParas.bundleName, kvParas.storeId, path)) { + if (!CheckBackupFileExist(storeMeta)) { return Status::CRYPT_ERROR; } // remove damaged database - if (DeleteKvStoreOnly(kvParas.storeId, kvParas.userId, kvParas.bundleName) != Status::SUCCESS) { + if (DeleteKvStoreOnly(storeMeta) != Status::SUCCESS) { ZLOGE("DeleteKvStoreOnly failed."); return Status::DB_ERROR; } // recover database - return RecoverKvStore(options, kvParas.bundleName, kvParas.storeId, secKeyParas.secretKey, kvStore); + return RecoverKvStore(options, storeMeta, secKey.data, kvStore); } return statusTmp; } -bool KvStoreDataService::CheckOptions(const Options &options, const std::vector &metaKey) const +bool KvStoreDataService::CheckOptions(const Options &options, const StoreMetaData &metaData) const { ZLOGI("begin."); - KvStoreMetaData metaData; - metaData.version = 0; - Status statusTmp = KvStoreMetaManager::GetInstance().GetKvStoreMeta(metaKey, metaData); - if (statusTmp == Status::KEY_NOT_FOUND) { - ZLOGI("get metaKey not found."); - return true; - } - if (statusTmp != Status::SUCCESS) { - ZLOGE("get metaKey failed."); - return false; - } - ZLOGI("metaData encrypt is %d, kvStore type is %d, options encrypt is %d, kvStore type is %d", - static_cast(metaData.isEncrypt), static_cast(metaData.kvStoreType), - static_cast(options.encrypt), static_cast(options.kvStoreType)); + ZLOGI("metaData encrypt is %{public}d, kvStore type is %{public}d, options encrypt is %{public}d, kvStore type is %{public}d", + static_cast(metaData.isEncrypt), static_cast(metaData.kvStoreType), + static_cast(options.encrypt), static_cast(options.kvStoreType)); if (options.encrypt != metaData.isEncrypt) { ZLOGE("checkOptions encrypt type is not the same."); return false; @@ -466,14 +274,13 @@ bool KvStoreDataService::CheckOptions(const Options &options, const std::vector< return true; } -bool KvStoreDataService::CheckBackupFileExist(const std::string &userId, const std::string &bundleName, - const std::string &storeId, int pathType) +bool KvStoreDataService::CheckBackupFileExist(const StoreMetaData &storeMeta) { - std::initializer_list backupFileNameList = {Constant::DEFAULT_GROUP_ID, "_", - bundleName, "_", storeId}; + std::initializer_list backupFileNameList = { Constant::DEFAULT_GROUP_ID, "_", storeMeta.bundleName, + "_", storeMeta.storeId }; auto backupFileName = Constant::Concatenate(backupFileNameList); - std::initializer_list backFileList = {BackupHandler::GetBackupPath(userId, pathType), - "/", BackupHandler::GetHashedBackupName(backupFileName)}; + std::initializer_list backFileList = { BackupHandler::GetBackupPath(storeMeta), "/", + BackupHandler::GetHashedBackupName(backupFileName) }; auto backFilePath = Constant::Concatenate(backFileList); if (!BackupHandler::FileExists(backFilePath)) { ZLOGE("BackupHandler file is not exist."); @@ -481,16 +288,17 @@ bool KvStoreDataService::CheckBackupFileExist(const std::string &userId, const s } return true; } + template -Status KvStoreDataService::RecoverKvStore(const Options &options, const std::string &bundleName, - const std::string &storeId, const std::vector &secretKey, sptr &kvStore) +Status KvStoreDataService::RecoverKvStore(const Options &options, const DistributedData::StoreMetaData &storeMeta, + const std::vector &secretKey, sptr &kvStore) { // restore database - std::string storeIdTmp = storeId; + std::string storeIdTmp = storeMeta.storeId; Options optionsTmp = options; optionsTmp.createIfMissing = true; const int32_t uid = IPCSkeleton::GetCallingUid(); - std::string trueAppId = CheckerManager::GetInstance().GetAppId(bundleName, uid); + std::string trueAppId = CheckerManager::GetInstance().GetAppId(storeMeta.bundleName, uid); const std::string deviceAccountId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid); auto it = deviceAccountMap_.find(deviceAccountId); if (it == deviceAccountMap_.end()) { @@ -498,14 +306,14 @@ Status KvStoreDataService::RecoverKvStore(const Options &options, const std::str return Status::INVALID_ARGUMENT; } - Status statusTmp = (it->second).GetKvStore(optionsTmp, bundleName, storeIdTmp, uid, secretKey, kvStore); + Status statusTmp = (it->second).GetKvStore(storeMeta, optionsTmp, secretKey, kvStore); // restore database failed if (statusTmp != Status::SUCCESS || kvStore == nullptr) { ZLOGE("RecoverSingleKvStore reget GetSingleKvStore failed."); return Status::DB_ERROR; } // recover database from backup file - bool importRet = kvStore->Import(bundleName); + bool importRet = kvStore->Import(storeMeta.bundleName); if (!importRet) { ZLOGE("RecoverSingleKvStore Import failed."); return Status::RECOVER_FAILED; @@ -519,51 +327,27 @@ void KvStoreDataService::GetAllKvStoreId( { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); ZLOGI("GetAllKvStoreId begin."); - std::string bundleName = Constant::TrimCopy(appId.appId); std::vector storeIdList; - if (bundleName.empty() || bundleName.size() > MAX_APP_ID_LENGTH) { - ZLOGE("invalid appId."); + if (!appId.IsValid()) { + ZLOGE("invalid appId %{public}s.", appId.appId.c_str()); callback(Status::INVALID_ARGUMENT, storeIdList); return; } - auto &metaKvStoreDelegate = KvStoreMetaManager::GetInstance().GetMetaKvStore(); - if (metaKvStoreDelegate == nullptr) { - ZLOGE("metaKvStoreDelegate is null"); - callback(Status::DB_ERROR, storeIdList); - return; - } - - const int32_t uid = IPCSkeleton::GetCallingUid(); - const std::string userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid); - std::vector dbEntries; - DistributedDB::DBStatus dbStatus; - DistributedDB::Key dbKey = KvStoreMetaRow::GetKeyFor(DeviceKvStoreImpl::GetLocalDeviceId() + - Constant::KEY_SEPARATOR + userId + Constant::KEY_SEPARATOR + - "default" + Constant::KEY_SEPARATOR + bundleName + Constant::KEY_SEPARATOR); - DdsTrace traceDelegate(std::string(LOG_TAG "Delegate::") + std::string(__FUNCTION__)); - dbStatus = metaKvStoreDelegate->GetEntries(dbKey, dbEntries); - if (dbStatus != DistributedDB::DBStatus::OK) { - ZLOGE("GetEntries delegate return error: %d.", static_cast(dbStatus)); - if (dbEntries.empty()) { - callback(Status::SUCCESS, storeIdList); - } else { - callback(Status::DB_ERROR, storeIdList); - } + pid_t uid = IPCSkeleton::GetCallingUid(); + std::string trueAppId = CheckerManager::GetInstance().GetAppId(appId.appId, uid); + if (trueAppId.empty()) { + ZLOGE("get appId failed."); + callback(Status::PERMISSION_DENIED, storeIdList); return; } - - for (const auto &entry : dbEntries) { - std::string keyStr = std::string(entry.key.begin(), entry.key.end()); - size_t pos = keyStr.find_last_of(Constant::KEY_SEPARATOR); - if (pos == std::string::npos) { - continue; - } - StoreId storeId; - storeId.storeId = keyStr.substr(pos + 1); - storeIdList.push_back(storeId); + std::string userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid); + Status status = Status::SUCCESS; + { + DdsTrace trace(std::string(LOG_TAG "Delegate::") + std::string(__FUNCTION__)); + storeIdList = KvStoreMetaManager::GetInstance().GetStoreIdsOfApp(userId, appId, status); } - callback(Status::SUCCESS, storeIdList); + callback(status, storeIdList); } Status KvStoreDataService::CloseKvStore(const AppId &appId, const StoreId &storeId) @@ -571,7 +355,7 @@ Status KvStoreDataService::CloseKvStore(const AppId &appId, const StoreId &store DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); ZLOGI("begin."); if (!appId.IsValid() || !storeId.IsValid()) { - ZLOGE("invalid bundleName."); + ZLOGE("invalid appId or storeId."); return Status::INVALID_ARGUMENT; } @@ -582,22 +366,33 @@ Status KvStoreDataService::CloseKvStore(const AppId &appId, const StoreId &store return Status::PERMISSION_DENIED; } const std::string userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid); + Status status = Status::SUCCESS; + StoreMetaData storeMeta = KvStoreMetaManager::BuildStoreMeta({}, appId, storeId, uid, status); + if (status != Status::SUCCESS) { + return status; + } + status = CloseKvStore(storeMeta); + FaultMsg msg = { FaultType::RUNTIME_FAULT, "user", __FUNCTION__, Fault::RF_CLOSE_DB }; + Reporter::GetInstance()->ServiceFault()->Report(msg); + ZLOGE("return STORE_NOT_OPEN."); + return status; +} + +Status KvStoreDataService::CloseKvStore(const DistributedData::StoreMetaData &storeMeta) { std::lock_guard lg(accountMutex_); - auto it = deviceAccountMap_.find(userId); + auto it = deviceAccountMap_.find(storeMeta.userId); + Status status = Status::SUCCESS; if (it != deviceAccountMap_.end()) { - Status status = (it->second).CloseKvStore(appId.appId, storeId.storeId); + status = (it->second).CloseKvStore(storeMeta); if (status != Status::STORE_NOT_OPEN) { return status; } } - FaultMsg msg = {FaultType::RUNTIME_FAULT, "user", __FUNCTION__, Fault::RF_CLOSE_DB}; - Reporter::GetInstance()->ServiceFault()->Report(msg); - ZLOGE("return STORE_NOT_OPEN."); return Status::STORE_NOT_OPEN; } /* close all opened kvstore */ -Status KvStoreDataService::CloseAllKvStore(const AppId &appId) +Status KvStoreDataService::CloseAllKvStore(const AppId &appId, const int32_t &uid) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); ZLOGD("begin."); @@ -605,7 +400,7 @@ Status KvStoreDataService::CloseAllKvStore(const AppId &appId) ZLOGE("invalid bundleName."); return Status::INVALID_ARGUMENT; } - const int32_t uid = IPCSkeleton::GetCallingUid(); + std::string trueAppId = CheckerManager::GetInstance().GetAppId(appId.appId, uid); if (trueAppId.empty()) { ZLOGE("get appId failed."); @@ -613,53 +408,61 @@ Status KvStoreDataService::CloseAllKvStore(const AppId &appId) } const std::string userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid); + Status status = Status::SUCCESS; + StoreMetaData storeMeta = KvStoreMetaManager::BuildStoreMeta({}, appId, {}, uid, status); + if (status != Status::SUCCESS) { + return status; + } std::lock_guard lg(accountMutex_); auto it = deviceAccountMap_.find(userId); if (it != deviceAccountMap_.end()) { - return (it->second).CloseAllKvStore(appId.appId); + return (it->second).CloseAllKvStore(storeMeta); } ZLOGE("store not open."); return Status::STORE_NOT_OPEN; } +Status KvStoreDataService::CloseAllKvStore(const AppId &appId) +{ + const int32_t uid = IPCSkeleton::GetCallingUid(); + return CloseAllKvStore(appId, uid); +} + Status KvStoreDataService::DeleteKvStore(const AppId &appId, const StoreId &storeId) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); - if (!appId.IsValid()) { - ZLOGE("invalid bundleName."); + if (!appId.IsValid() || !storeId.IsValid()) { + ZLOGE("invalid appId: %{public}s or storeId: %{public}s.", appId.appId.c_str(), storeId.storeId.c_str()); return Status::INVALID_ARGUMENT; } - int32_t uid = IPCSkeleton::GetCallingUid(); - if (!CheckerManager::GetInstance().IsValid(appId.appId, uid)) { - ZLOGE("get appId failed."); + const int32_t uid = IPCSkeleton::GetCallingUid(); + const std::string userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid); + std::string trueAppId = CheckerManager::GetInstance().GetAppId(appId.appId, uid); + if (trueAppId.empty()) { + ZLOGE("invalid appId."); return Status::PERMISSION_DENIED; } - // delete the backup file - std::initializer_list backFileList = { - AccountDelegate::GetInstance()->GetCurrentAccountId(), "_", appId.appId, "_", storeId.storeId}; - auto backupFileName = Constant::Concatenate(backFileList); - const std::string userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid); - std::initializer_list backPathListDE = {BackupHandler::GetBackupPath(userId, - KvStoreAppManager::PATH_DE), "/", BackupHandler::GetHashedBackupName(backupFileName)}; - auto backFilePath = Constant::Concatenate(backPathListDE); - if (!BackupHandler::RemoveFile(backFilePath)) { - ZLOGE("DeleteKvStore RemoveFile backFilePath failed."); + Status status = Status::SUCCESS; + StoreMetaData storeMeta = KvStoreMetaManager::BuildStoreMeta({}, appId, storeId, uid, status); + if (status != Status::SUCCESS) { + return status; } - std::initializer_list backPathListCE = {BackupHandler::GetBackupPath(userId, - KvStoreAppManager::PATH_CE), "/", BackupHandler::GetHashedBackupName(backupFileName)}; - backFilePath = Constant::Concatenate(backPathListCE); + // delete the backup file + auto backupFileName = Constant::Concatenate({ userId, "_", appId.appId, "_", storeId.storeId }); + auto backFilePath = Constant::Concatenate( + { BackupHandler::GetBackupPath(storeMeta), "/", BackupHandler::GetHashedBackupName(backupFileName) }); if (!BackupHandler::RemoveFile(backFilePath)) { ZLOGE("DeleteKvStore RemoveFile backFilePath failed."); } - return DeleteKvStore(appId.appId, storeId); + return DeleteKvStore(storeMeta); } /* delete all kv store */ Status KvStoreDataService::DeleteAllKvStore(const AppId &appId) { DdsTrace trace(std::string(LOG_TAG "::") + std::string(__FUNCTION__)); - ZLOGI("%s", appId.appId.c_str()); + ZLOGI("%{public}s", appId.appId.c_str()); if (!appId.IsValid()) { ZLOGE("invalid bundleName."); return Status::INVALID_ARGUMENT; @@ -679,14 +482,14 @@ Status KvStoreDataService::DeleteAllKvStore(const AppId &appId) }); if (statusTmp != Status::SUCCESS) { - ZLOGE("%s, error: %d ", appId.appId.c_str(), static_cast(statusTmp)); + ZLOGE("%{public}s, error: %{public}d ", appId.appId.c_str(), static_cast(statusTmp)); return statusTmp; } for (const auto &storeId : existStoreIds) { statusTmp = DeleteKvStore(appId, storeId); if (statusTmp != Status::SUCCESS) { - ZLOGE("%s, error: %d ", appId.appId.c_str(), static_cast(statusTmp)); + ZLOGE("%{public}s, error: %{public}d ", appId.appId.c_str(), static_cast(statusTmp)); return statusTmp; } } @@ -703,51 +506,48 @@ Status KvStoreDataService::RegisterClientDeathObserver(const AppId &appId, sptr< ZLOGE("invalid bundleName."); return Status::INVALID_ARGUMENT; } - - int32_t uid = IPCSkeleton::GetCallingUid(); - if (!CheckerManager::GetInstance().IsValid(appId.appId, uid)) { + const int32_t uid = IPCSkeleton::GetCallingUid(); + std::string trueAppId = CheckerManager::GetInstance().GetAppId(appId.appId, uid); + if (trueAppId.empty()) { ZLOGE("no permission bundleName:%{public}s, uid:%{public}d.", appId.appId.c_str(), uid); return Status::PERMISSION_DENIED; } + std::string userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid); std::lock_guard lg(clientDeathObserverMutex_); - auto it = clientDeathObserverMap_.emplace(std::piecewise_construct, std::forward_as_tuple(appId.appId), - std::forward_as_tuple(appId, *this, std::move(observer))); + auto it = clientDeathObserverMap_.emplace(std::piecewise_construct, std::forward_as_tuple(userId, trueAppId), + std::forward_as_tuple(appId, uid, *this, std::move(observer))); ZLOGI("map size: %{public}zu.", clientDeathObserverMap_.size()); if (!it.second) { ZLOGI("insert failed"); return Status::ERROR; } ZLOGI("insert success"); - const std::string userId = AccountDelegate::GetInstance()->GetCurrentAccountId(); - KvStoreTuple kvStoreTuple {userId, CheckerManager::GetInstance().GetAppId(appId.appId, uid)}; + KvStoreTuple kvStoreTuple {userId, trueAppId, ""}; AppThreadInfo appThreadInfo {IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid()}; PermissionValidator::RegisterPermissionChanged(kvStoreTuple, appThreadInfo); return Status::SUCCESS; } -Status KvStoreDataService::AppExit(const AppId &appId) +Status KvStoreDataService::AppExit(const AppId &appId, const int32_t &uid) { ZLOGI("AppExit"); + auto userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid); + std::string trueAppId = CheckerManager::GetInstance().GetAppId(appId.appId, uid); + if (trueAppId.empty()) { + ZLOGE("get appid for KvStore failed because of permission denied."); + return Status::PERMISSION_DENIED; + } // memory of parameter appId locates in a member of clientDeathObserverMap_ and will be freed after // clientDeathObserverMap_ erase, so we have to take a copy if we want to use this parameter after erase operation. - AppId appIdTmp = appId; { std::lock_guard lg(clientDeathObserverMutex_); - clientDeathObserverMap_.erase(appIdTmp.appId); + clientDeathObserverMap_.erase({ userId, trueAppId }); ZLOGI("map size: %zu.", clientDeathObserverMap_.size()); } - - std::string trueAppId = CheckerManager::GetInstance().GetAppId(appId.appId, CheckerManager::INVALID_UID); - if (trueAppId.empty()) { - ZLOGE("get appid for KvStore failed because of permission denied."); - return Status::PERMISSION_DENIED; - } - const std::string userId = AccountDelegate::GetInstance()->GetCurrentAccountId(appIdTmp.appId); - KvStoreTuple kvStoreTuple {userId, trueAppId}; + KvStoreTuple kvStoreTuple{ userId, trueAppId }; PermissionValidator::UnregisterPermissionChanged(kvStoreTuple); - - CloseAllKvStore(appIdTmp); + CloseAllKvStore(appId, uid); return Status::SUCCESS; } @@ -766,7 +566,7 @@ int KvStoreDataService::Dump(int fd, const std::vector &args) dprintf(fd, "------------------------------------------------------------------\n"); dprintf(fd, "DeviceAccount count : %u\n", static_cast(deviceAccountMap_.size())); for (const auto &pair : deviceAccountMap_) { - dprintf(fd, "DeviceAccountID : %s\n", pair.first.c_str()); + dprintf(fd, "DeviceAccountID : %{public}s\n", pair.first.c_str()); pair.second.Dump(fd); } return 0; @@ -795,11 +595,11 @@ void KvStoreDataService::AddPermission() const void KvStoreDataService::OnStart() { ZLOGI("distributeddata service onStart"); - Initialize(); Bootstrap::GetInstance().LoadComponents(); Bootstrap::GetInstance().LoadDirectory(); Bootstrap::GetInstance().LoadCheckers(); Bootstrap::GetInstance().LoadNetworks(); + Initialize(); auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); if (samgr != nullptr) { ZLOGI("samgr exist."); @@ -836,25 +636,52 @@ void KvStoreDataService::StartService() // add softbus permission. AddPermission(); #endif - std::string backupPath = BackupHandler::GetBackupPath( - AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(getuid()), KvStoreAppManager::PATH_DE); - ZLOGI("backupPath is : %s ", backupPath.c_str()); - if (!ForceCreateDirectory(backupPath)) { - ZLOGE("backup create directory failed"); - } +// std::string backupPath = BackupHandler::GetBackupPath( +// AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(getuid()), PATH_DE); +// ZLOGI("backupPath is : %{public}s ", backupPath.c_str()); +// if (!ForceCreateDirectory(backupPath)) { +// ZLOGE("backup create directory failed"); +// } // Initialize meta db delegate manager. - KvStoreMetaManager::GetInstance().InitMetaListener([this](const KvStoreMetaData &metaData) { - if (!metaData.isDirty) { - return; - } - - AppId appId; - appId.appId = metaData.bundleName; - StoreId storeId; - storeId.storeId = metaData.storeId; - CloseKvStore(appId, storeId); - DeleteKvStore(appId, storeId); - }); + KvStoreMetaManager::GetInstance().InitMetaListener(); + KvStoreMetaManager::GetInstance().SubscribeMeta(KvStoreMetaRow::KEY_PREFIX, + [this](const std::vector &key, const std::vector &value, CHANGE_FLAG flag) { + if (flag != CHANGE_FLAG::UPDATE) { + return; + } + StoreMetaData metaData; + metaData.Unmarshall({ value.begin(), value.end() }); + ZLOGD("meta data info appType:%{public}s, storeId:%{public}s isDirty:%{public}d", metaData.appType.c_str(), + metaData.storeId.c_str(), metaData.isDirty); + if (metaData.deviceId != DeviceKvStoreImpl::GetLocalDeviceId() || metaData.deviceId.empty()) { + ZLOGD("ignore other device change or invalid meta device"); + return; + } + static constexpr const char *HARMONY_APP = "harmony"; + if (!metaData.isDirty || metaData.appType != HARMONY_APP) { + return; + } + ZLOGI("dirty kv store. storeId:%{public}s", metaData.storeId.c_str()); + CloseKvStore({ metaData.bundleName }, { metaData.storeId }); + DeleteKvStore(metaData); + }); + // subscribe user meta in other devices + KvStoreMetaManager::GetInstance().SubscribeMeta(UserMetaRow::KEY_PREFIX, + [this](const std::vector &key, const std::vector &value, CHANGE_FLAG flag) { + UserMetaData metaData; + metaData.Unmarshall({ value.begin(), value.end() }); + if (metaData.deviceId == DeviceKvStoreImpl::GetLocalDeviceId()) { + ZLOGD("ignore local device user meta change"); + return; + } + if (flag == CHANGE_FLAG::INSERT || flag == CHANGE_FLAG::UPDATE) { + UserDelegate::GetInstance().UpdateUsers(metaData, false); + } else if (flag == CHANGE_FLAG::DELETE) { + UserDelegate::GetInstance().DeleteUsers(metaData.deviceId); + } else { + ZLOGD("ignored operation"); + } + }); // subscribe account event listener to EventNotificationMgr AccountDelegate::GetInstance()->SubscribeAccountEvent(); @@ -862,7 +689,7 @@ void KvStoreDataService::StartService() [this](const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) -> bool { // temp add permission whilelist for ddmp; this should be config in ddmp manifest. - ZLOGD("checking sync permission start appid:%s, stid:%s.", appId.c_str(), storeId.c_str()); + ZLOGD("checking sync permission start appid:%{public}s, stid:%{public}s.", appId.c_str(), storeId.c_str()); return CheckPermissions(userId, appId, storeId, deviceId, flag); }; auto dbStatus = KvStoreDelegateManager::SetPermissionCheckCallback(permissionCheckCallback); @@ -884,7 +711,7 @@ void KvStoreDataService::StartService() KvStoreAppAccessor::GetInstance().EnableKvStoreAutoLaunch(); }); th.detach(); - ZLOGI("Publish ret: %d", static_cast(ret)); + ZLOGI("Publish ret: %{public}d", static_cast(ret)); } bool KvStoreDataService::ResolveAutoLaunchParamByIdentifier(const std::string &identifier, @@ -892,47 +719,102 @@ bool KvStoreDataService::ResolveAutoLaunchParamByIdentifier(const std::string &i { ZLOGI("start"); std::map entries; - if (KvStoreMetaManager::GetInstance().GetFullMetaData(entries)) { - for (const auto &entry : entries) { - const std::string userId = AccountDelegate::GetInstance()->GetCurrentAccountId( - entry.second.kvStoreMetaData.bundleName); - const std::string &curIdentifier = KvStoreDelegateManager::GetKvStoreIdentifier(userId, - entry.second.kvStoreMetaData.appId, entry.second.kvStoreMetaData.storeId); - if (identifier == curIdentifier) { - ZLOGI("identifier find"); - DistributedDB::AutoLaunchOption option; - option.createIfNecessary = false; - option.isEncryptedDb = entry.second.kvStoreMetaData.isEncrypt; - DistributedDB::CipherPassword password; - const std::vector &secretKey = entry.second.secretKeyMetaData.secretKey; - if (password.SetValue(secretKey.data(), secretKey.size()) != DistributedDB::CipherPassword::OK) { - ZLOGE("Get secret key failed."); - } - option.passwd = password; - option.schema = entry.second.kvStoreMetaData.schema; - option.createDirByStoreIdOnly = true; - option.dataDir = entry.second.kvStoreMetaData.dataDir; - option.secOption = KvStoreAppManager::ConvertSecurity(entry.second.kvStoreMetaData.securityLevel); - option.isAutoSync = entry.second.kvStoreMetaData.isAutoSync; - param.userId = userId; - param.appId = entry.second.kvStoreMetaData.appId; - param.storeId = entry.second.kvStoreMetaData.storeId; - param.option = option; - return true; + if (!KvStoreMetaManager::GetInstance().GetFullMetaData(entries)) { + ZLOGE("get full meta failed"); + return false; + } + std::string localDeviceId = DeviceKvStoreImpl::GetLocalDeviceId(); + for (const auto &entry : entries) { + auto &storeMeta = entry.second.kvStoreMetaData; + if ((!param.userId.empty() && (param.userId != storeMeta.userId)) || (localDeviceId != storeMeta.deviceId)) { + // judge local userid and local meta + continue; + } + const std::string &itemTripleIdentifier = DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier( + storeMeta.userId, storeMeta.appId, storeMeta.storeId, false); + const std::string &itemDualIdentifier = DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier( + "", storeMeta.appId, storeMeta.storeId, true); + if (identifier == itemTripleIdentifier) { + // old triple tuple identifier, should SetEqualIdentifier + ResolveAutoLaunchCompatible(entry.second, identifier); + } + if (identifier == itemDualIdentifier || identifier == itemTripleIdentifier) { + ZLOGI("identifier find"); + DistributedDB::AutoLaunchOption option; + option.createIfNecessary = false; + option.isEncryptedDb = storeMeta.isEncrypt; + DistributedDB::CipherPassword password; + const std::vector &secretKey = entry.second.secretKeyMetaData.sKey; + if (password.SetValue(secretKey.data(), secretKey.size()) != DistributedDB::CipherPassword::OK) { + ZLOGE("Get secret key failed."); } + option.passwd = password; + option.schema = storeMeta.schema; + option.createDirByStoreIdOnly = true; + option.dataDir = storeMeta.dataDir; + option.secOption = KvStoreAppManager::ConvertSecurity(storeMeta.securityLevel); + option.isAutoSync = storeMeta.isAutoSync; + option.syncDualTupleMode = true; // dual tuple flag + param.appId = storeMeta.appId; + param.storeId = storeMeta.storeId; + param.option = option; + return true; } } ZLOGI("not find identifier"); return false; } +void KvStoreDataService::ResolveAutoLaunchCompatible(const MetaData &meta, const std::string &identifier) { + ZLOGI("AutoLaunch:peer device is old tuple, begin to open store"); + if (meta.kvStoreType >= KvStoreType::MULTI_VERSION) { + ZLOGW("no longer support multi or higher version store type"); + return; + } + + // open store and SetEqualIdentifier, then close store after 60s + auto &storeMeta = meta.kvStoreMetaData; + auto *delegateManager = new (std::nothrow) DistributedDB::KvStoreDelegateManager(storeMeta.appId, storeMeta.userId); + if (delegateManager == nullptr) { + ZLOGE("get store delegate manager failed"); + return; + } + delegateManager->SetKvStoreConfig({ storeMeta.dataDir }); + Options options = { + .createIfMissing = true, + .encrypt = storeMeta.isEncrypt, + .autoSync = storeMeta.isAutoSync, + .securityLevel = storeMeta.securityLevel, + .kvStoreType = static_cast(storeMeta.kvStoreType), + .dataOwnership = true, + }; + DistributedDB::KvStoreNbDelegate::Option dbOptions; + KvStoreAppManager::InitNbDbOption(options, meta.secretKeyMetaData.sKey, dbOptions); + DistributedDB::KvStoreNbDelegate *store = nullptr; + delegateManager->GetKvStore(storeMeta.storeId, dbOptions, [&identifier, &store, &storeMeta](int status, DistributedDB::KvStoreNbDelegate *delegate){ + ZLOGI("temporary open db for equal identifier, ret:%{public}d", status); + if (delegate != nullptr) { + KvStoreTuple tuple = { storeMeta.deviceAccountId, storeMeta.appId, storeMeta.storeId }; + SingleKvStoreImpl::SetCompatibleIdentifyByType(delegate, tuple, IDENTICAL_ACCOUNT_GROUP); + SingleKvStoreImpl::SetCompatibleIdentifyByType(delegate, tuple, PEER_TO_PEER_GROUP); + store = delegate; + } + }); + std::thread([delegateManager, store]() { + std::this_thread::sleep_for(std::chrono::seconds(60)); + ZLOGI("AutoLaunch:close store after 60s while autolaunch finishied"); + delegateManager->CloseKvStore(store); + delete delegateManager; + }).detach(); +} + bool KvStoreDataService::CheckPermissions(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) const { ZLOGI("userId=%{public}.6s appId=%{public}s storeId=%{public}s flag=%{public}d deviceId=%{public}.4s", userId.c_str(), appId.c_str(), storeId.c_str(), flag, deviceId.c_str()); // only print 4 chars of device id auto &instance = KvStoreMetaManager::GetInstance(); - KvStoreMetaData metaData; + StoreMetaData metaData; auto localDevId = DeviceKvStoreImpl::GetLocalDeviceId(); auto qstatus = instance.QueryKvStoreMetaDataByDeviceIdAndAppId(localDevId, appId, metaData); if (qstatus != Status::SUCCESS) { @@ -961,7 +843,7 @@ bool KvStoreDataService::CheckPermissions(const std::string &userId, const std:: return true; } bool ret = PermissionValidator::CheckSyncPermission(userId, appId, metaData.uid); - ZLOGD("checking sync permission ret:%d.", ret); + ZLOGD("checking sync permission ret:%{public}d.", ret); return ret; } @@ -975,8 +857,8 @@ void KvStoreDataService::OnStop() } KvStoreDataService::KvStoreClientDeathObserverImpl::KvStoreClientDeathObserverImpl( - const AppId &appId, KvStoreDataService &service, sptr observer) - : appId_(appId), dataService_(service), observerProxy_(std::move(observer)), + const AppId &appId, const int32_t &uid, KvStoreDataService &service, sptr observer) + : appId_(appId), uid_(uid), dataService_(service), observerProxy_(std::move(observer)), deathRecipient_(new KvStoreDeathRecipient(*this)) { ZLOGI("KvStoreClientDeathObserverImpl"); @@ -1000,8 +882,8 @@ KvStoreDataService::KvStoreClientDeathObserverImpl::~KvStoreClientDeathObserverI void KvStoreDataService::KvStoreClientDeathObserverImpl::NotifyClientDie() { - ZLOGI("appId: %s", appId_.appId.c_str()); - dataService_.AppExit(appId_); + ZLOGI("appId: %{public}s", appId_.appId.c_str()); + dataService_.AppExit(appId_, uid_); } KvStoreDataService::KvStoreClientDeathObserverImpl::KvStoreDeathRecipient::KvStoreDeathRecipient( @@ -1023,66 +905,33 @@ void KvStoreDataService::KvStoreClientDeathObserverImpl::KvStoreDeathRecipient:: kvStoreClientDeathObserverImpl_.NotifyClientDie(); } -Status KvStoreDataService::DeleteKvStore(const std::string &bundleName, const StoreId &storeId) +Status KvStoreDataService::DeleteKvStore(const StoreMetaData &storeMeta) { ZLOGI("begin."); - if (!storeId.IsValid()) { - ZLOGE("invalid storeId."); - return Status::INVALID_ARGUMENT; - } - - const int32_t uid = IPCSkeleton::GetCallingUid(); - const std::string userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid); std::lock_guard lg(accountMutex_); - Status status; - auto it = deviceAccountMap_.find(userId); - if (it != deviceAccountMap_.end()) { - status = (it->second).DeleteKvStore(bundleName, storeId.storeId); - } else { - KvStoreUserManager kvStoreUserManager(userId); - status = kvStoreUserManager.DeleteKvStore(bundleName, storeId.storeId); - } - + Status status = DeleteKvStoreOnly(storeMeta); if (status == Status::SUCCESS) { - auto metaKey = KvStoreMetaManager::GetMetaKey(userId, "default", bundleName, storeId.storeId); - status = KvStoreMetaManager::GetInstance().CheckUpdateServiceMeta(metaKey, DELETE); - if (status != Status::SUCCESS) { - ZLOGW("Remove Kvstore Metakey failed."); - } - KvStoreMetaManager::GetInstance().RemoveSecretKey(uid, bundleName, storeId.storeId); - KvStoreMetaManager::GetInstance().DeleteStrategyMeta(bundleName, storeId.storeId, userId); + KvStoreMetaManager::GetInstance().DeleteKvStoreMeta(storeMeta); } return status; } - -Status KvStoreDataService::DeleteKvStoreOnly(const std::string &storeId, const std::string &userId, - const std::string &bundleName) +Status KvStoreDataService::DeleteKvStoreOnly(const StoreMetaData &storeMeta) { ZLOGI("DeleteKvStoreOnly begin."); - auto it = deviceAccountMap_.find(userId); + auto it = deviceAccountMap_.find(storeMeta.userId); if (it != deviceAccountMap_.end()) { - return (it->second).DeleteKvStore(bundleName, storeId); + return (it->second).DeleteKvStore(storeMeta); } - KvStoreUserManager kvStoreUserManager(userId); - return kvStoreUserManager.DeleteKvStore(bundleName, storeId); + KvStoreUserManager kvStoreUserManager(storeMeta.userId); + return kvStoreUserManager.DeleteKvStore(storeMeta); } void KvStoreDataService::AccountEventChanged(const AccountEventInfo &eventInfo) { - ZLOGI("account event %d changed process, begin.", eventInfo.status); + ZLOGI("account event %{public}d changed process, begin.", eventInfo.status); std::lock_guard lg(accountMutex_); switch (eventInfo.status) { - case AccountStatus::HARMONY_ACCOUNT_LOGIN: - case AccountStatus::HARMONY_ACCOUNT_LOGOUT: { - g_kvStoreAccountEventStatus = 1; - // migrate all kvstore belong to this device account - for (auto &it : deviceAccountMap_) { - (it.second).MigrateAllKvStore(eventInfo.harmonyAccountId); - } - g_kvStoreAccountEventStatus = 0; - break; - } case AccountStatus::DEVICE_ACCOUNT_DELETE: { g_kvStoreAccountEventStatus = 1; // delete all kvstore belong to this device account @@ -1107,7 +956,7 @@ void KvStoreDataService::AccountEventChanged(const AccountEventInfo &eventInfo) break; } } - ZLOGI("account event %d changed process, end.", eventInfo.status); + ZLOGI("account event %{public}d changed process, end.", eventInfo.status); } Status KvStoreDataService::GetLocalDevice(DeviceInfo &device) @@ -1124,7 +973,7 @@ Status KvStoreDataService::GetDeviceList(std::vector &deviceInfoList DeviceInfo deviceInfo = {device.deviceId, device.deviceName, device.deviceType}; deviceInfoList.push_back(deviceInfo); } - ZLOGD("strategy is %d.", strategy); + ZLOGD("strategy is %{public}d.", strategy); return Status::SUCCESS; } @@ -1162,7 +1011,7 @@ Status KvStoreDataService::StartWatchDeviceChange(sptrAsObject().GetRefPtr(); auto listenerPair = std::make_pair(objectPtr, observer); deviceListeners_.insert(listenerPair); - ZLOGD("strategy is %d.", strategy); + ZLOGD("strategy is %{public}d.", strategy); return Status::SUCCESS; } @@ -1182,6 +1031,25 @@ Status KvStoreDataService::StopWatchDeviceChange(sptrsecond.IsStoreOpened(appId, storeId); +} + +void KvStoreDataService::OnDeviceChanged( + const AppDistributedKv::DeviceInfo &info, const AppDistributedKv::DeviceChangeType &type) const +{ + if (type == AppDistributedKv::DeviceChangeType::DEVICE_OFFLINE) { + ZLOGE("ignore device offline"); + return; + } + + for (const auto &item : deviceAccountMap_) { + item.second.SetCompatibleIdentify(info.deviceId); + } +} + void KvStoreDataService::CreateRdbService() { rdbService_ = new(std::nothrow) DistributedRdb::RdbServiceImpl(); diff --git a/services/distributeddataservice/app/src/kvstore_data_service.h b/services/distributeddataservice/app/src/kvstore_data_service.h index ad981ff9f..93557f456 100755 --- a/services/distributeddataservice/app/src/kvstore_data_service.h +++ b/services/distributeddataservice/app/src/kvstore_data_service.h @@ -17,20 +17,22 @@ #define KVSTORE_DATASERVICE_H #include -#include #include -#include "constant.h" +#include + +#include "account_delegate.h" +#include "backup_handler.h" +#include "device_change_listener_impl.h" #include "ikvstore_data_service.h" +#include "key_manager.h" #include "kvstore_impl.h" #include "kvstore_user_manager.h" +#include "metadata/store_meta_data.h" +#include "reporter.h" #include "single_kvstore_impl.h" #include "system_ability.h" -#include "reporter.h" #include "types.h" -#include "account_delegate.h" -#include "backup_handler.h" -#include "device_change_listener_impl.h" -#include "security/security.h" +#include "utils/constant.h" namespace OHOS::DistributedRdb { class IRdbService; @@ -39,28 +41,31 @@ class RdbServiceImpl; namespace OHOS::DistributedKv { class KvStoreAccountObserver; -class KvStoreDataService : public SystemAbility, public KvStoreDataServiceStub { +class KvStoreDataService : public SystemAbility, public KvStoreDataServiceStub, public AppDistributedKv::AppDeviceStatusChangeListener { DECLARE_SYSTEM_ABILITY(KvStoreDataService); public: - // record kvstore meta version for compatible, should update when modify kvstore meta structure. - static constexpr uint32_t STORE_VERSION = 0x03000001; - explicit KvStoreDataService(bool runOnCreate = false); explicit KvStoreDataService(int32_t systemAbilityId, bool runOnCreate = false); virtual ~KvStoreDataService(); + template + Status GetIKvStore( + const Options &options, const AppId &appId, const StoreId &storeId, std::function)> callback); + Status GetKvStore(const Options &options, const AppId &appId, const StoreId &storeId, - std::function)> callback) override; + std::function)> callback) override; Status GetSingleKvStore(const Options &options, const AppId &appId, const StoreId &storeId, - std::function)> callback) override; + std::function)> callback) override; void GetAllKvStoreId(const AppId &appId, std::function &)> callback) override; Status CloseKvStore(const AppId &appId, const StoreId &storeId) override; + Status CloseKvStore(const DistributedData::StoreMetaData &storeMeta); Status CloseAllKvStore(const AppId &appId) override; + Status CloseAllKvStore(const AppId &appId, const int32_t &uid); Status DeleteKvStore(const AppId &appId, const StoreId &storeId) override; @@ -82,33 +87,16 @@ public: void OnStop() override; - Status DeleteKvStoreOnly(const std::string &storeId, const std::string &userId, const std::string &bundleName); + Status DeleteKvStore(const DistributedData::StoreMetaData &storeMeta); + Status DeleteKvStoreOnly(const DistributedData::StoreMetaData &storeMeta); void AccountEventChanged(const AccountEventInfo &eventInfo); - bool CheckBackupFileExist(const std::string &userId, const std::string &bundleName, - const std::string &storeId, int pathType); - - struct KvStoreParam { - std::string bundleName; - std::string storeId; - std::string trueAppId; - std::string userId; - pid_t uid; - Status status = Status::SUCCESS; - }; - struct SecretKeyPara { - std::vector metaKey; - std::vector secretKey; - std::vector metaSecretKey; - std::string secretKeyFile; - Status alreadyCreated = Status::SUCCESS; - bool outdated = false; - }; + bool CheckBackupFileExist(const DistributedData::StoreMetaData &storeMeta); private: class KvStoreClientDeathObserverImpl { public: - KvStoreClientDeathObserverImpl(const AppId &appId, KvStoreDataService &service, sptr observer); + KvStoreClientDeathObserverImpl(const AppId &appId, const int32_t &uid, KvStoreDataService &service, sptr observer); virtual ~KvStoreClientDeathObserverImpl(); @@ -124,6 +112,7 @@ private: }; void NotifyClientDie(); AppId appId_; + int32_t uid_; KvStoreDataService &dataService_; sptr observerProxy_; sptr deathRecipient_; @@ -135,50 +124,40 @@ private: void StartService(); - void InitSecurityAdapter(); - - Status DeleteKvStore(const std::string &bundleName, const StoreId &storeId); - template - Status RecoverKvStore(const Options &options, const std::string &bundleName, const std::string &storeId, + Status RecoverKvStore(const Options &options, const DistributedData::StoreMetaData &storeMeta, const std::vector &secretKey, sptr &kvStore); - Status GetSecretKey(const Options &options, const KvStoreParam &KvParas, SecretKeyPara &secretKeyParas); - Status RecoverSecretKey(const Status &alreadyCreated, bool &outdated, const std::vector &metaSecretKey, - std::vector &secretKey, const std::string &secretKeyFile); + template + Status GetKvStoreFailDo(const Options &options, const DistributedData::StoreMetaData &storeMeta, + DistributedData::SecretKey &secKey, KvStoreUserManager &kvUserManager, sptr &kvStore, + Status getKvStoreStatus); - Status UpdateMetaData(const Options &options, const KvStoreParam &kvParas, - const std::vector &metaKey, KvStoreUserManager &kvStoreUserManager); - - Status GetKvStoreFailDo(const Options &options, const KvStoreParam &kvParas, SecretKeyPara &secKeyParas, - KvStoreUserManager &kvUserManager, sptr &kvStore); - - Status GetSingleKvStoreFailDo(const Options &options, const KvStoreParam &kvParas, SecretKeyPara &secKeyParas, - KvStoreUserManager &kvUserManager, sptr &kvStore); - - Status AppExit(const AppId &appId); + Status AppExit(const AppId &appId, const int32_t &uid); bool CheckPermissions(const std::string &userId, const std::string &appId, const std::string &storeId, const std::string &deviceId, uint8_t flag) const; bool ResolveAutoLaunchParamByIdentifier(const std::string &identifier, DistributedDB::AutoLaunchParam ¶m); + static void ResolveAutoLaunchCompatible(const DistributedData::MetaData &meta, const std::string &identifier); - bool CheckOptions(const Options &options, const std::vector &metaKey) const; - + bool CheckOptions(const Options &options, const DistributedData::StoreMetaData &metaData) const; + void OnDeviceChanged( + const AppDistributedKv::DeviceInfo &info, const AppDistributedKv::DeviceChangeType &type) const override; void CreateRdbService(); + bool IsStoreOpened(const std::string &userId, const std::string &appId, const std::string &storeId); static constexpr int TEN_SEC = 10; std::mutex accountMutex_; std::map deviceAccountMap_; std::mutex clientDeathObserverMutex_; - std::map clientDeathObserverMap_; + std::map clientDeathObserverMap_; std::shared_ptr accountEventObserver_; std::unique_ptr backup_; std::map> deviceListeners_; std::mutex deviceListenerMutex_; std::shared_ptr deviceListener_; - - std::shared_ptr security_; + sptr rdbService_; }; diff --git a/services/distributeddataservice/app/src/kvstore_impl.cpp b/services/distributeddataservice/app/src/kvstore_impl.cpp index 19a002fe4..af8af258b 100755 --- a/services/distributeddataservice/app/src/kvstore_impl.cpp +++ b/services/distributeddataservice/app/src/kvstore_impl.cpp @@ -23,6 +23,7 @@ #include "checker/checker_manager.h" #include "constant.h" #include "dds_trace.h" +#include "key_manager.h" #include "kvstore_account_observer.h" #include "kvstore_data_service.h" #include "kvstore_meta_manager.h" @@ -33,10 +34,11 @@ namespace OHOS { namespace DistributedKv { +using namespace OHOS::DistributedData; KvStoreImpl::KvStoreImpl(const Options &options, const std::string &userId, const std::string &bundleName, const std::string &appId, const std::string &storeId, const std::string &directory, DistributedDB::KvStoreDelegate *delegate) - : options_(options), deviceAccountId_(userId), bundleName_(bundleName), storeId_(storeId), appId_(appId), + : options_(options), userId_(userId), bundleName_(bundleName), storeId_(storeId), appId_(appId), storePath_(Constant::Concatenate({ directory, storeId })), kvStoreDelegate_(delegate), storeObserverMutex_(), observerSet_(), openCount_(1) { @@ -497,21 +499,18 @@ Status KvStoreImpl::MigrateKvStore(const std::string &harmonyAccountId, } ZLOGI("create new KvStore."); - std::vector secretKey; // expected get secret key from meta kvstore successful when encrypt flag is true. - std::unique_ptr, void(*)(std::vector*)> cleanGuard( - &secretKey, [](std::vector *ptr) { ptr->assign(ptr->size(), 0); }); - auto metaSecretKey = KvStoreMetaManager::GetMetaKey(deviceAccountId_, "default", bundleName_, storeId_, "KEY"); + SecretKey secretKey; + Status status; if (options_.encrypt) { - bool outdated = false; // ignore outdated flag during rebuild kvstore. - KvStoreMetaManager::GetInstance().GetSecretKeyFromMeta(metaSecretKey, secretKey, outdated); - if (secretKey.empty()) { + secretKey = KeyManager::GetSecretKey(meta_, KeyName(), status); + if (secretKey.IsEmpty()) { ZLOGE("Get secret key from meta kvstore failed."); return Status::CRYPT_ERROR; } } DistributedDB::KvStoreDelegate::Option dbOption; - Status status = KvStoreAppManager::InitDbOption(options_, secretKey, dbOption); + status = KvStoreAppManager::InitDbOption(options_, secretKey.data, dbOption); if (status != Status::SUCCESS) { ZLOGE("InitDbOption failed."); return status; @@ -778,22 +777,29 @@ bool KvStoreImpl::Import(const std::string &bundleName) const { ZLOGI("KvStoreImpl Import start"); const std::string harmonyAccountId = AccountDelegate::GetInstance()->GetCurrentAccountId(); - auto metaSecretKey = KvStoreMetaManager::GetMetaKey(deviceAccountId_, harmonyAccountId, bundleName, storeId_, + auto metaSecretKey = KvStoreMetaManager::GetMetaKey(userId_, Constant::DEFAULT_GROUP_ID, bundleName, storeId_, "KEY"); - std::vector secretKey; - bool outdated = false; - KvStoreMetaManager::GetInstance().GetSecretKeyFromMeta(metaSecretKey, secretKey, outdated); + SecretKey secretKey; + KeyManager::GetSecretKeyFromMeta(metaSecretKey, secretKey); - MetaData metaData{0}; - metaData.kvStoreMetaData.deviceAccountId = deviceAccountId_; - metaData.kvStoreMetaData.userId = harmonyAccountId; + MetaData metaData; + metaData.kvStoreMetaData.deviceAccountId = userId_; + metaData.kvStoreMetaData.userId = Constant::DEFAULT_GROUP_ID; metaData.kvStoreMetaData.bundleName = bundleName; metaData.kvStoreMetaData.appId = appId_; metaData.kvStoreMetaData.storeId = storeId_; metaData.kvStoreMetaData.securityLevel = options_.securityLevel; - metaData.secretKeyMetaData.secretKey = secretKey; + metaData.secretKeyMetaData.sKey = secretKey.data; std::shared_lock lock(storeDelegateMutex_); return std::make_unique()->MultiKvStoreRecover(metaData, kvStoreDelegate_); } +std::string KvStoreImpl::GetName() const +{ + return KvStoreImpl::KeyName(); +} +std::string KvStoreImpl::KeyName() +{ + return "KEY"; +}; } // namespace DistributedKv } // namespace OHOS diff --git a/services/distributeddataservice/app/src/kvstore_impl.h b/services/distributeddataservice/app/src/kvstore_impl.h index d399045e9..96d5ec958 100755 --- a/services/distributeddataservice/app/src/kvstore_impl.h +++ b/services/distributeddataservice/app/src/kvstore_impl.h @@ -23,12 +23,14 @@ #include "ikvstore.h" #include "ikvstore_observer.h" #include "ikvstore_snapshot.h" +#include "kvstore_base.h" #include "kv_store_delegate.h" #include "kv_store_delegate_manager.h" #include "kvstore_observer_impl.h" #include "kvstore_snapshot_impl.h" #include "types.h" #include "inner_types.h" +#include "metadata/store_meta_data.h" namespace OHOS { namespace DistributedKv { @@ -48,7 +50,7 @@ struct KvStoreObserverImplPtrCompare { } }; -class KvStoreImpl : public KvStoreImplStub { +class KvStoreImpl : public KvStoreImplStub, KvStoreBase { public: KvStoreImpl(const Options &options, const std::string &userId, const std::string &bundleName, const std::string &appId, const std::string &storeId, const std::string &directory, @@ -99,8 +101,9 @@ public: void IncreaseOpenCount(); Status ReKey(const std::vector &key); - + std::string GetName() const override; bool Import(const std::string &bundleName) const; + static std::string KeyName(); private: Status RebuildKvStoreObserver(DistributedDB::KvStoreDelegate *kvStoreDelegate); @@ -110,7 +113,7 @@ private: const Options options_; // device account id - std::string deviceAccountId_; + std::string userId_; // appId get from PMS. const std::string bundleName_; @@ -133,6 +136,7 @@ private: std::mutex storeSnapshotMutex_; std::map> snapshotMap_; int openCount_; + DistributedData::StoreMetaData meta_; }; } // namespace DistributedKv } // namespace OHOS diff --git a/services/distributeddataservice/app/src/kvstore_meta_manager.cpp b/services/distributeddataservice/app/src/kvstore_meta_manager.cpp index 5cba848d3..71e88a57e 100755 --- a/services/distributeddataservice/app/src/kvstore_meta_manager.cpp +++ b/services/distributeddataservice/app/src/kvstore_meta_manager.cpp @@ -15,25 +15,32 @@ #define LOG_TAG "KvStoreMetaManager" #include "kvstore_meta_manager.h" -#include -#include + #include #include -#include #include -#include "hks_api.h" -#include "hks_param.h" + +#include +#include +#include + #include "account_delegate.h" +#include "checker/checker_manager.h" #include "constant.h" -#include "kvstore_utils.h" #include "device_kvstore_impl.h" +#include "directory_manager.h" +#include "directory_utils.h" +#include "hks_api.h" +#include "hks_param.h" #include "kvstore_data_service.h" +#include "kvstore_utils.h" #include "log_print.h" +#include "metadata/strategy_meta_data.h" +#include "metadata/user_meta_data.h" #include "reporter.h" -#include "directory_utils.h" -#include "kvstore_app_manager.h" -#include "utils/crypto.h" #include "rdb_types.h" +#include "serializable/serializable.h" +#include "user_delegate.h" namespace OHOS { namespace DistributedKv { @@ -57,18 +64,18 @@ KvStoreMetaManager::KvStoreMetaManager() } auto result = kvStoreDelegateManager_.CloseKvStore(delegate); if (result != DistributedDB::DBStatus::OK) { - ZLOGE("CloseMetaKvstore return error status: %d", static_cast(result)); + ZLOGE("CloseMetaKvstore return error status: %{public}d", static_cast(result)); } }), metaDBDirectory_("/data/service/el1/public/database/distributeddata/meta"), - kvStoreDelegateManager_(META_DB_APP_ID, Constant::GetDefaultHarmonyAccountName()) + kvStoreDelegateManager_(META_DB_APP_ID, AccountDelegate::MAIN_DEVICE_ACCOUNT_ID) { ZLOGI("begin."); + metaDBDirectory_ = DirectoryManager::GetInstance().GetMetaStorePath(); + metaDBBackupDir_ = DirectoryManager::GetInstance().GetStoreBackupPath(GenMetaData()); } -KvStoreMetaManager::~KvStoreMetaManager() -{ -} +KvStoreMetaManager::~KvStoreMetaManager() = default; KvStoreMetaManager &KvStoreMetaManager::GetInstance() { @@ -76,17 +83,42 @@ KvStoreMetaManager &KvStoreMetaManager::GetInstance() return instance; } -void KvStoreMetaManager::InitMetaListener(std::function observer) +void KvStoreMetaManager::SubscribeMeta(const std::string &keyPrefix, const ChangeObserver &observer) { - metaObserver_.notify_ = observer; + metaObserver_.handlerMap_[keyPrefix] = observer; +} +void KvStoreMetaManager::InitMetaListener() +{ InitMetaData(); - auto status = KvStoreUtils::GetProviderInstance().StartWatchDeviceChange(&listener_, {"metaMgr"}); + auto status = KvStoreUtils::GetProviderInstance().StartWatchDeviceChange(&listener_, { "metaMgr" }); if (status != AppDistributedKv::Status::SUCCESS) { ZLOGW("register failed."); + return; } ZLOGI("register meta device change success."); - GetInstance().SubscribeMetaKvStore(); + SubscribeMetaKvStore(); +} + +DistributedData::StoreMetaData KvStoreMetaManager::GenMetaData() +{ + StoreMetaData metaData; + metaData.appId = META_DB_APP_ID; + metaData.appType = "default"; + metaData.bundleName = META_DB_APP_ID; + metaData.dataDir = "default"; + metaData.deviceAccountId = AccountDelegate::MAIN_DEVICE_ACCOUNT_ID; + metaData.deviceId = DeviceKvStoreImpl::GetLocalDeviceId(); + metaData.isAutoSync = false; + metaData.isBackup = false; + metaData.isEncrypt = false; + metaData.kvStoreType = KvStoreType::SINGLE_VERSION; + metaData.schema = ""; + metaData.securityLevel = SecurityLevel::NO_LABEL; + metaData.storeId = Constant::SERVICE_META_DB_NAME; + metaData.uid = 1000; + metaData.userId = Constant::GetDefaultHarmonyAccountName(); + return metaData; } void KvStoreMetaManager::InitMetaData() @@ -97,39 +129,24 @@ void KvStoreMetaManager::InitMetaData() ZLOGI("get meta failed."); return; } - auto uid = getuid(); - const std::string accountId = AccountDelegate::GetInstance()->GetCurrentAccountId(); - const std::string userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid); - auto metaKey = GetMetaKey(userId, "default", META_DB_APP_ID, Constant::SERVICE_META_DB_NAME); - struct KvStoreMetaData metaData { - .appId = META_DB_APP_ID, - .appType = "default", - .bundleName = META_DB_APP_ID, - .dataDir = metaDBDirectory_, - .deviceAccountId = userId, - .deviceId = DeviceKvStoreImpl::GetLocalDeviceId(), - .isAutoSync = false, - .isBackup = false, - .isEncrypt = false, - .kvStoreType = KvStoreType::SINGLE_VERSION, - .schema = "", - .storeId = Constant::SERVICE_META_DB_NAME, - .userId = accountId, - .uid = int32_t(uid), - .version = META_STORE_VERSION, - .securityLevel = SecurityLevel::S1, - }; - std::string jsonStr = metaData.Marshal(); - std::vector value(jsonStr.begin(), jsonStr.end()); - if (CheckUpdateServiceMeta(metaKey, UPDATE, value) != Status::SUCCESS) { + auto metaKey = + GetMetaKey(AccountDelegate::MAIN_DEVICE_ACCOUNT_ID, "default", META_DB_APP_ID, Constant::SERVICE_META_DB_NAME); + + StoreMetaData metaData = GenMetaData(); + std::string jsonStr = to_string(metaData.Marshall()); + std::vector metaValue {jsonStr.begin(), jsonStr.end() }; + if (CheckUpdateServiceMeta(metaKey, UPDATE, metaValue) != Status::SUCCESS) { ZLOGW("CheckUpdateServiceMeta database failed."); } + + UpdateUserMetaData(); ZLOGI("end."); } void KvStoreMetaManager::InitMetaParameter() { ZLOGI("start."); + ZLOGI("byy:meta path :%{public}s", metaDBDirectory_.c_str()); bool ret = ForceCreateDirectory(metaDBDirectory_); if (!ret) { FaultMsg msg = {FaultType::SERVICE_FAULT, "user", __FUNCTION__, Fault::SF_CREATE_DIR}; @@ -141,10 +158,6 @@ void KvStoreMetaManager::InitMetaParameter() DistributedDB::KvStoreConfig kvStoreConfig {metaDBDirectory_}; kvStoreDelegateManager_.SetKvStoreConfig(kvStoreConfig); - - vecRootKeyAlias_ = std::vector(ROOT_KEY_ALIAS, ROOT_KEY_ALIAS + strlen(ROOT_KEY_ALIAS)); - vecNonce_ = std::vector(HKS_BLOB_TYPE_NONCE, HKS_BLOB_TYPE_NONCE + strlen(HKS_BLOB_TYPE_NONCE)); - vecAad_ = std::vector(HKS_BLOB_TYPE_AAD, HKS_BLOB_TYPE_AAD + strlen(HKS_BLOB_TYPE_AAD)); } const KvStoreMetaManager::NbDelegate &KvStoreMetaManager::GetMetaKvStore() @@ -169,16 +182,15 @@ KvStoreMetaManager::NbDelegate KvStoreMetaManager::CreateMetaKvStore() option.createDirByStoreIdOnly = true; option.isEncryptedDb = false; DistributedDB::KvStoreNbDelegate *kvStoreNbDelegatePtr = nullptr; - kvStoreDelegateManager_.GetKvStore( - Constant::SERVICE_META_DB_NAME, option, - [&kvStoreNbDelegatePtr, &dbStatusTmp](DistributedDB::DBStatus dbStatus, - DistributedDB::KvStoreNbDelegate *kvStoreNbDelegate) { + kvStoreDelegateManager_.GetKvStore(Constant::SERVICE_META_DB_NAME, option, + [&kvStoreNbDelegatePtr, &dbStatusTmp]( + DistributedDB::DBStatus dbStatus, DistributedDB::KvStoreNbDelegate *kvStoreNbDelegate) { kvStoreNbDelegatePtr = kvStoreNbDelegate; dbStatusTmp = dbStatus; }); if (dbStatusTmp != DistributedDB::DBStatus::OK) { - ZLOGE("GetKvStore return error status: %d", static_cast(dbStatusTmp)); + ZLOGE("GetKvStore return error status: %{public}d", static_cast(dbStatusTmp)); return nullptr; } auto release = [this](DistributedDB::KvStoreNbDelegate *delegate) { @@ -189,64 +201,36 @@ KvStoreMetaManager::NbDelegate KvStoreMetaManager::CreateMetaKvStore() auto result = kvStoreDelegateManager_.CloseKvStore(delegate); if (result != DistributedDB::DBStatus::OK) { - ZLOGE("CloseMetaKvStore return error status: %d", static_cast(result)); + ZLOGE("CloseMetaKvStore return error status: %{public}d", static_cast(result)); } }; return NbDelegate(kvStoreNbDelegatePtr, release); } -std::vector KvStoreMetaManager::GetMetaKey(const std::string &deviceAccountId, - const std::string &groupId, const std::string &bundleName, - const std::string &storeId, const std::string &key) +std::vector KvStoreMetaManager::GetMetaKey(const std::string &deviceAccountId, const std::string &groupId, + const std::string &bundleName, const std::string &storeId, const std::string &key) { std::string originKey; if (key.empty()) { - originKey = DeviceKvStoreImpl::GetLocalDeviceId() + Constant::KEY_SEPARATOR + - deviceAccountId + Constant::KEY_SEPARATOR + - groupId + Constant::KEY_SEPARATOR + - bundleName + Constant::KEY_SEPARATOR + - storeId; + originKey = DeviceKvStoreImpl::GetLocalDeviceId() + Constant::KEY_SEPARATOR + deviceAccountId + + Constant::KEY_SEPARATOR + groupId + Constant::KEY_SEPARATOR + bundleName + + Constant::KEY_SEPARATOR + storeId; return KvStoreMetaRow::GetKeyFor(originKey); } - originKey = deviceAccountId + Constant::KEY_SEPARATOR + - groupId + Constant::KEY_SEPARATOR + - bundleName + Constant::KEY_SEPARATOR + - storeId + Constant::KEY_SEPARATOR + - key; + originKey = deviceAccountId + Constant::KEY_SEPARATOR + groupId + Constant::KEY_SEPARATOR + bundleName + + Constant::KEY_SEPARATOR + storeId + Constant::KEY_SEPARATOR + key; return SecretMetaRow::GetKeyFor(originKey); } -std::string KvStoreMetaManager::GetSecretKeyFile(const std::string &userId, const std::string &appId, - const std::string &storeId, int pathType) -{ - std::string hashedStoreId; - DistributedDB::DBStatus result = DistributedDB::KvStoreDelegateManager::GetDatabaseDir(storeId, hashedStoreId); - if (DistributedDB::OK != result) { - ZLOGE("get data base directory by kvstore store id failed, result = %d.", result); - return ""; - } - std::string miscPath = (pathType == KvStoreAppManager::PATH_DE) ? Constant::ROOT_PATH_DE : Constant::ROOT_PATH_CE; - return miscPath + "/" + Constant::SERVICE_NAME + "/" + userId + "/" + Constant::GetDefaultHarmonyAccountName() - + "/" + appId + "/" + hashedStoreId + ".mul.key"; -} - -std::string KvStoreMetaManager::GetSecretSingleKeyFile(const std::string &userId, const std::string &appId, - const std::string &storeId, int pathType) -{ - std::string hashedStoreId; - DistributedDB::DBStatus result = DistributedDB::KvStoreDelegateManager::GetDatabaseDir(storeId, hashedStoreId); - if (DistributedDB::OK != result) { - ZLOGE("get data base directory by kvstore store id failed, result = %d.", result); - return ""; - } - std::string miscPath = (pathType == KvStoreAppManager::PATH_DE) ? Constant::ROOT_PATH_DE : Constant::ROOT_PATH_CE; - return miscPath + "/" + Constant::SERVICE_NAME + "/" + userId + "/" + Constant::GetDefaultHarmonyAccountName() - + "/" + appId + "/" + hashedStoreId + ".sig.key"; +Status KvStoreMetaManager::CheckUpdateServiceMeta( + const std::vector &metaKey, FLAG flag) { + std::vector val; + return CheckUpdateServiceMeta(metaKey, flag, val); } -Status KvStoreMetaManager::CheckUpdateServiceMeta(const std::vector &metaKey, FLAG flag, - const std::vector &val) +Status KvStoreMetaManager::CheckUpdateServiceMeta( + const std::vector &metaKey, FLAG flag, std::vector &val) { ZLOGD("begin."); auto &metaDelegate = GetMetaKvStore(); @@ -255,35 +239,29 @@ Status KvStoreMetaManager::CheckUpdateServiceMeta(const std::vector &me return Status::DB_ERROR; } - DistributedDB::Key dbKey = metaKey; - DistributedDB::Value dbValue = val; + const DistributedDB::Key& dbKey = metaKey; + DistributedDB::Value &dbValue = val; DistributedDB::DBStatus dbStatus; DistributedDB::CipherPassword dbPassword; - std::initializer_list backList = {META_DB_APP_ID, "_", Constant::SERVICE_META_DB_NAME}; - std::string backupName = Constant::Concatenate(backList); - std::initializer_list backFullList = {metaDBDirectory_, "/backup/", - BackupHandler::GetHashedBackupName(backupName)}; - auto backupFullName = Constant::Concatenate(backFullList); - switch (flag) { case UPDATE: dbStatus = metaDelegate->Put(dbKey, dbValue); - metaDelegate->Export(backupFullName, dbPassword); + metaDelegate->Export(metaDBBackupDir_, dbPassword); break; case DELETE: dbStatus = metaDelegate->Delete(dbKey); - metaDelegate->Export(backupFullName, dbPassword); + metaDelegate->Export(metaDBBackupDir_, dbPassword); break; case CHECK_EXIST: dbStatus = metaDelegate->Get(dbKey, dbValue); break; case UPDATE_LOCAL: dbStatus = metaDelegate->PutLocal(dbKey, dbValue); - metaDelegate->Export(backupFullName, dbPassword); + metaDelegate->Export(metaDBBackupDir_, dbPassword); break; case DELETE_LOCAL: dbStatus = metaDelegate->DeleteLocal(dbKey); - metaDelegate->Export(backupFullName, dbPassword); + metaDelegate->Export(metaDBBackupDir_, dbPassword); break; case CHECK_EXIST_LOCAL: dbStatus = metaDelegate->GetLocal(dbKey, dbValue); @@ -291,389 +269,16 @@ Status KvStoreMetaManager::CheckUpdateServiceMeta(const std::vector &me default: break; } - ZLOGI("Flag: %d status: %d", static_cast(flag), static_cast(dbStatus)); + ZLOGI("Flag: %{public}d status: %{public}d", static_cast(flag), static_cast(dbStatus)); SyncMeta(); return (dbStatus != DistributedDB::DBStatus::OK) ? Status::DB_ERROR : Status::SUCCESS; } -Status KvStoreMetaManager::GenerateRootKey() -{ - ZLOGI("GenerateRootKey."); - struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), &(vecRootKeyAlias_[0]) }; - struct HksParamSet *paramSet = nullptr; - int32_t ret = HksInitParamSet(¶mSet); - if (ret != HKS_SUCCESS) { - ZLOGE("HksInitParamSet() failed with error %{public}d", ret); - return Status::ERROR; - } - - struct HksParam genKeyParams[] = { - { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES }, - { .tag = HKS_TAG_KEY_SIZE, .uint32Param = HKS_AES_KEY_SIZE_256 }, - { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT | HKS_KEY_PURPOSE_DECRYPT }, - { .tag = HKS_TAG_DIGEST, .uint32Param = 0 }, - { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE }, - { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM }, - }; - - ret = HksAddParams(paramSet, genKeyParams, sizeof(genKeyParams) / sizeof(genKeyParams[0])); - if (ret != HKS_SUCCESS) { - ZLOGE("HksAddParams failed with error %{public}d", ret); - HksFreeParamSet(¶mSet); - return Status::ERROR; - } - - ret = HksBuildParamSet(¶mSet); - if (ret != HKS_SUCCESS) { - ZLOGE("HksBuildParamSet failed with error %{public}d", ret); - HksFreeParamSet(¶mSet); - return Status::ERROR; - } - - ret = HksGenerateKey(&rootKeyName, paramSet, NULL); - if (ret != HKS_SUCCESS) { - ZLOGE("HksGenerateKey failed with error %{public}d", ret); - HksFreeParamSet(¶mSet); - return Status::ERROR; - } - HksFreeParamSet(¶mSet); - - auto &metaDelegate = GetMetaKvStore(); - if (metaDelegate == nullptr) { - ZLOGE("GetMetaKvStore return nullptr."); - return Status::DB_ERROR; - } - - DistributedDB::Key dbKey = std::vector(Constant::ROOT_KEY_GENERATED.begin(), - Constant::ROOT_KEY_GENERATED.end()); - if (metaDelegate->PutLocal(dbKey, {ROOT_KEY_ALIAS, ROOT_KEY_ALIAS + strlen(ROOT_KEY_ALIAS)}) != - DistributedDB::DBStatus::OK) { - return Status::ERROR; - } - ZLOGI("GenerateRootKey Succeed."); - return Status::SUCCESS; -} - -Status KvStoreMetaManager::CheckRootKeyExist() -{ - ZLOGI("GenerateRootKey."); - auto &metaDelegate = GetMetaKvStore(); - if (metaDelegate == nullptr) { - ZLOGE("GetMetaKvStore return nullptr."); - return Status::DB_ERROR; - } - - DistributedDB::Key dbKey = std::vector(Constant::ROOT_KEY_GENERATED.begin(), - Constant::ROOT_KEY_GENERATED.end()); - DistributedDB::Value dbValue; - if (metaDelegate->GetLocal(dbKey, dbValue) == DistributedDB::DBStatus::OK) { - ZLOGI("root key exist."); - return Status::SUCCESS; - } - return Status::ERROR; -} - -std::vector KvStoreMetaManager::EncryptWorkKey(const std::vector &key) -{ - struct HksBlob blobAad = { uint32_t(vecAad_.size()), &(vecAad_[0]) }; - struct HksBlob blobNonce = { uint32_t(vecNonce_.size()), &(vecNonce_[0]) }; - struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), &(vecRootKeyAlias_[0]) }; - struct HksBlob plainKey = { uint32_t(key.size()), const_cast(&(key[0])) }; - uint8_t cipherBuf[256] = { 0 }; - struct HksBlob encryptedKey = { sizeof(cipherBuf), cipherBuf }; - std::vector encryptedKeyVec; - struct HksParamSet *encryptParamSet = nullptr; - int32_t ret = HksInitParamSet(&encryptParamSet); - if (ret != HKS_SUCCESS) { - ZLOGE("HksInitParamSet() failed with error %{public}d", ret); - return {}; - } - struct HksParam encryptParams[] = { - { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES }, - { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_ENCRYPT }, - { .tag = HKS_TAG_DIGEST, .uint32Param = 0 }, - { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM }, - { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE }, - { .tag = HKS_TAG_NONCE, .blob = blobNonce }, - { .tag = HKS_TAG_ASSOCIATED_DATA, .blob = blobAad }, - }; - ret = HksAddParams(encryptParamSet, encryptParams, sizeof(encryptParams) / sizeof(encryptParams[0])); - if (ret != HKS_SUCCESS) { - ZLOGE("HksAddParams failed with error %{public}d", ret); - HksFreeParamSet(&encryptParamSet); - return {}; - } - - ret = HksBuildParamSet(&encryptParamSet); - if (ret != HKS_SUCCESS) { - ZLOGE("HksBuildParamSet failed with error %{public}d", ret); - HksFreeParamSet(&encryptParamSet); - return {}; - } - - ret = HksEncrypt(&rootKeyName, encryptParamSet, &plainKey, &encryptedKey); - if (ret != HKS_SUCCESS) { - ZLOGE("HksEncrypt failed with error %{public}d", ret); - HksFreeParamSet(&encryptParamSet); - return {}; - } - (void)HksFreeParamSet(&encryptParamSet); - - for (uint32_t i = 0; i < encryptedKey.size; i++) { - encryptedKeyVec.push_back(encryptedKey.data[i]); - } - return encryptedKeyVec; -} - -bool KvStoreMetaManager::DecryptWorkKey(const std::vector &encryptedKey, std::vector &key) -{ - struct HksBlob blobAad = { uint32_t(vecAad_.size()), &(vecAad_[0]) }; - struct HksBlob blobNonce = { uint32_t(vecNonce_.size()), &(vecNonce_[0]) }; - struct HksBlob rootKeyName = { uint32_t(vecRootKeyAlias_.size()), &(vecRootKeyAlias_[0]) }; - struct HksBlob encryptedKeyBlob = { uint32_t(encryptedKey.size()), const_cast(&(encryptedKey[0])) }; - uint8_t plainBuf[256] = { 0 }; - struct HksBlob plainKeyBlob = { sizeof(plainBuf), plainBuf }; - struct HksParamSet *decryptParamSet = nullptr; - int32_t ret = HksInitParamSet(&decryptParamSet); - if (ret != HKS_SUCCESS) { - ZLOGE("HksInitParamSet() failed with error %{public}d", ret); - return false; - } - struct HksParam decryptParams[] = { - { .tag = HKS_TAG_ALGORITHM, .uint32Param = HKS_ALG_AES }, - { .tag = HKS_TAG_PURPOSE, .uint32Param = HKS_KEY_PURPOSE_DECRYPT }, - { .tag = HKS_TAG_DIGEST, .uint32Param = 0 }, - { .tag = HKS_TAG_BLOCK_MODE, .uint32Param = HKS_MODE_GCM }, - { .tag = HKS_TAG_PADDING, .uint32Param = HKS_PADDING_NONE }, - { .tag = HKS_TAG_NONCE, .blob = blobNonce }, - { .tag = HKS_TAG_ASSOCIATED_DATA, .blob = blobAad }, - }; - ret = HksAddParams(decryptParamSet, decryptParams, sizeof(decryptParams) / sizeof(decryptParams[0])); - if (ret != HKS_SUCCESS) { - ZLOGE("HksAddParams failed with error %{public}d", ret); - HksFreeParamSet(&decryptParamSet); - return false; - } - - ret = HksBuildParamSet(&decryptParamSet); - if (ret != HKS_SUCCESS) { - ZLOGE("HksBuildParamSet failed with error %{public}d", ret); - HksFreeParamSet(&decryptParamSet); - return false; - } - - ret = HksDecrypt(&rootKeyName, decryptParamSet, &encryptedKeyBlob, &plainKeyBlob); - if (ret != HKS_SUCCESS) { - ZLOGW("HksDecrypt failed with error %{public}d", ret); - HksFreeParamSet(&decryptParamSet); - return false; - } - (void)HksFreeParamSet(&decryptParamSet); - - for (uint32_t i = 0; i < plainKeyBlob.size; i++) { - key.push_back(plainKeyBlob.data[i]); - } - return true; -} - -Status KvStoreMetaManager::WriteSecretKeyToMeta(const std::vector &metaKey, const std::vector &key) -{ - ZLOGD("start"); - auto &metaDelegate = GetMetaKvStore(); - if (metaDelegate == nullptr) { - ZLOGE("GetMetaKvStore return nullptr."); - return Status::DB_ERROR; - } - - SecretKeyMetaData secretKey; - secretKey.kvStoreType = KvStoreType::DEVICE_COLLABORATION; - secretKey.timeValue = TransferTypeToByteArray(system_clock::to_time_t(system_clock::now())); - secretKey.secretKey = EncryptWorkKey(key); - if (secretKey.secretKey.empty()) { - ZLOGE("encrypt work key error."); - return Status::CRYPT_ERROR; - } - - DistributedDB::DBStatus dbStatus = metaDelegate->PutLocal(metaKey, secretKey); - if (dbStatus != DistributedDB::DBStatus::OK) { - ZLOGE("end with %d", static_cast(dbStatus)); - return Status::DB_ERROR; - } else { - ZLOGD("normal end"); - return Status::SUCCESS; - } -} - -Status KvStoreMetaManager::WriteSecretKeyToFile(const std::string &secretKeyFile, const std::vector &key) -{ - ZLOGD("start"); - std::vector secretKey = EncryptWorkKey(key); - if (secretKey.empty()) { - ZLOGW("encrypt work key error."); - return Status::CRYPT_ERROR; - } - std::string dbDir = secretKeyFile.substr(0, secretKeyFile.find_last_of('/')); - if (!ForceCreateDirectory(dbDir)) { - return Status::ERROR; - } - - std::vector secretKeyInByte = - TransferTypeToByteArray(system_clock::to_time_t(system_clock::now())); - std::vector secretKeyInChar; - secretKeyInChar.insert(secretKeyInChar.end(), secretKeyInByte.begin(), secretKeyInByte.end()); - secretKeyInChar.insert(secretKeyInChar.end(), secretKey.begin(), secretKey.end()); - if (SaveBufferToFile(secretKeyFile, secretKeyInChar)) { - ZLOGD("normal end"); - return Status::SUCCESS; - } - ZLOGW("failure end"); - return Status::ERROR; -} - -Status KvStoreMetaManager::RemoveSecretKey(pid_t uid, const std::string &bundleName, const std::string &storeId) -{ - auto &metaDelegate = GetMetaKvStore(); - if (metaDelegate == nullptr) { - ZLOGE("GetMetaKvStore return nullptr."); - return Status::DB_ERROR; - } - const std::string userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid); - Status status = Status::SUCCESS; - DistributedDB::Key secretDbKey = GetMetaKey(userId, "default", bundleName, storeId, "KEY"); - DistributedDB::Key secretSingleDbKey = GetMetaKey(userId, "default", bundleName, storeId, "SINGLE_KEY"); - DistributedDB::DBStatus dbStatus = metaDelegate->DeleteLocal(secretDbKey); - if (dbStatus != DistributedDB::DBStatus::OK) { - ZLOGE("delete secretDbKey fail Status %d", static_cast(dbStatus)); - status = Status::DB_ERROR; - } - dbStatus = metaDelegate->DeleteLocal(secretSingleDbKey); - if (dbStatus != DistributedDB::DBStatus::OK) { - ZLOGE("delete secretSingleDbKey fail Status %d", static_cast(dbStatus)); - status = Status::DB_ERROR; - } - - for (int32_t pathType = KvStoreAppManager::PATH_DE; pathType < KvStoreAppManager::PATH_TYPE_MAX; ++pathType) { - std::string keyFile = GetSecretKeyFile(userId, bundleName, storeId, pathType); - if (!RemoveFile(keyFile)) { - ZLOGW("remove secret key file %{public}s fail.", keyFile.c_str()); - status = Status::DB_ERROR; - } - keyFile = GetSecretSingleKeyFile(userId, bundleName, storeId, pathType); - if (!RemoveFile(keyFile)) { - ZLOGW("remove secretKeyFile Single fail."); - status = Status::DB_ERROR; - } - } - return status; -} - -Status KvStoreMetaManager::GetSecretKeyFromMeta(const std::vector &metaSecretKey, std::vector &key, - bool &outdated) -{ - auto &metaDelegate = GetMetaKvStore(); - if (metaDelegate == nullptr) { - ZLOGE("GetMetaKvStore return nullptr."); - return Status::DB_ERROR; - } - - DistributedDB::Key dbKey = metaSecretKey; - DistributedDB::Value dbValue; - DistributedDB::DBStatus dbStatus = metaDelegate->GetLocal(dbKey, dbValue); - if (dbStatus != DistributedDB::DBStatus::OK) { - return Status::DB_ERROR; - } - std::string jsonStr(dbValue.begin(), dbValue.end()); - json jsonObj = json::parse(jsonStr, nullptr, false); - if (jsonObj.is_discarded()) { - ZLOGE("parse json error"); - return Status::ERROR; - } - SecretKeyMetaData sKeyValue(jsonObj); - time_t createTime = TransferByteArrayToType(sKeyValue.timeValue); - DecryptWorkKey(sKeyValue.secretKey, key); - system_clock::time_point createTimeChrono = system_clock::from_time_t(createTime); - outdated = ((createTimeChrono + hours(HOURS_PER_YEAR)) < system_clock::now()); // secretKey valid for 1 year. - return Status::SUCCESS; -} - -Status KvStoreMetaManager::RecoverSecretKeyFromFile(const std::string &secretKeyFile, - const std::vector &metaSecretKey, - std::vector &key, bool &outdated) -{ - std::vector fileBuffer; - if (!LoadBufferFromFile(secretKeyFile, fileBuffer)) { - return Status::ERROR; - } - if (fileBuffer.size() < sizeof(time_t) / sizeof(uint8_t) + KEY_SIZE) { - return Status::ERROR; - } - std::vector timeVec; - auto iter = fileBuffer.begin(); - for (int i = 0; i < static_cast(sizeof(time_t) / sizeof(uint8_t)); i++) { - timeVec.push_back(*iter); - iter++; - } - time_t createTime = TransferByteArrayToType(timeVec); - SecretKeyMetaData secretKey; - secretKey.secretKey.insert(secretKey.secretKey.end(), iter, fileBuffer.end()); - if (!DecryptWorkKey(secretKey.secretKey, key)) { - return Status::ERROR; - } - system_clock::time_point createTimeChrono = system_clock::from_time_t(createTime); - outdated = ((createTimeChrono + hours(HOURS_PER_YEAR)) < system_clock::now()); // secretKey valid for 1 year. - - auto &metaDelegate = GetMetaKvStore(); - if (metaDelegate == nullptr) { - ZLOGE("GetMetaKvStore return nullptr."); - return Status::DB_ERROR; - } - - secretKey.timeValue = TransferTypeToByteArray(createTime); - secretKey.kvStoreType = KvStoreType::DEVICE_COLLABORATION; - - DistributedDB::DBStatus dbStatus = metaDelegate->PutLocal(metaSecretKey, secretKey); - if (dbStatus != DistributedDB::DBStatus::OK) { - ZLOGE("put work key failed."); - return Status::DB_ERROR; - } - return Status::SUCCESS; -} - -void KvStoreMetaManager::ReKey(const std::string &userId, const std::string &bundleName, const std::string &storeId, - int32_t pathType, sptr store) -{ - if (store == nullptr) { - return; - } - std::vector key = Crypto::Random(KEY_SIZE); - WriteSecretKeyToMeta(GetMetaKey(userId, "default", bundleName, storeId, "KEY"), key); - Status status = store->ReKey(key); - if (status == Status::SUCCESS) { - WriteSecretKeyToFile(GetSecretKeyFile(userId, bundleName, storeId, pathType), key); - } - key.assign(key.size(), 0); -} - -void KvStoreMetaManager::ReKey(const std::string &userId, const std::string &bundleName, const std::string &storeId, - int32_t pathType, sptr store) -{ - if (store == nullptr) { - return; - } - std::vector key = Crypto::Random(KEY_SIZE); - WriteSecretKeyToMeta(GetMetaKey(userId, "default", bundleName, storeId, "SINGLE_KEY"), key); - Status status = store->ReKey(key); - if (status == Status::SUCCESS) { - WriteSecretKeyToFile(GetSecretSingleKeyFile(userId, bundleName, storeId, pathType), key); - } - key.assign(key.size(), 0); -} - // StrategyMetaData###deviceId###deviceAccountID###${groupId}###bundleName###storeId void KvStoreMetaManager::GetStrategyMetaKey(const StrategyMeta ¶ms, std::string &retVal) { - std::vector keys = {STRATEGY_META_PREFIX, params.devId, params.devAccId, params.grpId, - params.bundleName, params.storeId}; + std::vector keys = { STRATEGY_META_PREFIX, params.devId, params.devAccId, params.grpId, + params.bundleName, params.storeId }; ConcatWithSharps(keys, retVal); } @@ -729,9 +334,8 @@ Status KvStoreMetaManager::SaveStrategyMetaEnable(const std::string &key, bool e return Status::SUCCESS; } -Status KvStoreMetaManager::SaveStrategyMetaLabels(const std::string &key, - const std::vector &localLabels, - const std::vector &remoteSupportLabels) +Status KvStoreMetaManager::SaveStrategyMetaLabels(const std::string &key, const std::vector &localLabels, + const std::vector &remoteSupportLabels) { auto &metaDelegate = GetMetaKvStore(); if (metaDelegate == nullptr) { @@ -770,8 +374,8 @@ Status KvStoreMetaManager::SaveStrategyMetaLabels(const std::string &key, return Status::SUCCESS; } -Status KvStoreMetaManager::DeleteStrategyMeta(const std::string &bundleName, const std::string &storeId, - const std::string &userId) +Status KvStoreMetaManager::DeleteStrategyMeta( + const std::string &userId, const std::string &bundleName, const std::string &storeId) { ZLOGI("start"); std::string key; @@ -821,7 +425,7 @@ void KvStoreMetaManager::SyncMeta() }; auto dbStatus = metaDelegate->Sync(devs, DistributedDB::SyncMode::SYNC_MODE_PUSH_PULL, onComplete); if (dbStatus != DistributedDB::OK) { - ZLOGW("meta db sync error %d.", dbStatus); + ZLOGW("meta db sync error %{public}d.", dbStatus); } } @@ -833,10 +437,10 @@ void KvStoreMetaManager::SubscribeMetaKvStore() return; } - int mode = DistributedDB::OBSERVER_CHANGES_NATIVE; + int mode = DistributedDB::OBSERVER_CHANGES_NATIVE | DistributedDB::OBSERVER_CHANGES_FOREIGN; auto dbStatus = metaDelegate->RegisterObserver(DistributedDB::Key(), mode, &metaObserver_); if (dbStatus != DistributedDB::DBStatus::OK) { - ZLOGW("register meta observer failed :%d.", dbStatus); + ZLOGW("register meta observer failed :%{public}d.", dbStatus); } } @@ -848,7 +452,7 @@ Status KvStoreMetaManager::CheckSyncPermission(const std::string &userId, const ZLOGE("get device id empty."); return Status::ERROR; } - KvStoreMetaData localMeta; + StoreMetaData localMeta; auto queryStatus = QueryKvStoreMetaDataByDeviceIdAndAppId(localId, appId, localMeta); if (queryStatus != Status::SUCCESS) { ZLOGE("get kvstore by deviceId and appId empty."); @@ -859,46 +463,65 @@ Status KvStoreMetaManager::CheckSyncPermission(const std::string &userId, const storeId}; std::string localKey; GetStrategyMetaKey(params, localKey); - if (localKey.empty()) { - ZLOGE("get key empty."); - return Status::ERROR; - } - std::string remoteKey; - params.devId = remoteId; - GetStrategyMetaKey(params, remoteKey); - if (remoteKey.empty()) { - ZLOGE("get key empty."); + std::map> localStrategies; + GetStrategyMeta(localKey, localStrategies); + if (localStrategies.empty()) { + ZLOGD("no local sync strategy, sync permission success."); + return Status::SUCCESS; + } + auto localSupportRemotes = localStrategies.find(REMOTE_LABEL); + if (localSupportRemotes == localStrategies.end()) { + ZLOGD("local sync strategy not contains remoteLabel."); return Status::ERROR; } + std::vector lremotes = localSupportRemotes->second; + auto peerUsers = UserDelegate::GetInstance().GetActiveUsers(remoteId); + bool isRemoteLabelExist = false; + for (const auto &peerUser : peerUsers) { + ZLOGD("get peer strategy with user %{public}d begin", peerUser); + std::string remoteKey; + params.devId = remoteId; + params.devAccId = std::to_string(peerUser); + GetStrategyMetaKey(params, remoteKey); + + std::map> remoteStrategies; + GetStrategyMeta(remoteKey, remoteStrategies); + if (remoteStrategies.empty()) { + ZLOGD("no remote strategy in user %{public}d", peerUser); + continue; + } - std::map> localStrategies; - std::map> remoteStrategies; - GetStategyMeta(localKey, localStrategies); - GetStategyMeta(remoteKey, remoteStrategies); - if (localStrategies.empty() || remoteStrategies.empty()) { - ZLOGD("no range, sync permission success."); - return Status::SUCCESS; + auto remoteSupportLocals = remoteStrategies.find(LOCAL_LABEL); + if (remoteSupportLocals == remoteStrategies.end()) { + ZLOGD("find remote localLabel failed in user %{public}d", peerUser); + continue; + } + isRemoteLabelExist = true; + std::vector rlocals = remoteSupportLocals->second; + if (CompareStrategyMeta(lremotes, rlocals)) { + ZLOGD("find range, sync permission success."); + return Status::SUCCESS; + } } + ZLOGD("is remote label exist:%{public}d", isRemoteLabelExist); + return isRemoteLabelExist ? Status::ERROR : Status::SUCCESS; +} - auto localSupportRemotes = localStrategies.find(REMOTE_LABEL); - auto remoteSupportLocals = remoteStrategies.find(LOCAL_LABEL); - if (localSupportRemotes != localStrategies.end() && remoteSupportLocals != remoteStrategies.end()) { - std::vector lremotes = localSupportRemotes->second; - for (auto const &lremote : lremotes) { - std::vector rlocals = remoteSupportLocals->second; - if (std::find(rlocals.begin(), rlocals.end(), lremote) != rlocals.end()) { - ZLOGD("find range, sync permission success."); - return Status::SUCCESS; - } +bool KvStoreMetaManager::CompareStrategyMeta( + const std::vector &strategy1, const std::vector &strategy2) +{ + for (auto const &item : strategy1) { + if (std::find(strategy2.begin(), strategy2.end(), item) != strategy2.end()) { + ZLOGD("find range, sync permission success."); + return true; } } - ZLOGD("check strategy failed, sync permission fail."); - return Status::ERROR; + return false; } -Status KvStoreMetaManager::GetStategyMeta(const std::string &key, - std::map> &strategies) +Status KvStoreMetaManager::GetStrategyMeta( + const std::string &key, std::map> &strategies) { ZLOGD("get meta key:%s.", key.c_str()); auto &metaDelegate = GetMetaKvStore(); @@ -910,7 +533,7 @@ Status KvStoreMetaManager::GetStategyMeta(const std::string &key, DistributedDB::Value values; auto dbStatus = metaDelegate->Get(DistributedDB::Key(key.begin(), key.end()), values); if (dbStatus != DistributedDB::DBStatus::OK) { - ZLOGW("get meta error %d.", dbStatus); + ZLOGW("get meta error %{public}d.", dbStatus); return Status::DB_ERROR; } @@ -936,7 +559,7 @@ Status KvStoreMetaManager::GetStategyMeta(const std::string &key, if (obj.is_array()) { std::vector v; obj.get_to(v); - strategies.insert({LOCAL_LABEL, v}); + strategies.insert({ LOCAL_LABEL, v }); } } auto remote = range->find(REMOTE_LABEL); @@ -945,7 +568,7 @@ Status KvStoreMetaManager::GetStategyMeta(const std::string &key, if (obj.is_array()) { std::vector v; obj.get_to(v); - strategies.insert({REMOTE_LABEL, v}); + strategies.insert({ REMOTE_LABEL, v }); } } return Status::SUCCESS; @@ -959,27 +582,23 @@ KvStoreMetaManager::KvStoreMetaObserver::~KvStoreMetaObserver() void KvStoreMetaManager::KvStoreMetaObserver::OnChange(const DistributedDB::KvStoreChangedData &data) { ZLOGD("on data change."); - if (notify_ != nullptr) { - auto &updated = data.GetEntriesUpdated(); - for (const auto &entry : updated) { - std::string key(entry.key.begin(), entry.key.end()); - if (key.find(KvStoreMetaRow::KEY_PREFIX) != 0) { - continue; - } + HandleChanges(CHANGE_FLAG::INSERT, data.GetEntriesInserted()); + HandleChanges(CHANGE_FLAG::UPDATE, data.GetEntriesUpdated()); + HandleChanges(CHANGE_FLAG::DELETE, data.GetEntriesDeleted()); + KvStoreMetaManager::GetInstance().SyncMeta(); +} - KvStoreMetaData metaData; - std::string json(entry.value.begin(), entry.value.end()); - metaData.Unmarshal(Serializable::ToJson(json)); - ZLOGD("meta data info appType:%s, storeId:%s isDirty:%d", - metaData.appType.c_str(), metaData.storeId.c_str(), metaData.isDirty); - if (!metaData.isDirty || metaData.appType != HARMONY_APP) { - continue; +void KvStoreMetaManager::KvStoreMetaObserver::HandleChanges( + CHANGE_FLAG flag, const std::list &entries) +{ + for (const auto &entry : entries) { + std::string key(entry.key.begin(), entry.key.end()); + for (const auto &item : handlerMap_) { + if (key.find(item.first) == 0) { + item.second(entry.key, entry.value, flag); } - ZLOGI("dirty kv store. storeId:%s", metaData.storeId.c_str()); - notify_(metaData); } } - KvStoreMetaManager::GetInstance().SyncMeta(); } void KvStoreMetaManager::MetaDeviceChangeListenerImpl::OnDeviceChanged( @@ -1000,8 +619,8 @@ AppDistributedKv::ChangeLevelType KvStoreMetaManager::MetaDeviceChangeListenerIm return AppDistributedKv::ChangeLevelType::HIGH; } -Status KvStoreMetaManager::QueryKvStoreMetaDataByDeviceIdAndAppId(const std::string &devId, const std::string &appId, - KvStoreMetaData &val) +Status KvStoreMetaManager::QueryKvStoreMetaDataByDeviceIdAndAppId( + const std::string &devId, const std::string &appId, StoreMetaData &val) { ZLOGD("query meta start."); auto &metaDelegate = GetMetaKvStore(); @@ -1011,13 +630,13 @@ Status KvStoreMetaManager::QueryKvStoreMetaDataByDeviceIdAndAppId(const std::str } std::string dbPrefixKey; std::string prefix = KvStoreMetaRow::KEY_PREFIX; - ConcatWithSharps({prefix, devId}, dbPrefixKey); + ConcatWithSharps({ prefix, devId }, dbPrefixKey); std::vector values; auto status = metaDelegate->GetEntries(DistributedDB::Key(dbPrefixKey.begin(), dbPrefixKey.end()), values); if (status != DistributedDB::DBStatus::OK) { status = metaDelegate->GetEntries(DistributedDB::Key(prefix.begin(), prefix.end()), values); if (status != DistributedDB::DBStatus::OK) { - ZLOGW("query db failed key:%s, ret:%d.", dbPrefixKey.c_str(), static_cast(status)); + ZLOGW("query db failed key:%s, ret:%{public}d.", dbPrefixKey.c_str(), static_cast(status)); return Status::ERROR; } } @@ -1032,11 +651,11 @@ Status KvStoreMetaManager::QueryKvStoreMetaDataByDeviceIdAndAppId(const std::str } } - ZLOGW("find meta failed id: %{public}s", appId.c_str()); + ZLOGW("find meta failed id:%s.", appId.c_str()); return Status::ERROR; } -Status KvStoreMetaManager::GetKvStoreMeta(const std::vector &metaKey, KvStoreMetaData &metaData) +Status KvStoreMetaManager::GetKvStoreMeta(const std::vector &metaKey, StoreMetaData &metaData) { ZLOGD("begin."); auto &metaDelegate = GetMetaKvStore(); @@ -1046,7 +665,7 @@ Status KvStoreMetaManager::GetKvStoreMeta(const std::vector &metaKey, K } DistributedDB::Value dbValue; DistributedDB::DBStatus dbStatus = metaDelegate->Get(metaKey, dbValue); - ZLOGI("status: %d", static_cast(dbStatus)); + ZLOGI("status: %{public}d", static_cast(dbStatus)); if (dbStatus == DistributedDB::DBStatus::NOT_FOUND) { ZLOGI("key not found."); return Status::KEY_NOT_FOUND; @@ -1057,102 +676,106 @@ Status KvStoreMetaManager::GetKvStoreMeta(const std::vector &metaKey, K } std::string jsonStr(dbValue.begin(), dbValue.end()); - metaData.Unmarshal(Serializable::ToJson(jsonStr)); + metaData.Unmarshall(jsonStr); return Status::SUCCESS; } -std::string KvStoreMetaData::Marshal() const +StoreMetaData KvStoreMetaManager::GetStoreMeta(pid_t uid, const AppId &appId, const StoreId &storeId, Status &status) { - json jval = { - {DEVICE_ID, deviceId}, - {USER_ID, userId}, - {APP_ID, appId}, - {STORE_ID, storeId}, - {BUNDLE_NAME, bundleName}, - {KVSTORE_TYPE, kvStoreType}, - {ENCRYPT, isEncrypt}, - {BACKUP, isBackup}, - {AUTO_SYNC, isAutoSync}, - {SCHEMA, schema}, - {DATA_DIR, dataDir}, // Reserved for kvstore data storage directory. - {APP_TYPE, appType}, // Reserved for the APP type which used kvstore. - {DEVICE_ACCOUNT_ID, deviceAccountId}, - {UID, uid}, - {VERSION, version}, - {SECURITY_LEVEL, securityLevel}, - {DIRTY_KEY, isDirty}, - }; - return jval.dump(); + status = Status::INVALID_ARGUMENT; + if (!appId.IsValid() || !storeId.IsValid()) { + ZLOGE("invalid appId or storeId."); + return {}; + } + auto trueAppId = CheckerManager::GetInstance().GetAppId(appId.appId, uid); + if (trueAppId.empty()) { + ZLOGW("appId empty(permission issues?)"); + status = Status::PERMISSION_DENIED; + return {}; + } + std::string userId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid); + auto metaKey = KvStoreMetaManager::GetMetaKey(userId, "default", appId.appId, storeId.storeId); + StoreMetaData metaData; + status = GetKvStoreMeta(metaKey, metaData); + return metaData; } -json Serializable::ToJson(const std::string &jsonStr) +Status KvStoreMetaManager::DeleteKvStoreMeta(const StoreMetaData &storeMeta) { - json jsonObj = json::parse(jsonStr, nullptr, false); - if (jsonObj.is_discarded()) { - // if the string size is less than 1, means the string is invalid. - if (jsonStr.empty()) { - ZLOGE("empty jsonStr, error."); - return {}; - } - jsonObj = json::parse(jsonStr.substr(1), nullptr, false); // drop first char to adapt A's value; - if (jsonObj.is_discarded()) { - ZLOGE("parse jsonStr, error."); - return {}; - } + auto metaKey = KvStoreMetaManager::GetMetaKey(storeMeta.deviceAccountId, "default", storeMeta.appId, storeMeta.storeId); + Status status = KvStoreMetaManager::GetInstance().CheckUpdateServiceMeta(metaKey, DELETE); + if (status != Status::SUCCESS) { + ZLOGW("Remove Kvstore Metakey failed."); } - return jsonObj; + KeyManager::RemoveSecretKey(storeMeta); + KvStoreMetaManager::GetInstance().DeleteStrategyMeta(storeMeta.deviceAccountId, storeMeta.appId, storeMeta.storeId); + return status; } -void KvStoreMetaData::Unmarshal(const nlohmann::json &jObject) +Status KvStoreMetaManager::UpdateKvStoreMeta(const StoreMetaData &metaData) { - kvStoreType = Serializable::GetVal(jObject, KVSTORE_TYPE, json::value_t::number_unsigned, kvStoreType); - isBackup = Serializable::GetVal(jObject, BACKUP, json::value_t::boolean, isBackup); - isEncrypt = Serializable::GetVal(jObject, ENCRYPT, json::value_t::boolean, isEncrypt); - isAutoSync = Serializable::GetVal(jObject, AUTO_SYNC, json::value_t::boolean, isAutoSync); - appId = Serializable::GetVal(jObject, APP_ID, json::value_t::string, appId); - userId = Serializable::GetVal(jObject, USER_ID, json::value_t::string, userId); - storeId = Serializable::GetVal(jObject, STORE_ID, json::value_t::string, storeId); - bundleName = Serializable::GetVal(jObject, BUNDLE_NAME, json::value_t::string, bundleName); - deviceAccountId = Serializable::GetVal(jObject, DEVICE_ACCOUNT_ID, json::value_t::string, - deviceAccountId); - dataDir = Serializable::GetVal(jObject, DATA_DIR, json::value_t::string, dataDir); - appType = Serializable::GetVal(jObject, APP_TYPE, json::value_t::string, appType); - deviceId = Serializable::GetVal(jObject, DEVICE_ID, json::value_t::string, deviceId); - schema = Serializable::GetVal(jObject, SCHEMA, json::value_t::string, schema); - uid = Serializable::GetVal(jObject, UID, json::value_t::number_unsigned, uid); - version = Serializable::GetVal(jObject, VERSION, json::value_t::number_unsigned, version); - securityLevel = Serializable::GetVal(jObject, SECURITY_LEVEL, json::value_t::number_unsigned, - securityLevel); - isDirty = Serializable::GetVal(jObject, DIRTY_KEY, json::value_t::boolean, isDirty); + std::string jsonStr = to_string(metaData.Marshall()); + std::vector jsonVec(jsonStr.begin(), jsonStr.end()); + auto metaKey = + KvStoreMetaManager::GetMetaKey(metaData.deviceAccountId, "default", metaData.bundleName, metaData.storeId); + return KvStoreMetaManager::GetInstance().CheckUpdateServiceMeta(metaKey, UPDATE, jsonVec); } -template -T Serializable::GetVal(const json &j, const std::string &name, json::value_t type, const T &val) +DistributedData::StoreMetaData KvStoreMetaManager::BuildStoreMeta( + const Options &options, const AppId &appId, const StoreId &storeId, int uid, Status &status) { - auto it = j.find(name); - if (it != j.end() && it->type() == type) { - return *it; + auto trueAppId = CheckerManager::GetInstance().GetAppId(appId.appId, uid); + if (trueAppId.empty()) { + ZLOGW("appId empty(permission issues?)"); + status = Status::PERMISSION_DENIED; + return {}; } - ZLOGW("not found name:%s.", name.c_str()); - return val; -} - -std::vector SecretKeyMetaData::Marshal() const + StoreMetaData storeMeta; + storeMeta.appId = trueAppId; + storeMeta.appType = "harmony"; + storeMeta.bundleName = appId.appId; + storeMeta.deviceAccountId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid); + storeMeta.deviceId = DeviceKvStoreImpl::GetLocalDeviceId(); + storeMeta.isAutoSync = options.autoSync; + storeMeta.isBackup = options.backup; + storeMeta.isEncrypt = options.encrypt; + storeMeta.kvStoreType = options.kvStoreType; + storeMeta.schema = options.schema; + storeMeta.securityLevel = options.securityLevel; + storeMeta.storeId = storeId.storeId; + storeMeta.uid = uid; + storeMeta.userId = storeMeta.deviceAccountId; + storeMeta.dataDir = DirectoryManager::GetInstance().GetStorePath(storeMeta); + status = Status::SUCCESS; + return storeMeta; +} + +std::vector KvStoreMetaManager::GetStoreIdsOfApp(const std::string &userId, const AppId &appId, Status &status) { - json jval = { - {TIME, timeValue}, - {SKEY, secretKey}, - {KVSTORE_TYPE, kvStoreType} - }; - auto value = jval.dump(); - return std::vector(value.begin(), value.end()); -} - -void SecretKeyMetaData::Unmarshal(const nlohmann::json &jObject) -{ - timeValue = Serializable::GetVal>(jObject, TIME, json::value_t::array, timeValue); - secretKey = Serializable::GetVal>(jObject, SKEY, json::value_t::array, secretKey); - kvStoreType = Serializable::GetVal(jObject, KVSTORE_TYPE, json::value_t::number_unsigned, kvStoreType); + auto &metaDelegate = GetMetaKvStore(); + if (metaDelegate == nullptr) { + ZLOGE("GetMetaKvStore return nullptr."); + status = Status::DB_ERROR; + return {}; + } + std::vector dbEntries; + DistributedDB::Key dbKey = KvStoreMetaRow::GetKeyFor( + DeviceKvStoreImpl::GetLocalDeviceId() + Constant::KEY_SEPARATOR + userId + Constant::KEY_SEPARATOR + "default" + + Constant::KEY_SEPARATOR + appId.appId + Constant::KEY_SEPARATOR); + DistributedDB::DBStatus dbStatus = metaDelegate->GetEntries(dbKey, dbEntries); + if (dbStatus != DistributedDB::DBStatus::OK) { + status = dbEntries.empty() ? Status::SUCCESS : Status::DB_ERROR; + } + std::vector storeIds; + for (const auto &entry : dbEntries) { + std::string keyStr = std::string(entry.key.begin(), entry.key.end()); + size_t pos = keyStr.find_last_of(Constant::KEY_SEPARATOR); + if (pos == std::string::npos) { + continue; + } + storeIds.push_back({ keyStr.substr(pos + 1) }); + } + return storeIds; } bool KvStoreMetaManager::GetFullMetaData(std::map &entries, enum DatabaseType type) @@ -1167,7 +790,7 @@ bool KvStoreMetaManager::GetFullMetaData(std::map &entrie const std::string &metaKey = KvStoreMetaRow::KEY_PREFIX; DistributedDB::DBStatus dbStatus = metaDelegate->GetEntries({metaKey.begin(), metaKey.end()}, kvStoreMetaEntries); if (dbStatus != DistributedDB::DBStatus::OK) { - ZLOGE("Get kvstore meta data entries from metaDB failed, dbStatus: %d.", static_cast(dbStatus)); + ZLOGE("Get kvstore meta data entries from metaDB failed, dbStatus: %{public}d.", static_cast(dbStatus)); return false; } @@ -1187,28 +810,27 @@ bool KvStoreMetaManager::GetFullMetaData(std::map &entrie if (metaData.kvStoreMetaData.isEncrypt) { ZLOGE("isEncrypt."); const std::string keyType = ((metaData.kvStoreType == KvStoreType::SINGLE_VERSION) ? "SINGLE_KEY" : "KEY"); - const std::vector metaSecretKey = KvStoreMetaManager::GetInstance().GetMetaKey( - metaData.kvStoreMetaData.deviceAccountId, "default", metaData.kvStoreMetaData.bundleName, - metaData.kvStoreMetaData.storeId, keyType); + const std::vector metaSecretKey = + KvStoreMetaManager::GetInstance().GetMetaKey(metaData.kvStoreMetaData.deviceAccountId, "default", + metaData.kvStoreMetaData.bundleName, metaData.kvStoreMetaData.storeId, keyType); DistributedDB::Value secretValue; - metaDelegate->GetLocal(metaSecretKey, secretValue); - auto secretObj = Serializable::ToJson({secretValue.begin(), secretValue.end()}); - if (secretObj.empty()) { + auto ret = metaDelegate->GetLocal(metaSecretKey, secretValue); + if (ret != DistributedDB::OK + || !metaData.secretKeyMetaData.Unmarshall({ secretValue.begin(), secretValue.end() })) { ZLOGE("Failed to find SKEY in SecretKeyMetaData."); continue; } - metaData.secretKeyMetaData.Unmarshal(secretObj); - KvStoreMetaManager::GetInstance().DecryptWorkKey(metaData.secretKeyMetaData.secretKey, decryptKey); + KeyManager::DecryptWorkKey(metaData.secretKeyMetaData.sKey, decryptKey); } - entries.insert({{kvStoreMeta.key.begin(), kvStoreMeta.key.end()}, {metaData}}); + entries.insert({ { kvStoreMeta.key.begin(), kvStoreMeta.key.end() }, { metaData } }); std::fill(decryptKey.begin(), decryptKey.end(), 0); } return true; } -bool KvStoreMetaManager::GetKvStoreMetaByType(const std::string &name, const std::string &val, - KvStoreMetaData &metaData) +bool KvStoreMetaManager::GetKvStoreMetaByType( + const std::string &name, const std::string &val, StoreMetaData &metaData) { auto &metaDelegate = GetMetaKvStore(); if (metaDelegate == nullptr) { @@ -1219,7 +841,7 @@ bool KvStoreMetaManager::GetKvStoreMetaByType(const std::string &name, const std std::vector metaEntries; DistributedDB::DBStatus dbStatus = metaDelegate->GetEntries(metaKeyPrefix, metaEntries); if (dbStatus != DistributedDB::DBStatus::OK) { - ZLOGE("Get meta entries from metaDB failed, dbStatus: %d.", static_cast(dbStatus)); + ZLOGE("Get meta entries from metaDB failed, dbStatus: %{public}d.", static_cast(dbStatus)); return false; } @@ -1235,20 +857,44 @@ bool KvStoreMetaManager::GetKvStoreMetaByType(const std::string &name, const std std::string metaTypeVal; jsonObj[name].get_to(metaTypeVal); if (metaTypeVal == val) { - metaData.Unmarshal(Serializable::ToJson(jsonStr)); + metaData.Unmarshall(jsonStr); } } return true; } -bool KvStoreMetaManager::GetKvStoreMetaDataByBundleName(const std::string &bundleName, KvStoreMetaData &metaData) +bool KvStoreMetaManager::GetKvStoreMetaDataByBundleName(const std::string &bundleName, StoreMetaData &metaData) { - return GetKvStoreMetaByType(KvStoreMetaData::BUNDLE_NAME, bundleName, metaData); + return GetKvStoreMetaByType("bundleName", bundleName, metaData); } -bool KvStoreMetaManager::GetKvStoreMetaDataByAppId(const std::string &appId, KvStoreMetaData &metaData) +bool KvStoreMetaManager::GetKvStoreMetaDataByAppId(const std::string &appId, StoreMetaData &metaData) { - return GetKvStoreMetaByType(KvStoreMetaData::APP_ID, appId, metaData); + return GetKvStoreMetaByType("appId", appId, metaData); +} + +void KvStoreMetaManager::UpdateUserMetaData() +{ + auto &metaDelegate = GetMetaKvStore(); + if (metaDelegate == nullptr) { + ZLOGE("GetMetaKvStore return nullptr."); + return; + } + + std::vector userStatus = UserDelegate::GetInstance().GetAllLocalUserStatus(); + if (userStatus.empty()) { + ZLOGE("failed to all users"); + return; + } + UserMetaData userMetaData; + userMetaData.deviceId = DeviceKvStoreImpl::GetLocalDeviceId(); + userMetaData.users = userStatus; + + auto dbKey = UserMetaRow::GetKeyFor(userMetaData.deviceId); + std::string jsonData = to_string(userMetaData.Marshall()); + DistributedDB::Value dbValue{ jsonData.begin(), jsonData.end() }; + auto ret = metaDelegate->Put(dbKey, dbValue); + ZLOGI("put user meta data ret %{public}d", ret); } -} // namespace DistributedKv -} // namespace OHOS +} // namespace DistributedKv +} // namespace OHOS diff --git a/services/distributeddataservice/app/src/kvstore_meta_manager.h b/services/distributeddataservice/app/src/kvstore_meta_manager.h index c67d6b70c..2d653c30a 100755 --- a/services/distributeddataservice/app/src/kvstore_meta_manager.h +++ b/services/distributeddataservice/app/src/kvstore_meta_manager.h @@ -19,12 +19,18 @@ #include #include "app_device_status_change_listener.h" -#include "types.h" -#include "system_ability.h" #include "kv_store_delegate.h" #include "kv_store_delegate_manager.h" #include "kvstore_impl.h" +#include "metadata/capability_meta_data.h" +#include "metadata/meta_data.h" +#include "metadata/secret_key_meta_data.h" +#include "metadata/store_meta_data.h" +#include "metadata/strategy_meta_data.h" +#include "metadata/user_meta_data.h" #include "single_kvstore_impl.h" +#include "system_ability.h" +#include "types.h" namespace OHOS { namespace DistributedKv { @@ -37,121 +43,24 @@ enum FLAG { CHECK_EXIST_LOCAL, }; -struct Serializable { - using json = nlohmann::json; - template - static T GetVal(const json &j, const std::string &name, json::value_t type, const T &def); - static json ToJson(const std::string &jsonStr); -}; - -struct StrategyMeta { - std::string devId; - std::string devAccId; - std::string grpId; - std::string bundleName; - std::string storeId; -}; - -struct SecretKeyMetaData { - static constexpr const char *SKEY = "skey"; - std::vector timeValue {}; - std::vector secretKey {}; - KvStoreType kvStoreType = KvStoreType::INVALID_TYPE; - SecretKeyMetaData() {} - ~SecretKeyMetaData() - { - secretKey.assign(secretKey.size(), 0); - } - explicit SecretKeyMetaData(const nlohmann::json &jObject) - { - Unmarshal(jObject); - } - - std::vector Marshal() const; - void Unmarshal(const nlohmann::json &jObject); - operator std::vector() const - { - return Marshal(); - } -private: - static constexpr const char *TIME = "time"; - static constexpr const char *KVSTORE_TYPE = "kvStoreType"; -}; - -struct KvStoreMetaData { - static constexpr const char *APP_ID = "appId"; - static constexpr const char *BUNDLE_NAME = "bundleName"; - using json = nlohmann::json; - std::string appId = ""; - std::string appType = ""; - std::string bundleName = ""; - std::string dataDir = ""; - std::string deviceAccountId = ""; - std::string deviceId = ""; - bool isAutoSync = false; - bool isBackup = false; - bool isEncrypt = false; - KvStoreType kvStoreType = KvStoreType::DEVICE_COLLABORATION; - std::string schema = ""; - std::string storeId = ""; - std::string userId = ""; - std::int32_t uid = -1; - std::uint32_t version = 0; - int securityLevel = 0; - bool isDirty = false; - std::string Marshal() const; - void Unmarshal(const json &jObject); - - static inline std::string GetAppId(const json &jObject) - { - return Serializable::GetVal(jObject, APP_ID, json::value_t::string, ""); - } - - static inline std::string GetStoreId(const json &jObject) - { - return Serializable::GetVal(jObject, STORE_ID, json::value_t::string, ""); - } -private: - static constexpr const char *KVSTORE_TYPE = "kvStoreType"; - static constexpr const char *DEVICE_ID = "deviceId"; - static constexpr const char *USER_ID = "userId"; - static constexpr const char *STORE_ID = "storeId"; - static constexpr const char *ENCRYPT = "isEncrypt"; - static constexpr const char *BACKUP = "isBackup"; - static constexpr const char *AUTO_SYNC = "isAutoSync"; - static constexpr const char *SCHEMA = "schema"; - static constexpr const char *DATA_DIR = "dataDir"; - static constexpr const char *APP_TYPE = "appType"; - static constexpr const char *DEVICE_ACCOUNT_ID = "deviceAccountID"; - static constexpr const char *UID = "UID"; - static constexpr const char *VERSION = "version"; - static constexpr const char *SECURITY_LEVEL = "securityLevel"; - static constexpr const char *DIRTY_KEY = "isDirty"; +enum class CHANGE_FLAG { + INSERT, + UPDATE, + DELETE }; -struct MetaData { - std::int32_t kvStoreType; - KvStoreMetaData kvStoreMetaData; - SecretKeyMetaData secretKeyMetaData; - - static inline KvStoreType GetKvStoreType(const nlohmann::json &jObject) - { - return Serializable::GetVal(jObject, KVSTORE_TYPE, nlohmann::json::value_t::number_unsigned, - KvStoreType::INVALID_TYPE); - } -private: - static constexpr const char *KVSTORE_TYPE = "kvStoreType"; -}; +template +using Handler = std::function; class KvStoreMetaManager { public: - static constexpr uint32_t META_STORE_VERSION = 0x03000001; enum DatabaseType { KVDB, RDB, }; using NbDelegate = std::unique_ptr>; + using ChangeObserver = std::function &, const std::vector &, CHANGE_FLAG)>; class MetaDeviceChangeListenerImpl : public AppDistributedKv::AppDeviceStatusChangeListener { void OnDeviceChanged(const AppDistributedKv::DeviceInfo &info, @@ -164,55 +73,27 @@ public: static KvStoreMetaManager &GetInstance(); - void InitMetaParameter(); - - void InitMetaListener(std::function observer); - - const NbDelegate &GetMetaKvStore(); + DistributedData::StoreMetaData GetStoreMeta(pid_t uid, const AppId &appId, const StoreId &storeId, Status &status); + Status DeleteKvStoreMeta(const DistributedData::StoreMetaData &storeMeta); + Status UpdateKvStoreMeta(const DistributedData::StoreMetaData &metaData); + static DistributedData::StoreMetaData BuildStoreMeta( + const Options &options, const AppId &appId, const StoreId &storeId, int uid, Status &status); + std::vector GetStoreIdsOfApp(const std::string &userId, const AppId &appId, Status &status); - Status CheckUpdateServiceMeta(const std::vector &metaKey, FLAG flag, const std::vector &val = {}); - - Status GenerateRootKey(); + void InitMetaParameter(); + void InitMetaListener(); + void SubscribeMeta(const std::string &keyPrefix, const ChangeObserver &observer); - Status CheckRootKeyExist(); + Status CheckUpdateServiceMeta(const std::vector &metaKey, FLAG flag); + Status CheckUpdateServiceMeta(const std::vector &metaKey, FLAG flag, std::vector &val); static std::vector GetMetaKey( const std::string &deviceAccountId, const std::string &groupId, const std::string &bundleName, const std::string &storeId, const std::string &key = ""); - static std::string GetSecretKeyFile(const std::string &userId, const std::string &appId, - const std::string &storeId, int pathType); - - static std::string GetSecretSingleKeyFile(const std::string &userId, const std::string &appId, - const std::string &storeId, int pathType); - - Status GetSecretKeyFromMeta(const std::vector &metaSecretKey, - std::vector &key, bool &outdated); - - std::vector EncryptWorkKey(const std::vector &key); - - bool DecryptWorkKey(const std::vector &encryptedKey, std::vector &key); - - Status WriteSecretKeyToMeta(const std::vector &metaKey, const std::vector &key); - - Status WriteSecretKeyToFile(const std::string &secretKeyFile, const std::vector &key); - - Status - RemoveSecretKey(pid_t uid, const std::string &bundleName, const std::string &storeId); - - Status - RecoverSecretKeyFromFile(const std::string &secretKeyFile, const std::vector &metaSecretKey, - std::vector &key, bool &outdated); + void GetStrategyMetaKey(const DistributedData::StrategyMeta ¶ms, std::string &retVal); - void ReKey(const std::string &userId, const std::string &bundleName, const std::string &storeId, int32_t pathType, - sptr store); - - void ReKey(const std::string &userId, const std::string &bundleName, const std::string &storeId, int32_t pathType, - sptr store); - - void GetStrategyMetaKey(const StrategyMeta ¶ms, std::string &retVal); - - Status DeleteStrategyMeta(const std::string &bundleName, const std::string &storeId, const std::string &userId); + Status DeleteStrategyMeta(const std::string &userId, const std::string &bundleName, const std::string &storeId); Status SaveStrategyMetaEnable(const std::string &key, bool enable); @@ -224,31 +105,37 @@ public: uint8_t flag, const std::string &remoteId); Status QueryKvStoreMetaDataByDeviceIdAndAppId(const std::string &devId, const std::string &appId, - KvStoreMetaData &val); + DistributedData::StoreMetaData &val); - Status GetKvStoreMeta(const std::vector &metaKey, KvStoreMetaData &kvStoreMetaData); + Status GetKvStoreMeta(const std::vector &metaKey, DistributedData::StoreMetaData &kvStoreMetaData); - bool GetKvStoreMetaDataByBundleName(const std::string &bundleName, KvStoreMetaData &metaData); + bool GetKvStoreMetaDataByBundleName(const std::string &bundleName, DistributedData::StoreMetaData &metaData); - bool GetKvStoreMetaDataByAppId(const std::string &appId, KvStoreMetaData &metaData); + bool GetKvStoreMetaDataByAppId(const std::string &appId, DistributedData::StoreMetaData &metaData); - bool GetFullMetaData(std::map &entries, enum DatabaseType type = KVDB); + bool GetFullMetaData(std::map &entries, enum DatabaseType type = KVDB); private: + KvStoreMetaManager(); + const NbDelegate &GetMetaKvStore(); NbDelegate CreateMetaKvStore(); - KvStoreMetaManager(); + static DistributedData::StoreMetaData GenMetaData(); void InitMetaData(); + void UpdateUserMetaData(); + void SubscribeMetaKvStore(); void SyncMeta(); - void ConcatWithSharps(const std::vector ¶ms, std::string &retVal); + static void ConcatWithSharps(const std::vector ¶ms, std::string &retVal); - Status GetStategyMeta(const std::string &key, std::map> &strategies); + Status GetStrategyMeta(const std::string &key, std::map> &strategies); - bool GetKvStoreMetaByType(const std::string &name, const std::string &val, KvStoreMetaData &metaData); + static bool CompareStrategyMeta(const std::vector &strategy1, const std::vector &strategy2); + + bool GetKvStoreMetaByType(const std::string &name, const std::string &val, DistributedData::StoreMetaData &metaData); class KvStoreMetaObserver : public DistributedDB::KvStoreObserver { public: @@ -256,28 +143,23 @@ private: // Database change callback void OnChange(const DistributedDB::KvStoreChangedData &data) override; - std::function notify_ = nullptr; + std::map handlerMap_; + private: + void HandleChanges(CHANGE_FLAG flag, const std::list &list); }; static const inline std::string META_DB_APP_ID = "distributeddata"; - static constexpr const char *ROOT_KEY_ALIAS = "distributed_db_root_key"; static constexpr const char *STRATEGY_META_PREFIX = "StrategyMetaData"; static constexpr const char *CAPABILITY_ENABLED = "capabilityEnabled"; static constexpr const char *CAPABILITY_RANGE = "capabilityRange"; static constexpr const char *LOCAL_LABEL = "localLabel"; static constexpr const char *REMOTE_LABEL = "remoteLabel"; - static constexpr const char *HARMONY_APP = "harmony"; - static constexpr const char *HKS_BLOB_TYPE_NONCE = "Z5s0Bo571KoqwIi6"; - static constexpr const char *HKS_BLOB_TYPE_AAD = "distributeddata"; - static constexpr int KEY_SIZE = 32; - static constexpr int HOURS_PER_YEAR = (24 * 365); NbDelegate metaDelegate_; std::string metaDBDirectory_; + std::string metaDBBackupDir_; DistributedDB::KvStoreDelegateManager kvStoreDelegateManager_; - std::vector vecRootKeyAlias_ {}; - std::vector vecNonce_ {}; - std::vector vecAad_ {}; + static std::condition_variable cv_; static std::mutex cvMutex_; static MetaDeviceChangeListenerImpl listener_; diff --git a/services/distributeddataservice/app/src/kvstore_user_manager.cpp b/services/distributeddataservice/app/src/kvstore_user_manager.cpp index 7e61eaf67..e010cc78c 100755 --- a/services/distributeddataservice/app/src/kvstore_user_manager.cpp +++ b/services/distributeddataservice/app/src/kvstore_user_manager.cpp @@ -16,6 +16,7 @@ #define LOG_TAG "KvStoreUserManager" #include "kvstore_user_manager.h" +#include "kvstore_meta_manager.h" #include "account_delegate.h" #include "checker/checker_manager.h" #include "constant.h" @@ -40,26 +41,26 @@ KvStoreUserManager::~KvStoreUserManager() appMap_.clear(); } -Status KvStoreUserManager::CloseKvStore(const std::string &appId, const std::string &storeId) +Status KvStoreUserManager::CloseKvStore(const StoreMetaData &storeMeta) { ZLOGI("begin."); std::lock_guard lg(appMutex_); - auto it = appMap_.find(appId); + auto it = appMap_.find(storeMeta.appId); if (it != appMap_.end()) { - return (it->second).CloseKvStore(storeId); + return (it->second).CloseKvStore(storeMeta); } ZLOGE("store not open."); return Status::STORE_NOT_OPEN; } -Status KvStoreUserManager::CloseAllKvStore(const std::string &appId) +Status KvStoreUserManager::CloseAllKvStore(const DistributedData::StoreMetaData &storeMeta) { ZLOGI("begin."); std::lock_guard lg(appMutex_); - auto it = appMap_.find(appId); + auto it = appMap_.find(storeMeta.bundleName); if (it != appMap_.end()) { - return (it->second).CloseAllKvStore(); + return (it->second).CloseAllKvStore(storeMeta); } ZLOGE("store not open."); @@ -71,25 +72,25 @@ void KvStoreUserManager::CloseAllKvStore() ZLOGI("begin."); std::lock_guard lg(appMutex_); for (auto &it : appMap_) { - (it.second).CloseAllKvStore(); + (it.second).CloseAllKvStore({}); // todo: delete } } -Status KvStoreUserManager::DeleteKvStore(const std::string &bundleName, const std::string &storeId) +Status KvStoreUserManager::DeleteKvStore(const DistributedData::StoreMetaData &storeMeta) { ZLOGI("begin."); std::lock_guard lg(appMutex_); - auto it = appMap_.find(bundleName); + auto it = appMap_.find(storeMeta.bundleName); if (it != appMap_.end()) { - auto status = (it->second).DeleteKvStore(storeId); + auto status = (it->second).DeleteKvStore(storeMeta); if ((it->second).GetTotalKvStoreNum() == 0) { ZLOGI("There is not kvstore, so remove the app manager."); appMap_.erase(it); } return status; } - KvStoreAppManager kvStoreAppManager(bundleName, CheckerManager::INVALID_UID); - return kvStoreAppManager.DeleteKvStore(storeId); + KvStoreAppManager kvStoreAppManager(storeMeta.bundleName, CheckerManager::INVALID_UID); + return kvStoreAppManager.DeleteKvStore(storeMeta); } void KvStoreUserManager::DeleteAllKvStore() @@ -97,7 +98,7 @@ void KvStoreUserManager::DeleteAllKvStore() ZLOGI("begin."); std::lock_guard lg(appMutex_); for (auto &it : appMap_) { - (it.second).DeleteAllKvStore(); + (it.second).DeleteAllKvStore(it.first); } appMap_.clear(); } @@ -119,20 +120,6 @@ Status KvStoreUserManager::MigrateAllKvStore(const std::string &harmonyAccountId return status; } -std::string KvStoreUserManager::GetDbDir(const std::string &bundleName, const Options &options) -{ - ZLOGI("begin."); - if (options.kvStoreType == KvStoreType::MULTI_VERSION) { - return "default"; - } - std::lock_guard lg(appMutex_); - auto it = appMap_.find(bundleName); - if (it != appMap_.end()) { - return (it->second).GetDbDir(options); - } - return ""; -} - void KvStoreUserManager::Dump(int fd) const { const std::string prefix(4, ' '); @@ -143,5 +130,19 @@ void KvStoreUserManager::Dump(int fd) const pair.second.Dump(fd); } } + +bool KvStoreUserManager::IsStoreOpened(const std::string &appId, const std::string &storeId) +{ + std::lock_guard lg(appMutex_); + auto it = appMap_.find(appId); + return it != appMap_.end() && it->second.IsStoreOpened(storeId); +} + +void KvStoreUserManager::SetCompatibleIdentify(const std::string &deviceId) const +{ + for (const auto &item : appMap_) { + item.second.SetCompatibleIdentify(deviceId); + } +} } // namespace DistributedKv } // namespace OHOS diff --git a/services/distributeddataservice/app/src/kvstore_user_manager.h b/services/distributeddataservice/app/src/kvstore_user_manager.h index af22549e1..ada943038 100755 --- a/services/distributeddataservice/app/src/kvstore_user_manager.h +++ b/services/distributeddataservice/app/src/kvstore_user_manager.h @@ -18,6 +18,7 @@ #include #include + #include "kvstore_app_manager.h" #include "kvstore_impl.h" #include "types.h" @@ -31,14 +32,14 @@ public: virtual ~KvStoreUserManager(); template - Status GetKvStore(const Options &options, const std::string &bundleName, const std::string &storeId, pid_t uid, + Status GetKvStore(const DistributedData::StoreMetaData &storeMeta, const Options &options, const std::vector &cipherKey, sptr &kvStore) { std::lock_guard lg(appMutex_); - auto it = appMap_.find(bundleName); + auto it = appMap_.find(storeMeta.bundleName); if (it == appMap_.end()) { auto result = appMap_.emplace( - std::piecewise_construct, std::forward_as_tuple(bundleName), std::forward_as_tuple(bundleName, uid)); + std::piecewise_construct, std::forward_as_tuple(storeMeta.bundleName), std::forward_as_tuple(storeMeta.bundleName, storeMeta.uid)); if (result.second) { it = result.first; } @@ -47,25 +48,26 @@ public: kvStore = nullptr; return Status::ERROR; } - return (it->second).GetKvStore(options, bundleName, storeId, cipherKey, kvStore); + return (it->second).GetKvStore(options, storeMeta, cipherKey, kvStore); } - Status CloseKvStore(const std::string &appId, const std::string &storeId); + Status CloseKvStore(const DistributedData::StoreMetaData &storeMeta); - Status CloseAllKvStore(const std::string &appId); + Status CloseAllKvStore(const DistributedData::StoreMetaData &storeMeta); void CloseAllKvStore(); - Status DeleteKvStore(const std::string &bundleName, const std::string &storeId); + Status DeleteKvStore(const DistributedData::StoreMetaData &storeMeta); void DeleteAllKvStore(); Status MigrateAllKvStore(const std::string &harmonyAccountId); - std::string GetDbDir(const std::string &bundleName, const Options &options); - void Dump(int fd) const; + bool IsStoreOpened(const std::string &appId, const std::string &storeId); + void SetCompatibleIdentify(const std::string &deviceId) const; + private: std::mutex appMutex_; std::map appMap_; diff --git a/services/distributeddataservice/app/src/kvstore_user_observer.cpp b/services/distributeddataservice/app/src/kvstore_user_observer.cpp new file mode 100644 index 000000000..083008d56 --- /dev/null +++ b/services/distributeddataservice/app/src/kvstore_user_observer.cpp @@ -0,0 +1,38 @@ +/* + * 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 "kvstore_user_observer.h" + +#define LOG_TAG "KvStoreUserObserver" + +#include + +#include "kv_store_delegate_manager.h" +#include "log_print.h" +namespace OHOS::DistributedData { +void OHOS::DistributedData::KvStoreUserObserver::OnUserChanged() +{ + std::thread th = std::thread([this]() { + std::lock_guard lockGuard(userSwitchMutex_); + auto ret = DistributedDB::KvStoreDelegateManager::NotifyUSerChanged(); + ZLOGI("notify delegate manager result:%{public}d", ret); + }); + th.detach(); +} +std::string OHOS::DistributedData::KvStoreUserObserver::Name() +{ + return "KvStoreUserObserver"; +} +} // namespace OHOS::DistributedData diff --git a/services/distributeddataservice/app/src/kvstore_user_observer.h b/services/distributeddataservice/app/src/kvstore_user_observer.h new file mode 100644 index 000000000..ecc15f621 --- /dev/null +++ b/services/distributeddataservice/app/src/kvstore_user_observer.h @@ -0,0 +1,29 @@ +/* + * 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. + */ + +#ifndef SDB_KVSTORE_USER_OBSERVER_H +#define SDB_KVSTORE_USER_OBSERVER_H +#include "user_delegate.h" +namespace OHOS::DistributedData { +class KvStoreUserObserver final : public UserDelegate::Observer { +public: + void OnUserChanged() override; + std::string Name() override; + +private: + std::mutex userSwitchMutex_; +}; +} +#endif //SDB_KVSTORE_USER_OBSERVER_H diff --git a/services/distributeddataservice/app/src/session_manager/route_head_handler.cpp b/services/distributeddataservice/app/src/session_manager/route_head_handler.cpp new file mode 100644 index 000000000..b7a052c6f --- /dev/null +++ b/services/distributeddataservice/app/src/session_manager/route_head_handler.cpp @@ -0,0 +1,225 @@ +/* + * 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 "route_head_handler.h" + +#define LOG_TAG "RouteHeadHandler" + +#include "auth/auth_delegate.h" +#include "device_kvstore_impl.h" +#include "log_print.h" +#include "securec.h" +#include "upgrade_manager.h" + +namespace OHOS::DistributedData { +using namespace OHOS::DistributedKv; +constexpr size_t MSG_ALIGN_WIDTH = 8; +std::shared_ptr RouteHeadHandlerImpl::GetInstance(const DistributedDB::ExtendInfo &info) +{ + auto handler = std::make_shared(info); + if (handler == nullptr) { + ZLOGE("new instance failed"); + return nullptr; + } + handler->Init(); + return handler; +} + +RouteHeadHandlerImpl::RouteHeadHandlerImpl(const DistributedDB::ExtendInfo &info) + : userId_(info.userId), appId_(info.appId), storeId_(info.storeId), deviceId_(info.dstTarget) +{ +} + +void RouteHeadHandlerImpl::Init() +{ + if (deviceId_.empty()) { + return; + } + SessionPoint localPoint{ DeviceKvStoreImpl::GetLocalDeviceId(), std::stoi(userId_), appId_ }; + validSession_ = SessionManager::GetInstance().GetValidSession(localPoint, deviceId_); +} + +DistributedDB::DBStatus RouteHeadHandlerImpl::GetHeadDataSize(uint32_t &headSize) +{ + auto peerCap = UpgradeManager::GetInstance().GetCapability(validSession_.targetDeviceId); + if (peerCap.version == CapMetaData::INVALID_VERSION) { + // older versions ignore pack extend head + ZLOGI("ignore older version device"); + headSize = 0; + return DistributedDB::OK; + } + size_t expectSize = sizeof(RouteHead) + sizeof(SessionDevicePair) + sizeof(SessionUserPair) + + validSession_.targetUserIds.size() * sizeof(int) + sizeof(SessionAppId) + + validSession_.appId.size(); + + // align message uint width + size_t alignSize = MSG_ALIGN_WIDTH - expectSize % MSG_ALIGN_WIDTH; + headSize = expectSize + (alignSize == MSG_ALIGN_WIDTH ? 0 : alignSize); + return DistributedDB::OK; +} + +DistributedDB::DBStatus RouteHeadHandlerImpl::FillHeadData(uint8_t *data, uint32_t headSize, uint32_t totalLen) +{ + uint32_t realHeadSize = 0; + GetHeadDataSize(realHeadSize); + if (realHeadSize == 0) { + ZLOGI("ignore older version device"); + return DistributedDB::OK; + } + auto packRet = PackData(data, headSize); + return packRet ? DistributedDB::OK : DistributedDB::DB_ERROR; +} + +bool RouteHeadHandlerImpl::PackData(uint8_t *data, uint32_t totalLen) +{ + uint32_t realHeadSize = 0; + GetHeadDataSize(realHeadSize); + if (realHeadSize > totalLen) { + ZLOGE("the buffer size is not enough"); + return false; + } + + // pack head + PackDataHead(data, realHeadSize); + PackDataBody(data + sizeof(RouteHead), realHeadSize - sizeof(RouteHead)); + return true; +} + +void RouteHeadHandlerImpl::PackDataHead(uint8_t *data, uint32_t totalLen) +{ + uint8_t *ptr = data; + RouteHead *head = reinterpret_cast(ptr); + head->magic = RouteHead::MAGIC_NUMBER; + head->version = RouteHead::VERSION; + head->checkSum = 0; + head->dataLen = static_cast(totalLen - sizeof(RouteHead)); +} + +void RouteHeadHandlerImpl::PackDataBody(uint8_t *data, uint32_t totalLen) +{ + uint8_t *ptr = data; + SessionDevicePair *devicePair = reinterpret_cast(ptr); + strcpy_s(devicePair->sourceDeviceId, DEVICE_ID_SIZE_MAX, validSession_.sourceDeviceId.c_str()); + strcpy_s(devicePair->targetDeviceId, DEVICE_ID_SIZE_MAX, validSession_.targetDeviceId.c_str()); + ptr += sizeof(SessionDevicePair); + + SessionUserPair *userPair = reinterpret_cast(ptr); + userPair->sourceUserId = validSession_.sourceUserId; + userPair->targetUserCount = validSession_.targetUserIds.size(); + for (size_t i = 0; i < validSession_.targetUserIds.size(); ++i) { + *((int *)(&(userPair->targetUserIds[0]) + i)) = validSession_.targetUserIds[i]; + } + ptr += (sizeof(SessionUserPair) + validSession_.targetUserIds.size() * sizeof(int)); + + SessionAppId *appPair = reinterpret_cast(ptr); + appPair->len = validSession_.appId.size(); + strcpy_s(appPair->appId, data + totalLen - ptr, validSession_.appId.c_str()); +} + +bool RouteHeadHandlerImpl::ParseHeadData( + const uint8_t *data, uint32_t len, uint32_t &headSize, std::vector &users) +{ + auto ret = UnPackData(data, len); + if (!ret) { + ZLOGE("unpack data head failed"); + return false; + } + + // flip the local and peer ends + SessionPoint local{ .deviceId = validSession_.targetDeviceId, .appId = validSession_.appId }; + SessionPoint peer{ + .deviceId = validSession_.sourceDeviceId, .userId = validSession_.sourceUserId, .appId = validSession_.appId + }; + for (const auto &item : validSession_.targetUserIds) { + local.userId = item; + if (SessionManager::GetInstance().CheckSession(local, peer)) { + users.emplace_back(std::to_string(item)); + } + } + return true; +} + +bool RouteHeadHandlerImpl::UnPackData(const uint8_t *data, uint32_t totalLen) +{ + if (data == nullptr || totalLen < sizeof(RouteHead)) { + ZLOGE("invalid input data"); + return false; + } + RouteHead *head = UnPackHeadHead(data, totalLen); + if (head != nullptr && head->version == RouteHead::VERSION) { + return UnPackHeadBody(data + sizeof(RouteHead), totalLen - sizeof(RouteHead)); + } + return false; +} + +RouteHead *RouteHeadHandlerImpl::UnPackHeadHead(const uint8_t *data, uint32_t totalLen) +{ + const uint8_t *ptr = data; + RouteHead *head = (RouteHead *)ptr; + if (head->magic != RouteHead::MAGIC_NUMBER) { + ZLOGE("not route head data"); + return nullptr; + } + if (head->dataLen + sizeof(RouteHead) > totalLen) { + ZLOGE("invalid route head len"); + return nullptr; + } + return head; +} + +bool RouteHeadHandlerImpl::UnPackHeadBody(const uint8_t *data, uint32_t totalLen) +{ + const uint8_t *ptr = data; + uint32_t leftSize = totalLen; + + if (leftSize < sizeof(SessionDevicePair)) { + ZLOGE("failed to parse device pair"); + return false; + } + SessionDevicePair *devicePair = (SessionDevicePair *)ptr; + validSession_.sourceDeviceId.append(devicePair->sourceDeviceId, DEVICE_ID_SIZE_MAX); + validSession_.targetDeviceId.append(devicePair->targetDeviceId, DEVICE_ID_SIZE_MAX); + ptr += sizeof(SessionDevicePair); + leftSize -= sizeof(SessionDevicePair); + + if (leftSize < sizeof(SessionUserPair)) { + ZLOGE("failed to parse user pair"); + return false; + } + SessionUserPair *userPair = (SessionUserPair *)ptr; + validSession_.sourceUserId = userPair->sourceUserId; + + if (leftSize < sizeof(SessionUserPair) + userPair->targetUserCount * sizeof(int)) { + ZLOGE("failed to parse user pair, target user"); + return false; + } + for (int i = 0; i < userPair->targetUserCount; ++i) { + validSession_.targetUserIds.push_back(*(userPair->targetUserIds + sizeof(int) * i)); + } + ptr += sizeof(SessionUserPair) + userPair->targetUserCount * sizeof(int); + + if (leftSize < sizeof(SessionAppId)) { + ZLOGE("failed to parse app id len"); + return false; + } + SessionAppId *appId = (SessionAppId *)ptr; + + if (leftSize < sizeof(SessionAppId) + appId->len) { + ZLOGE("failed to parse app id"); + return false; + } + validSession_.appId.append(appId->appId, appId->len); + return true; +} +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/app/src/session_manager/route_head_handler.h b/services/distributeddataservice/app/src/session_manager/route_head_handler.h new file mode 100644 index 000000000..2482d77ee --- /dev/null +++ b/services/distributeddataservice/app/src/session_manager/route_head_handler.h @@ -0,0 +1,77 @@ +/* + * 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. + */ + +#ifndef SDB_ROUTE_HEAD_HANDLER_H +#define SDB_ROUTE_HEAD_HANDLER_H +#include "extend_head_handler.h" +#include "process_communicator_impl.h" +#include "serializable/serializable.h" +#include "session_manager.h" + +namespace OHOS::DistributedData { +#pragma pack(1) +// format: head + device pair + user pair + appid +struct RouteHead { + static constexpr uint16_t MAGIC_NUMBER = 0x8421; + static constexpr uint16_t VERSION = 0x1; + uint16_t magic = MAGIC_NUMBER; + uint16_t version = VERSION; + uint64_t checkSum; + uint32_t dataLen; +}; + +constexpr int32_t DEVICE_ID_SIZE_MAX = 65; +struct SessionDevicePair { + char sourceDeviceId[DEVICE_ID_SIZE_MAX]; + char targetDeviceId[DEVICE_ID_SIZE_MAX]; +}; + +struct SessionUserPair { + int sourceUserId; + uint8_t targetUserCount; + int targetUserIds[0]; +}; + +struct SessionAppId { + uint32_t len; + char appId[0]; +}; +#pragma pack() + +class RouteHeadHandlerImpl : public DistributedData::RouteHeadHandler { +public: + static std::shared_ptr GetInstance(const DistributedDB::ExtendInfo &info); + explicit RouteHeadHandlerImpl(const DistributedDB::ExtendInfo &info); + DistributedDB::DBStatus GetHeadDataSize(uint32_t &headSize) override; + DistributedDB::DBStatus FillHeadData(uint8_t *data, uint32_t headSize, uint32_t totalLen) override; + bool ParseHeadData(const uint8_t *data, uint32_t len, uint32_t &headSize, std::vector &users) override; + +private: + void Init(); + bool PackData(uint8_t *data, uint32_t totalLen); + void PackDataHead(uint8_t *data, uint32_t totalLen); + void PackDataBody(uint8_t *data, uint32_t totalLen); + bool UnPackData(const uint8_t *data, uint32_t totalLen); + RouteHead *UnPackHeadHead(const uint8_t *data, uint32_t totalLen); + bool UnPackHeadBody(const uint8_t *data, uint32_t totalLen); + + std::string userId_; + std::string appId_; + std::string storeId_; + std::string deviceId_; + Session validSession_; +}; +} // namespace OHOS::DistributedData +#endif //SDB_ROUTE_HEAD_HANDLER_H diff --git a/services/distributeddataservice/app/src/session_manager/session_manager.cpp b/services/distributeddataservice/app/src/session_manager/session_manager.cpp new file mode 100644 index 000000000..dce74ce64 --- /dev/null +++ b/services/distributeddataservice/app/src/session_manager/session_manager.cpp @@ -0,0 +1,92 @@ +/* + * 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 "session_manager.h" + +#define LOG_TAG "SessionManager" + +#include "auth/auth_delegate.h" +#include "log/log_print.h" +#include "user_delegate.h" + +namespace OHOS::DistributedData { +using namespace OHOS::DistributedKv; +SessionManager &SessionManager::GetInstance() +{ + static SessionManager instance; + instance.Init(); + return instance; +} +void SessionManager::Init() const +{ + auto ret = UserDelegate::GetInstance().SubscribeUserEvent(std::make_shared()); + ZLOGD("subscribe user changelist with ret %{public}d", ret); +} +Session SessionManager::GetValidSession(const SessionPoint &from, const std::string &targetDeviceId) const +{ + auto users = UserDelegate::GetInstance().GetAllRemoteUserStatus(targetDeviceId); + Session session; + session.appId = from.appId; + session.sourceUserId = from.userId; + session.sourceDeviceId = from.deviceId; + session.targetDeviceId = targetDeviceId; + for (const auto &user : users) { + bool isPermitted = AuthDelegate::CheckAccess(from.userId, user.id, targetDeviceId, from.appId); + if (isPermitted) { + session.targetUserIds.push_back(user.id); + } + } + ZLOGD("valid access to peer users count:%{public}zu", session.targetUserIds.size()); + if (session.targetUserIds.empty()) { + return {}; + } + return session; +} +bool SessionManager::CheckSession(const SessionPoint &from, const SessionPoint &to) const +{ + return AuthDelegate::CheckAccess(from.userId, to.userId, to.deviceId, from.appId); +} +void SessionManager::UserObserver::OnUserChanged() +{ +} +std::string SessionManager::UserObserver::Name() +{ + return "session_observer"; +} + +bool Session::Marshal(Serializable::json &node) const +{ + bool ret = true; + ret &= SetValue(node[GET_NAME(sourceDeviceId)], sourceDeviceId); + ret &= SetValue(node[GET_NAME(targetDeviceId)], targetDeviceId); + ret &= SetValue(node[GET_NAME(sourceUserId)], sourceUserId); + ret &= SetValue(node[GET_NAME(targetUserIds)], targetUserIds); + ret &= SetValue(node[GET_NAME(appId)], appId); + + return ret; +} + +bool Session::Unmarshal(const Serializable::json &node) +{ + bool ret = true; + ret &= GetValue(node, GET_NAME(sourceDeviceId), sourceDeviceId); + ret &= GetValue(node, GET_NAME(targetDeviceId), targetDeviceId); + ret &= GetValue(node, GET_NAME(sourceUserId), sourceUserId); + ret &= GetValue(node, GET_NAME(targetUserIds), targetUserIds); + ret &= GetValue(node, GET_NAME(appId), appId); + + return ret; +} +} // namespace OHOS::DistributedData diff --git a/services/distributeddataservice/app/src/session_manager/session_manager.h b/services/distributeddataservice/app/src/session_manager/session_manager.h new file mode 100644 index 000000000..0fe550307 --- /dev/null +++ b/services/distributeddataservice/app/src/session_manager/session_manager.h @@ -0,0 +1,58 @@ +/* + * 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. + */ + +#ifndef SDB_SESSIONMANAGER_H +#define SDB_SESSIONMANAGER_H + +#include +#include + +#include "serializable/serializable.h" +#include "user_delegate.h" + +namespace OHOS::DistributedData { +struct SessionPoint { + std::string deviceId; + int userId; + std::string appId; +}; + +struct Session : public Serializable { + std::string sourceDeviceId; + std::string targetDeviceId; + int sourceUserId; + std::vector targetUserIds; + std::string appId; + bool Marshal(Serializable::json &node) const override; + bool Unmarshal(const Serializable::json &node) override; +}; + +class SessionManager { +public: + static SessionManager &GetInstance(); + Session GetValidSession(const SessionPoint &from, const std::string &targetDeviceId) const; + bool CheckSession(const SessionPoint &from, const SessionPoint &to) const; + +private: + void Init() const; + class UserObserver final : public UserDelegate::Observer { + public: + void OnUserChanged() override; + std::string Name() override; + }; +}; +} // namespace OHOS::DistributedData + +#endif //SDB_SESSIONMANAGER_H diff --git a/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp b/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp new file mode 100644 index 000000000..b82221cc7 --- /dev/null +++ b/services/distributeddataservice/app/src/session_manager/upgrade_manager.cpp @@ -0,0 +1,49 @@ +/* + * 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 "upgrade_manager.h" + +#include "kvstore_meta_manager.h" +#include "utils/constant.h" + +namespace OHOS::DistributedData { +using namespace OHOS::DistributedKv; +OHOS::DistributedData::UpgradeManager &OHOS::DistributedData::UpgradeManager::GetInstance() +{ + static UpgradeManager instance; + return instance; +} +void UpgradeManager::Init() +{ + KvStoreMetaManager::GetInstance().SubscribeMeta(CapMetaRow::KEY_PREFIX, + [this](const std::vector &key, const std::vector &value, CHANGE_FLAG flag) { + CapMetaData capMetaData; + capMetaData.Unmarshall({ value.begin(), value.end() }); + std::string deviceId = { key.begin() + CapMetaRow::KEY_PREFIX.size() + Constant::KEY_SEPARATOR.size(), + key.end() }; + if (flag == CHANGE_FLAG::INSERT || flag == CHANGE_FLAG::UPDATE) { + UpdateCapability(deviceId, capMetaData); + } + }); +} +CapMetaData UpgradeManager::GetCapability(const std::string &deviceId) +{ + return capabilityMap_.Find(deviceId).second; +} +void UpgradeManager::UpdateCapability(const std::string &deviceId, const CapMetaData &capMetaData) +{ + capabilityMap_[deviceId] = capMetaData; +} +} // namespace OHOS::DistributedData diff --git a/services/distributeddataservice/app/src/session_manager/upgrade_manager.h b/services/distributeddataservice/app/src/session_manager/upgrade_manager.h new file mode 100644 index 000000000..85435b7b7 --- /dev/null +++ b/services/distributeddataservice/app/src/session_manager/upgrade_manager.h @@ -0,0 +1,35 @@ +/* + * 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. + */ + +#ifndef SDB_UPGRADE_MANAGER_H +#define SDB_UPGRADE_MANAGER_H +#include + +#include "concurrent_map.h" +#include "metadata/capability_meta_data.h" +namespace OHOS::DistributedData { + +class UpgradeManager { +public: + static UpgradeManager &GetInstance(); + void UpdateCapability(const std::string &deviceId, const CapMetaData &capMetaData); + CapMetaData GetCapability(const std::string &deviceId); + +private: + void Init(); + ConcurrentMap capabilityMap_{}; +}; +} // namespace OHOS::DistributedData +#endif //SDB_UPGRADE_MANAGER_H diff --git a/services/distributeddataservice/app/src/single_kvstore_impl.cpp b/services/distributeddataservice/app/src/single_kvstore_impl.cpp index 984fe07bc..b158381f1 100755 --- a/services/distributeddataservice/app/src/single_kvstore_impl.cpp +++ b/services/distributeddataservice/app/src/single_kvstore_impl.cpp @@ -23,6 +23,7 @@ #include "constant.h" #include "dds_trace.h" #include "device_kvstore_impl.h" +#include "auth/auth_delegate.h" #include "kvstore_data_service.h" #include "kvstore_utils.h" #include "ipc_skeleton.h" @@ -30,6 +31,8 @@ #include "permission_validator.h" #include "query_helper.h" #include "reporter.h" +#include "metadata/strategy_meta_data.h" +#include "upgrade_manager.h" namespace OHOS::DistributedKv { using namespace OHOS::DistributedData; @@ -66,7 +69,7 @@ SingleKvStoreImpl::~SingleKvStoreImpl() SingleKvStoreImpl::SingleKvStoreImpl(const Options &options, const std::string &userId, const std::string &bundleName, const std::string &storeId, const std::string &appId, const std::string &directory, DistributedDB::KvStoreNbDelegate *delegate) - : options_(options), deviceAccountId_(userId), bundleName_(bundleName), storeId_(storeId), appId_(appId), + : options_(options), userId_(userId), bundleName_(bundleName), storeId_(storeId), appId_(appId), storePath_(Constant::Concatenate({ directory, storeId })), kvStoreNbDelegate_(delegate), observerMapMutex_(), observerMap_(), storeResultSetMutex_(), storeResultSetMap_(), openCount_(1), flowCtrl_(BURST_CAPACITY, SUSTAINED_CAPACITY) @@ -1081,15 +1084,11 @@ Status SingleKvStoreImpl::MigrateKvStore(const std::string &harmonyAccountId, } ZLOGI("create new KvStore."); - std::vector secretKey; // expected get secret key from meta kvstore successful when encrypt flag is true. - std::unique_ptr, void(*)(std::vector*)> cleanGuard( - &secretKey, [](std::vector *ptr) { ptr->assign(ptr->size(), 0); }); - bool outdated = false; // ignore outdated flag during rebuild kvstore. - auto metaSecretKey = KvStoreMetaManager::GetMetaKey(deviceAccountId_, "default", bundleName_, storeId_, - "SINGLE_KEY"); + SecretKey secretKey; + Status status; if (options_.encrypt) { - KvStoreMetaManager::GetInstance().GetSecretKeyFromMeta(metaSecretKey, secretKey, outdated); - if (secretKey.empty()) { + secretKey = KeyManager::GetSecretKey(meta_, KeyName(), status); + if (secretKey.IsEmpty()) { ZLOGE("Get secret key from meta kvstore failed."); return Status::CRYPT_ERROR; } @@ -1097,7 +1096,7 @@ Status SingleKvStoreImpl::MigrateKvStore(const std::string &harmonyAccountId, DistributedDB::DBStatus dbStatus; DistributedDB::KvStoreNbDelegate::Option dbOption; - Status status = KvStoreAppManager::InitNbDbOption(options_, secretKey, dbOption); + status = KvStoreAppManager::InitNbDbOption(options_, secretKey.data, dbOption); if (status != Status::SUCCESS) { ZLOGE("InitNbDbOption failed."); return status; @@ -1487,23 +1486,25 @@ void SingleKvStoreImpl::IncreaseOpenCount() bool SingleKvStoreImpl::Import(const std::string &bundleName) const { ZLOGI("Single KvStoreImpl Import start"); - const std::string harmonyAccountId = AccountDelegate::GetInstance()->GetCurrentAccountId(); - auto sKey = KvStoreMetaManager::GetMetaKey(deviceAccountId_, harmonyAccountId, bundleName, storeId_, "SINGLE_KEY"); - std::vector secretKey; - bool outdated = false; - KvStoreMetaManager::GetInstance().GetSecretKeyFromMeta(sKey, secretKey, outdated); - MetaData metaData{0}; - metaData.kvStoreMetaData.deviceAccountId = deviceAccountId_; - metaData.kvStoreMetaData.userId = harmonyAccountId; + const std::string accountId = AccountDelegate::GetInstance()->GetCurrentAccountId(); + auto sKey = KvStoreMetaManager::GetMetaKey(userId_, accountId, bundleName, storeId_, "SINGLE_KEY"); + SecretKey key; + KeyManager::GetSecretKeyFromMeta(sKey, key); + MetaData metaData; + metaData.kvStoreMetaData.deviceAccountId = userId_; + metaData.kvStoreMetaData.userId = accountId; metaData.kvStoreMetaData.bundleName = bundleName; metaData.kvStoreMetaData.appId = appId_; metaData.kvStoreMetaData.storeId = storeId_; metaData.kvStoreMetaData.securityLevel = options_.securityLevel; - metaData.secretKeyMetaData.secretKey = secretKey; + metaData.secretKeyMetaData.sKey = key.data; std::shared_lock lock(storeNbDelegateMutex_); return std::make_unique()->SingleKvStoreRecover(metaData, kvStoreNbDelegate_); } - +std::string SingleKvStoreImpl::GetName() const +{ + return SingleKvStoreImpl::KeyName(); +}; Status SingleKvStoreImpl::SetCapabilityEnabled(bool enabled) { ZLOGD("begin."); @@ -1519,7 +1520,7 @@ Status SingleKvStoreImpl::SetCapabilityEnabled(bool enabled) return Status::ERROR; } - StrategyMeta params = {devId, deviceAccountId_, Constant::DEFAULT_GROUP_ID, bundleName_, storeId_}; + StrategyMeta params = {devId, userId_, Constant::DEFAULT_GROUP_ID, bundleName_, storeId_}; KvStoreMetaManager::GetInstance().GetStrategyMetaKey(params, key); if (key.empty()) { ZLOGE("get key empty."); @@ -1544,7 +1545,7 @@ Status SingleKvStoreImpl::SetCapabilityRange(const std::vector &loc return Status::ERROR; } - StrategyMeta params = {devId, deviceAccountId_, Constant::DEFAULT_GROUP_ID, bundleName_, storeId_}; + StrategyMeta params = { devId, userId_, Constant::DEFAULT_GROUP_ID, bundleName_, storeId_}; KvStoreMetaManager::GetInstance().GetStrategyMetaKey(params, key); if (key.empty()) { ZLOGE("get key empty."); @@ -1610,4 +1611,68 @@ std::string SingleKvStoreImpl::GetStoreId() { return storeId_; } +std::string SingleKvStoreImpl::KeyName() +{ + return "SINGLE_KEY"; +} + +void SingleKvStoreImpl::SetCompatibleIdentify(const std::string &changedDevice) +{ + auto capability = UpgradeManager::GetInstance().GetCapability(changedDevice); + if (capability.version >= CapMetaData::CURRENT_VERSION) { + return; + } + auto accountId = AccountDelegate::GetInstance()->GetCurrentAccountId(); + if (accountId.empty()) { + ZLOGE("failed to get current account id"); + return; + } + + auto peerUserId = 0; // peer user id reversed here + auto groupType = AuthDelegate::GetGroupType(std::stoi(userId_), peerUserId, changedDevice, appId_); + + std::string compatibleUserId; + if (groupType == PEER_TO_PEER_GROUP) { + compatibleUserId = "default"; + } else if (groupType == IDENTICAL_ACCOUNT_GROUP) { + compatibleUserId = accountId; + } else { + ZLOGW("not supported group type:%{public}d", groupType); + } + // older version use bound account syncIdentifier instead of user syncIdentifier + ZLOGI("compatible user:%{public}s", compatibleUserId.c_str()); + auto syncIdentifier = + DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(compatibleUserId, appId_, storeId_); + kvStoreNbDelegate_->SetEqualIdentifier(syncIdentifier, { changedDevice }); +} + +void SingleKvStoreImpl::SetCompatibleIdentify() +{ + KvStoreTuple tuple = {userId_, appId_, storeId_}; + SetCompatibleIdentifyByType(kvStoreNbDelegate_, tuple, IDENTICAL_ACCOUNT_GROUP); + SetCompatibleIdentifyByType(kvStoreNbDelegate_, tuple, PEER_TO_PEER_GROUP); +} + +void SingleKvStoreImpl::SetCompatibleIdentifyByType(DistributedDB::KvStoreNbDelegate *storeDelegate, const KvStoreTuple &tuple, AUTH_GROUP_TYPE groupType) { + if (storeDelegate == nullptr) { + ZLOGE("null store delegate"); + return; + } + auto accountId = AccountDelegate::GetInstance()->GetCurrentAccountId(); + if (accountId.empty()) { + ZLOGE("failed to get current account id"); + return; + } + + const std::string &compatibleUser = (groupType == DistributedData::PEER_TO_PEER_GROUP) ? "default": accountId; + auto devices = AuthDelegate::GetTrustedDevicesByType(groupType, std::stoi(tuple.userId), tuple.appId); + std::remove_if(devices.begin(), devices.end(), [](const std::string& device) { + auto capability = UpgradeManager::GetInstance().GetCapability(device); + return capability.version >= CapMetaData::CURRENT_VERSION; + }); + auto syncIdentifier = + DistributedDB::KvStoreDelegateManager::GetKvStoreIdentifier(compatibleUser, tuple.appId, tuple.storeId); + ZLOGI("set compatible identifier, store:%{public}s, user:%{public}s", tuple.storeId.c_str(), compatibleUser.c_str()); + storeDelegate->SetEqualIdentifier(syncIdentifier, devices); +} } // namespace OHOS::DistributedKv diff --git a/services/distributeddataservice/app/src/single_kvstore_impl.h b/services/distributeddataservice/app/src/single_kvstore_impl.h index e1c2d5179..94c5af5af 100755 --- a/services/distributeddataservice/app/src/single_kvstore_impl.h +++ b/services/distributeddataservice/app/src/single_kvstore_impl.h @@ -20,19 +20,22 @@ #include #include #include + +#include "auth/auth_delegate.h" #include "flowctrl_manager/kvstore_flowctrl_manager.h" #include "ikvstore_observer.h" #include "ikvstore_single.h" #include "ikvstore_sync_callback.h" +#include "inner_types.h" #include "kv_store_delegate_manager.h" #include "kv_store_nb_delegate.h" +#include "kvstore_base.h" #include "kvstore_observer_impl.h" #include "kvstore_resultset_impl.h" #include "kvstore_sync_manager.h" -#include "inner_types.h" - +#include "metadata/store_meta_data.h" namespace OHOS::DistributedKv { -class SingleKvStoreImpl : public SingleKvStoreStub { +class SingleKvStoreImpl : public SingleKvStoreStub, KvStoreBase { public: SingleKvStoreImpl(const Options &options, const std::string &userId, const std::string &bundleName, const std::string &storeId, const std::string &appId, const std::string &directory, @@ -59,6 +62,8 @@ public: Status RegisterSyncCallback(sptr callback) override; Status UnRegisterSyncCallback() override; Status ReKey(const std::vector &key); + std::string GetName() const override; + static std::string KeyName(); InnerStatus Close(DistributedDB::KvStoreDelegateManager *kvStoreDelegateManager); Status ForceClose(DistributedDB::KvStoreDelegateManager *kvStoreDelegateManager); Status MigrateKvStore(const std::string &harmonyAccountId, const std::string &kvStoreDataDir, @@ -77,6 +82,9 @@ public: Status GetSecurityLevel(SecurityLevel &securityLevel) override; bool Import(const std::string &bundleName) const; void OnDump(int fd) const; + void SetCompatibleIdentify(const std::string &changedDevice); + void SetCompatibleIdentify(); + static void SetCompatibleIdentifyByType(DistributedDB::KvStoreNbDelegate *storeDelegate, const KvStoreTuple &tuple, DistributedData::AUTH_GROUP_TYPE groupType); protected: virtual KvStoreObserverImpl *CreateObserver(const SubscribeType subscribeType, sptr observer); @@ -122,7 +130,7 @@ private: // kvstore cipherKey. const std::vector cipherKey_; // deviceAccount id get from service - std::string deviceAccountId_; + std::string userId_; // appId get from PMS. const std::string bundleName_; // kvstore name. @@ -157,6 +165,7 @@ private: KvStoreFlowCtrlManager flowCtrl_; static constexpr int BURST_CAPACITY = 1000; static constexpr int SUSTAINED_CAPACITY = 10000; + DistributedData::StoreMetaData meta_; }; } // namespace OHOS::DistributedKv #endif // SINGLE_KVSTORE_IMPL_H diff --git a/services/distributeddataservice/app/src/uninstaller/BUILD.gn b/services/distributeddataservice/app/src/uninstaller/BUILD.gn index 3532513ca..4e64c1765 100755 --- a/services/distributeddataservice/app/src/uninstaller/BUILD.gn +++ b/services/distributeddataservice/app/src/uninstaller/BUILD.gn @@ -25,6 +25,9 @@ ohos_static_library("distributeddata_uninstaller_static") { "//foundation/distributeddatamgr/distributeddatamgr/frameworks/innerkitsimpl/distributeddatafwk/include", "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/distributeddata/include", "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/app_distributeddata/include", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/service/directory/include", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/app/src/key", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/framework/include", "//third_party/json/single_include", "//utils/native/base/include", "//base/security/huks/interfaces/innerkits/huks_standard/main/include", @@ -35,6 +38,7 @@ ohos_static_library("distributeddata_uninstaller_static") { deps = [ "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter:distributeddata_adapter", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/libs/distributeddb:distributeddb", + "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/framework:distributeddatasvcfwk", "//utils/native/base:utils", ] diff --git a/services/distributeddataservice/app/src/uninstaller/uninstaller_impl.cpp b/services/distributeddataservice/app/src/uninstaller/uninstaller_impl.cpp index a12e49682..36492d919 100755 --- a/services/distributeddataservice/app/src/uninstaller/uninstaller_impl.cpp +++ b/services/distributeddataservice/app/src/uninstaller/uninstaller_impl.cpp @@ -24,11 +24,13 @@ #include "log_print.h" #include "ohos/aafwk/base/array_wrapper.h" #include "ohos/aafwk/base/string_wrapper.h" +#include "metadata/store_meta_data.h" namespace OHOS::DistributedKv { using namespace OHOS::EventFwk; using namespace OHOS::AAFwk; using namespace OHOS::AppExecFwk; +using namespace OHOS::DistributedData; const std::string UninstallEventSubscriber::USER_ID = "userId"; const std::string PACKAGE_SCHEME = "package"; const std::string SCHEME_SPLIT = ":"; @@ -87,15 +89,14 @@ Status UninstallerImpl::Init(KvStoreDataService *kvStoreDataService) matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED); CommonEventSubscribeInfo info(matchingSkills); auto callback = [kvStoreDataService](const std::string &bundleName, int userId) { - KvStoreMetaData kvStoreMetaData; + ZLOGI("uninstalled bundleName:%s, userId:%d", bundleName.c_str(), userId); + StoreMetaData kvStoreMetaData; if (!KvStoreMetaManager::GetInstance().GetKvStoreMetaDataByBundleName(bundleName, kvStoreMetaData)) { return; } if (!kvStoreMetaData.appId.empty() && !kvStoreMetaData.storeId.empty()) { ZLOGI("Has been uninstalled bundleName:%s", bundleName.c_str()); - AppId appId = {kvStoreMetaData.bundleName}; - StoreId storeId = {kvStoreMetaData.storeId}; - kvStoreDataService->DeleteKvStore(appId, storeId); + kvStoreDataService->DeleteKvStore(kvStoreMetaData); } }; subscriber_ = std::make_shared(info, callback); diff --git a/services/distributeddataservice/app/test/unittest/kvstore_backup_test.cpp b/services/distributeddataservice/app/test/unittest/kvstore_backup_test.cpp index 89b2aa042..f655a26c9 100755 --- a/services/distributeddataservice/app/test/unittest/kvstore_backup_test.cpp +++ b/services/distributeddataservice/app/test/unittest/kvstore_backup_test.cpp @@ -249,8 +249,8 @@ HWTEST_F(KvStoreBackupTest, KvStoreBackupTest004, TestSize.Level1) std::initializer_list fileList = {currentAccountId, "_", trueAppId, "_", storeId.storeId}; auto backupFileName = Constant::Concatenate(fileList); auto backupFileNameHashed = BackupHandler::GetHashedBackupName(backupFileName); - auto pathType = KvStoreAppManager::ConvertPathType(1000, appId.appId, metaData.kvStoreMetaData.securityLevel); - std::initializer_list backFileList = {BackupHandler::GetBackupPath("0", pathType), + auto pathType = DirWorker::ConvertPathType(1000, appId.appId, metaData.kvStoreMetaData.securityLevel); + std::initializer_list backFileList = {BackupHandler::GetBackupPath(metaData.kvStoreMetaData), "/", backupFileNameHashed}; auto backFilePath = Constant::Concatenate(backFileList); bool ret = BackupHandler::FileExists(backFilePath); diff --git a/services/distributeddataservice/app/test/unittest/session_manager/session_manager_test.cpp b/services/distributeddataservice/app/test/unittest/session_manager/session_manager_test.cpp new file mode 100644 index 000000000..0cd0a8f00 --- /dev/null +++ b/services/distributeddataservice/app/test/unittest/session_manager/session_manager_test.cpp @@ -0,0 +1,79 @@ +/* + * 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 + +#include "gmock/gmock.h" +#include "route_head_handler.h" +#include "upgrade_manager.h" + +using namespace testing::ext; +using namespace OHOS::DistributedData; + +class SessionManagerTest : public testing::Test { +public: + static void SetUpTestCase() + { + // init peer device + UserMetaData userMetaData; + userMetaData.deviceId = "PEER_DEVICE_ID"; + + UserStatus status; + status.isActive = true; + status.id = 101; + userMetaData.users = { status }; + + UserDelegate::GetInstance().UpdateUsers(userMetaData, false); + + CapMetaData capMetaData; + capMetaData.version = CapMetaData::CURRENT_VERSION; + UpgradeManager::GetInstance().UpdateCapability(userMetaData.deviceId, capMetaData); + } + static void TearDownTestCase() + { + } + void SetUp() + { + } + void TearDown() + { + } +}; + +/** +* @tc.name: PackAndUnPack01 +* @tc.desc: test get db dir +* @tc.type: FUNC +* @tc.require: +* @tc.author: illybyy +*/ +HWTEST_F(SessionManagerTest, PackAndUnPack01, TestSize.Level0) +{ + const DistributedDB::ExtendInfo info = { + .userId = "100", .appId = "com.sample.helloworld", .storeId = "test_store", .deviceId = "PEER_DEVICE_ID" + }; + auto sendHandler = RouteHeadHandlerImpl::GetInstance(info); + ASSERT_NE(sendHandler, nullptr); + auto size = sendHandler->GetHeadDataSize(); + ASSERT_GT(size, 0); + std::unique_ptr data = std::make_unique(size); + sendHandler->FillHeadData(data.get(), size, size); + + std::vector users; + auto recvHandler = RouteHeadHandlerImpl::GetInstance({}); + recvHandler->ParseHeadData(data.get(), size, size, users); + EXPECT_EQ(users.size(), 1); + EXPECT_EQ(users[0], "101"); +} \ No newline at end of file diff --git a/services/distributeddataservice/framework/BUILD.gn b/services/distributeddataservice/framework/BUILD.gn index 60f591ddf..748dc1b7c 100644 --- a/services/distributeddataservice/framework/BUILD.gn +++ b/services/distributeddataservice/framework/BUILD.gn @@ -23,6 +23,7 @@ config("module_public_config") { "//third_party/json/single_include", "//third_party/openssl/include/", "//foundation/distributeddatamgr/distributeddatamgr/frameworks/common", + "//foundation/distributeddatamgr/distributeddatamgr/interfaces/innerkits/distributeddata/include", "//foundation/distributeddatamgr/distributeddatamgr/services/distributeddataservice/adapter/include", ] } @@ -34,9 +35,12 @@ ohos_shared_library("distributeddatasvcfwk") { "checker/default/system_checker.cpp", "eventcenter/event.cpp", "eventcenter/event_center.cpp", + "metadata/capability_meta_data.cpp", "metadata/meta_data.cpp", "metadata/secret_key_meta_data.cpp", "metadata/store_meta_data.cpp", + "metadata/strategy_meta_data.cpp", + "metadata/user_meta_data.cpp", "serializable/serializable.cpp", "utils/block_integer.cpp", "utils/constant.cpp", diff --git a/services/distributeddataservice/framework/include/metadata/capability_meta_data.h b/services/distributeddataservice/framework/include/metadata/capability_meta_data.h new file mode 100644 index 000000000..8cd5fc8fc --- /dev/null +++ b/services/distributeddataservice/framework/include/metadata/capability_meta_data.h @@ -0,0 +1,36 @@ +/* + * 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. + */ + +#ifndef SDB_CAPABILITY_META_DATA_H +#define SDB_CAPABILITY_META_DATA_H +#include "serializable/serializable.h" + +namespace OHOS::DistributedData { +struct API_EXPORT CapMetaData final : public Serializable { + const static int CURRENT_VERSION = 1; + const static int INVALID_VERSION = -1; + int version = INVALID_VERSION; + + API_EXPORT bool Marshal(Serializable::json &node) const override; + API_EXPORT bool Unmarshal(const Serializable::json &node) override; +}; + +class API_EXPORT CapMetaRow { +public: + static const std::string KEY_PREFIX; + API_EXPORT static std::vector GetKeyFor(const std::string &key); +}; +} // namespace OHOS::DistributedData +#endif //SDB_CAPABILITY_META_DATA_H diff --git a/services/distributeddataservice/framework/include/metadata/meta_data.h b/services/distributeddataservice/framework/include/metadata/meta_data.h index 8059e0c58..80b40f320 100644 --- a/services/distributeddataservice/framework/include/metadata/meta_data.h +++ b/services/distributeddataservice/framework/include/metadata/meta_data.h @@ -18,14 +18,28 @@ #include "metadata/secret_key_meta_data.h" #include "metadata/store_meta_data.h" #include "serializable/serializable.h" +#include "types.h" + namespace OHOS { namespace DistributedData { -struct MetaData final : public Serializable { +using namespace DistributedKv; +struct API_EXPORT MetaData { +public: int32_t kvStoreType; StoreMetaData kvStoreMetaData; SecretKeyMetaData secretKeyMetaData; - bool Marshal(json &node) const override; - bool Unmarshal(const json &node) override; + + API_EXPORT MetaData() = default; + API_EXPORT MetaData(int32_t kvStoreType) : kvStoreType(kvStoreType), kvStoreMetaData(), secretKeyMetaData() {} + API_EXPORT static inline KvStoreType GetKvStoreType(const nlohmann::json &jObject) + { + int32_t storeType = KvStoreType::INVALID_TYPE; + Serializable::GetValue(jObject, std::string(KVSTORE_TYPE), storeType); + return static_cast(storeType); + } + +private: + static constexpr const char *KVSTORE_TYPE = "kvStoreType"; }; } } diff --git a/services/distributeddataservice/framework/include/metadata/secret_key_meta_data.h b/services/distributeddataservice/framework/include/metadata/secret_key_meta_data.h index 2b93aa5fa..1b8cded25 100644 --- a/services/distributeddataservice/framework/include/metadata/secret_key_meta_data.h +++ b/services/distributeddataservice/framework/include/metadata/secret_key_meta_data.h @@ -18,13 +18,14 @@ #include "serializable/serializable.h" namespace OHOS { namespace DistributedData { -struct SecretKeyMetaData final : public Serializable { +struct API_EXPORT SecretKeyMetaData final : public Serializable { std::vector time {}; std::vector sKey {}; int32_t kvStoreType = 0; - ~SecretKeyMetaData(); - bool Marshal(json &node) const override; - bool Unmarshal(const json &node) override; + API_EXPORT SecretKeyMetaData(); + API_EXPORT ~SecretKeyMetaData(); + API_EXPORT bool Marshal(json &node) const override; + API_EXPORT bool Unmarshal(const json &node) override; }; } } diff --git a/services/distributeddataservice/framework/include/metadata/store_meta_data.h b/services/distributeddataservice/framework/include/metadata/store_meta_data.h index 2000d6c93..4159c0b7a 100644 --- a/services/distributeddataservice/framework/include/metadata/store_meta_data.h +++ b/services/distributeddataservice/framework/include/metadata/store_meta_data.h @@ -14,10 +14,16 @@ */ #ifndef OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_METADATA_STORE_META_DATA_H #define OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_METADATA_STORE_META_DATA_H + +#include + #include "serializable/serializable.h" -namespace OHOS { -namespace DistributedData { -struct StoreMetaData final : public Serializable { + +namespace OHOS::DistributedData { +struct API_EXPORT StoreMetaData final : public Serializable { + // record kvstore meta version for compatible, should update when modify kvstore meta structure. + static constexpr uint32_t META_VERSION_SUPPORT_MULTIUSER = 0x03000002; + static constexpr uint32_t META_VERSION_SUPPORT_MULTIUSER_HOS = 0x03000001; bool isAutoSync = false; bool isBackup = false; bool isDirty = false; @@ -34,11 +40,26 @@ struct StoreMetaData final : public Serializable { std::string schema = ""; std::string storeId = ""; std::string userId = ""; - uint32_t version = 0; + uint32_t version = META_VERSION_SUPPORT_MULTIUSER; + + API_EXPORT ~StoreMetaData(); + API_EXPORT StoreMetaData(); + API_EXPORT StoreMetaData(const std::string &appId, const std::string &storeId, const std::string &userId); + API_EXPORT bool Marshal(json &node) const override; + API_EXPORT bool Unmarshal(const json &node) override; +}; +class KvStoreMetaRow { +public: + KVSTORE_API static const std::string KEY_PREFIX; + + KVSTORE_API static std::vector GetKeyFor(const std::string &key); +}; + +class SecretMetaRow { +public: + KVSTORE_API static const std::string KEY_PREFIX; - bool Marshal(json &node) const override; - bool Unmarshal(const json &node) override; + KVSTORE_API static std::vector GetKeyFor(const std::string &key); }; -} -} +} // namespace OHOS::DistributedData #endif // OHOS_DISTRIBUTED_DATA_SERVICES_FRAMEWORK_METADATA_STORE_META_DATA_H diff --git a/services/distributeddataservice/framework/include/metadata/strategy_meta_data.h b/services/distributeddataservice/framework/include/metadata/strategy_meta_data.h new file mode 100644 index 000000000..034459191 --- /dev/null +++ b/services/distributeddataservice/framework/include/metadata/strategy_meta_data.h @@ -0,0 +1,33 @@ +/* + * 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. + */ + +#ifndef SDB_STRATEGY_META_DATA_H +#define SDB_STRATEGY_META_DATA_H +#include "serializable/serializable.h" +namespace OHOS::DistributedData { +struct API_EXPORT StrategyMeta final : public Serializable { + std::string devId; + std::string devAccId; + std::string grpId; + std::string bundleName; + std::string storeId; + + API_EXPORT StrategyMeta(const std::string &devId, const std::string &devAccId, const std::string &grpId, const std::string &bundleName, const std::string &storeId); + API_EXPORT ~StrategyMeta() {}; + API_EXPORT bool Marshal(Serializable::json &node) const override; + API_EXPORT bool Unmarshal(const Serializable::json &node) override; +}; +} // namespace OHOS::DistributedData +#endif //SDB_STRATEGY_META_DATA_H diff --git a/services/distributeddataservice/framework/include/metadata/user_meta_data.h b/services/distributeddataservice/framework/include/metadata/user_meta_data.h new file mode 100644 index 000000000..555d3c8cf --- /dev/null +++ b/services/distributeddataservice/framework/include/metadata/user_meta_data.h @@ -0,0 +1,47 @@ +/* + * 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. + */ + +#ifndef SDB_USER_META_DATA_H +#define SDB_USER_META_DATA_H +#include +#include + +#include "serializable/serializable.h" +namespace OHOS::DistributedData { +struct API_EXPORT UserStatus final : public Serializable { + int id; + bool isActive; + API_EXPORT UserStatus() = default; + API_EXPORT UserStatus(int id, bool isActive); + API_EXPORT bool Marshal(Serializable::json &node) const override; + API_EXPORT bool Unmarshal(const Serializable::json &node) override; +}; + +struct API_EXPORT UserMetaData : public Serializable { + std::string deviceId; + std::vector users; + + API_EXPORT bool Marshal(Serializable::json &node) const override; + API_EXPORT bool Unmarshal(const Serializable::json &node) override; +}; + +class API_EXPORT UserMetaRow { +public: + static const std::string KEY_PREFIX; + API_EXPORT static std::vector GetKeyFor(const std::string &key); +}; +} // namespace OHOS::DistributedData + +#endif //SDB_USER_META_DATA_H diff --git a/services/distributeddataservice/framework/include/serializable/serializable.h b/services/distributeddataservice/framework/include/serializable/serializable.h index 1bd6790fc..e60ae37b2 100644 --- a/services/distributeddataservice/framework/include/serializable/serializable.h +++ b/services/distributeddataservice/framework/include/serializable/serializable.h @@ -16,6 +16,7 @@ #ifndef OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_SERIALIZABLE_H #define OHOS_DISTRIBUTED_DATA_FRAMEWORKS_COMMON_SERIALIZABLE_H #include +#include #include "visibility.h" #ifndef JSON_NOEXCEPTION #define JSON_NOEXCEPTION @@ -31,7 +32,20 @@ public: using json = nlohmann::json; using size_type= nlohmann::json::size_type; API_EXPORT json Marshall() const; + template + static std::string Marshall(T &values) + { + json root; + SetValue(root, values); + return root.dump(); + } + API_EXPORT bool Unmarshall(const std::string &jsonStr); + template + static bool Unmarshall(const std::string &body, T &values) + { + return GetValue(ToJson(body), "", values); + } API_EXPORT static json ToJson(const std::string &jsonStr); virtual bool Marshal(json &node) const = 0; virtual bool Unmarshal(const json &node) = 0; diff --git a/services/distributeddataservice/framework/include/utils/constant.h b/services/distributeddataservice/framework/include/utils/constant.h index 244b1aecc..b03620e34 100644 --- a/services/distributeddataservice/framework/include/utils/constant.h +++ b/services/distributeddataservice/framework/include/utils/constant.h @@ -27,20 +27,6 @@ namespace OHOS { namespace DistributedKv { -class KvStoreMetaRow { -public: - API_EXPORT static const std::string KEY_PREFIX; - - API_EXPORT static std::vector GetKeyFor(const std::string &key); -}; - -class SecretMetaRow { -public: - API_EXPORT static const std::string KEY_PREFIX; - - API_EXPORT static std::vector GetKeyFor(const std::string &key); -}; - class Constant { public: // concatenate strings and return a composition string. diff --git a/services/distributeddataservice/framework/metadata/capability_meta_data.cpp b/services/distributeddataservice/framework/metadata/capability_meta_data.cpp new file mode 100644 index 000000000..a895949e9 --- /dev/null +++ b/services/distributeddataservice/framework/metadata/capability_meta_data.cpp @@ -0,0 +1,41 @@ +/* + * 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 "metadata/capability_meta_data.h" +#include "utils/constant.h" +namespace OHOS::DistributedData { +using namespace OHOS::DistributedKv; + +bool CapMetaData::Marshal(Serializable::json &node) const +{ + bool ret = true; + ret &= SetValue(node[GET_NAME(version)], version); + return ret; +} + +bool CapMetaData::Unmarshal(const Serializable::json &node) +{ + bool ret = true; + ret &= GetValue(node, GET_NAME(version), version); + return ret; +} + +const std::string CapMetaRow::KEY_PREFIX = "CapabilityMeta_"; +std::vector CapMetaRow::GetKeyFor(const std::string &key) +{ + std::string str = Constant::Concatenate({ KEY_PREFIX, Constant::KEY_SEPARATOR, key }); + return { str.begin(), str.end() }; +} +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/framework/metadata/meta_data.cpp b/services/distributeddataservice/framework/metadata/meta_data.cpp index 090ca2d3c..505e21ab6 100644 --- a/services/distributeddataservice/framework/metadata/meta_data.cpp +++ b/services/distributeddataservice/framework/metadata/meta_data.cpp @@ -16,19 +16,5 @@ #include "metadata/meta_data.h" namespace OHOS { namespace DistributedData { -bool MetaData::Marshal(json &node) const -{ - SetValue(node[GET_NAME(kvStoreType)], kvStoreType); - SetValue(node[GET_NAME(kvStoreMetaData)], kvStoreMetaData); - SetValue(node[GET_NAME(secretKeyMetaData)], secretKeyMetaData); - return true; -} -bool MetaData::Unmarshal(const json &node) -{ - GetValue(node, GET_NAME(kvStoreType), kvStoreType); - GetValue(node, GET_NAME(kvStoreMetaData), kvStoreMetaData); - GetValue(node, GET_NAME(secretKeyMetaData), secretKeyMetaData); - return true; -} } } \ No newline at end of file diff --git a/services/distributeddataservice/framework/metadata/secret_key_meta_data.cpp b/services/distributeddataservice/framework/metadata/secret_key_meta_data.cpp index b844394a2..9ea3a7e32 100644 --- a/services/distributeddataservice/framework/metadata/secret_key_meta_data.cpp +++ b/services/distributeddataservice/framework/metadata/secret_key_meta_data.cpp @@ -15,6 +15,9 @@ #include "metadata/secret_key_meta_data.h" namespace OHOS { namespace DistributedData { +SecretKeyMetaData::SecretKeyMetaData() +{ +} SecretKeyMetaData::~SecretKeyMetaData() { sKey.assign(sKey.size(), 0); diff --git a/services/distributeddataservice/framework/metadata/store_meta_data.cpp b/services/distributeddataservice/framework/metadata/store_meta_data.cpp index a730149dd..61b294db8 100644 --- a/services/distributeddataservice/framework/metadata/store_meta_data.cpp +++ b/services/distributeddataservice/framework/metadata/store_meta_data.cpp @@ -14,8 +14,10 @@ */ #include "metadata/store_meta_data.h" +#include "utils/constant.h" namespace OHOS { namespace DistributedData { +using namespace OHOS::DistributedKv; bool StoreMetaData::Marshal(Serializable::json &node) const { SetValue(node[GET_NAME(appId)], appId); @@ -56,5 +58,29 @@ bool StoreMetaData::Unmarshal(const Serializable::json &node) GetValue(node, GET_NAME(isDirty), isDirty); return true; } +StoreMetaData::StoreMetaData() +{ +} +StoreMetaData::~StoreMetaData() +{ +} +StoreMetaData::StoreMetaData(const std::string &appId, const std::string &storeId, const std::string &userId) + : appId(appId), storeId(storeId), userId(userId) +{ +} + +// the Key Prefix for Meta data of KvStore. +const std::string KvStoreMetaRow::KEY_PREFIX = "KvStoreMetaData"; +std::vector KvStoreMetaRow::GetKeyFor(const std::string &key) +{ + std::string str = Constant::Concatenate({ KvStoreMetaRow::KEY_PREFIX, Constant::KEY_SEPARATOR, key }); + return { str.begin(), str.end() }; +} + +const std::string SecretMetaRow::KEY_PREFIX = "SecretKey"; +std::vector SecretMetaRow::GetKeyFor(const std::string &key) +{ + std::string str = Constant::Concatenate({ SecretMetaRow::KEY_PREFIX, Constant::KEY_SEPARATOR, key }); + return { str.begin(), str.end() }; } -} \ No newline at end of file +}} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/framework/metadata/strategy_meta_data.cpp b/services/distributeddataservice/framework/metadata/strategy_meta_data.cpp new file mode 100644 index 000000000..54364afbf --- /dev/null +++ b/services/distributeddataservice/framework/metadata/strategy_meta_data.cpp @@ -0,0 +1,39 @@ +/* + * 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 "metadata/strategy_meta_data.h" +namespace OHOS::DistributedData { +bool StrategyMeta::Marshal(Serializable::json &node) const +{ + bool ret = true; + ret &= SetValue(node[GET_NAME(devId)], devId); + ret &= SetValue(node[GET_NAME(devAccId)], devAccId); + ret &= SetValue(node[GET_NAME(grpId)], grpId); + ret &= SetValue(node[GET_NAME(bundleName)], bundleName); + ret &= SetValue(node[GET_NAME(storeId)], storeId); + return ret; +} + +bool StrategyMeta::Unmarshal(const Serializable::json &node) +{ + bool ret = true; + ret &= GetValue(node, GET_NAME(devId), devId); + ret &= GetValue(node, GET_NAME(devAccId), devAccId); + ret &= GetValue(node, GET_NAME(grpId), grpId); + ret &= GetValue(node, GET_NAME(bundleName), bundleName); + ret &= GetValue(node, GET_NAME(storeId), storeId); + return ret; +} +StrategyMeta::StrategyMeta(const std::string &devId, const std::string &devAccId, const std::string &grpId, const std::string &bundleName, const std::string &storeId) : devId(devId), devAccId(devAccId), grpId(grpId), bundleName(bundleName), storeId(storeId) {} +} // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/framework/metadata/user_meta_data.cpp b/services/distributeddataservice/framework/metadata/user_meta_data.cpp new file mode 100644 index 000000000..d6351d762 --- /dev/null +++ b/services/distributeddataservice/framework/metadata/user_meta_data.cpp @@ -0,0 +1,64 @@ +/* + * 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 "metadata/user_meta_data.h" + +#include "utils/constant.h" + +namespace OHOS::DistributedData { +using namespace OHOS::DistributedKv; +bool UserMetaData::Marshal(Serializable::json &node) const +{ + bool ret = true; + ret &= SetValue(node[GET_NAME(deviceId)], deviceId); + ret &= SetValue(node[GET_NAME(users)], users); + + return ret; +} + +bool UserMetaData::Unmarshal(const Serializable::json &node) +{ + bool ret = true; + ret &= GetValue(node, GET_NAME(deviceId), deviceId); + ret &= GetValue(node, GET_NAME(users), users); + + return ret; +} + +bool UserStatus::Marshal(Serializable::json &node) const +{ + bool ret = true; + ret &= SetValue(node[GET_NAME(id)], id); + ret &= SetValue(node[GET_NAME(isActive)], isActive); + return ret; +} + +bool UserStatus::Unmarshal(const Serializable::json &node) +{ + bool ret = true; + ret &= GetValue(node, GET_NAME(id), id); + ret &= GetValue(node, GET_NAME(isActive), isActive); + return ret; +} +UserStatus::UserStatus(int id, bool isActive) : id(id), isActive(isActive) +{ +} + +const std::string UserMetaRow::KEY_PREFIX = "UserMeta_"; +std::vector UserMetaRow::GetKeyFor(const std::string &key) +{ + std::string str = Constant::Concatenate({ KEY_PREFIX, Constant::KEY_SEPARATOR, key }); + return { str.begin(), str.end() }; +} +} // namespace OHOS::DistributedData diff --git a/services/distributeddataservice/framework/test/serializable_test.cpp b/services/distributeddataservice/framework/test/serializable_test.cpp index c425811c8..5ad85c786 100644 --- a/services/distributeddataservice/framework/test/serializable_test.cpp +++ b/services/distributeddataservice/framework/test/serializable_test.cpp @@ -120,12 +120,46 @@ HWTEST_F(SerializableTest, GetNormalVal, TestSize.Level2) normal.value = -56; normal.isClear = true; normal.cols = {"adfasdfas"}; - auto jstr = to_string(normal.Marshall()); + // auto jstr = to_string(normal.Marshall()); + auto jstr = Normal::Marshall(normal); Normal normal1; - normal1.Unmarshall(jstr); + Normal::Unmarshall(jstr, normal1); + //normal1.Unmarshall(jstr); ASSERT_TRUE(normal == normal1) << normal1.name; } +/** +* @tc.name: SerializableSuiteGetVal +* @tc.desc: Get Value. +* @tc.type: FUNC +* @tc.require: +* @tc.author: Sven Wang +*/ +HWTEST_F(SerializableTest, GetNormalVals, TestSize.Level2) +{ + ZLOGI("SerializableSuite GetVal begin."); + std::vector normals(5); + normals[0].name = "normals2"; + normals[0].count = -1; + normals[0].status = 12; + normals[0].value = -56; + normals[0].isClear = true; + normals[0].cols = {"adfasdfas"}; + // auto jstr = to_string(normals2.Marshall()); + auto jstr = Normal::Marshall(normals); + std::vector *pNormals = nullptr; + + // @Deprecated + Normal::Unmarshall(jstr, pNormals); + ASSERT_NE(pNormals, nullptr); + ASSERT_TRUE(normals.size() == pNormals->size()); + delete pNormals; + + std::vector normals2; + Normal::Unmarshall(jstr, normals2); + ASSERT_TRUE(normals.size() == normals2.size()); +} + /** * @tc.name: Delete Serializable * @tc.desc: can delete child class, but not delete parent class point. @@ -150,6 +184,7 @@ HWTEST_F(SerializableTest, DeleteSerializable, TestSize.Level2) HWTEST_F(SerializableTest, GetMutilVal, TestSize.Level2) { ZLOGI("SerializableSuite GetVal begin."); + NormalEx normalEx; normalEx.normals = {Normal()}; normalEx.name = "normalEx"; diff --git a/services/distributeddataservice/framework/utils/constant.cpp b/services/distributeddataservice/framework/utils/constant.cpp index 910f564af..d473be2e2 100644 --- a/services/distributeddataservice/framework/utils/constant.cpp +++ b/services/distributeddataservice/framework/utils/constant.cpp @@ -20,11 +20,6 @@ namespace OHOS { namespace DistributedKv { -// the Key Prefix for Meta data of KvStore. -const std::string KvStoreMetaRow::KEY_PREFIX = "KvStoreMetaData"; - -const std::string SecretMetaRow::KEY_PREFIX = "SecretKey"; - /* version for distributed kv data service. */ const std::string Constant::VERSION = "1"; @@ -83,18 +78,6 @@ const std::string Constant::SERVICE_META_DB_NAME = "service_meta"; const std::string Constant::KEY_SEPARATOR = "###"; -std::vector KvStoreMetaRow::GetKeyFor(const std::string &key) -{ - std::string str = Constant::Concatenate({KvStoreMetaRow::KEY_PREFIX, Constant::KEY_SEPARATOR, key }); - return std::vector(str.begin(), str.end()); -} - -std::vector SecretMetaRow::GetKeyFor(const std::string &key) -{ - std::string str = Constant::Concatenate({SecretMetaRow::KEY_PREFIX, Constant::KEY_SEPARATOR, key }); - return std::vector(str.begin(), str.end()); -} - std::string Constant::Concatenate(std::initializer_list stringList) { std::string result; diff --git a/services/distributeddataservice/service/bootstrap/src/bootstrap.cpp b/services/distributeddataservice/service/bootstrap/src/bootstrap.cpp index 2d467d682..6b3e69b34 100644 --- a/services/distributeddataservice/service/bootstrap/src/bootstrap.cpp +++ b/services/distributeddataservice/service/bootstrap/src/bootstrap.cpp @@ -81,7 +81,7 @@ void Bootstrap::LoadDirectory() for (const auto &strategy : global->directory->strategy) { DirectoryManager::GetInstance().AddParams(strategy); } - DirectoryManager::GetInstance().SetCurrentVersion(global->directory->currentStrategyVersion); + DirectoryManager::GetInstance().SetCurrentVersion(global->directory->currentStrategyHolder); } } // namespace DistributedData } // namespace OHOS \ No newline at end of file diff --git a/services/distributeddataservice/service/config/include/model/directory_config.h b/services/distributeddataservice/service/config/include/model/directory_config.h index 7476cd96f..70bd00145 100644 --- a/services/distributeddataservice/service/config/include/model/directory_config.h +++ b/services/distributeddataservice/service/config/include/model/directory_config.h @@ -21,11 +21,11 @@ namespace OHOS { namespace DistributedData { class DirectoryConfig final : public Serializable { public: - struct DirectoryStrategy final : public Serializable, public DirectoryManager::Strategy { + struct DirectoryStrategy final : public Serializable, public Strategy { bool Marshal(json &node) const override; bool Unmarshal(const json &node) override; }; - std::string currentStrategyVersion; + std::string currentStrategyHolder; std::vector strategy; bool Marshal(json &node) const override; bool Unmarshal(const json &node) override; diff --git a/services/distributeddataservice/service/config/src/model/directory_config.cpp b/services/distributeddataservice/service/config/src/model/directory_config.cpp index 5cde0ec35..0f642431a 100644 --- a/services/distributeddataservice/service/config/src/model/directory_config.cpp +++ b/services/distributeddataservice/service/config/src/model/directory_config.cpp @@ -18,25 +18,27 @@ namespace OHOS { namespace DistributedData { bool DirectoryConfig::DirectoryStrategy::Marshal(json &node) const { - SetValue(node[GET_NAME(version)], version); SetValue(node[GET_NAME(holder)], holder); SetValue(node[GET_NAME(path)], path); + SetValue(node[GET_NAME(backupPath)], backupPath); + SetValue(node[GET_NAME(keyPath)], keyPath); SetValue(node[GET_NAME(metaPath)], metaPath); return true; } bool DirectoryConfig::DirectoryStrategy::Unmarshal(const json &node) { - GetValue(node, GET_NAME(version), version); GetValue(node, GET_NAME(holder), holder); GetValue(node, GET_NAME(path), path); + GetValue(node, GET_NAME(backupPath), backupPath); + GetValue(node, GET_NAME(keyPath), keyPath); GetValue(node, GET_NAME(metaPath), metaPath); return true; } bool DirectoryConfig::Marshal(json &node) const { - SetValue(node[GET_NAME(currentStrategyVersion)], currentStrategyVersion); + SetValue(node[GET_NAME(currentStrategyHolder)], currentStrategyHolder); SetValue(node[GET_NAME(strategy)], strategy); return true; } @@ -44,7 +46,7 @@ bool DirectoryConfig::Marshal(json &node) const bool DirectoryConfig::Unmarshal(const json &node) { bool ret = true; - ret &= GetValue(node, GET_NAME(currentStrategyVersion), currentStrategyVersion); + ret &= GetValue(node, GET_NAME(currentStrategyHolder), currentStrategyHolder); ret &= GetValue(node, GET_NAME(strategy), strategy); return ret; } diff --git a/services/distributeddataservice/service/directory/include/directory_manager.h b/services/distributeddataservice/service/directory/include/directory_manager.h index 433089578..88e6b667c 100644 --- a/services/distributeddataservice/service/directory/include/directory_manager.h +++ b/services/distributeddataservice/service/directory/include/directory_manager.h @@ -16,64 +16,62 @@ #ifndef SDB_DIRECTORY_MANAGER_H #define SDB_DIRECTORY_MANAGER_H +#include #include #include -#include "visibility.h" -#include "kvstore_context.h" +#include +#include + #include "metadata/store_meta_data.h" +#include "visibility.h" namespace OHOS::DistributedData { -enum PathType { - PATH_DE, - PATH_CE, -}; -class DirWorker { -public: - DirWorker() = default; - virtual std::string GetDir(ClientContext clientContext, PathType type) = 0; - virtual bool CreateDir(ClientContext clientContext, PathType type) = 0; - virtual std::string GetBackupDir(ClientContext clientContext, PathType type) = 0; - virtual std::string GetSecretKeyDir(ClientContext clientContext, PathType type) = 0; - virtual std::string GetMetaDir() = 0; -}; +enum PathType { PATH_DE, PATH_CE, PATH_TYPE_MAX }; -class ServerDirWorker : public DirWorker { -public: - static ServerDirWorker &GetInstance(); +struct Strategy { + std::string holder; + std::string path; + std::string backupPath; + std::string keyPath; + std::string metaPath; +}; - std::string GetDir(ClientContext clientContext, PathType type) override; - bool CreateDir(ClientContext clientContext, PathType type) override; - std::string GetBackupDir(ClientContext clientContext, PathType type) override; - std::string GetSecretKeyDir(ClientContext clientContext, PathType type) override; - std::string GetMetaDir() override; +static constexpr char HOLDER_DDMS_OLD[] = "ddms_old"; +static constexpr char HOLDER_DDMS_NEW[] = "ddms_new"; +static constexpr char HOLDER_CALLER[] = "caller"; +class DirWorker { public: - static std::map rootPathMap_; -}; + DirWorker() = default; + DirWorker(const Strategy &strategy); + std::string GetDir(const StoreMetaData &metaData); + bool CreateDir(const StoreMetaData &metaData); + std::string GetBackupDir(const StoreMetaData &metaData); + std::string GetSecretKeyDir(const StoreMetaData &metaData); + std::string GetMetaDir(); + API_EXPORT static PathType ConvertPathType(int32_t uid, const std::string &bundleName, int securityLevel); -class ClientDirWorker : public DirWorker { -public: - static ClientDirWorker &GetInstance(); +protected: + std::string GeneratePath( + const std::map> &converterMap, + const StoreMetaData &metaData, std::string pathTemplate); + static std::string ConvertPathTypeStr(const StoreMetaData &metaData); - std::string GetDir(ClientContext clientContext, PathType type) override; - bool CreateDir(ClientContext clientContext, PathType type) override; - std::string GetBackupDir(ClientContext clientContext, PathType type) override; - std::string GetSecretKeyDir(ClientContext clientContext, PathType type) override; - std::string GetMetaDir() override; + static constexpr char TEMPLATE_VAR_BEGIN = '{'; + static constexpr char TEMPLATE_VAR_END = '}'; + // variable -- converter + static const std::map> converterMap_; + // holder type -- path type + static const std::map> levelMap_; + Strategy strategy_; }; class DirectoryManager { public: - struct Strategy { - std::string version; - std::string holder; - std::string path; - std::string metaPath; - }; API_EXPORT static DirectoryManager &GetInstance(); - API_EXPORT std::string CreatePath(const ClientContext &context, PathType type); API_EXPORT std::string GetStorePath(const StoreMetaData &metaData); API_EXPORT std::string GetStoreBackupPath(const StoreMetaData &metaData); - API_EXPORT std::string GetMetaDataStorePath(); + API_EXPORT std::string GetMetaStorePath(); + API_EXPORT std::string GetStoreKeyPath(const StoreMetaData &metaData); API_EXPORT void AddParams(const Strategy &strategy); API_EXPORT void SetCurrentVersion(const std::string &version); @@ -86,9 +84,13 @@ public: } return tmpPath; } + private: + DirWorker GetWorker(const uint32_t &metaVersion); + + // holder type -- strategy std::map patterns_; - std::string version_; + std::string defaultHolder_; }; -} // namespace OHOS::DistributedKv -#endif // SDB_DIRECTORY_MANAGER_H +} // namespace OHOS::DistributedData +#endif //SDB_DIRECTORY_MANAGER_H diff --git a/services/distributeddataservice/service/directory/src/directory_manager.cpp b/services/distributeddataservice/service/directory/src/directory_manager.cpp index f4e8f331c..ad2a03e9d 100644 --- a/services/distributeddataservice/service/directory/src/directory_manager.cpp +++ b/services/distributeddataservice/service/directory/src/directory_manager.cpp @@ -13,88 +13,151 @@ * limitations under the License. */ #define LOG_TAG "DirectoryManager" + #include "directory_manager.h" #include -#include "utils/constant.h" +#include "autils/directory_utils.h" +#include "checker/checker_manager.h" #include "directory_ex.h" -#include "kvstore_context.h" #include "log/log_print.h" +#include "types.h" +#include "utils/constant.h" namespace OHOS::DistributedData { using namespace DistributedKv; -std::map ServerDirWorker::rootPathMap_ = { - { PATH_DE, "/data/misc_de/0/mdds" }, - { PATH_CE, "/data/misc_ce/0/mdds" }, +const std::map> DirWorker::converterMap_ = { + { "{type}", + [](const StoreMetaData &metaData) { + auto *checker = CheckerManager::GetInstance().GetChecker("SystemChecker"); + if (checker == nullptr || !checker->IsValid(metaData.uid, metaData.bundleName)) { + return "app"; + } + return "service"; + } }, + { "{userId}", [](const StoreMetaData &metaData) { return metaData.userId; } }, + { "{bundleName}", [](const StoreMetaData &metaData) { return metaData.bundleName; } }, + { "{security}", ConvertPathTypeStr } }; -std::string ServerDirWorker::GetDir(ClientContext clientContext, PathType type) -{ - if (rootPathMap_.find(type) == rootPathMap_.end()) { - return ""; + +const std::map> DirWorker::levelMap_ = { + { "ddms_old", { "misc_de", "misc_ce" } }, + { "ddms_new", { "el1", "el2" } }, + { "caller", { "el1", "el2" } }, +}; + +std::string DirWorker::GeneratePath( + const std::map> &converterMap, + const StoreMetaData &metaData, std::string pathTemplate) +{ + size_t front = std::string::npos; + std::string target; + for (size_t i = 0; i < pathTemplate.length(); ++i) { + if (pathTemplate[i] == TEMPLATE_VAR_BEGIN) { + front = i; + continue; + } + if (pathTemplate[i] == TEMPLATE_VAR_END) { + // calc var + if (front != std::string::npos) { + auto it = converterMap.find((pathTemplate.substr(front, i - front + 1))); + if (it != converterMap.end()) { + target.append(it->second(metaData)); + } + } + // reset var position + front = std::string::npos; + continue; + } + if (front == std::string::npos) { + target.push_back(pathTemplate[i]); + } } - return DirectoryManager::JoinPath({ rootPathMap_.at(type), clientContext.userId, - Constant::GetDefaultHarmonyAccountName(), clientContext.bundleName }); + return target; } -bool ServerDirWorker::CreateDir(ClientContext clientContext, PathType type) + +std::string DirWorker::ConvertPathTypeStr(const StoreMetaData &metaData) { - std::string directory = GetDir(clientContext, type); - bool ret = ForceCreateDirectory(directory); - if (!ret) { - ZLOGE("create directory[%s] failed, errstr=[%d].", directory.c_str(), errno); - return false; + std::string holder; + if (metaData.version <= StoreMetaData::META_VERSION_SUPPORT_MULTIUSER_HOS) { + holder = HOLDER_DDMS_OLD; + } else { + holder = HOLDER_CALLER; } - return true; -} -ServerDirWorker &ServerDirWorker::GetInstance() -{ - static ServerDirWorker instance; - return instance; -} -std::string ServerDirWorker::GetBackupDir(ClientContext clientContext, PathType type) -{ - if (rootPathMap_.find(type) == rootPathMap_.end()) { - return ""; + auto it = DirWorker::levelMap_.find(holder); + if (it == DirWorker::levelMap_.end()) { + ZLOGE("invalid meta version: %{public}u", metaData.version); + return {}; } - return DirectoryManager::JoinPath({ rootPathMap_.at(type), clientContext.userId, - Constant::GetDefaultHarmonyAccountName(), clientContext.bundleName, "backup" }); -} -std::string ServerDirWorker::GetMetaDir() -{ - return DirectoryManager::JoinPath({ rootPathMap_.at(PATH_DE), "Meta" }); -} -std::string ServerDirWorker::GetSecretKeyDir(ClientContext clientContext, PathType type) -{ - return GetDir(clientContext, type); + PathType pathType = ConvertPathType(metaData.uid, metaData.bundleName, metaData.securityLevel); + return it->second[pathType]; } -std::string ClientDirWorker::GetDir(ClientContext clientContext, PathType type) -{ - return clientContext.dataDir; + +PathType DirWorker::ConvertPathType(int32_t uid, const std::string &bundleName, int securityLevel) +{ + switch (securityLevel) { + case S0: // fallthrough + case S1: + return PATH_DE; + case S2: // fallthrough + case S3_EX: // fallthrough + case S3: // fallthrough + case S4: // fallthrough + return PATH_CE; + default: + break; + } + auto *checker = CheckerManager::GetInstance().GetChecker("SystemChecker"); + if (checker == nullptr || !checker->IsValid(uid, bundleName)) { + return PATH_CE; + } + return PATH_DE; } -bool ClientDirWorker::CreateDir(ClientContext clientContext, PathType type) + +std::string DirWorker::GetDir(const StoreMetaData &metaData) { - return true; + return GeneratePath(converterMap_, metaData, strategy_.path); } -ClientDirWorker &ClientDirWorker::GetInstance() + +std::string DirWorker::GetBackupDir(const StoreMetaData &metaData) { - static ClientDirWorker instance; - return instance; + return GeneratePath(converterMap_, metaData, strategy_.backupPath); } -std::string ClientDirWorker::GetBackupDir(ClientContext clientContext, PathType type) + +std::string DirWorker::GetSecretKeyDir(const StoreMetaData &metaData) { - return DirectoryManager::JoinPath({ clientContext.dataDir, "backup" }); + return GeneratePath(converterMap_, metaData, strategy_.keyPath); } -std::string ClientDirWorker::GetMetaDir() + +std::string DirWorker::GetMetaDir() { - return std::string("/data/service/el1/public/distributeddata/DistributedKvDataService/Meta/"); + return strategy_.metaPath; } -std::string ClientDirWorker::GetSecretKeyDir(ClientContext clientContext, PathType type) + +bool DirWorker::CreateDir(const StoreMetaData &metaData) { - return GetDir(clientContext, type); + std::string directory = GetDir(metaData); + bool ret = ForceCreateDirectory(directory); + if (!ret) { + ZLOGE("create directory[%s] failed, errstr=[%d].", directory.c_str(), errno); + return false; + } + // change mode for directories to 0755, and for files to 0600. + ret = DirectoryUtils::ChangeModeDirOnly(directory, Constant::DEFAULT_MODE_DIR); + if (!ret) { + ZLOGE("change directory[%s] mode failed, errstr=[%d].", directory.c_str(), errno); + return false; + } + ret = DirectoryUtils::ChangeModeFileOnly(directory, Constant::DEFAULT_MODE_FILE); + if (!ret) { + ZLOGE("change file[%s] mode failed, errstr=[%d].", directory.c_str(), errno); + return false; + } + return true; } -std::string DirectoryManager::CreatePath(const ClientContext &context, PathType type) +DirWorker::DirWorker(const Strategy &strategy) : strategy_(strategy) { - return ""; } DirectoryManager &DirectoryManager::GetInstance() @@ -103,26 +166,47 @@ DirectoryManager &DirectoryManager::GetInstance() return instance; } -std::string DirectoryManager::GetStorePath(const StoreMetaData &metaData) -{ - return {}; +std::string DirectoryManager::GetStorePath(const StoreMetaData &metaData) { + return GetWorker(metaData.version).GetDir(metaData); } -std::string DirectoryManager::GetStoreBackupPath(const StoreMetaData &metaData) -{ - return GetStorePath(metaData) + "/backup/"; +std::string DirectoryManager::GetStoreBackupPath(const StoreMetaData &metaData) { + return GetWorker(metaData.version).GetBackupDir(metaData); } -std::string DirectoryManager::GetMetaDataStorePath() +std::string DirectoryManager::GetMetaStorePath() { - return "/data/service/el0/0/database/ddms/metadata/"; + return GetWorker(StoreMetaData::META_VERSION_SUPPORT_MULTIUSER).GetMetaDir(); +} + +std::string DirectoryManager::GetStoreKeyPath(const StoreMetaData &metaData) { + return GetWorker(metaData.version).GetSecretKeyDir(metaData); } + void DirectoryManager::AddParams(const Strategy &strategy) { - patterns_[strategy.version] = strategy; + patterns_[strategy.holder] = strategy; } + void DirectoryManager::SetCurrentVersion(const std::string &version) { - version_ = version; + defaultHolder_ = version; +} + +DirWorker DirectoryManager::GetWorker(const uint32_t &metaVersion) +{ + std::string holder; + if (metaVersion <= StoreMetaData::META_VERSION_SUPPORT_MULTIUSER_HOS) { + holder = HOLDER_DDMS_OLD; + } else { + holder = defaultHolder_; + } + ZLOGE("byy: patter size:%{public}zu, holder:%{public}s", patterns_.size(), holder.c_str()); + auto it = patterns_.find(holder); + if (it == patterns_.end()) { + ZLOGE("failed to find valid dir worker pattern, metaVersion:%{public}u", metaVersion); + return DirWorker(); + } + return DirWorker(it->second); } } // namespace OHOS::DistributedData \ No newline at end of file diff --git a/services/distributeddataservice/service/rdb/rdb_service_impl.cpp b/services/distributeddataservice/service/rdb/rdb_service_impl.cpp index eb74d2077..79e63831e 100644 --- a/services/distributeddataservice/service/rdb/rdb_service_impl.cpp +++ b/services/distributeddataservice/service/rdb/rdb_service_impl.cpp @@ -25,7 +25,7 @@ using OHOS::DistributedKv::AccountDelegate; using OHOS::DistributedKv::KvStoreMetaManager; -using OHOS::DistributedKv::MetaData; +using OHOS::DistributedData::MetaData; using OHOS::AppDistributedKv::CommunicationProvider; using OHOS::DistributedData::CheckerManager; using DistributedDB::RelationalStoreManager; diff --git a/services/distributeddataservice/service/rdb/rdb_syncer.cpp b/services/distributeddataservice/service/rdb/rdb_syncer.cpp index 1c48d44cb..546dbb5a4 100644 --- a/services/distributeddataservice/service/rdb/rdb_syncer.cpp +++ b/services/distributeddataservice/service/rdb/rdb_syncer.cpp @@ -106,7 +106,7 @@ int32_t RdbSyncer::Init(pid_t pid, pid_t uid) int32_t RdbSyncer::CreateMetaData() { - DistributedKv::KvStoreMetaData meta; + DistributedData::StoreMetaData meta; meta.kvStoreType =static_cast(RDB_DEVICE_COLLABORATION); meta.appId = GetAppId(); meta.appType = "harmony"; @@ -118,12 +118,12 @@ int32_t RdbSyncer::CreateMetaData() meta.deviceAccountId = AccountDelegate::GetInstance()->GetDeviceAccountIdByUID(uid_); meta.dataDir = GetPath(); - std::string metaString = meta.Marshal(); + std::string metaString = DistributedData::Serializable::Marshall(meta); std::vector metaValue(metaString.begin(), metaString.end()); auto metaKey = KvStoreMetaManager::GetMetaKey(meta.deviceAccountId, "default", meta.bundleName, meta.storeId); - DistributedKv::KvStoreMetaData oldMeta; + DistributedData::StoreMetaData oldMeta; if (KvStoreMetaManager::GetInstance().GetKvStoreMeta(metaKey, oldMeta) == DistributedKv::Status::SUCCESS) { - if (metaString == oldMeta.Marshal()) { + if (metaString == DistributedData::Serializable::Marshall(oldMeta)) { ZLOGI("ignore same meta"); return RDB_OK; } diff --git a/services/distributeddataservice/service/test/directory_manager_test.cpp b/services/distributeddataservice/service/test/directory_manager_test.cpp index 1d2ad8d9d..21876bbef 100644 --- a/services/distributeddataservice/service/test/directory_manager_test.cpp +++ b/services/distributeddataservice/service/test/directory_manager_test.cpp @@ -16,10 +16,11 @@ #include "directory_manager.h" #include -#include + #include #include #include + #include "types.h" using namespace testing::ext; @@ -29,10 +30,18 @@ using namespace OHOS; class DirectoryManagerTest : public testing::Test { public: - static void SetUpTestCase() {} - static void TearDownTestCase() {} - void SetUp() { } - void TearDown() { } + static void SetUpTestCase() + { + } + static void TearDownTestCase() + { + } + void SetUp() + { + } + void TearDown() + { + } }; /** @@ -40,21 +49,26 @@ public: * @tc.desc: test get db dir * @tc.type: FUNC * @tc.require: -* @tc.author: baoyayong +* @tc.author: illybyy */ HWTEST_F(DirectoryManagerTest, GetStoragePath01, TestSize.Level0) { StoreMetaData metaData; - metaData.userId = "10"; + metaData.userId = "100"; metaData.bundleName = "com.sample.helloworld"; - metaData.dataDir = "/data/app/el1/10/com.sample.helloworld"; metaData.securityLevel = SecurityLevel::S2; + metaData.version = StoreMetaData::META_VERSION_SUPPORT_MULTIUSER; auto path = DirectoryManager::GetInstance().GetStorePath(metaData); - EXPECT_EQ(path, metaData.dataDir); + EXPECT_EQ(path, "/data/app/el2/" + metaData.userId + "/database/" + metaData.bundleName + "/"); + + metaData.securityLevel = SecurityLevel::S0; + path = DirectoryManager::GetInstance().GetStorePath(metaData); + EXPECT_EQ(path, "/data/app/el1/" + metaData.userId + "/database/" + metaData.bundleName + "/"); + metaData.version = StoreMetaData::META_VERSION_SUPPORT_MULTIUSER_HOS; metaData.securityLevel = SecurityLevel::S0; path = DirectoryManager::GetInstance().GetStorePath(metaData); - EXPECT_EQ(path, "/data/misc_de/0/mdds/10/default/com.sample.helloworld/"); + EXPECT_EQ(path, "/data/misc_de/0/mdds/" + metaData.userId + "/" + metaData.bundleName + "/"); } /** @@ -62,35 +76,37 @@ HWTEST_F(DirectoryManagerTest, GetStoragePath01, TestSize.Level0) * @tc.desc: test get db backup dir * @tc.type: FUNC * @tc.require: -* @tc.author: baoyayong +* @tc.author: illybyy */ HWTEST_F(DirectoryManagerTest, GetStorageBackupPath01, TestSize.Level0) { StoreMetaData metaData; - metaData.userId = "10"; + metaData.userId = "100"; metaData.bundleName = "com.sample.helloworld"; - metaData.dataDir = "/data/app/el1/10/com.sample.helloworld"; metaData.securityLevel = SecurityLevel::S2; + metaData.version = StoreMetaData::META_VERSION_SUPPORT_MULTIUSER; auto path = DirectoryManager::GetInstance().GetStoreBackupPath(metaData); - EXPECT_EQ(path, metaData.dataDir + "/backup/"); + EXPECT_EQ(path, "/data/app/el2/" + metaData.userId + "/database/" + metaData.bundleName + "/backup/"); metaData.securityLevel = SecurityLevel::S0; path = DirectoryManager::GetInstance().GetStoreBackupPath(metaData); - EXPECT_EQ(path, "/data/misc_de/0/mdds/10/default/com.sample.helloworld/backup/"); + EXPECT_EQ(path, "/data/app/el1/" + metaData.userId + "/database/" + metaData.bundleName + "/backup/"); + + metaData.version = StoreMetaData::META_VERSION_SUPPORT_MULTIUSER_HOS; + metaData.securityLevel = SecurityLevel::S0; + path = DirectoryManager::GetInstance().GetStoreBackupPath(metaData); + EXPECT_EQ(path, "/data/misc_de/0/mdds/" + metaData.userId + "/backup/"); } /** -* @tc.name: GetStorageMetaPath01 +* @tc.name: GetMetaStorePath01 * @tc.desc: test get db meta dir * @tc.type: FUNC * @tc.require: -* @tc.author: baoyayong +* @tc.author: illybyy */ -HWTEST_F(DirectoryManagerTest, GetStorageMetaPath01, TestSize.Level0) +HWTEST_F(DirectoryManagerTest, GetMetaStorePath01, TestSize.Level0) { - auto path = DirectoryManager::GetInstance().GetMetaDataStorePath(); - EXPECT_EQ(path, "/data/service/el1/public/distributeddata/DistributedKvDataService/Meta/"); - - path = DirectoryManager::GetInstance().GetMetaDataStorePath(); - EXPECT_EQ(path, "/data/misc_de/0/mdds/Meta/"); + auto path = DirectoryManager::GetInstance().GetMetaStorePath(); + EXPECT_EQ(path, "/data/service/el1/public/database/distributeddata/meta/"); } -- Gitee