• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 
16 #include "hichain_connector.h"
17 
18 #include <cstdlib>
19 #include <ctime>
20 #include <functional>
21 #include <securec.h>
22 
23 #include "dm_anonymous.h"
24 #include "dm_constants.h"
25 #include "dm_crypto.h"
26 #include "dm_dfx_constants.h"
27 #include "dm_hisysevent.h"
28 #include "dm_log.h"
29 #include "dm_random.h"
30 #include "dm_radar_helper.h"
31 #include "hichain_connector_callback.h"
32 #include "multiple_user_connector.h"
33 #include "json_object.h"
34 #include "parameter.h"
35 #include "unistd.h"
36 
37 namespace OHOS {
38 namespace DistributedHardware {
39 const int32_t PIN_CODE_NETWORK = 0;
40 const int32_t CREDENTIAL_NETWORK = 1;
41 const int32_t DELAY_TIME_MS = 10000; // 10ms
42 const int32_t FIELD_EXPIRE_TIME_VALUE = 7;
43 const int32_t SAME_ACCOUNT = 1;
44 const int32_t DEVICE_ID_HALF = 2;
45 
46 constexpr const char* DEVICE_ID = "DEVICE_ID";
47 constexpr const char* FIELD_CREDENTIAL = "credential";
48 constexpr const char* ADD_HICHAIN_GROUP_SUCCESS = "ADD_HICHAIN_GROUP_SUCCESS";
49 constexpr const char* ADD_HICHAIN_GROUP_FAILED = "ADD_HICHAIN_GROUP_FAILED";
50 constexpr const char* DM_CREATE_GROUP_SUCCESS = "DM_CREATE_GROUP_SUCCESS";
51 constexpr const char* DM_CREATE_GROUP_FAILED = "DM_CREATE_GROUP_FAILED";
52 constexpr const char* ADD_HICHAIN_GROUP_SUCCESS_MSG = "dm add member to group success.";
53 constexpr const char* ADD_HICHAIN_GROUP_FAILED_MSG = "dm add member to group failed.";
54 constexpr const char* DM_CREATE_GROUP_SUCCESS_MSG = "dm create group success.";
55 constexpr const char* DM_CREATE_GROUP_FAILED_MSG = "dm create group failed.";
56 constexpr const char* DM_PKG_NAME_EXT = "com.huawei.devicemanager";
57 constexpr const char* FIELD_OPERATION_CODE = "operationCode";
58 constexpr const char* FIELD_META_NODE_TYPE = "metaNodeType";
59 constexpr const char* FIELD_TYPE = "TType";
60 
61 static const std::unordered_map<int32_t, AuthFormPriority> g_authFormPriorityMap = {
62     {GROUP_TYPE_IDENTICAL_ACCOUNT_GROUP, AuthFormPriority::PRIORITY_IDENTICAL_ACCOUNT},
63     {GROUP_TYPE_ACROSS_ACCOUNT_GROUP, AuthFormPriority::PRIORITY_ACROSS_ACCOUNT},
64     {GROUP_TYPE_PEER_TO_PEER_GROUP, AuthFormPriority::PRIORITY_PEER_TO_PEER}
65 };
66 
FromJson(const JsonItemObject & jsonObject,GroupInfo & groupInfo)67 void FromJson(const JsonItemObject &jsonObject, GroupInfo &groupInfo)
68 {
69     if (jsonObject.Contains(FIELD_GROUP_NAME) && jsonObject.At(FIELD_GROUP_NAME).IsString()) {
70         groupInfo.groupName = jsonObject.At(FIELD_GROUP_NAME).Get<std::string>();
71     }
72 
73     if (jsonObject.Contains(FIELD_GROUP_ID) && jsonObject.At(FIELD_GROUP_ID).IsString()) {
74         groupInfo.groupId = jsonObject.At(FIELD_GROUP_ID).Get<std::string>();
75     }
76 
77     if (jsonObject.Contains(FIELD_GROUP_OWNER) && jsonObject.At(FIELD_GROUP_OWNER).IsString()) {
78         groupInfo.groupOwner = jsonObject.At(FIELD_GROUP_OWNER).Get<std::string>();
79     }
80 
81     if (jsonObject.Contains(FIELD_GROUP_TYPE) && jsonObject.At(FIELD_GROUP_TYPE).IsNumberInteger()) {
82         groupInfo.groupType = jsonObject.At(FIELD_GROUP_TYPE).Get<int32_t>();
83     }
84 
85     if (jsonObject.Contains(FIELD_GROUP_VISIBILITY) &&
86         jsonObject.At(FIELD_GROUP_VISIBILITY).IsNumberInteger()) {
87         groupInfo.groupVisibility = jsonObject.At(FIELD_GROUP_VISIBILITY).Get<int32_t>();
88     }
89 
90     if (jsonObject.Contains(FIELD_USER_ID) && jsonObject.At(FIELD_USER_ID).IsString()) {
91         groupInfo.userId = jsonObject.At(FIELD_USER_ID).Get<std::string>();
92     }
93 }
94 
95 std::shared_ptr<IHiChainConnectorCallback> HiChainConnector::hiChainConnectorCallback_ = nullptr;
96 std::shared_ptr<IDmGroupResCallback> HiChainConnector::hiChainResCallback_ = nullptr;
97 int32_t HiChainConnector::networkStyle_ = PIN_CODE_NETWORK;
98 bool g_createGroupFlag = false;
99 bool g_deleteGroupFlag = false;
100 bool g_groupIsRedundance = false;
101 
HiChainConnector()102 HiChainConnector::HiChainConnector()
103 {
104     LOGI("HiChainConnector::constructor");
105     deviceAuthCallback_ = {.onTransmit = nullptr,
106                            .onSessionKeyReturned = nullptr,
107                            .onFinish = HiChainConnector::onFinish,
108                            .onError = HiChainConnector::onError,
109                            .onRequest = HiChainConnector::onRequest};
110     deviceGroupManager_ = GetGmInstance();
111     if (deviceGroupManager_ == nullptr) {
112         LOGE("[HICHAIN]failed to init group manager.");
113         return;
114     }
115     int32_t ret = deviceGroupManager_->regCallback(DM_PKG_NAME, &deviceAuthCallback_);
116     if (ret != HC_SUCCESS) {
117         LOGE("[HICHAIN]fail to register callback to hachain with ret:%{public}d.", ret);
118         return;
119     }
120     LOGI("HiChainConnector::constructor success.");
121 }
122 
~HiChainConnector()123 HiChainConnector::~HiChainConnector()
124 {
125     LOGI("HiChainConnector::destructor.");
126 }
127 
RegisterHiChainCallback(std::shared_ptr<IHiChainConnectorCallback> callback)128 int32_t HiChainConnector::RegisterHiChainCallback(std::shared_ptr<IHiChainConnectorCallback> callback)
129 {
130     hiChainConnectorCallback_ = callback;
131     return DM_OK;
132 }
133 
UnRegisterHiChainCallback()134 int32_t HiChainConnector::UnRegisterHiChainCallback()
135 {
136     hiChainConnectorCallback_ = nullptr;
137     return DM_OK;
138 }
139 
CreateGroup(int64_t requestId,const std::string & groupName)140 int32_t HiChainConnector::CreateGroup(int64_t requestId, const std::string &groupName)
141 {
142     if (deviceGroupManager_ == nullptr) {
143         LOGE("HiChainConnector::CreateGroup group manager is null, requestId %{public}" PRId64, requestId);
144         return ERR_DM_INPUT_PARA_INVALID;
145     }
146     networkStyle_ = PIN_CODE_NETWORK;
147     GroupInfo groupInfo;
148     if (IsGroupCreated(groupName, groupInfo)) {
149         DeleteGroup(groupInfo.groupId);
150     }
151     LOGI("HiChainConnector::CreateGroup requestId %{public}" PRId64, requestId);
152     char localDeviceId[DEVICE_UUID_LENGTH] = {0};
153     GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
154     std::string sLocalDeviceId = localDeviceId;
155     JsonObject jsonObj;
156     jsonObj[FIELD_GROUP_TYPE] = GROUP_TYPE_PEER_TO_PEER_GROUP;
157     jsonObj[FIELD_DEVICE_ID] = sLocalDeviceId;
158     jsonObj[FIELD_GROUP_NAME] = groupName;
159     jsonObj[FIELD_USER_TYPE] = 0;
160     jsonObj[FIELD_GROUP_VISIBILITY] = GROUP_VISIBILITY_PUBLIC;
161     jsonObj[FIELD_EXPIRE_TIME] = FIELD_EXPIRE_TIME_VALUE;
162     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
163     if (userId < 0) {
164         LOGE("get current process account user id failed");
165         return ERR_DM_FAILED;
166     }
167     int32_t ret = deviceGroupManager_->createGroup(userId, requestId, DM_PKG_NAME, jsonObj.Dump().c_str());
168     struct RadarInfo info = {
169         .funcName = "CreateGroup",
170         .toCallPkg = HICHAINNAME,
171         .stageRes = (ret != 0) ?
172             static_cast<int32_t>(StageRes::STAGE_FAIL) : static_cast<int32_t>(StageRes::STAGE_IDLE),
173         .bizState = (ret != 0) ?
174             static_cast<int32_t>(BizState::BIZ_STATE_END) : static_cast<int32_t>(BizState::BIZ_STATE_START),
175         .errCode = DmRadarHelper::GetInstance().GetErrCode(ERR_DM_CREATE_GROUP_FAILED),
176     };
177     if (!DmRadarHelper::GetInstance().ReportAuthCreateGroup(info)) {
178         LOGE("ReportAuthCreateGroup failed");
179     }
180     if (ret != 0) {
181         LOGE("[HICHAIN]fail to create group with ret:%{public}d, requestId:%{public}" PRId64, ret, requestId);
182         return ERR_DM_CREATE_GROUP_FAILED;
183     }
184     return DM_OK;
185 }
186 
IsGroupCreated(std::string groupName,GroupInfo & groupInfo)187 bool HiChainConnector::IsGroupCreated(std::string groupName, GroupInfo &groupInfo)
188 {
189     JsonObject jsonObj;
190     jsonObj[FIELD_GROUP_NAME] = groupName.c_str();
191     std::string queryParams = jsonObj.Dump();
192     std::vector<GroupInfo> groupList;
193     if (GetGroupInfo(queryParams, groupList)) {
194         groupInfo = groupList[0];
195         return true;
196     }
197     return false;
198 }
199 
IsRedundanceGroup(const std::string & userId,int32_t authType,std::vector<GroupInfo> & groupList)200 bool HiChainConnector::IsRedundanceGroup(const std::string &userId, int32_t authType, std::vector<GroupInfo> &groupList)
201 {
202     JsonObject jsonObj;
203     jsonObj[FIELD_GROUP_TYPE] = authType;
204     std::string queryParams = jsonObj.Dump();
205 
206     int32_t osAccountUserId = MultipleUserConnector::GetCurrentAccountUserID();
207     if (osAccountUserId < 0) {
208         LOGE("get current process account user id failed");
209         return ERR_DM_FAILED;
210     }
211     if (!GetGroupInfo(osAccountUserId, queryParams, groupList)) {
212         return false;
213     }
214     for (auto iter = groupList.begin(); iter != groupList.end(); iter++) {
215         if (iter->userId != userId) {
216             return true;
217         }
218     }
219     return false;
220 }
221 
GetGroupInfo(const std::string & queryParams,std::vector<GroupInfo> & groupList)222 bool HiChainConnector::GetGroupInfo(const std::string &queryParams, std::vector<GroupInfo> &groupList)
223 {
224     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
225     if (userId < 0) {
226         LOGE("get current process account user id failed");
227         return false;
228     }
229     return GetGroupInfo(userId, queryParams, groupList);
230 }
231 
GetGroupInfo(const int32_t userId,const std::string & queryParams,std::vector<GroupInfo> & groupList)232 bool HiChainConnector::GetGroupInfo(const int32_t userId, const std::string &queryParams,
233     std::vector<GroupInfo> &groupList)
234 {
235     return GetGroupInfoCommon(userId, queryParams, DM_PKG_NAME, groupList);
236 }
237 
GetGroupInfoExt(const int32_t userId,const std::string & queryParams,std::vector<GroupInfo> & groupList)238 bool HiChainConnector::GetGroupInfoExt(const int32_t userId, const std::string &queryParams,
239     std::vector<GroupInfo> &groupList)
240 {
241     return GetGroupInfoCommon(userId, queryParams, DM_PKG_NAME_EXT, groupList);
242 }
243 
GetGroupInfoCommon(const int32_t userId,const std::string & queryParams,const char * pkgName,std::vector<GroupInfo> & groupList)244 bool HiChainConnector::GetGroupInfoCommon(const int32_t userId, const std::string &queryParams, const char* pkgName,
245     std::vector<GroupInfo> &groupList)
246 {
247     char *groupVec = nullptr;
248     uint32_t num = 0;
249     if (deviceGroupManager_ == nullptr) {
250         LOGE("deviceGroupManager_ is null");
251         return false;
252     }
253     int32_t ret = deviceGroupManager_->getGroupInfo(userId, pkgName, queryParams.c_str(), &groupVec, &num);
254     if (ret != 0) {
255         LOGE("[HICHAIN]fail to get group info with ret:%{public}d.", ret);
256         deviceGroupManager_->destroyInfo(&groupVec);
257         return false;
258     }
259     if (groupVec == nullptr) {
260         LOGE("[HICHAIN]return groups info point is nullptr");
261         return false;
262     }
263     if (num == 0) {
264         LOGE("[HICHAIN]return groups info number is zero.");
265         deviceGroupManager_->destroyInfo(&groupVec);
266         return false;
267     }
268     LOGI("HiChainConnector::GetGroupInfo groupNum(%{public}u)", num);
269     std::string relatedGroups = std::string(groupVec);
270     deviceGroupManager_->destroyInfo(&groupVec);
271     JsonObject jsonObject(relatedGroups);
272     if (jsonObject.IsDiscarded()) {
273         LOGE("returnGroups parse error");
274         return false;
275     }
276     if (!jsonObject.IsArray()) {
277         LOGE("json string is not array.");
278         return false;
279     }
280     std::vector<GroupInfo> groupInfos;
281     jsonObject.Get(groupInfos);
282     if (groupInfos.empty()) {
283         LOGE("HiChainConnector::GetGroupInfo group failed, groupInfos is empty.");
284         return false;
285     }
286     groupList = groupInfos;
287     return true;
288 }
289 
GetGroupType(const std::string & deviceId)290 DmAuthForm HiChainConnector::GetGroupType(const std::string &deviceId)
291 {
292     std::vector<OHOS::DistributedHardware::GroupInfo> groupList;
293     int32_t ret = GetRelatedGroups(deviceId, groupList);
294     if (ret != DM_OK) {
295         LOGE("HiChainConnector::GetGroupType get related groups failed");
296         return DmAuthForm::INVALID_TYPE;
297     }
298 
299     if (groupList.size() == 0) {
300         LOGE("HiChainConnector::GetGroupType group list is empty");
301         return DmAuthForm::INVALID_TYPE;
302     }
303 
304     AuthFormPriority highestPriority = AuthFormPriority::PRIORITY_PEER_TO_PEER;
305     for (auto it = groupList.begin(); it != groupList.end(); ++it) {
306         if (g_authFormPriorityMap.count(it->groupType) == 0) {
307             LOGE("HiChainConnector::GetGroupType unsupported auth form");
308             return DmAuthForm::INVALID_TYPE;
309         }
310         AuthFormPriority priority = g_authFormPriorityMap.at(it->groupType);
311         if (priority > highestPriority) {
312             highestPriority = priority;
313         }
314     }
315 
316     if (highestPriority == AuthFormPriority::PRIORITY_IDENTICAL_ACCOUNT) {
317         return DmAuthForm::IDENTICAL_ACCOUNT;
318     } else if (highestPriority == AuthFormPriority::PRIORITY_ACROSS_ACCOUNT) {
319         return DmAuthForm::ACROSS_ACCOUNT;
320     } else if (highestPriority == AuthFormPriority::PRIORITY_PEER_TO_PEER) {
321         return DmAuthForm::PEER_TO_PEER;
322     }
323 
324     return DmAuthForm::INVALID_TYPE;
325 }
326 
AddMember(const std::string & deviceId,const std::string & connectInfo)327 int32_t HiChainConnector::AddMember(const std::string &deviceId, const std::string &connectInfo)
328 {
329     LOGI("HiChainConnector::AddMember");
330     if (deviceGroupManager_ == nullptr) {
331         LOGI("HiChainConnector::AddMember group manager is null.");
332         return ERR_DM_POINT_NULL;
333     }
334     JsonObject jsonObject(connectInfo);
335     if (jsonObject.IsDiscarded()) {
336         LOGE("DecodeRequestAuth jsonStr error");
337         return ERR_DM_FAILED;
338     }
339     if (!IsString(jsonObject, TAG_DEVICE_ID) || !IsString(jsonObject, PIN_CODE_KEY) ||
340         !IsString(jsonObject, TAG_GROUP_ID) || !IsInt64(jsonObject, TAG_REQUEST_ID) ||
341         !IsString(jsonObject, TAG_GROUP_NAME)) {
342         LOGE("HiChainConnector::AddMember err json string.");
343         return ERR_DM_FAILED;
344     }
345     char localDeviceId[DEVICE_UUID_LENGTH] = {0};
346     GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
347     std::string connectInfomation = GetConnectPara(deviceId, jsonObject[TAG_DEVICE_ID].Get<std::string>());
348 
349     std::string pinCode = jsonObject[PIN_CODE_KEY].Get<std::string>();
350     std::string groupId = jsonObject[TAG_GROUP_ID].Get<std::string>();
351     std::string pinCodeHash = GetAnonyString(Crypto::Sha256(pinCode));
352     LOGI("AddMember pinCodeHash: %{public}s", pinCodeHash.c_str());
353     JsonObject jsonObj;
354     jsonObj[FIELD_GROUP_ID] = groupId;
355     jsonObj[FIELD_GROUP_TYPE] = GROUP_TYPE_PEER_TO_PEER_GROUP;
356     jsonObj[FIELD_PIN_CODE] = pinCode;
357     jsonObj[FIELD_IS_ADMIN] = false;
358     jsonObj[FIELD_DEVICE_ID] = localDeviceId;
359     jsonObj[FIELD_GROUP_NAME] = jsonObject[TAG_GROUP_NAME].Get<std::string>();
360     jsonObj[FIELD_CONNECT_PARAMS] = connectInfomation.c_str();
361     std::string tmpStr = jsonObj.Dump();
362     int64_t requestId = jsonObject[TAG_REQUEST_ID].Get<int64_t>();
363     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
364     if (userId < 0) {
365         LOGE("get current process account user id failed");
366         return ERR_DM_FAILED;
367     }
368     int32_t ret = deviceGroupManager_->addMemberToGroup(userId, requestId, DM_PKG_NAME, tmpStr.c_str());
369     if (ret != 0) {
370         LOGE("[HICHAIN]fail to add number to hichain group with ret:%{public}d.", ret);
371     }
372     LOGI("HiChainConnector::AddMember completed");
373     return ret;
374 }
375 
onFinish(int64_t requestId,int operationCode,const char * returnData)376 void HiChainConnector::onFinish(int64_t requestId, int operationCode, const char *returnData)
377 {
378     std::string data = (returnData != nullptr) ? std::string(returnData) : "";
379     LOGI("HiChainConnector::onFinish reqId:%{public}" PRId64 ", operation:%{public}d", requestId, operationCode);
380     if (operationCode == GroupOperationCode::MEMBER_JOIN) {
381         LOGI("Add Member To Group success");
382         if (!DmRadarHelper::GetInstance().ReportAuthAddGroupCb(
383             "onFinish", static_cast<int32_t>(StageRes::STAGE_SUCC))) {
384             LOGE("ReportAuthAddGroupCb failed");
385         }
386         SysEventWrite(std::string(ADD_HICHAIN_GROUP_SUCCESS), DM_HISYEVENT_BEHAVIOR,
387             std::string(ADD_HICHAIN_GROUP_SUCCESS_MSG));
388         if (hiChainConnectorCallback_ != nullptr) {
389             hiChainConnectorCallback_->OnMemberJoin(requestId, DM_OK, operationCode);
390         }
391     }
392     if (operationCode == GroupOperationCode::GROUP_CREATE) {
393         LOGI("Create group success");
394         if (!DmRadarHelper::GetInstance().ReportAuthCreateGroupCb(
395             "onFinish", static_cast<int32_t>(StageRes::STAGE_SUCC))) {
396             LOGE("ReportAuthCreateGroupCb failed");
397         }
398         SysEventWrite(std::string(DM_CREATE_GROUP_SUCCESS), DM_HISYEVENT_BEHAVIOR,
399             std::string(DM_CREATE_GROUP_SUCCESS_MSG));
400         if (networkStyle_ == CREDENTIAL_NETWORK) {
401             if (hiChainResCallback_ != nullptr) {
402                 int32_t importAction = 0;
403                 hiChainResCallback_->OnGroupResult(requestId, importAction, data);
404                 g_createGroupFlag = true;
405             }
406         } else {
407             if (hiChainConnectorCallback_ != nullptr) {
408                 hiChainConnectorCallback_->OnMemberJoin(requestId, DM_OK, operationCode);
409                 hiChainConnectorCallback_->OnGroupCreated(requestId, data);
410             }
411         }
412     }
413     if (operationCode == GroupOperationCode::MEMBER_DELETE) {
414         LOGI("Delete Member from group success");
415     }
416     if (operationCode == GroupOperationCode::GROUP_DISBAND) {
417         if (networkStyle_ == CREDENTIAL_NETWORK && hiChainResCallback_ != nullptr) {
418             if (!g_groupIsRedundance) {
419                 int32_t deleteAction = 1;
420                 hiChainResCallback_->OnGroupResult(requestId, deleteAction, data);
421             }
422             g_deleteGroupFlag = true;
423         }
424         LOGI("Disband group success");
425     }
426 }
427 
onError(int64_t requestId,int operationCode,int errorCode,const char * errorReturn)428 void HiChainConnector::onError(int64_t requestId, int operationCode, int errorCode, const char *errorReturn)
429 {
430     std::string data = (errorReturn != nullptr) ? std::string(errorReturn) : "";
431     LOGI("HichainAuthenCallBack::onError reqId:%{public}" PRId64 ", operation:%{public}d, errorCode:%{public}d.",
432         requestId, operationCode, errorCode);
433     if (operationCode == GroupOperationCode::MEMBER_JOIN) {
434         LOGE("Add Member To Group failed");
435         if (!DmRadarHelper::GetInstance().ReportAuthAddGroupCb(
436             "onError", static_cast<int32_t>(StageRes::STAGE_FAIL))) {
437             LOGE("ReportAuthAddGroupCb failed");
438         }
439         SysEventWrite(std::string(ADD_HICHAIN_GROUP_FAILED), DM_HISYEVENT_BEHAVIOR,
440             std::string(ADD_HICHAIN_GROUP_FAILED_MSG));
441         if (hiChainConnectorCallback_ != nullptr) {
442             hiChainConnectorCallback_->OnMemberJoin(requestId, ERR_DM_ADD_GROUP_FAILED, operationCode);
443         }
444     }
445     if (operationCode == GroupOperationCode::GROUP_CREATE) {
446         LOGE("Create group failed");
447         if (!DmRadarHelper::GetInstance().ReportAuthCreateGroupCb(
448             "onError", static_cast<int32_t>(StageRes::STAGE_FAIL))) {
449             LOGE("ReportAuthCreateGroupCb failed");
450         }
451         SysEventWrite(std::string(DM_CREATE_GROUP_FAILED), DM_HISYEVENT_BEHAVIOR,
452             std::string(DM_CREATE_GROUP_FAILED_MSG));
453         if (networkStyle_ == CREDENTIAL_NETWORK) {
454             if (hiChainResCallback_ != nullptr) {
455                 int32_t importAction = 0;
456                 hiChainResCallback_->OnGroupResult(requestId, importAction, data);
457                 g_createGroupFlag = true;
458             }
459         } else {
460             if (hiChainConnectorCallback_ != nullptr) {
461                 hiChainConnectorCallback_->OnGroupCreated(requestId, "{}");
462             }
463         }
464     }
465     if (operationCode == GroupOperationCode::MEMBER_DELETE) {
466         LOGE("Delete Member from group failed");
467     }
468     if (operationCode == GroupOperationCode::GROUP_DISBAND) {
469         if (networkStyle_ == CREDENTIAL_NETWORK && hiChainResCallback_ != nullptr) {
470             if (!g_groupIsRedundance) {
471                 int32_t deleteAction = 1;
472                 hiChainResCallback_->OnGroupResult(requestId, deleteAction, data);
473             }
474             g_deleteGroupFlag = true;
475         }
476         LOGE("Disband group failed");
477     }
478 }
479 
onRequest(int64_t requestId,int operationCode,const char * reqParams)480 char *HiChainConnector::onRequest(int64_t requestId, int operationCode, const char *reqParams)
481 {
482     (void)requestId;
483     (void)reqParams;
484     if (operationCode != GroupOperationCode::MEMBER_JOIN) {
485         LOGE("HiChainConnector::onRequest operationCode %{public}d", operationCode);
486         return nullptr;
487     }
488     if (hiChainConnectorCallback_ == nullptr) {
489         LOGE("HiChainConnector::onRequest hiChainConnectorCallback_ is nullptr.");
490         return nullptr;
491     }
492     JsonObject jsonObj;
493     std::string pinCode = "";
494     if (hiChainConnectorCallback_->GetPinCode(pinCode) == ERR_DM_FAILED || pinCode == "") {
495         jsonObj[FIELD_CONFIRMATION] = REQUEST_REJECTED;
496     } else {
497         jsonObj[FIELD_CONFIRMATION] = REQUEST_ACCEPTED;
498         jsonObj[FIELD_PIN_CODE] = pinCode;
499     }
500     char localDeviceId[DEVICE_UUID_LENGTH] = {0};
501     GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
502     jsonObj[FIELD_DEVICE_ID] = localDeviceId;
503 
504     std::string jsonStr = jsonObj.Dump();
505     char *buffer = strdup(jsonStr.c_str());
506     return buffer;
507 }
508 
GenRequestId()509 int64_t HiChainConnector::GenRequestId()
510 {
511     return GenRandLongLong(MIN_REQUEST_ID, MAX_REQUEST_ID);
512 }
513 
GetConnectPara(std::string deviceId,std::string reqDeviceId)514 std::string HiChainConnector::GetConnectPara(std::string deviceId, std::string reqDeviceId)
515 {
516     LOGI("HiChainConnector::GetConnectPara get addrInfo");
517     if (hiChainConnectorCallback_ == nullptr) {
518         LOGE("HiChainConnector::GetConnectPara hiChainConnectorCallback_ is nullptr.");
519         return "";
520     }
521     std::string connectAddr = hiChainConnectorCallback_->GetConnectAddr(deviceId);
522     JsonObject jsonObject(connectAddr);
523     if (jsonObject.IsDiscarded()) {
524         LOGE("DecodeRequestAuth jsonStr error");
525         return connectAddr;
526     }
527     jsonObject[DEVICE_ID] = reqDeviceId;
528 
529     return jsonObject.Dump();
530 }
531 
GetRelatedGroups(const std::string & deviceId,std::vector<GroupInfo> & groupList)532 int32_t HiChainConnector::GetRelatedGroups(const std::string &deviceId, std::vector<GroupInfo> &groupList)
533 {
534     return GetRelatedGroupsCommon(deviceId, DM_PKG_NAME, groupList);
535 }
536 
GetRelatedGroups(int32_t userId,const std::string & deviceId,std::vector<GroupInfo> & groupList)537 int32_t HiChainConnector::GetRelatedGroups(int32_t userId, const std::string &deviceId,
538     std::vector<GroupInfo> &groupList)
539 {
540     return GetRelatedGroupsCommon(userId, deviceId, DM_PKG_NAME, groupList);
541 }
542 
GetRelatedGroupsExt(const std::string & deviceId,std::vector<GroupInfo> & groupList)543 int32_t HiChainConnector::GetRelatedGroupsExt(const std::string &deviceId, std::vector<GroupInfo> &groupList)
544 {
545     return GetRelatedGroupsCommon(deviceId, DM_PKG_NAME_EXT, groupList);
546 }
547 
GetRelatedGroupsExt(int32_t userId,const std::string & deviceId,std::vector<GroupInfo> & groupList)548 int32_t HiChainConnector::GetRelatedGroupsExt(int32_t userId, const std::string &deviceId,
549     std::vector<GroupInfo> &groupList)
550 {
551     return GetRelatedGroupsCommon(userId, deviceId, DM_PKG_NAME_EXT, groupList);
552 }
553 
GetSyncGroupList(std::vector<GroupInfo> & groupList,std::vector<std::string> & syncGroupList)554 int32_t HiChainConnector::GetSyncGroupList(std::vector<GroupInfo> &groupList, std::vector<std::string> &syncGroupList)
555 {
556     if (groupList.empty()) {
557         LOGE("groupList is empty.");
558         return ERR_DM_FAILED;
559     }
560     for (auto group : groupList) {
561         if (IsGroupInfoInvalid(group)) {
562             continue;
563         }
564         syncGroupList.push_back(group.groupId);
565     }
566     return DM_OK;
567 }
568 
IsDevicesInP2PGroup(const std::string & hostDevice,const std::string & peerDevice)569 bool HiChainConnector::IsDevicesInP2PGroup(const std::string &hostDevice, const std::string &peerDevice)
570 {
571     LOGI("HiChainConnector::IsDevicesInP2PGroup");
572     if (hostDevice == peerDevice || peerDevice == "" || hostDevice == "") {
573         LOGE("invalid param");
574         return false;
575     }
576     std::vector<GroupInfo> hostGroupInfoList;
577     GetRelatedGroups(hostDevice, hostGroupInfoList);
578     std::vector<GroupInfo> peerGroupInfoList;
579     GetRelatedGroups(peerDevice, peerGroupInfoList);
580     for (const auto &hostGroupInfo : hostGroupInfoList) {
581         if (hostGroupInfo.groupType != GROUP_TYPE_PEER_TO_PEER_GROUP) {
582             continue;
583         }
584         for (const auto &peerGroupInfo : peerGroupInfoList) {
585             if (peerGroupInfo.groupType != GROUP_TYPE_PEER_TO_PEER_GROUP) {
586                 continue;
587             }
588             if (hostGroupInfo.groupId == peerGroupInfo.groupId && hostGroupInfo.groupName == peerGroupInfo.groupName) {
589                 LOGE("these are authenticated");
590                 return true;
591             }
592         }
593     }
594     return false;
595 }
596 
IsGroupInfoInvalid(GroupInfo & group)597 bool HiChainConnector::IsGroupInfoInvalid(GroupInfo &group)
598 {
599     if (group.groupType == GROUP_TYPE_IDENTICAL_ACCOUNT_GROUP || group.groupVisibility == GROUP_VISIBILITY_PUBLIC ||
600         group.groupOwner != std::string(DM_PKG_NAME)) {
601         return true;
602     }
603     return false;
604 }
605 
SyncGroups(std::string deviceId,std::vector<std::string> & remoteGroupIdList)606 int32_t HiChainConnector::SyncGroups(std::string deviceId, std::vector<std::string> &remoteGroupIdList)
607 {
608     std::vector<GroupInfo> groupInfoList;
609     GetRelatedGroups(deviceId, groupInfoList);
610     for (auto &groupInfo : groupInfoList) {
611         if (IsGroupInfoInvalid(groupInfo)) {
612             continue;
613         }
614         auto iter = std::find(remoteGroupIdList.begin(), remoteGroupIdList.end(), groupInfo.groupId);
615         if (iter == remoteGroupIdList.end()) {
616             (void)DelMemberFromGroup(groupInfo.groupId, deviceId);
617         }
618     }
619     return DM_OK;
620 }
621 
DelMemberFromGroup(const std::string & groupId,const std::string & deviceId)622 int32_t HiChainConnector::DelMemberFromGroup(const std::string &groupId, const std::string &deviceId)
623 {
624     int64_t requestId = GenRequestId();
625     LOGI("Start to delete member from group, requestId %{public}" PRId64", deviceId %{public}s, groupId %{public}s",
626         requestId, GetAnonyString(deviceId).c_str(), GetAnonyString(groupId).c_str());
627     JsonObject jsonObj;
628     jsonObj[FIELD_GROUP_ID] = groupId;
629     jsonObj[FIELD_DELETE_ID] = deviceId;
630     std::string deleteParams = jsonObj.Dump();
631     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
632     if (userId < 0) {
633         LOGE("get current process account user id failed");
634         return ERR_DM_FAILED;
635     }
636     int32_t ret = deviceGroupManager_->deleteMemberFromGroup(userId, requestId, DM_PKG_NAME, deleteParams.c_str());
637     if (ret != 0) {
638         LOGE("[HICHAIN]fail to delete member from group with ret:%{public}d.", ret);
639         return ret;
640     }
641     return DM_OK;
642 }
643 
DeleteGroup(std::string & groupId)644 int32_t HiChainConnector::DeleteGroup(std::string &groupId)
645 {
646     int64_t requestId = GenRequestId();
647     JsonObject jsonObj;
648     jsonObj[FIELD_GROUP_ID] = groupId;
649     std::string disbandParams = jsonObj.Dump();
650     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
651     if (userId < 0) {
652         LOGE("get current process account user id failed");
653         return ERR_DM_FAILED;
654     }
655 
656     int32_t ret = deviceGroupManager_->deleteGroup(userId, requestId, DM_PKG_NAME, disbandParams.c_str());
657     if (ret != 0) {
658         LOGE("[HICHAIN]fail to delete group with ret:%{public}d.", ret);
659         return ERR_DM_FAILED;
660     }
661     return DM_OK;
662 }
663 
DeleteGroupExt(std::string & groupId)664 int32_t HiChainConnector::DeleteGroupExt(std::string &groupId)
665 {
666     int64_t requestId = GenRequestId();
667     JsonObject jsonObj;
668     jsonObj[FIELD_GROUP_ID] = groupId;
669     std::string disbandParams = jsonObj.Dump();
670     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
671     if (userId < 0) {
672         LOGE("get current process account user id failed");
673         return ERR_DM_FAILED;
674     }
675 
676     int32_t ret = deviceGroupManager_->deleteGroup(userId, requestId, DM_PKG_NAME_EXT, disbandParams.c_str());
677     if (ret != 0) {
678         LOGE("[HICHAIN]fail to delete group with ret:%{public}d.", ret);
679         return ERR_DM_FAILED;
680     }
681     return DM_OK;
682 }
683 
DeleteGroupExt(int32_t userId,std::string & groupId)684 int32_t HiChainConnector::DeleteGroupExt(int32_t userId, std::string &groupId)
685 {
686     int64_t requestId = GenRequestId();
687     JsonObject jsonObj;
688     jsonObj[FIELD_GROUP_ID] = groupId;
689     std::string disbandParams = jsonObj.Dump();
690     int32_t ret = deviceGroupManager_->deleteGroup(userId, requestId, DM_PKG_NAME_EXT, disbandParams.c_str());
691     if (ret != 0) {
692         LOGE("[HICHAIN]fail to delete group with ret:%{public}d.", ret);
693         return ERR_DM_FAILED;
694     }
695     return DM_OK;
696 }
697 
DeleteGroup(int64_t requestId_,const std::string & userId,const int32_t authType)698 int32_t HiChainConnector::DeleteGroup(int64_t requestId_, const std::string &userId, const int32_t authType)
699 {
700     networkStyle_ = CREDENTIAL_NETWORK;
701     JsonObject jsonObj;
702     jsonObj[FIELD_GROUP_TYPE] = authType;
703     std::string queryParams = jsonObj.Dump();
704     std::vector<GroupInfo> groupList;
705     if (!GetGroupInfo(queryParams, groupList)) {
706         LOGE("failed to get device join groups");
707         return ERR_DM_FAILED;
708     }
709     LOGI("HiChainConnector::DeleteGroup groupList count = %{public}zu", groupList.size());
710     bool userIsExist = false;
711     std::string groupId = "";
712     for (auto iter = groupList.begin(); iter != groupList.end(); iter++) {
713         if (iter->userId == userId) {
714             userIsExist = true;
715             groupId = iter->groupId;
716             break;
717         }
718     }
719     if (!userIsExist) {
720         LOGE("input userId is exist in groupList!");
721         return ERR_DM_FAILED;
722     }
723     jsonObj[FIELD_GROUP_ID] = groupId;
724     std::string disbandParams = jsonObj.Dump();
725     g_deleteGroupFlag = false;
726     int32_t osAccountUserId = MultipleUserConnector::GetCurrentAccountUserID();
727     if (osAccountUserId < 0) {
728         LOGE("get current process account user id failed");
729         return ERR_DM_FAILED;
730     }
731     int32_t ret = deviceGroupManager_->deleteGroup(osAccountUserId, requestId_, DM_PKG_NAME,
732         disbandParams.c_str());
733     if (ret != 0) {
734         LOGE("[HICHAIN]fail to delete hichain group with ret:%{public}d.", ret);
735         return ERR_DM_FAILED;
736     }
737     int32_t nTickTimes = 0;
738     while (!g_deleteGroupFlag) {
739         usleep(DELAY_TIME_MS);
740         if (++nTickTimes > SERVICE_INIT_TRY_MAX_NUM) {
741             LOGE("failed to delete group because timeout!");
742             return ERR_DM_FAILED;
743         }
744     }
745     return DM_OK;
746 }
747 
DeleteTimeOutGroup(const char * deviceId)748 int32_t HiChainConnector::DeleteTimeOutGroup(const char* deviceId)
749 {
750     LOGI("HiChainConnector::DeleteTimeOutGroup start");
751     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
752     if (userId < 0) {
753         LOGE("get current process account user id failed");
754         return ERR_DM_FAILED;
755     }
756     std::vector<GroupInfo> peerGroupInfoList;
757     GetRelatedGroups(deviceId, peerGroupInfoList);
758     char localDeviceId[DEVICE_UUID_LENGTH] = {0};
759     GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
760     for (auto &group : peerGroupInfoList) {
761         if (!(deviceGroupManager_->isDeviceInGroup(userId, DM_PKG_NAME, group.groupId.c_str(), localDeviceId))) {
762             continue;
763         }
764         if ((!group.groupName.empty()) && (group.groupName[CHECK_AUTH_ALWAYS_POS] == AUTH_ALWAYS)) {
765             LOGI("HiChainConnector::DeleteTimeOutGroup always trusted group");
766             continue;
767         }
768         if (group.groupType == GROUP_TYPE_PEER_TO_PEER_GROUP) {
769             DeleteGroup(group.groupId);
770         }
771     }
772     return DM_OK;
773 }
774 
DeleteRedundanceGroup(std::string & userId)775 void HiChainConnector::DeleteRedundanceGroup(std::string &userId)
776 {
777     int32_t nTickTimes = 0;
778     g_deleteGroupFlag = false;
779     DeleteGroup(userId);
780     while (!g_deleteGroupFlag) {
781         usleep(DELAY_TIME_MS);
782         if (++nTickTimes > SERVICE_INIT_TRY_MAX_NUM) {
783             LOGE("failed to delete group because timeout!");
784             return;
785         }
786     }
787 }
788 
DealRedundanceGroup(const std::string & userId,int32_t authType)789 void HiChainConnector::DealRedundanceGroup(const std::string &userId, int32_t authType)
790 {
791     g_groupIsRedundance = false;
792     std::vector<GroupInfo> groupList;
793     if (IsRedundanceGroup(userId, authType, groupList)) {
794         LOGI("HiChainConnector::CreateGroup IsRedundanceGroup");
795         g_groupIsRedundance = true;
796         for (auto iter = groupList.begin(); iter != groupList.end(); iter++) {
797             if (iter->userId != userId) {
798                 DeleteRedundanceGroup(iter->userId);
799             }
800         }
801         g_groupIsRedundance = false;
802     }
803 }
804 
CreateGroup(int64_t requestId,int32_t authType,const std::string & userId,JsonObject & jsonOutObj)805 int32_t HiChainConnector::CreateGroup(int64_t requestId, int32_t authType, const std::string &userId,
806     JsonObject &jsonOutObj)
807 {
808     LOGI("HiChainConnector::CreateGroup start.");
809     if (deviceGroupManager_ == nullptr) {
810         LOGE("HiChainConnector::CreateGroup group manager is null, requestId %{public}" PRId64, requestId);
811         return ERR_DM_INPUT_PARA_INVALID;
812     }
813     DealRedundanceGroup(userId, authType);
814     networkStyle_ = CREDENTIAL_NETWORK;
815     LOGI("HiChainConnector::CreateGroup requestId %{public}" PRId64, requestId);
816     char localDeviceId[DEVICE_UUID_LENGTH] = {0};
817     GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
818     std::string sLocalDeviceId = localDeviceId;
819     JsonObject jsonObj;
820     jsonObj[FIELD_GROUP_TYPE] = authType;
821     jsonObj[FIELD_USER_ID] = userId;
822     jsonObj.Insert(FIELD_CREDENTIAL, jsonOutObj);
823     jsonObj[FIELD_DEVICE_ID] = sLocalDeviceId;
824     jsonObj[FIELD_USER_TYPE] = 0;
825     jsonObj[FIELD_GROUP_VISIBILITY] = GROUP_VISIBILITY_PUBLIC;
826     jsonObj[FIELD_EXPIRE_TIME] = FIELD_EXPIRE_TIME_VALUE;
827     g_createGroupFlag = false;
828     int32_t osAccountUserId = MultipleUserConnector::GetCurrentAccountUserID();
829     if (osAccountUserId < 0) {
830         LOGE("get current process account user id failed");
831         return ERR_DM_FAILED;
832     }
833     int32_t ret = deviceGroupManager_->createGroup(osAccountUserId, requestId, DM_PKG_NAME,
834         jsonObj.Dump().c_str());
835     if (ret != DM_OK) {
836         LOGE("[HICHAIN]fail to create group with ret:%{public}d, requestId:%{public}" PRId64, ret, requestId);
837         return ERR_DM_CREATE_GROUP_FAILED;
838     }
839     int32_t nTickTimes = 0;
840     while (!g_createGroupFlag) {
841         usleep(DELAY_TIME_MS);
842         if (++nTickTimes > SERVICE_INIT_TRY_MAX_NUM) {
843             LOGE("failed to create group because timeout!");
844             return ERR_DM_CREATE_GROUP_FAILED;
845         }
846     }
847     return DM_OK;
848 }
849 
RegisterHiChainGroupCallback(const std::shared_ptr<IDmGroupResCallback> & callback)850 int32_t HiChainConnector::RegisterHiChainGroupCallback(const std::shared_ptr<IDmGroupResCallback> &callback)
851 {
852     hiChainResCallback_ = callback;
853     return DM_OK;
854 }
855 
UnRegisterHiChainGroupCallback()856 int32_t HiChainConnector::UnRegisterHiChainGroupCallback()
857 {
858     hiChainResCallback_ = nullptr;
859     return DM_OK;
860 }
861 
getRegisterInfo(const std::string & queryParams,std::string & returnJsonStr)862 int32_t HiChainConnector::getRegisterInfo(const std::string &queryParams, std::string &returnJsonStr)
863 {
864     if (deviceGroupManager_ == nullptr) {
865         LOGE("HiChainConnector::deviceGroupManager_ is nullptr.");
866         return ERR_DM_INPUT_PARA_INVALID;
867     }
868     char *credentialInfo = nullptr;
869     if (deviceGroupManager_->getRegisterInfo(queryParams.c_str(), &credentialInfo) != DM_OK) {
870         LOGE("[HICHAIN]fail to request hichain registerinfo.");
871         deviceGroupManager_->destroyInfo(&credentialInfo);
872         return ERR_DM_FAILED;
873     }
874 
875     returnJsonStr = credentialInfo;
876     deviceGroupManager_->destroyInfo(&credentialInfo);
877     LOGI("request hichain device registerinfo successfully.");
878     return DM_OK;
879 }
880 
GetGroupId(const std::string & userId,const int32_t groupType,std::string & groupId)881 int32_t HiChainConnector::GetGroupId(const std::string &userId, const int32_t groupType, std::string &groupId)
882 {
883     JsonObject jsonObjGroup;
884     jsonObjGroup[FIELD_GROUP_TYPE] = groupType;
885     std::string queryParams = jsonObjGroup.Dump();
886     std::vector<GroupInfo> groupList;
887 
888     if (!GetGroupInfo(queryParams.c_str(), groupList)) {
889         LOGE("failed to get device join groups");
890         return ERR_DM_FAILED;
891     }
892     for (auto &groupinfo : groupList) {
893         LOGI("groupinfo.groupId:%{public}s", GetAnonyString(groupinfo.groupId).c_str());
894         if (groupinfo.userId == userId) {
895             groupId = groupinfo.groupId;
896             return DM_OK;
897         }
898     }
899     return ERR_DM_FAILED;
900 }
901 
ParseRemoteCredential(const int32_t groupType,const std::string & userId,const JsonObject & jsonDeviceList,std::string & params,int32_t & osAccountUserId)902 int32_t HiChainConnector::ParseRemoteCredential(const int32_t groupType, const std::string &userId,
903     const JsonObject &jsonDeviceList, std::string &params, int32_t &osAccountUserId)
904 {
905     if (userId.empty() || !jsonDeviceList.Contains(FIELD_DEVICE_LIST)) {
906         LOGE("userId or deviceList is empty");
907         return ERR_DM_INPUT_PARA_INVALID;
908     }
909     std::string groupId;
910     if (GetGroupId(userId, groupType, groupId) != DM_OK) {
911         LOGE("failed to get groupid");
912         return ERR_DM_FAILED;
913     }
914     JsonObject jsonObj;
915     jsonObj[FIELD_GROUP_ID] = groupId;
916     jsonObj[FIELD_GROUP_TYPE] = groupType;
917     std::string jsonStr = jsonDeviceList[FIELD_DEVICE_LIST].Dump();
918     JsonObject jsonArray(JsonCreateType::JSON_CREATE_TYPE_ARRAY);
919     jsonArray.Parse(jsonStr);
920     jsonObj.Insert(FIELD_DEVICE_LIST, jsonArray);
921     params = jsonObj.Dump();
922     osAccountUserId = MultipleUserConnector::GetCurrentAccountUserID();
923     if (osAccountUserId < 0) {
924         LOGE("get current process account user id failed");
925         return ERR_DM_FAILED;
926     }
927     return DM_OK;
928 }
929 
addMultiMembers(const int32_t groupType,const std::string & userId,const JsonObject & jsonDeviceList)930 int32_t HiChainConnector::addMultiMembers(const int32_t groupType, const std::string &userId,
931     const JsonObject &jsonDeviceList)
932 {
933     if (deviceGroupManager_ == nullptr) {
934         LOGE("HiChainConnector::deviceGroupManager_ is nullptr.");
935         return ERR_DM_INPUT_PARA_INVALID;
936     }
937     std::string addParams;
938     int32_t osAccountUserId = 0;
939     if (ParseRemoteCredential(groupType, userId, jsonDeviceList, addParams, osAccountUserId) != DM_OK) {
940         LOGE("addMultiMembers ParseRemoteCredential failed!");
941         return ERR_DM_FAILED;
942     }
943 
944     int32_t ret = deviceGroupManager_->addMultiMembersToGroup(osAccountUserId, DM_PKG_NAME, addParams.c_str());
945     if (ret != DM_OK) {
946         LOGE("[HICHAIN]fail to add member to hichain group with ret:%{public}d.", ret);
947         return ERR_DM_ADD_GROUP_FAILED;
948     }
949     return DM_OK;
950 }
951 
GetJsonStr(const JsonObject & jsonObj,const std::string & key)952 std::string HiChainConnector::GetJsonStr(const JsonObject &jsonObj, const std::string &key)
953 {
954     if (!IsString(jsonObj, key)) {
955         LOGE("User string key not exist!");
956         return "";
957     }
958     return jsonObj[key].Get<std::string>();
959 }
960 
GetJsonInt(const JsonObject & jsonObj,const std::string & key)961 int32_t HiChainConnector::GetJsonInt(const JsonObject &jsonObj, const std::string &key)
962 {
963     if (!IsInt32(jsonObj, key)) {
964         LOGE("User string key not exist!");
965         return ERR_DM_FAILED;
966     }
967     return jsonObj[key].Get<int32_t>();
968 }
969 
GetGroupIdExt(const std::string & userId,const int32_t groupType,std::string & groupId,std::string & groupOwner)970 int32_t HiChainConnector::GetGroupIdExt(const std::string &userId, const int32_t groupType,
971     std::string &groupId, std::string &groupOwner)
972 {
973     JsonObject jsonObjGroup;
974     jsonObjGroup[FIELD_GROUP_TYPE] = groupType;
975     std::string queryParams = jsonObjGroup.Dump();
976     std::vector<GroupInfo> groupList;
977 
978     if (!GetGroupInfo(queryParams.c_str(), groupList)) {
979         LOGE("failed to get device join groups");
980         return ERR_DM_FAILED;
981     }
982     for (auto &groupinfo : groupList) {
983         LOGI("groupinfo.groupId:%{public}s", GetAnonyString(groupinfo.groupId).c_str());
984         if (groupinfo.userId == userId) {
985             groupId = groupinfo.groupId;
986             groupOwner = groupinfo.groupOwner;
987             return DM_OK;
988         }
989     }
990     return ERR_DM_FAILED;
991 }
992 
ParseRemoteCredentialExt(const std::string & credentialInfo,std::string & params,std::string & groupOwner)993 int32_t HiChainConnector::ParseRemoteCredentialExt(const std::string &credentialInfo, std::string &params,
994     std::string &groupOwner)
995 {
996     LOGI("ParseRemoteCredentialExt start.");
997     JsonObject jsonObject(credentialInfo);
998     if (jsonObject.IsDiscarded()) {
999         LOGE("CredentialInfo string not a json type.");
1000         return ERR_DM_FAILED;
1001     }
1002     JsonObject jsonObj;
1003     int32_t groupType = 0;
1004     std::string userId = "";
1005     int32_t authType = GetJsonInt(jsonObject, AUTH_TYPE);
1006     if (authType == SAME_ACCOUNT) {
1007         groupType = IDENTICAL_ACCOUNT_GROUP;
1008         userId = GetJsonStr(jsonObject, FIELD_USER_ID);
1009     } else {
1010         LOGE("Failed to get userId.");
1011         return ERR_DM_FAILED;
1012     }
1013     std::string groupId = "";
1014     if (GetGroupIdExt(userId, groupType, groupId, groupOwner) != DM_OK) {
1015         LOGE("Failed to get groupid");
1016         return ERR_DM_FAILED;
1017     }
1018     jsonObj[FIELD_GROUP_TYPE] = groupType;
1019     jsonObj[FIELD_GROUP_ID] = groupId;
1020     jsonObj[FIELD_USER_ID] = userId;
1021     jsonObj[FIELD_CREDENTIAL_TYPE] = GetJsonInt(jsonObject, FIELD_CREDENTIAL_TYPE);
1022     jsonObj[FIELD_OPERATION_CODE] = GetJsonInt(jsonObject, FIELD_OPERATION_CODE);
1023     jsonObj[FIELD_META_NODE_TYPE] = GetJsonStr(jsonObject, FIELD_TYPE);
1024     if (!jsonObject.Contains(FIELD_DEVICE_LIST)) {
1025         LOGE("Credentaildata or authType string key not exist!");
1026         return ERR_DM_FAILED;
1027     }
1028     std::string jsonStr = jsonObject[FIELD_DEVICE_LIST].Dump();
1029     JsonObject jsonArray(JsonCreateType::JSON_CREATE_TYPE_ARRAY);
1030     jsonArray.Parse(jsonStr);
1031     jsonObj.Insert(FIELD_DEVICE_LIST, jsonArray);
1032     params = jsonObj.Dump();
1033     return DM_OK;
1034 }
1035 
addMultiMembersExt(const std::string & credentialInfo)1036 int32_t HiChainConnector::addMultiMembersExt(const std::string &credentialInfo)
1037 {
1038     if (deviceGroupManager_ == nullptr) {
1039         LOGE("HiChainConnector::deviceGroupManager_ is nullptr.");
1040         return ERR_DM_INPUT_PARA_INVALID;
1041     }
1042     std::string addParams = "";
1043     std::string groupOwner = "";
1044     if (ParseRemoteCredentialExt(credentialInfo, addParams, groupOwner) != DM_OK) {
1045         LOGE("AddMultiMembers ParseRemoteCredentialExt failed!");
1046         return ERR_DM_FAILED;
1047     }
1048     int32_t osAccountUserId = MultipleUserConnector::GetCurrentAccountUserID();
1049     if (osAccountUserId < 0) {
1050         LOGE("Get current process account user id failed");
1051         return ERR_DM_FAILED;
1052     }
1053     int32_t ret = deviceGroupManager_->addMultiMembersToGroup(osAccountUserId, groupOwner.c_str(), addParams.c_str());
1054     if (ret != DM_OK) {
1055         LOGE("[HICHAIN]fail to add member to hichain group with ret:%{public}d.", ret);
1056         return ret;
1057     }
1058     return DM_OK;
1059 }
1060 
deleteMultiMembers(const int32_t groupType,const std::string & userId,const JsonObject & jsonDeviceList)1061 int32_t HiChainConnector::deleteMultiMembers(const int32_t groupType, const std::string &userId,
1062     const JsonObject &jsonDeviceList)
1063 {
1064     if (deviceGroupManager_ == nullptr) {
1065         LOGE("HiChainConnector::deviceGroupManager_ is nullptr.");
1066         return ERR_DM_INPUT_PARA_INVALID;
1067     }
1068 
1069     std::string deleteParams;
1070     int32_t osAccountUserId = 0;
1071     if (ParseRemoteCredential(groupType, userId, jsonDeviceList, deleteParams, osAccountUserId) != DM_OK) {
1072         LOGE("deleteMultiMembers ParseRemoteCredential failed!");
1073         return ERR_DM_FAILED;
1074     }
1075 
1076     int32_t ret = deviceGroupManager_->delMultiMembersFromGroup(osAccountUserId, DM_PKG_NAME, deleteParams.c_str());
1077     if (ret != DM_OK) {
1078         LOGE("[HICHAIN]fail to delete member from hichain group with ret:%{public}d.", ret);
1079         return ret;
1080     }
1081     return DM_OK;
1082 }
1083 
GetTrustedDevices(const std::string & localDeviceUdid)1084 std::vector<std::string> HiChainConnector::GetTrustedDevices(const std::string &localDeviceUdid)
1085 {
1086     LOGI("get localDeviceUdid: %{public}s trusted devices.", GetAnonyString(localDeviceUdid).c_str());
1087     std::vector<GroupInfo> groups;
1088     int32_t ret = GetRelatedGroups(localDeviceUdid, groups);
1089     if (ret != DM_OK) {
1090         LOGE("failed to get groupInfo, ret: %{public}d", ret);
1091         return {};
1092     }
1093 
1094     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
1095     if (userId < 0) {
1096         LOGE("get current process account user id failed");
1097         return {};
1098     }
1099     std::vector<std::string> trustedDevices;
1100     for (const auto &group : groups) {
1101         char *devicesJson = nullptr;
1102         uint32_t devNum = 0;
1103         ret = deviceGroupManager_->getTrustedDevices(userId, DM_PKG_NAME, group.groupId.c_str(),
1104         &devicesJson, &devNum);
1105         if (ret != 0 || devicesJson == nullptr) {
1106             LOGE("[HICHAIN]failed to get trusted devicesJson, ret: %{public}d", ret);
1107             deviceGroupManager_->destroyInfo(&devicesJson);
1108             return {};
1109         }
1110         GetTrustedDevicesUdid(devicesJson, trustedDevices);
1111         deviceGroupManager_->destroyInfo(&devicesJson);
1112     }
1113     return trustedDevices;
1114 }
1115 
GetTrustedDevicesUdid(const char * jsonStr,std::vector<std::string> & udidList)1116 int32_t HiChainConnector::GetTrustedDevicesUdid(const char* jsonStr, std::vector<std::string> &udidList)
1117 {
1118     JsonObject jsonObject(jsonStr);
1119     if (jsonObject.IsDiscarded()) {
1120         LOGE("credentialInfo string not a json type.");
1121         return ERR_DM_FAILED;
1122     }
1123     std::vector<JsonItemObject> children = jsonObject.Items();
1124     for (auto it1 = children.begin(); it1 != children.end(); it1++) {
1125         if (!IsString((*it1), FIELD_AUTH_ID)) {
1126             continue;
1127         }
1128         std::string udid = (*it1)[FIELD_AUTH_ID].Get<std::string>();
1129         udidList.push_back(udid);
1130     }
1131     return DM_OK;
1132 }
1133 
DeleteAllGroup(int32_t userId)1134 void HiChainConnector::DeleteAllGroup(int32_t userId)
1135 {
1136     LOGI("HiChainConnector::DeleteAllGroup");
1137     char localDeviceId[DEVICE_UUID_LENGTH] = {0};
1138     GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
1139     std::string localUdid = static_cast<std::string>(localDeviceId);
1140     std::vector<GroupInfo> groupList;
1141     GetRelatedGroups(userId, localUdid, groupList);
1142     for (auto &iter : groupList) {
1143         if (iter.groupType == GROUP_TYPE_IDENTICAL_ACCOUNT_GROUP) {
1144             continue;
1145         }
1146         if (DeleteGroup(userId, iter.groupId) != DM_OK) {
1147             LOGE("Delete groupId %{public}s failed.", GetAnonyString(iter.groupId).c_str());
1148         }
1149     }
1150     std::vector<GroupInfo> groupListExt;
1151     GetRelatedGroupsExt(userId, localUdid, groupListExt);
1152     for (auto &iter : groupListExt) {
1153         if (iter.groupType == GROUP_TYPE_IDENTICAL_ACCOUNT_GROUP) {
1154             continue;
1155         }
1156         if (DeleteGroupExt(userId, iter.groupId) != DM_OK) {
1157             LOGE("DeleteGroupExt groupId %{public}s failed.", GetAnonyString(iter.groupId).c_str());
1158         }
1159     }
1160 }
1161 
GetRelatedGroupsCommon(const std::string & deviceId,const char * pkgName,std::vector<GroupInfo> & groupList)1162 int32_t HiChainConnector::GetRelatedGroupsCommon(const std::string &deviceId, const char* pkgName,
1163     std::vector<GroupInfo> &groupList)
1164 {
1165     LOGI("HiChainConnector::GetRelatedGroupsCommon Start to get local related groups.");
1166     uint32_t groupNum = 0;
1167     char *returnGroups = nullptr;
1168     int32_t userId = MultipleUserConnector::GetCurrentAccountUserID();
1169     if (userId < 0) {
1170         LOGE("get current process account user id failed");
1171         return ERR_DM_FAILED;
1172     }
1173     int32_t ret =
1174         deviceGroupManager_->getRelatedGroups(userId, pkgName, deviceId.c_str(), &returnGroups, &groupNum);
1175     if (ret != 0) {
1176         LOGE("[HICHAIN] fail to get related groups with ret:%{public}d.", ret);
1177         deviceGroupManager_->destroyInfo(&returnGroups);
1178         return ERR_DM_FAILED;
1179     }
1180     if (returnGroups == nullptr) {
1181         LOGE("[HICHAIN] return related goups point is nullptr");
1182         return ERR_DM_FAILED;
1183     }
1184     if (groupNum == 0) {
1185         LOGE("[HICHAIN]return related goups number is zero.");
1186         deviceGroupManager_->destroyInfo(&returnGroups);
1187         return ERR_DM_FAILED;
1188     }
1189     std::string relatedGroups = std::string(returnGroups);
1190     deviceGroupManager_->destroyInfo(&returnGroups);
1191     JsonObject jsonObject(relatedGroups);
1192     if (jsonObject.IsDiscarded()) {
1193         LOGE("returnGroups parse error");
1194         return ERR_DM_FAILED;
1195     }
1196     if (!jsonObject.IsArray()) {
1197         LOGE("jsonObject is not an array.");
1198         return ERR_DM_FAILED;
1199     }
1200     std::vector<GroupInfo> groupInfos;
1201     jsonObject.Get(groupInfos);
1202     if (groupInfos.empty()) {
1203         LOGE("HiChainConnector::GetRelatedGroups group failed, groupInfos is empty.");
1204         return ERR_DM_FAILED;
1205     }
1206     groupList = groupInfos;
1207     return DM_OK;
1208 }
1209 
DeleteGroup(const int32_t userId,std::string & groupId)1210 int32_t HiChainConnector::DeleteGroup(const int32_t userId, std::string &groupId)
1211 {
1212     if (userId < 0) {
1213         LOGE("user id failed");
1214         return ERR_DM_FAILED;
1215     }
1216     int64_t requestId = GenRequestId();
1217     JsonObject jsonObj;
1218     jsonObj[FIELD_GROUP_ID] = groupId;
1219     std::string disbandParams = jsonObj.Dump();
1220     int32_t ret = deviceGroupManager_->deleteGroup(userId, requestId, DM_PKG_NAME, disbandParams.c_str());
1221     if (ret != 0) {
1222         LOGE("[HICHAIN]fail to delete group with ret:%{public}d.", ret);
1223         return ERR_DM_FAILED;
1224     }
1225     return DM_OK;
1226 }
1227 
GetRelatedGroupsCommon(int32_t userId,const std::string & deviceId,const char * pkgName,std::vector<GroupInfo> & groupList)1228 int32_t HiChainConnector::GetRelatedGroupsCommon(int32_t userId, const std::string &deviceId, const char* pkgName,
1229     std::vector<GroupInfo> &groupList)
1230 {
1231     LOGI("Start to get related groups.");
1232     if (userId < 0) {
1233         LOGE("user id failed");
1234         return ERR_DM_FAILED;
1235     }
1236     uint32_t groupNum = 0;
1237     char *returnGroups = nullptr;
1238     int32_t ret =
1239         deviceGroupManager_->getRelatedGroups(userId, pkgName, deviceId.c_str(), &returnGroups, &groupNum);
1240     if (ret != 0) {
1241         LOGE("[HICHAIN] fail to get related groups with ret:%{public}d.", ret);
1242         deviceGroupManager_->destroyInfo(&returnGroups);
1243         return ERR_DM_FAILED;
1244     }
1245     if (returnGroups == nullptr) {
1246         LOGE("[HICHAIN] return related goups point is nullptr");
1247         return ERR_DM_FAILED;
1248     }
1249     if (groupNum == 0) {
1250         LOGE("[HICHAIN]return related goups number is zero.");
1251         deviceGroupManager_->destroyInfo(&returnGroups);
1252         return ERR_DM_FAILED;
1253     }
1254     std::string relatedGroups = std::string(returnGroups);
1255     deviceGroupManager_->destroyInfo(&returnGroups);
1256     JsonObject jsonObject(relatedGroups);
1257     if (jsonObject.IsDiscarded()) {
1258         LOGE("returnGroups parse error");
1259         return ERR_DM_FAILED;
1260     }
1261     if (!jsonObject.IsArray()) {
1262         LOGE("jsonObject is not an array.");
1263         return ERR_DM_FAILED;
1264     }
1265     std::vector<GroupInfo> groupInfos;
1266     jsonObject.Get(groupInfos);
1267     if (groupInfos.empty()) {
1268         LOGE("HiChainConnector::GetRelatedGroups group failed, groupInfos is empty.");
1269         return ERR_DM_FAILED;
1270     }
1271     groupList = groupInfos;
1272     return DM_OK;
1273 }
1274 
DeleteAllGroupByUdid(const std::string & udid)1275 void HiChainConnector::DeleteAllGroupByUdid(const std::string &udid)
1276 {
1277     LOGI("HiChainConnector::DeleteAllGroupByUdid %{public}s.", GetAnonyString(udid).c_str());
1278     std::vector<GroupInfo> groupList;
1279     GetRelatedGroups(udid, groupList);
1280     for (auto &iter : groupList) {
1281         if (DeleteGroup(iter.groupId) != DM_OK) {
1282             LOGE("Delete groupId %{public}s failed.", GetAnonyString(iter.groupId).c_str());
1283         }
1284     }
1285     std::vector<GroupInfo> groupListExt;
1286     GetRelatedGroupsExt(udid, groupListExt);
1287     for (auto &iter : groupListExt) {
1288         if (DeleteGroupExt(iter.groupId) != DM_OK) {
1289             LOGE("DeleteGroupExt groupId %{public}s failed.", GetAnonyString(iter.groupId).c_str());
1290         }
1291     }
1292 }
1293 
DeleteGroupByACL(std::vector<std::pair<int32_t,std::string>> & delACLInfoVec,std::vector<int32_t> & userIdVec)1294 int32_t HiChainConnector::DeleteGroupByACL(std::vector<std::pair<int32_t, std::string>> &delACLInfoVec,
1295     std::vector<int32_t> &userIdVec)
1296 {
1297     if (delACLInfoVec.size() == 0) {
1298         LOGI("delACLInfoVec is empty");
1299         return DM_OK;
1300     }
1301     if (userIdVec.size() == 0) {
1302         LOGI("userIdVec is empty");
1303         return DM_OK;
1304     }
1305     JsonObject jsonObj;
1306     jsonObj[FIELD_GROUP_TYPE] = GROUP_TYPE_PEER_TO_PEER_GROUP;
1307     std::string queryParams = jsonObj.Dump();
1308     for (int32_t userId : userIdVec) {
1309         std::vector<GroupInfo> groupList;
1310         if (!GetGroupInfo(userId, queryParams, groupList)) {
1311             continue;
1312         }
1313         for (auto iter = groupList.begin(); iter != groupList.end(); iter++) {
1314             if (!IsNeedDelete(iter->groupName, userId, delACLInfoVec)) {
1315                 continue;
1316             }
1317             if (DeleteGroup(userId, iter->groupId) != DM_OK) {
1318                 LOGE("failed to delete group %{public}s", GetAnonyString(iter->groupId).c_str());
1319             }
1320         }
1321     }
1322     return DM_OK;
1323 }
1324 
IsNeedDelete(std::string & groupName,int32_t userId,std::vector<std::pair<int32_t,std::string>> & delACLInfoVec)1325 bool HiChainConnector::IsNeedDelete(std::string &groupName, int32_t userId,
1326     std::vector<std::pair<int32_t, std::string>> &delACLInfoVec)
1327 {
1328     if (delACLInfoVec.size() == 0 || groupName.empty()) {
1329         LOGI("delACLInfoVec or groupName is empty");
1330         return false;
1331     }
1332     for (auto item : delACLInfoVec) {
1333         uint32_t interceptLength = item.second.size() / DEVICE_ID_HALF;
1334         std::string interceptUdid = item.second.substr(0, interceptLength);
1335         if (groupName.find(interceptUdid) != std::string::npos && userId == item.first) {
1336             return true;
1337         }
1338     }
1339     return false;
1340 }
1341 
DeleteHoDevice(const std::string & peerUdid,const std::vector<int32_t> & foreGroundUserIds,const std::vector<int32_t> & backGroundUserIds)1342 void HiChainConnector::DeleteHoDevice(const std::string &peerUdid, const std::vector<int32_t> &foreGroundUserIds,
1343     const std::vector<int32_t> &backGroundUserIds)
1344 {
1345     LOGI("peerudid %{public}s, foreGroundUserIds %{public}s, backGroundUserIds %{public}s.",
1346         GetAnonyString(peerUdid).c_str(), GetIntegerList(foreGroundUserIds).c_str(),
1347         GetIntegerList(backGroundUserIds).c_str());
1348     std::vector<int32_t> localUserIds(foreGroundUserIds.begin(), foreGroundUserIds.end());
1349     std::copy(backGroundUserIds.begin(), backGroundUserIds.end(), std::back_inserter(localUserIds));
1350     for (const auto &item : localUserIds) {
1351         std::vector<GroupInfo> groupList;
1352         GetRelatedGroupsCommon(item, peerUdid, DM_PKG_NAME_EXT, groupList);
1353         for (auto &iter : groupList) {
1354             if (iter.groupType == GROUP_TYPE_IDENTICAL_ACCOUNT_GROUP) {
1355                 continue;
1356             }
1357             if (DeleteGroupExt(item, iter.groupId) != DM_OK) {
1358                 LOGE("DeleteGroupExt groupId %{public}s failed.", GetAnonyString(iter.groupId).c_str());
1359             }
1360         }
1361     }
1362 }
1363 } // namespace DistributedHardware
1364 } // namespace OHOS