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