1 /*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #define LOG_TAG "GetDataStrategy"
16
17 #include "get_data_strategy.h"
18
19 #include "accesstoken_kit.h"
20 #include "data_proxy/load_config_from_data_proxy_node_strategy.h"
21 #include "general/load_config_common_strategy.h"
22 #include "log_print.h"
23 #include "utils/anonymous.h"
24
25 namespace OHOS::DataShare {
Execute(std::shared_ptr<Context> context,int & errorCode)26 Data GetDataStrategy::Execute(std::shared_ptr<Context> context, int &errorCode)
27 {
28 auto &preProcess = GetStrategy();
29 if (preProcess.IsEmpty()) {
30 ZLOGE("get strategy fail, maybe memory not enough");
31 errorCode = E_ERROR;
32 return Data();
33 }
34 if (!preProcess(context)) {
35 ZLOGE("pre process fail, uri: %{public}s", DistributedData::Anonymous::Change(context->uri).c_str());
36 errorCode = context->errCode;
37 return Data();
38 }
39 auto result = PublishedData::Query(context->calledBundleName, context->currentUserId);
40 Data data;
41 for (auto &item : result) {
42 if (!CheckPermission(context, item.value.key)) {
43 ZLOGI("uri: %{private}s not allowed", context->uri.c_str());
44 continue;
45 }
46 if (item.GetVersion() > data.version_) {
47 data.version_ = item.GetVersion();
48 }
49 data.datas_.emplace_back(
50 item.value.key, item.value.subscriberId, PublishedDataNode::MoveTo(item.value.value));
51 }
52 return data;
53 }
54
GetStrategy()55 SeqStrategy &GetDataStrategy::GetStrategy()
56 {
57 std::lock_guard<decltype(mutex_)> lock(mutex_);
58 if (!strategies_.IsEmpty()) {
59 return strategies_;
60 }
61 std::initializer_list<Strategy *> list = {
62 new (std::nothrow) LoadConfigCommonStrategy(),
63 new (std::nothrow) LoadConfigFromDataProxyNodeStrategy()
64 };
65 auto ret = strategies_.Init(list);
66 if (!ret) {
67 std::for_each(list.begin(), list.end(), [](Strategy *item) {
68 delete item;
69 });
70 return strategies_;
71 }
72 return strategies_;
73 }
74
CheckPermission(std::shared_ptr<Context> context,const std::string & key)75 bool GetDataStrategy::CheckPermission(std::shared_ptr<Context> context, const std::string &key)
76 {
77 if (context->callerBundleName == context->calledBundleName) {
78 ZLOGI("access private data, caller and called is same, go");
79 return true;
80 }
81 for (const auto &moduleInfo : context->bundleInfo.hapModuleInfos) {
82 auto proxyDatas = moduleInfo.proxyDatas;
83 for (auto &proxyData : proxyDatas) {
84 if (proxyData.uri != key) {
85 continue;
86 }
87 if (proxyData.requiredReadPermission.empty()) {
88 ZLOGE("no read permission");
89 return false;
90 }
91 int status = Security::AccessToken::AccessTokenKit::VerifyAccessToken(
92 context->callerTokenId, proxyData.requiredReadPermission);
93 if (status != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
94 ZLOGE("Verify permission denied! callerTokenId:%{public}u permission:%{public}s",
95 context->callerTokenId, proxyData.requiredReadPermission.c_str());
96 return false;
97 }
98 return true;
99 }
100 }
101 return false;
102 }
103 } // namespace OHOS::DataShare