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 
16 #include "batch_uri.h"
17 
18 #include "file_permission_manager.h"
19 #include "hilog_tag_wrapper.h"
20 #include "uri_permission_utils.h"
21 
22 namespace OHOS {
23 namespace AAFwk {
24 
Init(const std::vector<Uri> & uriVec,uint32_t mode,const std::string & callerBundleName,const std::string & targetBundleName)25 int32_t BatchUri::Init(const std::vector<Uri> &uriVec, uint32_t mode, const std::string &callerBundleName,
26     const std::string &targetBundleName)
27 {
28     if (uriVec.empty()) {
29         TAG_LOGE(AAFwkTag::URIPERMMGR, "uriVec is empty.");
30         return 0;
31     }
32     targetAppName = targetBundleName;
33     totalUriCount = static_cast<int32_t>(uriVec.size());
34     validUriCount = 0;
35     result = std::vector<bool>(totalUriCount, false);
36     isDocsUriVec = std::vector<bool>(totalUriCount, false);
37     isTargetBundleUri = std::vector<bool>(totalUriCount, false);
38     for (size_t index = 0; index < uriVec.size(); index++) {
39         auto uriInner = uriVec[index];
40         auto &&scheme = uriInner.GetScheme();
41         if (scheme != "content" && scheme != "file") {
42             TAG_LOGW(AAFwkTag::URIPERMMGR, "uri is invalid: %{private}s.", uriInner.ToString().c_str());
43             continue;
44         }
45         validUriCount++;
46         // content uri
47         if (scheme == "content") {
48             contentUris.emplace_back(uriInner);
49             contentIndexs.emplace_back(index);
50             continue;
51         }
52         InitFileUriInfo(uriInner, index, mode, callerBundleName, targetBundleName);
53     }
54     TAG_LOGI(AAFwkTag::URIPERMMGR, "count of uri is %{public}d, count of valid uri is %{public}d.",
55         totalUriCount, validUriCount);
56     return validUriCount;
57 }
58 
InitFileUriInfo(Uri & uriInner,uint32_t index,const uint32_t mode,const std::string & callerBundleName,const std::string & targetBundleName)59 void BatchUri::InitFileUriInfo(Uri &uriInner, uint32_t index, const uint32_t mode,
60     const std::string &callerBundleName, const std::string &targetBundleName)
61 {
62     auto &&authority = uriInner.GetAuthority();
63     TAG_LOGD(AAFwkTag::URIPERMMGR, "Authority of uri is %{public}s.", authority.c_str());
64     // media uri
65     if (authority == "media") {
66         mediaUris.emplace_back(uriInner);
67         mediaIndexs.emplace_back(index);
68         return;
69     }
70     // bundle uri
71     isTargetBundleUri[index] = (!targetBundleName.empty() && authority == targetBundleName);
72     if (!callerBundleName.empty() && authority == callerBundleName) {
73         result[index] = true;
74         if (isTargetBundleUri[index]) {
75             TAG_LOGI(AAFwkTag::URIPERMMGR, "uri belong to targetBundle.");
76             targetBundleUriCount++;
77             return;
78         }
79         if (mode > 0) {
80             // need set policy
81             auto policyInfo = FilePermissionManager::GetPathPolicyInfoFromUri(uriInner, mode);
82             selfBundlePolicyInfos.emplace_back(policyInfo);
83         }
84         return;
85     }
86     if (authority == "docs") {
87         isDocsUriVec[index] = true;
88     }
89     // docs and bundle uri, need to check uri pemission
90     otherUris.emplace_back(uriInner);
91     otherIndexs.emplace_back(index);
92 }
93 
SetContentUriCheckResult(const std::vector<bool> & contentUriResult)94 void BatchUri::SetContentUriCheckResult(const std::vector<bool> &contentUriResult)
95 {
96     for (size_t i = 0; i < contentUriResult.size(); i++) {
97         auto index = contentIndexs[i];
98         result[index] = contentUriResult[i];
99     }
100 }
101 
SetMediaUriCheckResult(const std::vector<bool> & mediaUriResult)102 void BatchUri::SetMediaUriCheckResult(const std::vector<bool> &mediaUriResult)
103 {
104     for (size_t i = 0; i < mediaUriResult.size(); i++) {
105         auto index = mediaIndexs[i];
106         result[index] = mediaUriResult[i];
107     }
108 }
109 
SetOtherUriCheckResult(const std::vector<bool> & otherUriResult)110 void BatchUri::SetOtherUriCheckResult(const std::vector<bool> &otherUriResult)
111 {
112     for (size_t i = 0; i < otherUriResult.size(); i++) {
113         auto index = otherIndexs[i];
114         result[index] = otherUriResult[i];
115         if (result[index] && isTargetBundleUri[index]) {
116             targetBundleUriCount++;
117         }
118     }
119 }
120 
GetNeedCheckProxyPermissionURI(std::vector<PolicyInfo> & proxyUrisByPolicy,std::vector<Uri> & proxyUrisByMap)121 void BatchUri::GetNeedCheckProxyPermissionURI(std::vector<PolicyInfo> &proxyUrisByPolicy,
122     std::vector<Uri> &proxyUrisByMap)
123 {
124     // docs uri and bundle uri
125     for (size_t i = 0; i < otherIndexs.size(); i++) {
126         auto index = otherIndexs[i];
127         if (!result[index]) {
128             proxyIndexsByPolicy.emplace_back(index);
129             proxyUrisByPolicy.emplace_back(otherPolicyInfos[i]);
130         }
131     }
132     // media uri
133     for (size_t i = 0; i < mediaIndexs.size(); i++) {
134         auto index = mediaIndexs[i];
135         if (!result[index]) {
136             proxyIndexsByMap.emplace_back(index);
137             proxyUrisByMap.emplace_back(mediaUris[i]);
138         }
139     }
140 }
141 
SetCheckProxyByMapResult(std::vector<bool> & proxyResultByMap)142 void BatchUri::SetCheckProxyByMapResult(std::vector<bool> &proxyResultByMap)
143 {
144     for (size_t i = 0; i < proxyResultByMap.size(); i++) {
145         auto index = proxyIndexsByMap[i];
146         result[index] = proxyResultByMap[i];
147     }
148     proxyIndexsByMap.clear();
149 }
150 
SetCheckProxyByPolicyResult(std::vector<bool> & proxyResultByPolicy)151 void BatchUri::SetCheckProxyByPolicyResult(std::vector<bool> &proxyResultByPolicy)
152 {
153     for (size_t i = 0; i < proxyResultByPolicy.size(); i++) {
154         auto index = proxyIndexsByPolicy[i];
155         result[index] = proxyResultByPolicy[i];
156     }
157     proxyIndexsByPolicy.clear();
158 }
159 
GetUriToGrantByMap(std::vector<std::string> & uriVec)160 int32_t BatchUri::GetUriToGrantByMap(std::vector<std::string> &uriVec)
161 {
162     // content
163     SelectPermissionedUri(contentUris, contentIndexs, uriVec);
164     // media
165     SelectPermissionedUri(mediaUris, mediaIndexs, uriVec);
166     return uriVec.size();
167 }
168 
SelectPermissionedUri(std::vector<Uri> & uris,std::vector<int32_t> & indexs,std::vector<std::string> & uriVec)169 void BatchUri::SelectPermissionedUri(std::vector<Uri> &uris, std::vector<int32_t> &indexs,
170     std::vector<std::string> &uriVec)
171 {
172     for (size_t i = 0; i < indexs.size(); i++) {
173         if (result[indexs[i]]) {
174             auto uriStr = uris[i].ToString();
175             uriVec.emplace_back(uriStr);
176         }
177     }
178 }
179 
GetUriToGrantByPolicy(std::vector<PolicyInfo> & docsPolicyInfoVec,std::vector<PolicyInfo> & bundlePolicyInfoVec)180 int32_t BatchUri::GetUriToGrantByPolicy(std::vector<PolicyInfo> &docsPolicyInfoVec,
181     std::vector<PolicyInfo> &bundlePolicyInfoVec)
182 {
183     // bundleName + docs
184     int32_t count = 0;
185     for (auto &selfBundleUriPolicy : selfBundlePolicyInfos) {
186         bundlePolicyInfoVec.emplace_back(selfBundleUriPolicy);
187         count++;
188     }
189     for (size_t i = 0; i < otherPolicyInfos.size(); i++) {
190         auto index = otherIndexs[i];
191         if (!result[index]) {
192             continue;
193         }
194         // the uri belong to target app.
195         if (isTargetBundleUri[index]) {
196             continue;
197         }
198         TAG_LOGD(AAFwkTag::URIPERMMGR, "Add policy: path is %{private}s, mode is %{public}u.",
199             otherPolicyInfos[i].path.c_str(), static_cast<uint32_t>(otherPolicyInfos[i].mode));
200         if (isDocsUriVec[index]) {
201             docsPolicyInfoVec.emplace_back(otherPolicyInfos[i]);
202         } else {
203             bundlePolicyInfoVec.emplace_back(otherPolicyInfos[i]);
204         }
205         count++;
206     }
207     return count;
208 }
209 
GetPermissionedUriCount()210 int32_t BatchUri::GetPermissionedUriCount()
211 {
212     int32_t permissionedUriCount = 0;
213     for (auto checkRes: result) {
214         if (checkRes) {
215             permissionedUriCount++;
216         }
217     }
218     return permissionedUriCount;
219 }
220 } // OHOS
221 } // AAFwk