diff --git a/services/distributeddataservice/service/data_share/common/proxy_data_manager.cpp b/services/distributeddataservice/service/data_share/common/proxy_data_manager.cpp index 59bfbf8c9626950d399c20fadc0f9020a6f7db1a..59e6f7d3713309f87f6b2013c5695df871cde5f3 100644 --- a/services/distributeddataservice/service/data_share/common/proxy_data_manager.cpp +++ b/services/distributeddataservice/service/data_share/common/proxy_data_manager.cpp @@ -13,6 +13,7 @@ * limitations under the License. */ +#include #define LOG_TAG "ProxyDataManager" #include "datashare_observer.h" @@ -51,14 +52,32 @@ std::string PublishedProxyData::GetValue() const return DistributedData::Serializable::Marshall(value); } +ProxyDataList::ProxyDataList(const ProxyDataListNode &node) + : KvData(Id(std::to_string(node.tokenId), node.userId)), value(node) +{ +} + +bool ProxyDataList::HasVersion() const +{ + return true; +} + +int ProxyDataList::GetVersion() const +{ + return value.GetVersion(); +} + +std::string ProxyDataList::GetValue() const +{ + return DistributedData::Serializable::Marshall(value); +} + ProxyDataNode::ProxyDataNode() : VersionData(-1) {} bool ProxyDataNode::Marshal(DistributedData::Serializable::json &node) const { bool ret = SetValue(node[GET_NAME(proxyData)], proxyData); - ret = ret && SetValue(node[GET_NAME(bundleName)], bundleName); ret = ret && SetValue(node[GET_NAME(userId)], userId); - ret = ret && SetValue(node[GET_NAME(appIndex)], appIndex); ret = ret && SetValue(node[GET_NAME(tokenId)], tokenId); return ret && VersionData::Marshal(node); } @@ -66,23 +85,36 @@ bool ProxyDataNode::Marshal(DistributedData::Serializable::json &node) const bool ProxyDataNode::Unmarshal(const DistributedData::Serializable::json &node) { bool ret = GetValue(node, GET_NAME(proxyData), proxyData); - ret = ret && GetValue(node, GET_NAME(bundleName), bundleName); ret = ret && GetValue(node, GET_NAME(userId), userId); - ret = ret && GetValue(node, GET_NAME(appIndex), appIndex); + return ret && GetValue(node, GET_NAME(tokenId), tokenId); +} + +bool ProxyDataListNode::Marshal(DistributedData::Serializable::json &node) const +{ + bool ret = SetValue(node[GET_NAME(uris)], uris); + ret = ret && SetValue(node[GET_NAME(userId)], userId); + ret = ret && SetValue(node[GET_NAME(tokenId)], tokenId); + return ret && VersionData::Marshal(node); +} + +bool ProxyDataListNode::Unmarshal(const DistributedData::Serializable::json &node) +{ + bool ret = GetValue(node, GET_NAME(uris), uris); + ret = ret && GetValue(node, GET_NAME(userId), userId); return ret && GetValue(node, GET_NAME(tokenId), tokenId); } bool PublishedProxyData::VerifySelfAccess(const BundleInfo &callerBundleInfo, const ProxyDataNode &data, bool isInstallEvent) { - std::string bundleName; - URIUtils::GetBundleNameFromProxyURI(data.proxyData.uri, bundleName); - if (callerBundleInfo.bundleName == bundleName && callerBundleInfo.appIndex == data.appIndex && - callerBundleInfo.userId == data.userId) { - return true; - } - ZLOGE("only allow to modify the proxyData of self bundle"); - return false; + // std::string bundleName; + // URIUtils::GetBundleNameFromProxyURI(data.proxyData.uri, bundleName); + // if (callerBundleInfo.bundleName == bundleName && callerBundleInfo.appIndex == data.appIndex && + // callerBundleInfo.userId == data.userId) { + // return true; + // } + // ZLOGE("only allow to modify the proxyData of self bundle"); + return callerBundleInfo.tokenId == data.tokenId; } bool PublishedProxyData::VerifyPermission(const BundleInfo &callerBundleInfo, const ProxyDataNode &data) @@ -140,11 +172,23 @@ int32_t PublishedProxyData::Upsert(const DataShareProxyData &proxyData, const Bu return INNER_ERROR; } + ProxyDataListNode proxyDataList; std::string filter = Id(proxyData.uri_, callerBundleInfo.userId); std::string queryResult; delegate->Get(KvDBDelegate::PROXYDATA_TABLE, filter, "{}", queryResult); - if (queryResult.empty()) { + std::string listFilter = Id(std::to_string(callerBundleInfo.tokenId), callerBundleInfo.userId); + std::string listQueryResult; + delegate->Get(KvDBDelegate::PROXYDATA_TABLE, listFilter, "{}", listQueryResult); + if (!listQueryResult.empty()) { + if (!ProxyDataListNode::Unmarshall(listQueryResult, proxyDataList)) { + ZLOGE("Unmarshall failed, %{private}s", listQueryResult.c_str()); + return INNER_ERROR; + } + if (proxyDataList.uris.size() > PROXY_DATA_MAX_COUNT) { + return OVER_LIMIT; + } + } type = DataShareObserver::ChangeType::INSERT; std::string modifyBundle; URIUtils::GetBundleNameFromProxyURI(proxyData.uri_, modifyBundle); @@ -162,16 +206,20 @@ int32_t PublishedProxyData::Upsert(const DataShareProxyData &proxyData, const Bu return NO_PERMISSION; } } + SerialDataShareProxyData serialProxyData(proxyData.uri_, proxyData.value_, proxyData.allowList_); auto [status, count] = delegate->Upsert(KvDBDelegate::PROXYDATA_TABLE, PublishedProxyData(ProxyDataNode( - serialProxyData, callerBundleInfo.bundleName, callerBundleInfo.userId, - callerBundleInfo.appIndex, callerBundleInfo.tokenId))); + serialProxyData, callerBundleInfo.userId, callerBundleInfo.tokenId))); if (status != E_OK) { ZLOGE("db Upsert failed, %{public}s %{public}d", DistributedData::Anonymous::Change(proxyData.uri_).c_str(), status); type = DataShareObserver::ChangeType::INVAILD; return INNER_ERROR; } + auto it = std::find(proxyDataList.uris.begin(), proxyDataList.uris.end(), proxyData.uri_); + if (it == proxyDataList.uris.end()) { + proxyDataList.uris.emplace_back(proxyData.uri_); + } type = DataShareObserver::ChangeType::UPDATE; return SUCCESS; } @@ -219,6 +267,125 @@ int32_t PublishedProxyData::Delete(const std::string &uri, const BundleInfo &cal return SUCCESS; } +int32_t ProxyDataList::GetProxyDataCount(const uint32_t &tokenId, const int32_t &userId) +{ + int32_t defaultNum = 0; + auto delegate = KvDBDelegate::GetInstance(); + if (delegate == nullptr) { + ZLOGE("db open failed"); + return defaultNum; + } + + std::string filter = Id(std::to_string(tokenId), userId); + std::string queryResult; + delegate->Get(KvDBDelegate::PROXYDATA_TABLE, filter, "{}", queryResult); + if (queryResult.empty()) { + return defaultNum; + } + ProxyDataListNode data; + if (!ProxyDataListNode::Unmarshall(queryResult, data)) { + ZLOGE("Unmarshall failed, %{private}s", queryResult.c_str()); + return defaultNum; + } + + return data.uris.size(); +} + +int32_t ProxyDataList::Query(const uint32_t &tokenId, const int32_t &userId, std::vector &proxyDataList) +{ + int32_t defaultNum = 0; + auto delegate = KvDBDelegate::GetInstance(); + if (delegate == nullptr) { + ZLOGE("db open failed"); + return defaultNum; + } + std::string filter = Id(std::to_string(tokenId), userId); + std::string queryResult; + delegate->Get(KvDBDelegate::PROXYDATA_TABLE, filter, "{}", queryResult); + if (queryResult.empty()) { + return defaultNum; + } + ProxyDataListNode data; + if (!ProxyDataListNode::Unmarshall(queryResult, data)) { + ZLOGE("Unmarshall failed, %{private}s", queryResult.c_str()); + return defaultNum; + } + + proxyDataList = std::move(data.uris); + return data.uris.size(); +} + +int32_t ProxyDataList::Upsert(const std::vector &uris, const uint32_t &tokenId, const int32_t &userId) +{ + int32_t defaultNum = 0; + auto delegate = KvDBDelegate::GetInstance(); + if (delegate == nullptr) { + ZLOGE("db open failed"); + return defaultNum; + } + + std::string filter = Id(std::to_string(tokenId), userId); + std::string queryResult; + delegate->Get(KvDBDelegate::PROXYDATA_TABLE, filter, "{}", queryResult); + ProxyDataListNode node; + if (queryResult.empty()) { + return defaultNum; + } else if (!ProxyDataListNode::Unmarshall(queryResult, node)){ + ZLOGE("Unmarshall failed, %{private}s", queryResult.c_str()); + return defaultNum; + } + std::for_each(uris.begin(), uris.end(), [&node](const auto &uri) { + auto it = std::find(node.uris.begin(), node.uris.end(), uri); + if (it != node.uris.end()) { + return; + } + node.uris.emplace_back(uri); + }); + auto [status, res] = delegate->Upsert(KvDBDelegate::PROXYDATA_TABLE, ProxyDataList(ProxyDataListNode( + node.uris, userId, tokenId))); + if (status != E_OK) { + ZLOGE("db Upsert failed, %{public}x %{public}d", tokenId, status); + return defaultNum; + } + return res; +} + +int32_t ProxyDataList::Delete(const std::vector uris, const uint32_t &tokenId, const int32_t &userId) +{ + int32_t defaultNum = 0; + auto delegate = KvDBDelegate::GetInstance(); + if (delegate == nullptr) { + ZLOGE("db open failed"); + return defaultNum; + } + + std::string filter = Id(std::to_string(tokenId), userId); + std::string queryResult; + delegate->Get(KvDBDelegate::PROXYDATA_TABLE, filter, "{}", queryResult); + if (queryResult.empty()) { + return defaultNum; + } + + ProxyDataListNode node; + if (!ProxyDataListNode::Unmarshall(queryResult, node)) { + ZLOGE("Unmarshall failed, %{private}s", queryResult.c_str()); + return defaultNum; + } + std::for_each(uris.begin(), uris.end(), [&node](const auto &uri) { + auto it = std::find(node.uris.begin(), node.uris.end(), uri); + if (it != node.uris.end()) { + node.uris.erase(it); + } + }); + auto [status, res] = delegate->Upsert(KvDBDelegate::PROXYDATA_TABLE, ProxyDataList(ProxyDataListNode( + node.uris, userId, tokenId))); + if (status != E_OK) { + ZLOGE("db Upsert failed, %{public}x %{public}d", tokenId, status); + return defaultNum; + } + return res; +} + bool ProxyDataManager::GetCrossAppSharedConfig(const std::string &bundleName, int32_t user, int32_t index, std::vector &proxyDatas) { diff --git a/services/distributeddataservice/service/data_share/common/proxy_data_manager.h b/services/distributeddataservice/service/data_share/common/proxy_data_manager.h index 3fe7db49230eefd6b79b11d9d86d945bd4725521..2e9092daab166d78a67676677fa620c8f05ccf99 100644 --- a/services/distributeddataservice/service/data_share/common/proxy_data_manager.h +++ b/services/distributeddataservice/service/data_share/common/proxy_data_manager.h @@ -25,17 +25,13 @@ namespace OHOS::DataShare { class ProxyDataNode final : public VersionData { public: ProxyDataNode(); - ProxyDataNode(const SerialDataShareProxyData proxyData, const std::string bundleName, - const int32_t userId, const int32_t &appIndex, const uint32_t tokenId) - : VersionData(0), proxyData(proxyData), bundleName(bundleName), - userId(userId), appIndex(appIndex), tokenId(tokenId) {} + ProxyDataNode(const SerialDataShareProxyData proxyData, const int32_t userId, const uint32_t tokenId) + : VersionData(0), proxyData(proxyData), userId(userId), tokenId(tokenId) {} ~ProxyDataNode() = default; bool Marshal(json &node) const override; bool Unmarshal(const json &node) override; SerialDataShareProxyData proxyData; - std::string bundleName; int32_t userId = Id::INVALID_USER; - int32_t appIndex = 0; uint32_t tokenId; }; @@ -60,6 +56,35 @@ private: ProxyDataNode value; }; +class ProxyDataListNode final : public VersionData { +public: + ProxyDataListNode(); + ProxyDataListNode(const std::vector &uris, const int32_t &userId, const uint32_t &tokenId) + : VersionData(0), uris(uris), userId(userId), tokenId(tokenId) {} + ~ProxyDataListNode() = default; + bool Marshal(json &node) const override; + bool Unmarshal(const json &node) override; + std::vector uris; + int32_t userId = Id::INVALID_USER; + uint32_t tokenId; +}; + +class ProxyDataList final : public KvData { +public: + explicit ProxyDataList(const ProxyDataListNode &node); + ~ProxyDataList() = default; + static int32_t Query(const uint32_t &tokenId, const int32_t &userId, std::vector &proxyDataList); + static int32_t Delete(const std::vector uris, const uint32_t &tokenId, const int32_t &userId); + static int32_t Upsert(const std::vector &uris, const uint32_t &tokenId, const int32_t &userId); + static int32_t GetProxyDataCount(const uint32_t &tokenId, const int32_t &userId); + bool HasVersion() const override; + int GetVersion() const override; + std::string GetValue() const override; + +private: + ProxyDataListNode value; +}; + class ProxyDataManager { public: static ProxyDataManager &GetInstance(); diff --git a/services/distributeddataservice/service/data_share/data_share_service_impl.cpp b/services/distributeddataservice/service/data_share/data_share_service_impl.cpp index 3c1a3ded34286a7d149ea4c67bfc62ca39ea5442..eeb696013b04982e8ccd03c360393f0d14f5cf67 100644 --- a/services/distributeddataservice/service/data_share/data_share_service_impl.cpp +++ b/services/distributeddataservice/service/data_share/data_share_service_impl.cpp @@ -1017,6 +1017,11 @@ std::vector DataShareServiceImpl::PublishProxyData(const std::v datas[type].emplace_back(data); } } + std::vector uris; + std::for_each(keys.begin(), keys.end(), [&uris](const auto &uri) { + uris.emplace_back(uri); + }); + ProxyDataList::Upsert(uris, callerBundleInfo.tokenId, callerBundleInfo.userId); ProxyDataSubscriberManager::GetInstance().Emit(keys, datas, callerBundleInfo.userId); return result; } @@ -1042,6 +1047,11 @@ std::vector DataShareServiceImpl::DeleteProxyData(const std::ve datas[type].emplace_back(oldProxyData); } } + std::vector lastDelUris; + std::for_each(keys.begin(), keys.end(), [&lastDelUris](const auto &uri) { + lastDelUris.emplace_back(uri); + }); + ProxyDataList::Upsert(uris, callerBundleInfo.tokenId, callerBundleInfo.userId); ProxyDataSubscriberManager::GetInstance().Emit(keys, datas, callerBundleInfo.userId); return result; }