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 "CloudServiceStub"
16 #include "cloud_service_stub.h"
17 
18 #include "cloud/cloud_config_manager.h"
19 #include "cloud_types_util.h"
20 #include "ipc_skeleton.h"
21 #include "log_print.h"
22 #include "permission/permission_validator.h"
23 #include "rdb_types.h"
24 #include "tokenid_kit.h"
25 #include "utils/anonymous.h"
26 namespace OHOS::CloudData {
27 using namespace DistributedData;
28 using namespace OHOS::Security::AccessToken;
29 const CloudServiceStub::Handler CloudServiceStub::HANDLERS[TRANS_BUTT] = {
30     &CloudServiceStub::OnEnableCloud,
31     &CloudServiceStub::OnDisableCloud,
32     &CloudServiceStub::OnChangeAppSwitch,
33     &CloudServiceStub::OnClean,
34     &CloudServiceStub::OnNotifyDataChange,
35     &CloudServiceStub::OnNotifyChange,
36     &CloudServiceStub::OnQueryStatistics,
37     &CloudServiceStub::OnQueryLastSyncInfo,
38     &CloudServiceStub::OnSetGlobalCloudStrategy,
39     &CloudServiceStub::OnAllocResourceAndShare,
40     &CloudServiceStub::OnShare,
41     &CloudServiceStub::OnUnshare,
42     &CloudServiceStub::OnExit,
43     &CloudServiceStub::OnChangePrivilege,
44     &CloudServiceStub::OnQuery,
45     &CloudServiceStub::OnQueryByInvitation,
46     &CloudServiceStub::OnConfirmInvitation,
47     &CloudServiceStub::OnChangeConfirmation,
48     &CloudServiceStub::OnSetCloudStrategy,
49 };
50 
OnRemoteRequest(uint32_t code,OHOS::MessageParcel & data,OHOS::MessageParcel & reply)51 int CloudServiceStub::OnRemoteRequest(uint32_t code, OHOS::MessageParcel &data, OHOS::MessageParcel &reply)
52 {
53     ZLOGI("code:%{public}u callingPid:%{public}u", code, IPCSkeleton::GetCallingPid());
54     std::u16string local = CloudServiceStub::GetDescriptor();
55     std::u16string remote = data.ReadInterfaceToken();
56     if (local != remote) {
57         ZLOGE("local is not equal to remote");
58         return -1;
59     }
60 
61     if (TRANS_HEAD > code || code >= TRANS_BUTT || HANDLERS[code] == nullptr) {
62         ZLOGE("not support code:%{public}u, BUTT:%{public}d", code, TRANS_BUTT);
63         return -1;
64     }
65 
66     if (((code >= TRANS_CONFIG_HEAD && code < TRANS_CONFIG_BUTT) ||
67         (code >= TRANS_SHARE_HEAD && code < TRANS_SHARE_BUTT)) &&
68         !TokenIdKit::IsSystemAppByFullTokenID(IPCSkeleton::GetCallingFullTokenID())) {
69         ZLOGE("permission denied! code:%{public}u", code);
70         auto result = static_cast<int32_t>(PERMISSION_DENIED);
71         return ITypesUtil::Marshal(reply, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
72     }
73 
74     if (code >= TRANS_CONFIG_HEAD && code < TRANS_CONFIG_BUTT &&
75         !DistributedKv::PermissionValidator::GetInstance().IsCloudConfigPermit(IPCSkeleton::GetCallingTokenID())) {
76         ZLOGE("cloud config permission denied! code:%{public}u, BUTT:%{public}d", code, TRANS_BUTT);
77         auto result = static_cast<int32_t>(CLOUD_CONFIG_PERMISSION_DENIED);
78         return ITypesUtil::Marshal(reply, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
79     }
80     return (this->*HANDLERS[code])(data, reply);
81 }
82 
OnEnableCloud(MessageParcel & data,MessageParcel & reply)83 int32_t CloudServiceStub::OnEnableCloud(MessageParcel &data, MessageParcel &reply)
84 {
85     std::string id;
86     std::map<std::string, int32_t> switches;
87     if (!ITypesUtil::Unmarshal(data, id, switches)) {
88         ZLOGE("Unmarshal id:%{public}s", Anonymous::Change(id).c_str());
89         return IPC_STUB_INVALID_DATA_ERR;
90     }
91     std::map<std::string, int32_t> localSwitches;
92     for (const auto &[bundle, status] : switches) {
93         localSwitches.insert_or_assign(CloudConfigManager::GetInstance().ToLocal(bundle), status);
94     }
95     auto result = EnableCloud(id, localSwitches);
96     return ITypesUtil::Marshal(reply, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
97 }
98 
OnDisableCloud(MessageParcel & data,MessageParcel & reply)99 int32_t CloudServiceStub::OnDisableCloud(MessageParcel &data, MessageParcel &reply)
100 {
101     std::string id;
102     if (!ITypesUtil::Unmarshal(data, id)) {
103         ZLOGE("Unmarshal id:%{public}s", Anonymous::Change(id).c_str());
104         return IPC_STUB_INVALID_DATA_ERR;
105     }
106     auto result = DisableCloud(id);
107     return ITypesUtil::Marshal(reply, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
108 }
109 
OnChangeAppSwitch(MessageParcel & data,MessageParcel & reply)110 int32_t CloudServiceStub::OnChangeAppSwitch(MessageParcel &data, MessageParcel &reply)
111 {
112     std::string id;
113     std::string bundleName;
114     int32_t appSwitch = SWITCH_OFF;
115     if (!ITypesUtil::Unmarshal(data, id, bundleName, appSwitch)) {
116         ZLOGE("Unmarshal id:%{public}s", Anonymous::Change(id).c_str());
117         return IPC_STUB_INVALID_DATA_ERR;
118     }
119     auto result = ChangeAppSwitch(id, CloudConfigManager::GetInstance().ToLocal(bundleName), appSwitch);
120     return ITypesUtil::Marshal(reply, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
121 }
122 
OnClean(MessageParcel & data,MessageParcel & reply)123 int32_t CloudServiceStub::OnClean(MessageParcel &data, MessageParcel &reply)
124 {
125     std::string id;
126     std::map<std::string, int32_t> actions;
127     if (!ITypesUtil::Unmarshal(data, id, actions)) {
128         ZLOGE("Unmarshal id:%{public}s", Anonymous::Change(id).c_str());
129         return IPC_STUB_INVALID_DATA_ERR;
130     }
131     std::map<std::string, int32_t> localActions;
132     for (const auto &[bundle, action] : actions) {
133         localActions.insert_or_assign(CloudConfigManager::GetInstance().ToLocal(bundle), action);
134     }
135     auto result = Clean(id, localActions);
136     return ITypesUtil::Marshal(reply, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
137 }
138 
OnNotifyDataChange(MessageParcel & data,MessageParcel & reply)139 int32_t CloudServiceStub::OnNotifyDataChange(MessageParcel &data, MessageParcel &reply)
140 {
141     std::string id;
142     std::string bundleName;
143     if (!ITypesUtil::Unmarshal(data, id, bundleName)) {
144         ZLOGE("Unmarshal id:%{public}s", Anonymous::Change(id).c_str());
145         return IPC_STUB_INVALID_DATA_ERR;
146     }
147     auto result = NotifyDataChange(id, CloudConfigManager::GetInstance().ToLocal(bundleName));
148     return ITypesUtil::Marshal(reply, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
149 }
150 
OnQueryLastSyncInfo(MessageParcel & data,MessageParcel & reply)151 int32_t CloudServiceStub::OnQueryLastSyncInfo(MessageParcel &data, MessageParcel &reply)
152 {
153     std::string id;
154     std::string bundleName;
155     std::string storeId;
156     if (!ITypesUtil::Unmarshal(data, id, bundleName, storeId)) {
157         ZLOGE("Unmarshal id:%{public}s, bundleName:%{public}s, storeId:%{public}s", Anonymous::Change(id).c_str(),
158             bundleName.c_str(), Anonymous::Change(storeId).c_str());
159         return IPC_STUB_INVALID_DATA_ERR;
160     }
161     auto [status, results] = QueryLastSyncInfo(id, bundleName, storeId);
162     return ITypesUtil::Marshal(reply, status, results) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
163 }
164 
OnSetGlobalCloudStrategy(MessageParcel & data,MessageParcel & reply)165 int32_t CloudServiceStub::OnSetGlobalCloudStrategy(MessageParcel &data, MessageParcel &reply)
166 {
167     Strategy strategy;
168     std::vector<CommonType::Value> values;
169     if (!ITypesUtil::Unmarshal(data, strategy, values)) {
170         ZLOGE("Unmarshal strategy:%{public}d, values size:%{public}zu", strategy, values.size());
171         return IPC_STUB_INVALID_DATA_ERR;
172     }
173     auto status = SetGlobalCloudStrategy(strategy, values);
174     return ITypesUtil::Marshal(reply, status) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
175 }
176 
OnAllocResourceAndShare(MessageParcel & data,MessageParcel & reply)177 int32_t CloudServiceStub::OnAllocResourceAndShare(MessageParcel &data, MessageParcel &reply)
178 {
179     std::string storeId;
180     DistributedRdb::PredicatesMemo predicatesMemo;
181     std::vector<std::string> columns;
182     std::vector<Participant> participants;
183     if (!ITypesUtil::Unmarshal(data, storeId, predicatesMemo, columns, participants)) {
184         ZLOGE("Unmarshal storeId:%{public}s", Anonymous::Change(storeId).c_str());
185         return IPC_STUB_INVALID_DATA_ERR;
186     }
187     auto [status, resultSet] = AllocResourceAndShare(storeId, predicatesMemo, columns, participants);
188     return ITypesUtil::Marshal(reply, status, resultSet) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
189 }
190 
OnNotifyChange(MessageParcel & data,MessageParcel & reply)191 int32_t CloudServiceStub::OnNotifyChange(MessageParcel &data, MessageParcel &reply)
192 {
193     std::string eventId;
194     std::string extraData;
195     int32_t userId;
196     if (!ITypesUtil::Unmarshal(data, eventId, extraData, userId)) {
197         ZLOGE("Unmarshal eventId:%{public}s", Anonymous::Change(eventId).c_str());
198         return IPC_STUB_INVALID_DATA_ERR;
199     }
200     auto result = NotifyDataChange(eventId, extraData, userId);
201     return ITypesUtil::Marshal(reply, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
202 }
203 
OnQueryStatistics(MessageParcel & data,MessageParcel & reply)204 int32_t CloudServiceStub::OnQueryStatistics(MessageParcel &data, MessageParcel &reply)
205 {
206     std::string id;
207     std::string bundleName;
208     std::string storeId;
209     if (!ITypesUtil::Unmarshal(data, id, bundleName, storeId)) {
210         ZLOGE("Unmarshal id:%{public}s", Anonymous::Change(id).c_str());
211         return IPC_STUB_INVALID_DATA_ERR;
212     }
213     auto result = QueryStatistics(id, bundleName, storeId);
214     return ITypesUtil::Marshal(reply, result.first, result.second) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
215 }
216 
OnShare(MessageParcel & data,MessageParcel & reply)217 int32_t CloudServiceStub::OnShare(MessageParcel &data, MessageParcel &reply)
218 {
219     std::string sharingRes;
220     Participants participants;
221     if (!ITypesUtil::Unmarshal(data, sharingRes, participants)) {
222         ZLOGE("Unmarshal sharingRes:%{public}s", Anonymous::Change(sharingRes).c_str());
223         return IPC_STUB_INVALID_DATA_ERR;
224     }
225     Results results;
226     auto status = Share(sharingRes, participants, results);
227     return ITypesUtil::Marshal(reply, status, results) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
228 }
229 
OnUnshare(MessageParcel & data,MessageParcel & reply)230 int32_t CloudServiceStub::OnUnshare(MessageParcel &data, MessageParcel &reply)
231 {
232     std::string sharingRes;
233     Participants participants;
234     if (!ITypesUtil::Unmarshal(data, sharingRes, participants)) {
235         ZLOGE("Unmarshal sharingRes:%{public}s", Anonymous::Change(sharingRes).c_str());
236         return IPC_STUB_INVALID_DATA_ERR;
237     }
238     Results results;
239     auto status = Unshare(sharingRes, participants, results);
240     return ITypesUtil::Marshal(reply, status, results) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
241 }
242 
OnExit(MessageParcel & data,MessageParcel & reply)243 int32_t CloudServiceStub::OnExit(MessageParcel &data, MessageParcel &reply)
244 {
245     std::string sharingRes;
246     if (!ITypesUtil::Unmarshal(data, sharingRes)) {
247         ZLOGE("Unmarshal sharingRes:%{public}s", Anonymous::Change(sharingRes).c_str());
248         return IPC_STUB_INVALID_DATA_ERR;
249     }
250     std::pair<int32_t, std::string> result;
251     auto status = Exit(sharingRes, result);
252     return ITypesUtil::Marshal(reply, status, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
253 }
254 
OnChangePrivilege(MessageParcel & data,MessageParcel & reply)255 int32_t CloudServiceStub::OnChangePrivilege(MessageParcel &data, MessageParcel &reply)
256 {
257     std::string sharingRes;
258     Participants participants;
259     if (!ITypesUtil::Unmarshal(data, sharingRes, participants)) {
260         ZLOGE("Unmarshal sharingRes:%{public}s", Anonymous::Change(sharingRes).c_str());
261         return IPC_STUB_INVALID_DATA_ERR;
262     }
263     Results results;
264     auto status = ChangePrivilege(sharingRes, participants, results);
265     return ITypesUtil::Marshal(reply, status, results) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
266 }
267 
OnQuery(MessageParcel & data,MessageParcel & reply)268 int32_t CloudServiceStub::OnQuery(MessageParcel &data, MessageParcel &reply)
269 {
270     std::string sharingRes;
271     if (!ITypesUtil::Unmarshal(data, sharingRes)) {
272         ZLOGE("Unmarshal sharingRes:%{public}s", Anonymous::Change(sharingRes).c_str());
273         return IPC_STUB_INVALID_DATA_ERR;
274     }
275     QueryResults results;
276     auto status = Query(sharingRes, results);
277     return ITypesUtil::Marshal(reply, status, results) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
278 }
279 
OnQueryByInvitation(MessageParcel & data,MessageParcel & reply)280 int32_t CloudServiceStub::OnQueryByInvitation(MessageParcel &data, MessageParcel &reply)
281 {
282     std::string invitation;
283     if (!ITypesUtil::Unmarshal(data, invitation)) {
284         ZLOGE("Unmarshal invitation:%{public}s", Anonymous::Change(invitation).c_str());
285         return IPC_STUB_INVALID_DATA_ERR;
286     }
287     QueryResults results;
288     auto status = QueryByInvitation(invitation, results);
289     return ITypesUtil::Marshal(reply, status, results) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
290 }
291 
OnConfirmInvitation(MessageParcel & data,MessageParcel & reply)292 int32_t CloudServiceStub::OnConfirmInvitation(MessageParcel &data, MessageParcel &reply)
293 {
294     std::string invitation;
295     int32_t confirmation;
296     if (!ITypesUtil::Unmarshal(data, invitation, confirmation)) {
297         ZLOGE("Unmarshal invitation:%{public}s", Anonymous::Change(invitation).c_str());
298         return IPC_STUB_INVALID_DATA_ERR;
299     }
300     std::tuple<int32_t, std::string, std::string> result;
301     auto status = ConfirmInvitation(invitation, confirmation, result);
302     return ITypesUtil::Marshal(reply, status, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
303 }
304 
OnChangeConfirmation(MessageParcel & data,MessageParcel & reply)305 int32_t CloudServiceStub::OnChangeConfirmation(MessageParcel &data, MessageParcel &reply)
306 {
307     std::string sharingRes;
308     int32_t confirmation;
309     if (!ITypesUtil::Unmarshal(data, sharingRes, confirmation)) {
310         ZLOGE("Unmarshal sharingRes:%{public}s", Anonymous::Change(sharingRes).c_str());
311         return IPC_STUB_INVALID_DATA_ERR;
312     }
313     std::pair<int32_t, std::string> result;
314     auto status = ChangeConfirmation(sharingRes, confirmation, result);
315     return ITypesUtil::Marshal(reply, status, result) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
316 }
317 
OnSetCloudStrategy(MessageParcel & data,MessageParcel & reply)318 int32_t CloudServiceStub::OnSetCloudStrategy(MessageParcel &data, MessageParcel &reply)
319 {
320     Strategy strategy;
321     std::vector<CommonType::Value> values;
322     if (!ITypesUtil::Unmarshal(data, strategy, values)) {
323         ZLOGE("Unmarshal strategy:%{public}d, values size:%{public}zu", strategy, values.size());
324         return IPC_STUB_INVALID_DATA_ERR;
325     }
326     auto status = SetCloudStrategy(strategy, values);
327     return ITypesUtil::Marshal(reply, status) ? ERR_NONE : IPC_STUB_WRITE_PARCEL_ERR;
328 }
329 } // namespace OHOS::CloudData