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