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 "LoadConfigFromDataShareBundleInfoStrategy"
16
17 #include "load_config_from_data_share_bundle_info_strategy.h"
18
19 #include "bundle_mgr_proxy.h"
20 #include "data_share_profile_config.h"
21 #include "datashare_errno.h"
22 #include "log_print.h"
23 #include "uri_utils.h"
24 #include "utils/anonymous.h"
25
26 namespace OHOS::DataShare {
27 struct ConfigData {
28 constexpr static int8_t TABLE_MATCH_PRIORITY = 3;
29 constexpr static int8_t STORE_MATCH_PRIORITY = 2;
30 constexpr static int8_t COMMON_MATCH_PRIORITY = 1;
31 constexpr static int8_t UNDEFINED_PRIORITY = -1;
ConfigDataOHOS::DataShare::ConfigData32 ConfigData() : crossMode_(AccessSystemMode::UNDEFINED, UNDEFINED_PRIORITY) {}
SetCrossUserModeOHOS::DataShare::ConfigData33 void SetCrossUserMode(uint8_t priority, uint8_t crossMode)
34 {
35 if (crossMode_.second < priority && crossMode > AccessSystemMode::UNDEFINED &&
36 crossMode < AccessSystemMode::MAX) {
37 crossMode_.first = static_cast<AccessSystemMode>(crossMode);
38 crossMode_.second = priority;
39 }
40 }
FillIntoContextOHOS::DataShare::ConfigData41 void FillIntoContext(std::shared_ptr<Context> context)
42 {
43 if (crossMode_.second != ConfigData::UNDEFINED_PRIORITY) {
44 context->accessSystemMode = crossMode_.first;
45 }
46 }
47
48 private:
49 std::pair<AccessSystemMode, int8_t> crossMode_;
50 };
51
LoadConfigFromProfile(const ProfileInfo & profileInfo,std::shared_ptr<Context> context)52 bool LoadConfigFromDataShareBundleInfoStrategy::LoadConfigFromProfile(
53 const ProfileInfo &profileInfo, std::shared_ptr<Context> context)
54 {
55 std::string storeUri = URIUtils::DATA_SHARE_SCHEMA + context->calledBundleName + "/" + context->calledModuleName +
56 "/" + context->calledStoreName;
57 std::string tableUri = storeUri + "/" + context->calledTableName;
58 ConfigData result;
59 for (auto const &item : profileInfo.tableConfig) {
60 if (item.uri == tableUri) {
61 result.SetCrossUserMode(ConfigData::TABLE_MATCH_PRIORITY, item.crossUserMode);
62 continue;
63 }
64 if (item.uri == storeUri) {
65 result.SetCrossUserMode(ConfigData::STORE_MATCH_PRIORITY, item.crossUserMode);
66 continue;
67 }
68 if (item.uri == "*") {
69 result.SetCrossUserMode(ConfigData::COMMON_MATCH_PRIORITY, item.crossUserMode);
70 continue;
71 }
72 }
73 result.FillIntoContext(context);
74 return true;
75 }
76
operator ()(std::shared_ptr<Context> context)77 bool LoadConfigFromDataShareBundleInfoStrategy::operator()(std::shared_ptr<Context> context)
78 {
79 if (!LoadConfigFromUri(context)) {
80 ZLOGE("LoadConfigFromUri failed! bundleName: %{public}s", context->calledBundleName.c_str());
81 return false;
82 }
83 if (BundleMgrProxy::GetInstance()->GetBundleInfoFromBMS(
84 context->calledBundleName, context->currentUserId, context->bundleInfo) != E_OK) {
85 ZLOGE("GetBundleInfoFromBMS failed! bundleName: %{public}s", context->calledBundleName.c_str());
86 return false;
87 }
88 for (auto const &item : context->bundleInfo.extensionInfos) {
89 if (item.type == AppExecFwk::ExtensionAbilityType::DATASHARE) {
90 context->permission = context->isRead ? item.readPermission : item.writePermission;
91
92 auto profileInfo = item.profileInfo;
93 if (profileInfo.resultCode == NOT_FOUND) {
94 return true; // optional meta data config
95 }
96 if (profileInfo.resultCode == ERROR) {
97 ZLOGE("parse failed! %{public}s", context->calledBundleName.c_str());
98 return false;
99 }
100 LoadConfigFromProfile(profileInfo.profile, context);
101 return true;
102 }
103 }
104 return false;
105 }
LoadConfigFromUri(std::shared_ptr<Context> context)106 bool LoadConfigFromDataShareBundleInfoStrategy::LoadConfigFromUri(std::shared_ptr<Context> context)
107 {
108 UriInfo uriInfo;
109 if (!URIUtils::GetInfoFromURI(context->uri, uriInfo)) {
110 return false;
111 }
112 context->calledBundleName = std::move(uriInfo.bundleName);
113 context->calledModuleName = std::move(uriInfo.moduleName);
114 context->calledStoreName = std::move(uriInfo.storeName);
115 context->calledTableName = std::move(uriInfo.tableName);
116 return true;
117 }
118 } // namespace OHOS::DataShare