• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 "across_account_group.h"
17 
18 #include "account_module.h"
19 #include "alg_defs.h"
20 #include "callback_manager.h"
21 #include "common_defs.h"
22 #include "cred_manager.h"
23 #include "data_manager.h"
24 #include "device_auth_defines.h"
25 #include "group_operation_common.h"
26 #include "hc_dev_info.h"
27 #include "hc_log.h"
28 #include "string_util.h"
29 
30 /* 1: s1 > s2, -1: s1 <= s2 */
CompareString(const char * s1,const char * s2)31 static int32_t CompareString(const char *s1, const char *s2)
32 {
33     if ((s1 == NULL) || (s2 == NULL)) {
34         LOGE("The input string contains NULL value!");
35         return 0;
36     }
37     const char *tempChar1 = s1;
38     const char *tempChar2 = s2;
39     while ((*tempChar1 != '\0') && (*tempChar2 != '\0')) {
40         if (*tempChar1 > *tempChar2) {
41             return 1;
42         } else if (*tempChar1 < *tempChar2) {
43             return -1;
44         }
45         tempChar1++;
46         tempChar2++;
47     }
48     if (*tempChar1 != '\0') {
49         return 1;
50     }
51     return -1;
52 }
53 
GenerateGroupId(const char * userId,const char * sharedUserId,char ** returnGroupId)54 static int32_t GenerateGroupId(const char *userId, const char *sharedUserId, char **returnGroupId)
55 {
56     /* across account group: groupId = sha256(userId1 | userId2) */
57     uint8_t *hashMessage = NULL;
58     uint32_t messageSize = 0;
59     const char *firstUserId = userId;
60     const char *secondUserId = sharedUserId;
61     if (CompareString(firstUserId, secondUserId) > 0) {
62         firstUserId = sharedUserId;
63         secondUserId = userId;
64     }
65     Uint8Buff firstUserIdBuff = { (uint8_t *)firstUserId, HcStrlen(firstUserId) };
66     Uint8Buff secondUserIdBuff = { (uint8_t *)secondUserId, HcStrlen(secondUserId) };
67     int32_t result = GetHashMessage(&firstUserIdBuff, &secondUserIdBuff, &hashMessage, &messageSize);
68     if (result != HC_SUCCESS) {
69         return result;
70     }
71     int hashStrLen = SHA256_LEN * BYTE_TO_HEX_OPER_LENGTH + 1;
72     *returnGroupId = (char *)HcMalloc(hashStrLen, 0);
73     if (*returnGroupId == NULL) {
74         LOGE("Failed to allocate returnGroupId memory!");
75         HcFree(hashMessage);
76         return HC_ERR_ALLOC_MEMORY;
77     }
78     result = GetHashResult(hashMessage, messageSize, *returnGroupId, hashStrLen);
79     HcFree(hashMessage);
80     if (result != HC_SUCCESS) {
81         LOGE("Failed to get hash for groupId!");
82         HcFree(*returnGroupId);
83         *returnGroupId = NULL;
84         return HC_ERR_HASH_FAIL;
85     }
86     return HC_SUCCESS;
87 }
88 
AddCredTypeToParamsFromIdenticalGroup(int32_t osAccountId,CJson * jsonParams)89 static int32_t AddCredTypeToParamsFromIdenticalGroup(int32_t osAccountId, CJson *jsonParams)
90 {
91     char *userId = NULL;
92     int32_t result = GetUserIdFromJson(jsonParams, &userId);
93     if (result != HC_SUCCESS) {
94         return result;
95     }
96     char localUdid[INPUT_UDID_LEN] = { 0 };
97     int32_t res = HcGetUdid((uint8_t *)localUdid, INPUT_UDID_LEN);
98     if (res != HC_SUCCESS) {
99         LOGE("Failed to get local udid!");
100         HcFree(userId);
101         return res;
102     }
103     DeviceEntryVec deviceEntryVec = CREATE_HC_VECTOR(DeviceEntryVec);
104     QueryDeviceParams params = InitQueryDeviceParams();
105     params.userId = userId;
106     params.udid = localUdid;
107     if ((QueryDevices(osAccountId, &params, &deviceEntryVec) != HC_SUCCESS) ||
108         (deviceEntryVec.size(&deviceEntryVec) <= 0)) {
109         LOGE("query trusted devices failed!");
110         HcFree(userId);
111         ClearDeviceEntryVec(&deviceEntryVec);
112         return HC_ERR_DEVICE_NOT_EXIST;
113     }
114     TrustedDeviceEntry *deviceEntry = deviceEntryVec.get(&deviceEntryVec, 0);
115     if (AddIntToJson(jsonParams, FIELD_CREDENTIAL_TYPE, deviceEntry->credential) != HC_SUCCESS) {
116         LOGE("Failed to add credentialType to jsonParams!");
117         HcFree(userId);
118         ClearDeviceEntryVec(&deviceEntryVec);
119         return HC_ERR_JSON_ADD;
120     }
121     HcFree(userId);
122     ClearDeviceEntryVec(&deviceEntryVec);
123     return HC_SUCCESS;
124 }
125 
GenerateDevParams(const CJson * jsonParams,const char * groupId,TrustedDeviceEntry * devParams)126 static int32_t GenerateDevParams(const CJson *jsonParams, const char *groupId, TrustedDeviceEntry *devParams)
127 {
128     int32_t result;
129     if (((result = AddSelfUdidToParams(devParams)) != HC_SUCCESS) ||
130         ((result = AddAuthIdToParamsOrDefault(jsonParams, devParams)) != HC_SUCCESS) ||
131         ((result = AddCredTypeToParams(jsonParams, devParams)) != HC_SUCCESS) ||
132         ((result = AddUserIdToDevParams(jsonParams, devParams)) != HC_SUCCESS) ||
133         ((result = AddSourceToParams(SELF_CREATED, devParams)) != HC_SUCCESS) ||
134         ((result = AddUserTypeToParamsOrDefault(jsonParams, devParams)) != HC_SUCCESS) ||
135         ((result = AddGroupIdToDevParams(groupId, devParams)) != HC_SUCCESS) ||
136         ((result = AddServiceTypeToParams(groupId, devParams)) != HC_SUCCESS)) {
137         return result;
138     }
139     return HC_SUCCESS;
140 }
141 
GenerateGroupParams(const CJson * jsonParams,const char * groupId,TrustedGroupEntry * groupParams)142 static int32_t GenerateGroupParams(const CJson *jsonParams, const char *groupId, TrustedGroupEntry *groupParams)
143 {
144     const char *appId = GetStringFromJson(jsonParams, FIELD_APP_ID);
145     if (appId == NULL) {
146         LOGE("Failed to get appId from jsonParams!");
147         return HC_ERR_JSON_GET;
148     }
149     int32_t result;
150     if (((result = AddGroupTypeToParams(ACROSS_ACCOUNT_AUTHORIZE_GROUP, groupParams)) != HC_SUCCESS) ||
151         ((result = AddGroupNameToParams(groupId, groupParams)) != HC_SUCCESS) ||
152         ((result = AddGroupIdToParams(groupId, groupParams)) != HC_SUCCESS) ||
153         ((result = AddUserIdToGroupParams(jsonParams, groupParams)) != HC_SUCCESS) ||
154         ((result = AddSharedUserIdToGroupParams(jsonParams, groupParams)) != HC_SUCCESS) ||
155         ((result = AddGroupOwnerToParams(appId, groupParams)) != HC_SUCCESS) ||
156         ((result = AddGroupVisibilityOrDefault(jsonParams, groupParams)) != HC_SUCCESS) ||
157         ((result = AddExpireTimeOrDefault(jsonParams, groupParams)) != HC_SUCCESS)) {
158         return result;
159     }
160     return HC_SUCCESS;
161 }
162 
GenerateAcrossAccountGroupId(const CJson * jsonParams,char ** returnGroupId)163 static int32_t GenerateAcrossAccountGroupId(const CJson *jsonParams, char **returnGroupId)
164 {
165     char *userId = NULL;
166     char *sharedUserId = NULL;
167     int32_t result = GetUserIdFromJson(jsonParams, &userId);
168     if (result != HC_SUCCESS) {
169         return result;
170     }
171     result = GetSharedUserIdFromJson(jsonParams, &sharedUserId);
172     if (result != HC_SUCCESS) {
173         HcFree(userId);
174         return result;
175     }
176     result = GenerateGroupId(userId, sharedUserId, returnGroupId);
177     HcFree(userId);
178     HcFree(sharedUserId);
179     if (result != HC_SUCCESS) {
180         LOGE("Failed to generate groupId!");
181         return result;
182     }
183     return HC_SUCCESS;
184 }
185 
AssertIdenticalGroupExist(int32_t osAccountId,const CJson * jsonParams)186 static int32_t AssertIdenticalGroupExist(int32_t osAccountId, const CJson *jsonParams)
187 {
188     char *userId = NULL;
189     int32_t result = GetUserIdFromJson(jsonParams, &userId);
190     if (result != HC_SUCCESS) {
191         return result;
192     }
193     GroupEntryVec groupEntryVec = CreateGroupEntryVec();
194     QueryGroupParams params = InitQueryGroupParams();
195     params.groupType = IDENTICAL_ACCOUNT_GROUP;
196     result = QueryGroups(osAccountId, &params, &groupEntryVec);
197     if (result != HC_SUCCESS) {
198         LOGE("Failed to query groups!");
199         HcFree(userId);
200         ClearGroupEntryVec(&groupEntryVec);
201         return result;
202     }
203     bool isExist = false;
204     uint32_t index;
205     TrustedGroupEntry **entry = NULL;
206     FOR_EACH_HC_VECTOR(groupEntryVec, index, entry) {
207         if (strcmp(userId, StringGet(&((*entry)->userId))) == 0) {
208             isExist = true;
209             break;
210         }
211     }
212     HcFree(userId);
213     ClearGroupEntryVec(&groupEntryVec);
214     if (!isExist) {
215         LOGE("The identical account group has not been created!");
216         return HC_ERR_GROUP_NOT_EXIST;
217     }
218     return HC_SUCCESS;
219 }
220 
AssertSharedUserIdValid(const CJson * jsonParams)221 static int32_t AssertSharedUserIdValid(const CJson *jsonParams)
222 {
223     const char *userId = GetStringFromJson(jsonParams, FIELD_USER_ID);
224     if (userId == NULL) {
225         LOGE("Failed to get userId from jsonParams!");
226         return HC_ERR_JSON_GET;
227     }
228     const char *sharedUserId = GetStringFromJson(jsonParams, FIELD_PEER_USER_ID);
229     if (sharedUserId == NULL) {
230         LOGE("Failed to get sharedUserId from jsonParams!");
231         return HC_ERR_JSON_GET;
232     }
233     if (strcmp(sharedUserId, userId) == 0) {
234         LOGE("The input peerUserId is the same as the local userId!");
235         return HC_ERR_INVALID_PARAMS;
236     }
237     return HC_SUCCESS;
238 }
239 
CheckCreateParams(int32_t osAccountId,const CJson * jsonParams)240 static int32_t CheckCreateParams(int32_t osAccountId, const CJson *jsonParams)
241 {
242     const char *appId = GetStringFromJson(jsonParams, FIELD_APP_ID);
243     if (appId == NULL) {
244         LOGE("Failed to get appId from jsonParams!");
245         return HC_ERR_JSON_GET;
246     }
247     int32_t result;
248     if (((result = CheckUserTypeIfExist(jsonParams)) != HC_SUCCESS) ||
249         ((result = CheckGroupVisibilityIfExist(jsonParams)) != HC_SUCCESS) ||
250         ((result = CheckExpireTimeIfExist(jsonParams)) != HC_SUCCESS) ||
251         ((result = AssertUserIdExist(jsonParams)) != HC_SUCCESS) ||
252         ((result = AssertSharedUserIdValid(jsonParams)) != HC_SUCCESS) ||
253         ((result = AssertIdenticalGroupExist(osAccountId, jsonParams)) != HC_SUCCESS)) {
254         return result;
255     }
256     return HC_SUCCESS;
257 }
258 
GenerateAddTokenParams(const CJson * deviceInfo,CJson * addParams)259 static int32_t GenerateAddTokenParams(const CJson *deviceInfo, CJson *addParams)
260 {
261     const char *userId = GetStringFromJson(deviceInfo, FIELD_USER_ID);
262     if (userId == NULL) {
263         LOGE("Failed to get userId from json!");
264         return HC_ERR_JSON_GET;
265     }
266     const char *deviceId = GetStringFromJson(deviceInfo, FIELD_DEVICE_ID);
267     if (deviceId == NULL) {
268         LOGE("Failed to get deviceId from json!");
269         return HC_ERR_JSON_GET;
270     }
271     if (AddStringToJson(addParams, FIELD_DEVICE_ID, deviceId) != HC_SUCCESS) {
272         LOGE("Failed to add deviceId to json!");
273         return HC_ERR_JSON_ADD;
274     }
275     if (AddStringToJson(addParams, FIELD_USER_ID, userId) != HC_SUCCESS) {
276         LOGE("Failed to add userId to json!");
277         return HC_ERR_JSON_ADD;
278     }
279     return HC_SUCCESS;
280 }
281 
GenerateDelTokenParams(const TrustedDeviceEntry * entry,CJson * delParams)282 static int32_t GenerateDelTokenParams(const TrustedDeviceEntry *entry, CJson *delParams)
283 {
284     if (AddIntToJson(delParams, FIELD_CREDENTIAL_TYPE, (int32_t)entry->credential) != HC_SUCCESS) {
285         LOGE("Failed to add credentialType to json!");
286         return HC_ERR_JSON_ADD;
287     }
288     if (AddStringToJson(delParams, FIELD_USER_ID, StringGet(&entry->userId)) != HC_SUCCESS) {
289         LOGE("Failed to add userId to json!");
290         return HC_ERR_JSON_ADD;
291     }
292     if (AddStringToJson(delParams, FIELD_DEVICE_ID, StringGet(&entry->authId)) != HC_SUCCESS) {
293         LOGE("Failed to add deviceId to json!");
294         return HC_ERR_JSON_ADD;
295     }
296     return HC_SUCCESS;
297 }
298 
DelPeerDeviceToken(int32_t osAccountId,const TrustedDeviceEntry * entry)299 static int32_t DelPeerDeviceToken(int32_t osAccountId, const TrustedDeviceEntry *entry)
300 {
301     CJson *delParams = CreateJson();
302     if (delParams == NULL) {
303         LOGE("Failed to allocate delParams memory!");
304         return HC_ERR_ALLOC_MEMORY;
305     }
306     int32_t res = GenerateDelTokenParams(entry, delParams);
307     if (res != HC_SUCCESS) {
308         FreeJson(delParams);
309         return res;
310     }
311     res = ProcCred(ACCOUNT_RELATED_PLUGIN, osAccountId, DELETE_TRUSTED_CREDENTIALS, delParams, NULL);
312     FreeJson(delParams);
313     return res;
314 }
315 
DelAllPeerTokens(int32_t osAccountId,const DeviceEntryVec * vec)316 static void DelAllPeerTokens(int32_t osAccountId, const DeviceEntryVec *vec)
317 {
318     int32_t res;
319     uint32_t index;
320     TrustedDeviceEntry **entry = NULL;
321     FOR_EACH_HC_VECTOR(*vec, index, entry) {
322         if (IsLocalDevice(StringGet(&(*entry)->udid))) {
323             continue;
324         }
325         res = DelPeerDeviceToken(osAccountId, *entry);
326         if (res != HC_SUCCESS) {
327             LOGE("Failed to delete peer device token! res: %d", res);
328         }
329     }
330 }
331 
DelGroupAndTokens(int32_t osAccountId,const char * groupId)332 static int32_t DelGroupAndTokens(int32_t osAccountId, const char *groupId)
333 {
334     DeviceEntryVec deviceList = CreateDeviceEntryVec();
335     (void)GetTrustedDevices(osAccountId, groupId, &deviceList);
336     int32_t res = DelGroupFromDb(osAccountId, groupId);
337     DelAllPeerTokens(osAccountId, &deviceList);
338     ClearDeviceEntryVec(&deviceList);
339     return res;
340 }
341 
CheckChangeParams(int32_t osAccountId,const char * appId,CJson * jsonParams)342 static int32_t CheckChangeParams(int32_t osAccountId, const char *appId, CJson *jsonParams)
343 {
344     const char *groupId = GetStringFromJson(jsonParams, FIELD_GROUP_ID);
345     if (groupId == NULL) {
346         LOGE("Failed to get groupId from json!");
347         return HC_ERR_JSON_GET;
348     }
349     int32_t groupType;
350     int32_t result;
351     if (((result = CheckGroupExist(osAccountId, groupId)) != HC_SUCCESS) ||
352         ((result = GetGroupTypeFromDb(osAccountId, groupId, &groupType)) != HC_SUCCESS) ||
353         ((result = AssertGroupTypeMatch(groupType, ACROSS_ACCOUNT_AUTHORIZE_GROUP)) != HC_SUCCESS) ||
354         ((result = CheckGroupEditAllowed(osAccountId, groupId, appId)) != HC_SUCCESS)) {
355         return result;
356     }
357     return HC_SUCCESS;
358 }
359 
DelDeviceById(int32_t osAccountId,const char * groupId,const char * deviceId,bool isUdid)360 static int32_t DelDeviceById(int32_t osAccountId, const char *groupId, const char *deviceId, bool isUdid)
361 {
362     QueryDeviceParams queryDeviceParams = InitQueryDeviceParams();
363     queryDeviceParams.groupId = groupId;
364     if (isUdid) {
365         queryDeviceParams.udid = deviceId;
366     } else {
367         queryDeviceParams.authId = deviceId;
368     }
369     return DelTrustedDevice(osAccountId, &queryDeviceParams);
370 }
371 
GenerateTrustedDevParams(const CJson * jsonParams,const char * groupId,TrustedDeviceEntry * devParams)372 static int32_t GenerateTrustedDevParams(const CJson *jsonParams, const char *groupId, TrustedDeviceEntry *devParams)
373 {
374     int32_t result;
375     if (((result = AddUdidToParams(jsonParams, devParams)) != HC_SUCCESS) ||
376         ((result = AddAuthIdToParams(jsonParams, devParams)) != HC_SUCCESS) ||
377         ((result = AddCredTypeToParams(jsonParams, devParams)) != HC_SUCCESS) ||
378         ((result = AddUserIdToDevParams(jsonParams, devParams)) != HC_SUCCESS) ||
379         ((result = AddSourceToParams(IMPORTED_FROM_CLOUD, devParams)) != HC_SUCCESS) ||
380         ((result = AddUserTypeToParamsOrDefault(jsonParams, devParams)) != HC_SUCCESS) ||
381         ((result = AddGroupIdToDevParams(groupId, devParams)) != HC_SUCCESS) ||
382         ((result = AddServiceTypeToParams(groupId, devParams)) != HC_SUCCESS)) {
383         return result;
384     }
385     return HC_SUCCESS;
386 }
387 
CheckPeerDeviceNotSelf(const CJson * deviceInfo)388 static int32_t CheckPeerDeviceNotSelf(const CJson *deviceInfo)
389 {
390     const char *udid = GetStringFromJson(deviceInfo, FIELD_UDID);
391     if (udid == NULL) {
392         LOGE("Failed to get udid from json!");
393         return HC_ERR_JSON_GET;
394     }
395     return AssertPeerDeviceNotSelf(udid);
396 }
397 
AddDeviceAndToken(int32_t osAccountId,const CJson * jsonParams,CJson * deviceInfo)398 static int32_t AddDeviceAndToken(int32_t osAccountId, const CJson *jsonParams, CJson *deviceInfo)
399 {
400     const char *groupId = GetStringFromJson(jsonParams, FIELD_GROUP_ID);
401     if (groupId == NULL) {
402         LOGE("Failed to get groupId from json!");
403         return HC_ERR_JSON_GET;
404     }
405     CJson *credential = GetObjFromJson(deviceInfo, FIELD_CREDENTIAL);
406     if (credential == NULL) {
407         LOGE("Failed to get credential from json!");
408         return HC_ERR_JSON_GET;
409     }
410     int32_t res = GenerateAddTokenParams(deviceInfo, credential);
411     if (res != HC_SUCCESS) {
412         return res;
413     }
414     res = ProcCred(ACCOUNT_RELATED_PLUGIN, osAccountId, IMPORT_TRUSTED_CREDENTIALS, credential, NULL);
415     if (res != HC_SUCCESS) {
416         LOGE("Failed to import device token! res: %d", res);
417         return res;
418     }
419     res = AddDeviceToDatabaseByJson(osAccountId, GenerateTrustedDevParams, deviceInfo, groupId);
420     if (res != HC_SUCCESS) {
421         LOGE("Failed to add device to database! res: %d", res);
422     }
423     return res;
424 }
425 
DelPeerDeviceAndToken(int32_t osAccountId,CJson * jsonParams,CJson * deviceInfo)426 static int32_t DelPeerDeviceAndToken(int32_t osAccountId, CJson *jsonParams, CJson *deviceInfo)
427 {
428     const char *groupId = GetStringFromJson(jsonParams, FIELD_GROUP_ID);
429     if (groupId == NULL) {
430         LOGE("Failed to get groupId from json!");
431         return HC_ERR_JSON_GET;
432     }
433     const char *deviceId = GetStringFromJson(deviceInfo, FIELD_DEVICE_ID);
434     if (deviceId == NULL) {
435         LOGE("Failed to get deviceId from json!");
436         return HC_ERR_JSON_GET;
437     }
438     TrustedDeviceEntry *entry = GetTrustedDeviceEntryById(osAccountId, deviceId, false, groupId);
439     if (entry == NULL) {
440         LOGE("Failed to get device from db!");
441         return HC_ERR_DEVICE_NOT_EXIST;
442     }
443     if (IsLocalDevice(StringGet(&entry->udid))) {
444         LOGE("Do not delete the local device!");
445         DestroyDeviceEntry(entry);
446         return HC_ERR_INVALID_PARAMS;
447     }
448     int32_t res = DelDeviceById(osAccountId, groupId, deviceId, false);
449     if (res != HC_SUCCESS) {
450         LOGE("Failed to delete device from database! res: %d", res);
451         DestroyDeviceEntry(entry);
452         return res;
453     }
454     res = DelPeerDeviceToken(osAccountId, entry);
455     DestroyDeviceEntry(entry);
456     if (res != HC_SUCCESS) {
457         LOGE("Failed to delete token! res: %d", res);
458     }
459     return res;
460 }
461 
AddGroupAndLocalDev(int32_t osAccountId,CJson * jsonParams,const char * groupId)462 static int32_t AddGroupAndLocalDev(int32_t osAccountId, CJson *jsonParams, const char *groupId)
463 {
464     int32_t res = AddGroupToDatabaseByJson(osAccountId, GenerateGroupParams, jsonParams, groupId);
465     if (res != HC_SUCCESS) {
466         LOGE("Failed to add group to database!");
467         return res;
468     }
469     res = AddDeviceToDatabaseByJson(osAccountId, GenerateDevParams, jsonParams, groupId);
470     if (res != HC_SUCCESS) {
471         LOGE("Failed to add device to database!");
472         (void)DelGroupFromDb(osAccountId, groupId);
473         return res;
474     }
475     res = SaveOsAccountDb(osAccountId);
476     if (res != HC_SUCCESS) {
477         LOGE("Failed to save database!");
478         (void)DelGroupFromDb(osAccountId, groupId);
479     }
480     return res;
481 }
482 
CheckUserIdValid(int32_t osAccountId,const CJson * jsonParams,const CJson * deviceInfo)483 static int32_t CheckUserIdValid(int32_t osAccountId, const CJson *jsonParams, const CJson *deviceInfo)
484 {
485     const char *userId = GetStringFromJson(deviceInfo, FIELD_USER_ID);
486     if (userId == NULL) {
487         LOGE("Failed to get userId from json!");
488         return HC_ERR_JSON_GET;
489     }
490     const char *groupId = GetStringFromJson(jsonParams, FIELD_GROUP_ID);
491     if (groupId == NULL) {
492         LOGE("Failed to get groupId from json!");
493         return HC_ERR_JSON_GET;
494     }
495     uint32_t index;
496     TrustedGroupEntry **entry = NULL;
497     GroupEntryVec groupEntryVec = CreateGroupEntryVec();
498     QueryGroupParams params = InitQueryGroupParams();
499     params.groupId = groupId;
500     params.groupType = ACROSS_ACCOUNT_AUTHORIZE_GROUP;
501     if (QueryGroups(osAccountId, &params, &groupEntryVec) != HC_SUCCESS) {
502         LOGE("Failed to query groups!");
503         ClearGroupEntryVec(&groupEntryVec);
504         return HC_ERR_DB;
505     }
506     FOR_EACH_HC_VECTOR(groupEntryVec, index, entry) {
507         if (strcmp(userId, StringGet(&(*entry)->sharedUserId)) == 0) {
508             ClearGroupEntryVec(&groupEntryVec);
509             return HC_SUCCESS;
510         }
511     }
512     LOGE("The input userId is inconsistent with the sharedUserId!");
513     ClearGroupEntryVec(&groupEntryVec);
514     return HC_ERR_INVALID_PARAMS;
515 }
516 
CheckDeviceInfoValid(int32_t osAccountId,const CJson * jsonParams,const CJson * deviceInfo)517 static int32_t CheckDeviceInfoValid(int32_t osAccountId, const CJson *jsonParams, const CJson *deviceInfo)
518 {
519     int32_t res = CheckPeerDeviceNotSelf(deviceInfo);
520     if (res != HC_SUCCESS) {
521         LOGE("The peer device udid is equals to the local udid!");
522         return res;
523     }
524     /* Across account group: input userId must be consistent with the sharedUserId. */
525     return CheckUserIdValid(osAccountId, jsonParams, deviceInfo);
526 }
527 
CreateGroup(int32_t osAccountId,CJson * jsonParams,char ** returnJsonStr)528 static int32_t CreateGroup(int32_t osAccountId, CJson *jsonParams, char **returnJsonStr)
529 {
530     LOGI("[Start]: Start to create a across account group!");
531     if ((jsonParams == NULL) || (returnJsonStr == NULL)) {
532         LOGE("The input parameters contains NULL value!");
533         return HC_ERR_INVALID_PARAMS;
534     }
535     char *groupId = NULL;
536     int32_t result;
537     if (((result = CheckCreateParams(osAccountId, jsonParams)) != HC_SUCCESS) ||
538         ((result = GenerateAcrossAccountGroupId(jsonParams, &groupId)) != HC_SUCCESS) ||
539         ((result = AssertSameGroupNotExist(osAccountId, groupId)) != HC_SUCCESS) ||
540         ((result = AddCredTypeToParamsFromIdenticalGroup(osAccountId, jsonParams)) != HC_SUCCESS) ||
541         ((result = AddGroupAndLocalDev(osAccountId, jsonParams, groupId)) != HC_SUCCESS) ||
542         ((result = ConvertGroupIdToJsonStr(groupId, returnJsonStr)) != HC_SUCCESS)) {
543         HcFree(groupId);
544         return result;
545     }
546     HcFree(groupId);
547     LOGI("[End]: Create a across account group successfully!");
548     return HC_SUCCESS;
549 }
550 
DeleteGroup(int32_t osAccountId,CJson * jsonParams,char ** returnJsonStr)551 static int32_t DeleteGroup(int32_t osAccountId, CJson *jsonParams, char **returnJsonStr)
552 {
553     LOGI("[Start]: Start to delete a across account group!");
554     if ((jsonParams == NULL) || (returnJsonStr == NULL)) {
555         LOGE("The input parameters contains NULL value!");
556         return HC_ERR_INVALID_PARAMS;
557     }
558     int32_t result;
559     const char *groupId = NULL;
560     if (((result = GetGroupIdFromJson(jsonParams, &groupId)) != HC_SUCCESS) ||
561         ((result = DelGroupAndTokens(osAccountId, groupId)) != HC_SUCCESS) ||
562         ((result = ConvertGroupIdToJsonStr(groupId, returnJsonStr)) != HC_SUCCESS)) {
563         return result;
564     }
565     LOGI("[End]: Delete a across account group successfully!");
566     return HC_SUCCESS;
567 }
568 
AddMultiMembersToGroup(int32_t osAccountId,const char * appId,CJson * jsonParams)569 static int32_t AddMultiMembersToGroup(int32_t osAccountId, const char *appId, CJson *jsonParams)
570 {
571     LOGI("[Start]: Start to add multiple members to a across account group!");
572     if ((appId == NULL) || (jsonParams == NULL)) {
573         LOGE("Invalid params!");
574         return HC_ERR_INVALID_PARAMS;
575     }
576     int32_t res = CheckChangeParams(osAccountId, appId, jsonParams);
577     if (res != HC_SUCCESS) {
578         return res;
579     }
580     CJson *deviceList = GetObjFromJson(jsonParams, FIELD_DEVICE_LIST);
581     if (deviceList == NULL) {
582         LOGE("Failed to get deviceList from json!");
583         return HC_ERR_JSON_GET;
584     }
585     int32_t deviceNum = GetItemNum(deviceList);
586     int32_t addedCount = 0;
587     for (int32_t i = 0; i < deviceNum; i++) {
588         CJson *deviceInfo = GetItemFromArray(deviceList, i);
589         if (deviceInfo == NULL) {
590             LOGE("The deviceInfo is NULL!");
591             continue;
592         }
593         if (CheckDeviceInfoValid(osAccountId, jsonParams, deviceInfo) != HC_SUCCESS) {
594             continue;
595         }
596         if (AddDeviceAndToken(osAccountId, jsonParams, deviceInfo) == HC_SUCCESS) {
597             addedCount++;
598         }
599     }
600     res = SaveOsAccountDb(osAccountId);
601     if (res != HC_SUCCESS) {
602         LOGE("Failed to save database!");
603         return res;
604     }
605     LOGI("[End]: Add multiple members to a across account group successfully! [ListNum]: %d, [AddedNum]: %d",
606         deviceNum, addedCount);
607     return HC_SUCCESS;
608 }
609 
DelMultiMembersFromGroup(int32_t osAccountId,const char * appId,CJson * jsonParams)610 static int32_t DelMultiMembersFromGroup(int32_t osAccountId, const char *appId, CJson *jsonParams)
611 {
612     LOGI("[Start]: Start to delete multiple members from a across account group!");
613     if ((appId == NULL) || (jsonParams == NULL)) {
614         LOGE("Invalid params!");
615         return HC_ERR_INVALID_PARAMS;
616     }
617     int32_t res = CheckChangeParams(osAccountId, appId, jsonParams);
618     if (res != HC_SUCCESS) {
619         return res;
620     }
621     CJson *deviceList = GetObjFromJson(jsonParams, FIELD_DEVICE_LIST);
622     if (deviceList == NULL) {
623         LOGE("Failed to get deviceList from json!");
624         return HC_ERR_JSON_GET;
625     }
626     int32_t deviceNum = GetItemNum(deviceList);
627     int32_t deletedCount = 0;
628     for (int32_t i = 0; i < deviceNum; i++) {
629         CJson *deviceInfo = GetItemFromArray(deviceList, i);
630         if (deviceInfo == NULL) {
631             LOGE("The deviceInfo is NULL!");
632             continue;
633         }
634         if (DelPeerDeviceAndToken(osAccountId, jsonParams, deviceInfo) == HC_SUCCESS) {
635             deletedCount++;
636         }
637     }
638     res = SaveOsAccountDb(osAccountId);
639     if (res != HC_SUCCESS) {
640         LOGE("Failed to save database!");
641         return res;
642     }
643     LOGI("[End]: Delete multiple members from a across account group successfully! [ListNum]: %d, [DeletedNum]: %d",
644         deviceNum, deletedCount);
645     return HC_SUCCESS;
646 }
647 
648 static AcrossAccountGroup g_acrossAccountGroup = {
649     .base.type = ACROSS_ACCOUNT_AUTHORIZE_GROUP,
650     .base.createGroup = CreateGroup,
651     .base.deleteGroup = DeleteGroup,
652     .addMultiMembersToGroup = AddMultiMembersToGroup,
653     .delMultiMembersFromGroup = DelMultiMembersFromGroup,
654 };
655 
GetAcrossAccountGroupInstance(void)656 BaseGroup *GetAcrossAccountGroupInstance(void)
657 {
658     return (BaseGroup *)&g_acrossAccountGroup;
659 }
660 
IsAcrossAccountGroupSupported(void)661 bool IsAcrossAccountGroupSupported(void)
662 {
663     return true;
664 }
665