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