1 /*
2 * Copyright (c) 2024 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 "DataShareCalledConfig"
16
17 #include "data_share_called_config.h"
18
19 #include <string>
20 #include <utility>
21
22 #include "access_token.h"
23 #include "accesstoken_kit.h"
24 #include "bundle_mgr_helper.h"
25 #include "datashare_errno.h"
26 #include "datashare_log.h"
27 #include "datashare_string_utils.h"
28 #include "if_system_ability_manager.h"
29 #include "iservice_registry.h"
30 #include "system_ability_definition.h"
31
32 namespace OHOS::DataShare {
33 using namespace OHOS::AppExecFwk;
34 using namespace OHOS::Security::AccessToken;
DataShareCalledConfig(const std::string & uri)35 DataShareCalledConfig::DataShareCalledConfig(const std::string &uri)
36 {
37 providerInfo_.uri = uri;
38 }
39
GetUserByToken(uint32_t tokenId)40 int32_t DataShareCalledConfig::GetUserByToken(uint32_t tokenId)
41 {
42 auto type = AccessTokenKit::GetTokenTypeFlag(tokenId);
43 if (type == TOKEN_NATIVE || type == TOKEN_SHELL) {
44 return 0;
45 }
46 HapTokenInfo tokenInfo;
47 auto result = AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo);
48 if (result != RET_SUCCESS) {
49 LOG_ERROR("Get user failed!token:0x%{public}x, result:%{public}d, uri:%{public}s",
50 tokenId, result, DataShareStringUtils::Anonymous(providerInfo_.uri).c_str());
51 return -1;
52 }
53 return tokenInfo.userID;
54 }
55
GetFromProxyData()56 int DataShareCalledConfig::GetFromProxyData()
57 {
58 auto [success, bundleInfo] = GetBundleInfoFromBMS();
59 if (!success) {
60 LOG_ERROR("Get bundleInfo failed! bundleName:%{public}s, userId:%{public}d, uri:%{public}s",
61 providerInfo_.bundleName.c_str(), providerInfo_.currentUserId,
62 DataShareStringUtils::Anonymous(providerInfo_.uri).c_str());
63 return E_BUNDLE_NAME_NOT_EXIST;
64 }
65 std::string uriWithoutQuery = providerInfo_.uri;
66 DataShareStringUtils::RemoveFromQuery(uriWithoutQuery);
67 size_t schemePos = uriWithoutQuery.find(Constants::PARAM_URI_SEPARATOR);
68 if (schemePos != uriWithoutQuery.npos) {
69 uriWithoutQuery.replace(schemePos, Constants::PARAM_URI_SEPARATOR_LEN, Constants::URI_SEPARATOR);
70 }
71 for (auto &hapModuleInfo : bundleInfo.hapModuleInfos) {
72 for (auto &data : hapModuleInfo.proxyDatas) {
73 if (data.uri != uriWithoutQuery) {
74 continue;
75 }
76 providerInfo_.readPermission = std::move(data.requiredReadPermission);
77 providerInfo_.writePermission = std::move(data.requiredWritePermission);
78 providerInfo_.moduleName = std::move(hapModuleInfo.moduleName);
79 return E_OK;
80 }
81 }
82 return E_URI_NOT_EXIST;
83 }
84
GetProviderInfo(uint32_t tokenId)85 std::pair<int, DataShareCalledConfig::ProviderInfo> DataShareCalledConfig::GetProviderInfo(uint32_t tokenId)
86 {
87 Uri uriTemp(providerInfo_.uri);
88 auto isProxyData = PROXY_URI_SCHEMA == uriTemp.GetScheme();
89 std::string bundleName = uriTemp.GetAuthority();
90 if (!isProxyData) {
91 std::vector<std::string> pathSegments;
92 uriTemp.GetPathSegments(pathSegments);
93 if (pathSegments.size() != 0) {
94 bundleName = pathSegments[0];
95 }
96 }
97 if (bundleName.empty()) {
98 LOG_ERROR("BundleName not exist!, tokenId:0x%{public}x, uri:%{public}s",
99 tokenId, DataShareStringUtils::Anonymous(providerInfo_.uri).c_str());
100 return std::make_pair(E_BUNDLE_NAME_NOT_EXIST, DataShareCalledConfig::ProviderInfo{});
101 }
102 providerInfo_.bundleName = bundleName;
103 providerInfo_.currentUserId = GetUserByToken(tokenId);
104 auto ret = GetFromProxyData();
105 if (ret != E_OK) {
106 LOG_ERROR("Failed! isProxyData:%{public}d,ret:%{public}d,tokenId:0x%{public}x,uri:%{public}s",
107 isProxyData, ret, tokenId, DataShareStringUtils::Anonymous(providerInfo_.uri).c_str());
108 }
109 return std::make_pair(ret, providerInfo_);
110 }
111
GetBundleInfoFromBMS()112 std::pair<bool, BundleInfo> DataShareCalledConfig::GetBundleInfoFromBMS()
113 {
114 BundleInfo bundleInfo;
115 auto bmsHelper = DelayedSingleton<BundleMgrHelper>::GetInstance();
116 if (bmsHelper == nullptr) {
117 LOG_ERROR("BmsHelper is nullptr!.uri: %{public}s",
118 DataShareStringUtils::Anonymous(providerInfo_.uri).c_str());
119 return std::make_pair(false, bundleInfo);
120 }
121 bool ret = bmsHelper->GetBundleInfo(providerInfo_.bundleName,
122 BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, providerInfo_.currentUserId);
123 if (!ret) {
124 LOG_ERROR("Get BundleInfo failed! bundleName:%{public}s, userId:%{public}d,uri:%{public}s",
125 providerInfo_.bundleName.c_str(), providerInfo_.currentUserId,
126 DataShareStringUtils::Anonymous(providerInfo_.uri).c_str());
127 return std::make_pair(false, bundleInfo);
128 }
129 return std::make_pair(true, bundleInfo);
130 }
131 } // namespace OHOS::DataShare