1094332d3Sopenharmony_ci/*
2094332d3Sopenharmony_ci * Copyright (C) 2022-2024 Huawei Device Co., Ltd.
3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License.
5094332d3Sopenharmony_ci * You may obtain a copy of the License at
6094332d3Sopenharmony_ci *
7094332d3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8094332d3Sopenharmony_ci *
9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and
13094332d3Sopenharmony_ci * limitations under the License.
14094332d3Sopenharmony_ci */
15094332d3Sopenharmony_ci
16094332d3Sopenharmony_ci#include "idm_database.h"
17094332d3Sopenharmony_ci
18094332d3Sopenharmony_ci#include "inttypes.h"
19094332d3Sopenharmony_ci#include "securec.h"
20094332d3Sopenharmony_ci
21094332d3Sopenharmony_ci#include "adaptor_algorithm.h"
22094332d3Sopenharmony_ci#include "adaptor_log.h"
23094332d3Sopenharmony_ci#include "adaptor_time.h"
24094332d3Sopenharmony_ci#include "idm_file_manager.h"
25094332d3Sopenharmony_ci#include "global_config_file_manager.h"
26094332d3Sopenharmony_ci
27094332d3Sopenharmony_ci#define MAX_DUPLICATE_CHECK 100
28094332d3Sopenharmony_ci#define PRE_APPLY_NUM 5
29094332d3Sopenharmony_ci#define MEM_GROWTH_FACTOR 2
30094332d3Sopenharmony_ci#define MAX_CREDENTIAL_RETURN 5000
31094332d3Sopenharmony_ci
32094332d3Sopenharmony_ci#ifdef IAM_TEST_ENABLE
33094332d3Sopenharmony_ci#define IAM_STATIC
34094332d3Sopenharmony_ci#else
35094332d3Sopenharmony_ci#define IAM_STATIC static
36094332d3Sopenharmony_ci#endif
37094332d3Sopenharmony_ci
38094332d3Sopenharmony_ci// Caches IDM user information.
39094332d3Sopenharmony_ciIAM_STATIC LinkedList *g_userInfoList = NULL;
40094332d3Sopenharmony_ci
41094332d3Sopenharmony_ci// Caches the current user to reduce the number of user list traversal times.
42094332d3Sopenharmony_ciIAM_STATIC UserInfo *g_currentUser = NULL;
43094332d3Sopenharmony_ci
44094332d3Sopenharmony_ci// Caches global config info.
45094332d3Sopenharmony_ciIAM_STATIC GlobalConfigInfo g_globalConfigArray[MAX_GLOBAL_CONFIG_NUM];
46094332d3Sopenharmony_ciIAM_STATIC uint32_t g_globalConfigInfoNum = 0;
47094332d3Sopenharmony_ci
48094332d3Sopenharmony_citypedef bool (*DuplicateCheckFunc)(LinkedList *collection, uint64_t value);
49094332d3Sopenharmony_ci
50094332d3Sopenharmony_ciIAM_STATIC UserInfo *QueryUserInfo(int32_t userId);
51094332d3Sopenharmony_ciIAM_STATIC ResultCode GetAllEnrolledInfoFromUser(UserInfo *userInfo, EnrolledInfoHal **enrolledInfos, uint32_t *num);
52094332d3Sopenharmony_ciIAM_STATIC ResultCode DeleteUser(int32_t userId);
53094332d3Sopenharmony_ciIAM_STATIC CredentialInfoHal *QueryCredentialById(uint64_t credentialId, LinkedList *credentialList);
54094332d3Sopenharmony_ciIAM_STATIC CredentialInfoHal *QueryCredentialByAuthType(uint32_t authType, LinkedList *credentialList);
55094332d3Sopenharmony_ciIAM_STATIC bool MatchCredentialById(const void *data, const void *condition);
56094332d3Sopenharmony_ciIAM_STATIC ResultCode GenerateDeduplicateUint64(LinkedList *collection, uint64_t *destValue, DuplicateCheckFunc func);
57094332d3Sopenharmony_ciIAM_STATIC bool IsUserValid(UserInfo *user);
58094332d3Sopenharmony_ciIAM_STATIC ResultCode GetInvalidUser(int32_t *invalidUserId, uint32_t maxUserCount, uint32_t *userCount,
59094332d3Sopenharmony_ci    bool *cachePinRemoved);
60094332d3Sopenharmony_ciIAM_STATIC void RemoveCachePin(UserInfo *user, bool *isRemoved);
61094332d3Sopenharmony_ciIAM_STATIC ResultCode ClearInvalidData(void);
62094332d3Sopenharmony_ci
63094332d3Sopenharmony_ciResultCode InitUserInfoList(void)
64094332d3Sopenharmony_ci{
65094332d3Sopenharmony_ci    LOG_INFO("InitUserInfoList start");
66094332d3Sopenharmony_ci    if (g_userInfoList != NULL) {
67094332d3Sopenharmony_ci        DestroyUserInfoList();
68094332d3Sopenharmony_ci        g_userInfoList = NULL;
69094332d3Sopenharmony_ci    }
70094332d3Sopenharmony_ci    g_userInfoList = LoadFileInfo();
71094332d3Sopenharmony_ci    if (g_userInfoList == NULL) {
72094332d3Sopenharmony_ci        LOG_ERROR("load file info failed");
73094332d3Sopenharmony_ci        return RESULT_NEED_INIT;
74094332d3Sopenharmony_ci    }
75094332d3Sopenharmony_ci    ResultCode ret = ClearInvalidData();
76094332d3Sopenharmony_ci    if (ret != RESULT_SUCCESS) {
77094332d3Sopenharmony_ci        LOG_ERROR("clear invalid user failed");
78094332d3Sopenharmony_ci        DestroyUserInfoList();
79094332d3Sopenharmony_ci        return ret;
80094332d3Sopenharmony_ci    }
81094332d3Sopenharmony_ci    ret = LoadGlobalConfigInfo(g_globalConfigArray, MAX_GLOBAL_CONFIG_NUM, &g_globalConfigInfoNum);
82094332d3Sopenharmony_ci    if (ret != RESULT_SUCCESS) {
83094332d3Sopenharmony_ci        LOG_ERROR("load global config info failed");
84094332d3Sopenharmony_ci    }
85094332d3Sopenharmony_ci    LOG_INFO("InitUserInfoList end");
86094332d3Sopenharmony_ci    return RESULT_SUCCESS;
87094332d3Sopenharmony_ci}
88094332d3Sopenharmony_ci
89094332d3Sopenharmony_civoid DestroyUserInfoList(void)
90094332d3Sopenharmony_ci{
91094332d3Sopenharmony_ci    DestroyLinkedList(g_userInfoList);
92094332d3Sopenharmony_ci    g_userInfoList = NULL;
93094332d3Sopenharmony_ci}
94094332d3Sopenharmony_ci
95094332d3Sopenharmony_ciIAM_STATIC bool MatchUserInfo(const void *data, const void *condition)
96094332d3Sopenharmony_ci{
97094332d3Sopenharmony_ci    if (data == NULL || condition == NULL) {
98094332d3Sopenharmony_ci        LOG_ERROR("please check invalid node");
99094332d3Sopenharmony_ci        return false;
100094332d3Sopenharmony_ci    }
101094332d3Sopenharmony_ci    const UserInfo *userInfo = (const UserInfo *)data;
102094332d3Sopenharmony_ci    int32_t userId = *(const int32_t *)condition;
103094332d3Sopenharmony_ci    if (userInfo->userId == userId) {
104094332d3Sopenharmony_ci        return true;
105094332d3Sopenharmony_ci    }
106094332d3Sopenharmony_ci    return false;
107094332d3Sopenharmony_ci}
108094332d3Sopenharmony_ci
109094332d3Sopenharmony_ciIAM_STATIC bool IsUserInfoValid(UserInfo *userInfo)
110094332d3Sopenharmony_ci{
111094332d3Sopenharmony_ci    if (userInfo == NULL) {
112094332d3Sopenharmony_ci        LOG_ERROR("userInfo is null");
113094332d3Sopenharmony_ci        return false;
114094332d3Sopenharmony_ci    }
115094332d3Sopenharmony_ci    if (userInfo->credentialInfoList == NULL) {
116094332d3Sopenharmony_ci        LOG_ERROR("credentialInfoList is null");
117094332d3Sopenharmony_ci        return false;
118094332d3Sopenharmony_ci    }
119094332d3Sopenharmony_ci    if (userInfo->enrolledInfoList == NULL) {
120094332d3Sopenharmony_ci        LOG_ERROR("enrolledInfoList is null");
121094332d3Sopenharmony_ci        return false;
122094332d3Sopenharmony_ci    }
123094332d3Sopenharmony_ci    return true;
124094332d3Sopenharmony_ci}
125094332d3Sopenharmony_ci
126094332d3Sopenharmony_ciResultCode GetSecureUid(int32_t userId, uint64_t *secUid)
127094332d3Sopenharmony_ci{
128094332d3Sopenharmony_ci    if (secUid == NULL) {
129094332d3Sopenharmony_ci        LOG_ERROR("secUid is null");
130094332d3Sopenharmony_ci        return RESULT_BAD_PARAM;
131094332d3Sopenharmony_ci    }
132094332d3Sopenharmony_ci    UserInfo *user = QueryUserInfo(userId);
133094332d3Sopenharmony_ci    if (user == NULL) {
134094332d3Sopenharmony_ci        LOG_ERROR("can't find this user");
135094332d3Sopenharmony_ci        return RESULT_NOT_FOUND;
136094332d3Sopenharmony_ci    }
137094332d3Sopenharmony_ci    *secUid = user->secUid;
138094332d3Sopenharmony_ci    return RESULT_SUCCESS;
139094332d3Sopenharmony_ci}
140094332d3Sopenharmony_ci
141094332d3Sopenharmony_ciResultCode GetEnrolledInfoAuthType(int32_t userId, uint32_t authType, EnrolledInfoHal *enrolledInfo)
142094332d3Sopenharmony_ci{
143094332d3Sopenharmony_ci    if (enrolledInfo == NULL) {
144094332d3Sopenharmony_ci        LOG_ERROR("enrolledInfo is null");
145094332d3Sopenharmony_ci        return RESULT_BAD_PARAM;
146094332d3Sopenharmony_ci    }
147094332d3Sopenharmony_ci    UserInfo *user = QueryUserInfo(userId);
148094332d3Sopenharmony_ci    if (user == NULL) {
149094332d3Sopenharmony_ci        LOG_ERROR("can't find this user");
150094332d3Sopenharmony_ci        return RESULT_NOT_FOUND;
151094332d3Sopenharmony_ci    }
152094332d3Sopenharmony_ci    if (user->enrolledInfoList == NULL) {
153094332d3Sopenharmony_ci        LOG_ERROR("enrolledInfoList is null");
154094332d3Sopenharmony_ci        return RESULT_UNKNOWN;
155094332d3Sopenharmony_ci    }
156094332d3Sopenharmony_ci
157094332d3Sopenharmony_ci    LinkedListNode *temp = user->enrolledInfoList->head;
158094332d3Sopenharmony_ci    while (temp != NULL) {
159094332d3Sopenharmony_ci        EnrolledInfoHal *nodeInfo = temp->data;
160094332d3Sopenharmony_ci        if (nodeInfo != NULL && nodeInfo->authType == authType) {
161094332d3Sopenharmony_ci            *enrolledInfo = *nodeInfo;
162094332d3Sopenharmony_ci            return RESULT_SUCCESS;
163094332d3Sopenharmony_ci        }
164094332d3Sopenharmony_ci        temp = temp->next;
165094332d3Sopenharmony_ci    }
166094332d3Sopenharmony_ci
167094332d3Sopenharmony_ci    return RESULT_NOT_FOUND;
168094332d3Sopenharmony_ci}
169094332d3Sopenharmony_ci
170094332d3Sopenharmony_ciResultCode GetEnrolledInfo(int32_t userId, EnrolledInfoHal **enrolledInfos, uint32_t *num)
171094332d3Sopenharmony_ci{
172094332d3Sopenharmony_ci    if (enrolledInfos == NULL || num == NULL) {
173094332d3Sopenharmony_ci        LOG_ERROR("param is invalid");
174094332d3Sopenharmony_ci        return RESULT_BAD_PARAM;
175094332d3Sopenharmony_ci    }
176094332d3Sopenharmony_ci    UserInfo *user = QueryUserInfo(userId);
177094332d3Sopenharmony_ci    if (!IsUserInfoValid(user)) {
178094332d3Sopenharmony_ci        LOG_ERROR("can't find this user");
179094332d3Sopenharmony_ci        return RESULT_NOT_FOUND;
180094332d3Sopenharmony_ci    }
181094332d3Sopenharmony_ci    return GetAllEnrolledInfoFromUser(user, enrolledInfos, num);
182094332d3Sopenharmony_ci}
183094332d3Sopenharmony_ci
184094332d3Sopenharmony_ciResultCode DeleteUserInfo(int32_t userId, LinkedList **creds)
185094332d3Sopenharmony_ci{
186094332d3Sopenharmony_ci    if (creds == NULL) {
187094332d3Sopenharmony_ci        LOG_ERROR("param is invalid");
188094332d3Sopenharmony_ci        return RESULT_BAD_PARAM;
189094332d3Sopenharmony_ci    }
190094332d3Sopenharmony_ci    UserInfo *user = QueryUserInfo(userId);
191094332d3Sopenharmony_ci    if (!IsUserInfoValid(user)) {
192094332d3Sopenharmony_ci        LOG_ERROR("can't find this user");
193094332d3Sopenharmony_ci        return RESULT_NOT_FOUND;
194094332d3Sopenharmony_ci    }
195094332d3Sopenharmony_ci    CredentialCondition condition = {};
196094332d3Sopenharmony_ci    SetCredentialConditionUserId(&condition, userId);
197094332d3Sopenharmony_ci    *creds = QueryCredentialLimit(&condition);
198094332d3Sopenharmony_ci    if (*creds == NULL) {
199094332d3Sopenharmony_ci        LOG_ERROR("query credential failed");
200094332d3Sopenharmony_ci        return RESULT_UNKNOWN;
201094332d3Sopenharmony_ci    }
202094332d3Sopenharmony_ci    g_currentUser = NULL;
203094332d3Sopenharmony_ci
204094332d3Sopenharmony_ci    ResultCode ret = DeleteUser(userId);
205094332d3Sopenharmony_ci    if (ret != RESULT_SUCCESS) {
206094332d3Sopenharmony_ci        LOG_ERROR("deleteUser failed");
207094332d3Sopenharmony_ci        DestroyLinkedList(*creds);
208094332d3Sopenharmony_ci        *creds = NULL;
209094332d3Sopenharmony_ci        return ret;
210094332d3Sopenharmony_ci    }
211094332d3Sopenharmony_ci    ret = UpdateFileInfo(g_userInfoList);
212094332d3Sopenharmony_ci    if (ret != RESULT_SUCCESS) {
213094332d3Sopenharmony_ci        LOG_ERROR("update file info failed");
214094332d3Sopenharmony_ci        DestroyLinkedList(*creds);
215094332d3Sopenharmony_ci        *creds = NULL;
216094332d3Sopenharmony_ci        return ret;
217094332d3Sopenharmony_ci    }
218094332d3Sopenharmony_ci    return ret;
219094332d3Sopenharmony_ci}
220094332d3Sopenharmony_ci
221094332d3Sopenharmony_ciIAM_STATIC UserInfo *QueryUserInfo(int32_t userId)
222094332d3Sopenharmony_ci{
223094332d3Sopenharmony_ci    UserInfo *user = g_currentUser;
224094332d3Sopenharmony_ci    if (user != NULL && user->userId == userId) {
225094332d3Sopenharmony_ci        return user;
226094332d3Sopenharmony_ci    }
227094332d3Sopenharmony_ci    if (g_userInfoList == NULL) {
228094332d3Sopenharmony_ci        return NULL;
229094332d3Sopenharmony_ci    }
230094332d3Sopenharmony_ci    LinkedListNode *temp = g_userInfoList->head;
231094332d3Sopenharmony_ci    while (temp != NULL) {
232094332d3Sopenharmony_ci        user = (UserInfo *)temp->data;
233094332d3Sopenharmony_ci        if (user != NULL && user->userId == userId) {
234094332d3Sopenharmony_ci            break;
235094332d3Sopenharmony_ci        }
236094332d3Sopenharmony_ci        temp = temp->next;
237094332d3Sopenharmony_ci    }
238094332d3Sopenharmony_ci    if (temp == NULL) {
239094332d3Sopenharmony_ci        return NULL;
240094332d3Sopenharmony_ci    }
241094332d3Sopenharmony_ci    if (IsUserInfoValid(user)) {
242094332d3Sopenharmony_ci        g_currentUser = user;
243094332d3Sopenharmony_ci        return user;
244094332d3Sopenharmony_ci    }
245094332d3Sopenharmony_ci    return NULL;
246094332d3Sopenharmony_ci}
247094332d3Sopenharmony_ci
248094332d3Sopenharmony_ciIAM_STATIC ResultCode GetAllEnrolledInfoFromUser(UserInfo *userInfo, EnrolledInfoHal **enrolledInfos, uint32_t *num)
249094332d3Sopenharmony_ci{
250094332d3Sopenharmony_ci    LinkedList *enrolledInfoList = userInfo->enrolledInfoList;
251094332d3Sopenharmony_ci    uint32_t size = enrolledInfoList->getSize(enrolledInfoList);
252094332d3Sopenharmony_ci    *enrolledInfos = Malloc(sizeof(EnrolledInfoHal) * size);
253094332d3Sopenharmony_ci    if (*enrolledInfos == NULL) {
254094332d3Sopenharmony_ci        LOG_ERROR("enrolledInfos malloc failed");
255094332d3Sopenharmony_ci        return RESULT_NO_MEMORY;
256094332d3Sopenharmony_ci    }
257094332d3Sopenharmony_ci    (void)memset_s(*enrolledInfos, sizeof(EnrolledInfoHal) * size, 0, sizeof(EnrolledInfoHal) * size);
258094332d3Sopenharmony_ci    LinkedListNode *temp = enrolledInfoList->head;
259094332d3Sopenharmony_ci    ResultCode result = RESULT_SUCCESS;
260094332d3Sopenharmony_ci    for (*num = 0; *num < size; (*num)++) {
261094332d3Sopenharmony_ci        if (temp == NULL) {
262094332d3Sopenharmony_ci            LOG_ERROR("temp node is null, something wrong");
263094332d3Sopenharmony_ci            result = RESULT_BAD_PARAM;
264094332d3Sopenharmony_ci            goto EXIT;
265094332d3Sopenharmony_ci        }
266094332d3Sopenharmony_ci        EnrolledInfoHal *tempInfo = (EnrolledInfoHal *)temp->data;
267094332d3Sopenharmony_ci        if (memcpy_s(*enrolledInfos + *num, sizeof(EnrolledInfoHal) * (size - *num),
268094332d3Sopenharmony_ci            tempInfo, sizeof(EnrolledInfoHal)) != EOK) {
269094332d3Sopenharmony_ci            LOG_ERROR("copy the %u information failed", *num);
270094332d3Sopenharmony_ci            result = RESULT_NO_MEMORY;
271094332d3Sopenharmony_ci            goto EXIT;
272094332d3Sopenharmony_ci        }
273094332d3Sopenharmony_ci        temp = temp->next;
274094332d3Sopenharmony_ci    }
275094332d3Sopenharmony_ci
276094332d3Sopenharmony_ciEXIT:
277094332d3Sopenharmony_ci    if (result != RESULT_SUCCESS) {
278094332d3Sopenharmony_ci        Free(*enrolledInfos);
279094332d3Sopenharmony_ci        *enrolledInfos = NULL;
280094332d3Sopenharmony_ci        *num = 0;
281094332d3Sopenharmony_ci    }
282094332d3Sopenharmony_ci    return result;
283094332d3Sopenharmony_ci}
284094332d3Sopenharmony_ci
285094332d3Sopenharmony_ciIAM_STATIC bool IsSecureUidDuplicate(LinkedList *userInfoList, uint64_t secureUid)
286094332d3Sopenharmony_ci{
287094332d3Sopenharmony_ci    if (userInfoList == NULL) {
288094332d3Sopenharmony_ci        LOG_ERROR("the user list is empty, and the branch is abnormal");
289094332d3Sopenharmony_ci        return false;
290094332d3Sopenharmony_ci    }
291094332d3Sopenharmony_ci
292094332d3Sopenharmony_ci    LinkedListNode *temp = userInfoList->head;
293094332d3Sopenharmony_ci    UserInfo *userInfo = NULL;
294094332d3Sopenharmony_ci    while (temp != NULL) {
295094332d3Sopenharmony_ci        userInfo = (UserInfo *)temp->data;
296094332d3Sopenharmony_ci        if (userInfo != NULL && userInfo->secUid == secureUid) {
297094332d3Sopenharmony_ci            return true;
298094332d3Sopenharmony_ci        }
299094332d3Sopenharmony_ci        temp = temp->next;
300094332d3Sopenharmony_ci    }
301094332d3Sopenharmony_ci
302094332d3Sopenharmony_ci    return false;
303094332d3Sopenharmony_ci}
304094332d3Sopenharmony_ci
305094332d3Sopenharmony_ciIAM_STATIC UserInfo *CreateUser(int32_t userId, int32_t userType)
306094332d3Sopenharmony_ci{
307094332d3Sopenharmony_ci    UserInfo *user = InitUserInfoNode();
308094332d3Sopenharmony_ci    if (!IsUserInfoValid(user)) {
309094332d3Sopenharmony_ci        LOG_ERROR("user is invalid");
310094332d3Sopenharmony_ci        DestroyUserInfoNode(user);
311094332d3Sopenharmony_ci        return NULL;
312094332d3Sopenharmony_ci    }
313094332d3Sopenharmony_ci    user->userId = userId;
314094332d3Sopenharmony_ci    user->userType = userType;
315094332d3Sopenharmony_ci    ResultCode ret = GenerateDeduplicateUint64(g_userInfoList, &user->secUid, IsSecureUidDuplicate);
316094332d3Sopenharmony_ci    if (ret != RESULT_SUCCESS) {
317094332d3Sopenharmony_ci        LOG_ERROR("generate secureUid failed");
318094332d3Sopenharmony_ci        DestroyUserInfoNode(user);
319094332d3Sopenharmony_ci        return NULL;
320094332d3Sopenharmony_ci    }
321094332d3Sopenharmony_ci    return user;
322094332d3Sopenharmony_ci}
323094332d3Sopenharmony_ci
324094332d3Sopenharmony_ciIAM_STATIC ResultCode DeleteUser(int32_t userId)
325094332d3Sopenharmony_ci{
326094332d3Sopenharmony_ci    if (g_userInfoList == NULL) {
327094332d3Sopenharmony_ci        return RESULT_BAD_PARAM;
328094332d3Sopenharmony_ci    }
329094332d3Sopenharmony_ci    return g_userInfoList->remove(g_userInfoList, &userId, MatchUserInfo, true);
330094332d3Sopenharmony_ci}
331094332d3Sopenharmony_ci
332094332d3Sopenharmony_ciIAM_STATIC bool IsCredentialIdDuplicate(LinkedList *userInfoList, uint64_t credentialId)
333094332d3Sopenharmony_ci{
334094332d3Sopenharmony_ci    (void)userInfoList;
335094332d3Sopenharmony_ci    CredentialCondition condition = {};
336094332d3Sopenharmony_ci    SetCredentialConditionCredentialId(&condition, credentialId);
337094332d3Sopenharmony_ci    LinkedList *credList = QueryCredentialLimit(&condition);
338094332d3Sopenharmony_ci    if (credList == NULL) {
339094332d3Sopenharmony_ci        LOG_ERROR("query failed");
340094332d3Sopenharmony_ci        return true;
341094332d3Sopenharmony_ci    }
342094332d3Sopenharmony_ci    if (credList->getSize(credList) != 0) {
343094332d3Sopenharmony_ci        LOG_ERROR("duplicate credential id");
344094332d3Sopenharmony_ci        DestroyLinkedList(credList);
345094332d3Sopenharmony_ci        return true;
346094332d3Sopenharmony_ci    }
347094332d3Sopenharmony_ci    DestroyLinkedList(credList);
348094332d3Sopenharmony_ci    return false;
349094332d3Sopenharmony_ci}
350094332d3Sopenharmony_ci
351094332d3Sopenharmony_ciIAM_STATIC bool IsEnrolledIdDuplicate(LinkedList *enrolledList, uint64_t enrolledId)
352094332d3Sopenharmony_ci{
353094332d3Sopenharmony_ci    LinkedListNode *temp = enrolledList->head;
354094332d3Sopenharmony_ci    EnrolledInfoHal *enrolledInfo = NULL;
355094332d3Sopenharmony_ci    const static uint16_t num = 0xFFFF;
356094332d3Sopenharmony_ci    while (temp != NULL) {
357094332d3Sopenharmony_ci        enrolledInfo = (EnrolledInfoHal *)temp->data;
358094332d3Sopenharmony_ci        if ((enrolledInfo != NULL) && (enrolledInfo->enrolledId & num) == (enrolledId & num)) {
359094332d3Sopenharmony_ci            return true;
360094332d3Sopenharmony_ci        }
361094332d3Sopenharmony_ci        temp = temp->next;
362094332d3Sopenharmony_ci    }
363094332d3Sopenharmony_ci
364094332d3Sopenharmony_ci    return false;
365094332d3Sopenharmony_ci}
366094332d3Sopenharmony_ci
367094332d3Sopenharmony_ciIAM_STATIC ResultCode GenerateDeduplicateUint64(LinkedList *collection, uint64_t *destValue, DuplicateCheckFunc func)
368094332d3Sopenharmony_ci{
369094332d3Sopenharmony_ci    if (collection == NULL || destValue == NULL || func == NULL) {
370094332d3Sopenharmony_ci        LOG_ERROR("param is null");
371094332d3Sopenharmony_ci        return RESULT_BAD_PARAM;
372094332d3Sopenharmony_ci    }
373094332d3Sopenharmony_ci
374094332d3Sopenharmony_ci    for (uint32_t i = 0; i < MAX_DUPLICATE_CHECK; ++i) {
375094332d3Sopenharmony_ci        uint64_t tempRandom;
376094332d3Sopenharmony_ci        if (SecureRandom((uint8_t *)&tempRandom, sizeof(uint64_t)) != RESULT_SUCCESS) {
377094332d3Sopenharmony_ci            LOG_ERROR("get random failed");
378094332d3Sopenharmony_ci            return RESULT_GENERAL_ERROR;
379094332d3Sopenharmony_ci        }
380094332d3Sopenharmony_ci        if (!func(collection, tempRandom)) {
381094332d3Sopenharmony_ci            *destValue = tempRandom;
382094332d3Sopenharmony_ci            return RESULT_SUCCESS;
383094332d3Sopenharmony_ci        }
384094332d3Sopenharmony_ci    }
385094332d3Sopenharmony_ci
386094332d3Sopenharmony_ci    LOG_ERROR("generate random failed");
387094332d3Sopenharmony_ci    return RESULT_GENERAL_ERROR;
388094332d3Sopenharmony_ci}
389094332d3Sopenharmony_ci
390094332d3Sopenharmony_ciIAM_STATIC ResultCode UpdateEnrolledId(LinkedList *enrolledList, uint32_t authType)
391094332d3Sopenharmony_ci{
392094332d3Sopenharmony_ci    LinkedListNode *temp = enrolledList->head;
393094332d3Sopenharmony_ci    EnrolledInfoHal *enrolledInfo = NULL;
394094332d3Sopenharmony_ci    while (temp != NULL) {
395094332d3Sopenharmony_ci        EnrolledInfoHal *nodeData = (EnrolledInfoHal *)temp->data;
396094332d3Sopenharmony_ci        if (nodeData != NULL && nodeData->authType == authType) {
397094332d3Sopenharmony_ci            enrolledInfo = nodeData;
398094332d3Sopenharmony_ci            break;
399094332d3Sopenharmony_ci        }
400094332d3Sopenharmony_ci        temp = temp->next;
401094332d3Sopenharmony_ci    }
402094332d3Sopenharmony_ci
403094332d3Sopenharmony_ci    if (enrolledInfo != NULL) {
404094332d3Sopenharmony_ci        return GenerateDeduplicateUint64(enrolledList, &enrolledInfo->enrolledId, IsEnrolledIdDuplicate);
405094332d3Sopenharmony_ci    }
406094332d3Sopenharmony_ci
407094332d3Sopenharmony_ci    enrolledInfo = Malloc(sizeof(EnrolledInfoHal));
408094332d3Sopenharmony_ci    if (enrolledInfo == NULL) {
409094332d3Sopenharmony_ci        LOG_ERROR("enrolledInfo malloc failed");
410094332d3Sopenharmony_ci        return RESULT_NO_MEMORY;
411094332d3Sopenharmony_ci    }
412094332d3Sopenharmony_ci    enrolledInfo->authType = authType;
413094332d3Sopenharmony_ci    ResultCode ret = GenerateDeduplicateUint64(enrolledList, &enrolledInfo->enrolledId, IsEnrolledIdDuplicate);
414094332d3Sopenharmony_ci    if (ret != RESULT_SUCCESS) {
415094332d3Sopenharmony_ci        LOG_ERROR("generate enrolledId failed");
416094332d3Sopenharmony_ci        Free(enrolledInfo);
417094332d3Sopenharmony_ci        return ret;
418094332d3Sopenharmony_ci    }
419094332d3Sopenharmony_ci    ret = enrolledList->insert(enrolledList, enrolledInfo);
420094332d3Sopenharmony_ci    if (ret != RESULT_SUCCESS) {
421094332d3Sopenharmony_ci        LOG_ERROR("enrolledInfo insert failed");
422094332d3Sopenharmony_ci        Free(enrolledInfo);
423094332d3Sopenharmony_ci    }
424094332d3Sopenharmony_ci    return ret;
425094332d3Sopenharmony_ci}
426094332d3Sopenharmony_ci
427094332d3Sopenharmony_ci// add for reliable pin updates
428094332d3Sopenharmony_ciIAM_STATIC uint32_t GetRealAuthTypeForEnrolledId(uint32_t authType)
429094332d3Sopenharmony_ci{
430094332d3Sopenharmony_ci    if (authType == DEFAULT_AUTH_TYPE) {
431094332d3Sopenharmony_ci        return PIN_AUTH;
432094332d3Sopenharmony_ci    }
433094332d3Sopenharmony_ci    return authType;
434094332d3Sopenharmony_ci}
435094332d3Sopenharmony_ci
436094332d3Sopenharmony_ciIAM_STATIC ResultCode AddCredentialToUser(UserInfo *user, CredentialInfoHal *credentialInfo)
437094332d3Sopenharmony_ci{
438094332d3Sopenharmony_ci    if (g_userInfoList == NULL) {
439094332d3Sopenharmony_ci        LOG_ERROR("g_userInfoList is uninitialized");
440094332d3Sopenharmony_ci        return RESULT_NEED_INIT;
441094332d3Sopenharmony_ci    }
442094332d3Sopenharmony_ci    LinkedList *credentialList = user->credentialInfoList;
443094332d3Sopenharmony_ci    LinkedList *enrolledList = user->enrolledInfoList;
444094332d3Sopenharmony_ci    if (credentialList->getSize(credentialList) >= MAX_CREDENTIAL) {
445094332d3Sopenharmony_ci        LOG_ERROR("the number of credentials reaches the maximum");
446094332d3Sopenharmony_ci        return RESULT_EXCEED_LIMIT;
447094332d3Sopenharmony_ci    }
448094332d3Sopenharmony_ci
449094332d3Sopenharmony_ci    ResultCode ret = UpdateEnrolledId(enrolledList, GetRealAuthTypeForEnrolledId(credentialInfo->authType));
450094332d3Sopenharmony_ci    if (ret != RESULT_SUCCESS) {
451094332d3Sopenharmony_ci        LOG_ERROR("update enrolledId failed");
452094332d3Sopenharmony_ci        return ret;
453094332d3Sopenharmony_ci    }
454094332d3Sopenharmony_ci    ret = GenerateDeduplicateUint64(g_userInfoList, &credentialInfo->credentialId, IsCredentialIdDuplicate);
455094332d3Sopenharmony_ci    if (ret != RESULT_SUCCESS) {
456094332d3Sopenharmony_ci        LOG_ERROR("GenerateDeduplicateUint64 failed");
457094332d3Sopenharmony_ci        return ret;
458094332d3Sopenharmony_ci    }
459094332d3Sopenharmony_ci    if (credentialInfo->authType == DEFAULT_AUTH_TYPE) {
460094332d3Sopenharmony_ci        bool isRemoved = false;
461094332d3Sopenharmony_ci        RemoveCachePin(user, &isRemoved);
462094332d3Sopenharmony_ci    }
463094332d3Sopenharmony_ci    CredentialInfoHal *credential = Malloc(sizeof(CredentialInfoHal));
464094332d3Sopenharmony_ci    if (credential == NULL) {
465094332d3Sopenharmony_ci        LOG_ERROR("credential malloc failed");
466094332d3Sopenharmony_ci        return RESULT_NO_MEMORY;
467094332d3Sopenharmony_ci    }
468094332d3Sopenharmony_ci    if (memcpy_s(credential, sizeof(CredentialInfoHal), credentialInfo, sizeof(CredentialInfoHal)) != EOK) {
469094332d3Sopenharmony_ci        LOG_ERROR("credential copy failed");
470094332d3Sopenharmony_ci        Free(credential);
471094332d3Sopenharmony_ci        return RESULT_BAD_COPY;
472094332d3Sopenharmony_ci    }
473094332d3Sopenharmony_ci    credential->enrolledSysTime = GetReeTime();
474094332d3Sopenharmony_ci    ret = credentialList->insert(credentialList, credential);
475094332d3Sopenharmony_ci    if (ret != RESULT_SUCCESS) {
476094332d3Sopenharmony_ci        LOG_ERROR("insert credential failed");
477094332d3Sopenharmony_ci        Free(credential);
478094332d3Sopenharmony_ci    }
479094332d3Sopenharmony_ci    return ret;
480094332d3Sopenharmony_ci}
481094332d3Sopenharmony_ci
482094332d3Sopenharmony_ciIAM_STATIC ResultCode AddUser(int32_t userId, CredentialInfoHal *credentialInfo, int32_t userType)
483094332d3Sopenharmony_ci{
484094332d3Sopenharmony_ci    if (g_userInfoList == NULL) {
485094332d3Sopenharmony_ci        LOG_ERROR("please init");
486094332d3Sopenharmony_ci        return RESULT_NEED_INIT;
487094332d3Sopenharmony_ci    }
488094332d3Sopenharmony_ci    if (g_userInfoList->getSize(g_userInfoList) >= MAX_USER) {
489094332d3Sopenharmony_ci        LOG_ERROR("the number of users reaches the maximum");
490094332d3Sopenharmony_ci        return RESULT_EXCEED_LIMIT;
491094332d3Sopenharmony_ci    }
492094332d3Sopenharmony_ci
493094332d3Sopenharmony_ci    UserInfo *user = QueryUserInfo(userId);
494094332d3Sopenharmony_ci    if (user != NULL) {
495094332d3Sopenharmony_ci        LOG_ERROR("Please check pin");
496094332d3Sopenharmony_ci        return RESULT_BAD_PARAM;
497094332d3Sopenharmony_ci    }
498094332d3Sopenharmony_ci
499094332d3Sopenharmony_ci    user = CreateUser(userId, userType);
500094332d3Sopenharmony_ci    if (user == NULL) {
501094332d3Sopenharmony_ci        LOG_ERROR("create user failed");
502094332d3Sopenharmony_ci        return RESULT_UNKNOWN;
503094332d3Sopenharmony_ci    }
504094332d3Sopenharmony_ci    LOG_INFO("user userType %{public}d", user->userType);
505094332d3Sopenharmony_ci    ResultCode ret = AddCredentialToUser(user, credentialInfo);
506094332d3Sopenharmony_ci    if (ret != RESULT_SUCCESS) {
507094332d3Sopenharmony_ci        LOG_ERROR("add credential to user failed");
508094332d3Sopenharmony_ci        goto FAIL;
509094332d3Sopenharmony_ci    }
510094332d3Sopenharmony_ci
511094332d3Sopenharmony_ci    ret = g_userInfoList->insert(g_userInfoList, user);
512094332d3Sopenharmony_ci    if (ret != RESULT_SUCCESS) {
513094332d3Sopenharmony_ci        LOG_ERROR("insert failed");
514094332d3Sopenharmony_ci        goto FAIL;
515094332d3Sopenharmony_ci    }
516094332d3Sopenharmony_ci    return ret;
517094332d3Sopenharmony_ci
518094332d3Sopenharmony_ciFAIL:
519094332d3Sopenharmony_ci    DestroyUserInfoNode(user);
520094332d3Sopenharmony_ci    return ret;
521094332d3Sopenharmony_ci}
522094332d3Sopenharmony_ci
523094332d3Sopenharmony_ciResultCode AddCredentialInfo(int32_t userId, CredentialInfoHal *credentialInfo, int32_t userType)
524094332d3Sopenharmony_ci{
525094332d3Sopenharmony_ci    if ((credentialInfo == NULL) || (credentialInfo->authType == DEFAULT_AUTH_TYPE)) {
526094332d3Sopenharmony_ci        LOG_ERROR("credentialInfo is invalid");
527094332d3Sopenharmony_ci        return RESULT_BAD_PARAM;
528094332d3Sopenharmony_ci    }
529094332d3Sopenharmony_ci    UserInfo *user = QueryUserInfo(userId);
530094332d3Sopenharmony_ci    if (user == NULL && credentialInfo->authType == PIN_AUTH) {
531094332d3Sopenharmony_ci        ResultCode ret = AddUser(userId, credentialInfo, userType);
532094332d3Sopenharmony_ci        if (ret != RESULT_SUCCESS) {
533094332d3Sopenharmony_ci            LOG_ERROR("add user failed");
534094332d3Sopenharmony_ci            return ret;
535094332d3Sopenharmony_ci        }
536094332d3Sopenharmony_ci        ret = UpdateFileInfo(g_userInfoList);
537094332d3Sopenharmony_ci        if (ret != RESULT_SUCCESS) {
538094332d3Sopenharmony_ci            LOG_ERROR("updateFileInfo failed");
539094332d3Sopenharmony_ci        }
540094332d3Sopenharmony_ci        return ret;
541094332d3Sopenharmony_ci    }
542094332d3Sopenharmony_ci    if (user == NULL) {
543094332d3Sopenharmony_ci        LOG_ERROR("user is null");
544094332d3Sopenharmony_ci        return RESULT_BAD_PARAM;
545094332d3Sopenharmony_ci    }
546094332d3Sopenharmony_ci    if (credentialInfo->authType == PIN_AUTH) {
547094332d3Sopenharmony_ci        CredentialCondition condition = {};
548094332d3Sopenharmony_ci        SetCredentialConditionAuthType(&condition, PIN_AUTH);
549094332d3Sopenharmony_ci        SetCredentialConditionUserId(&condition, userId);
550094332d3Sopenharmony_ci        LinkedList *credList = QueryCredentialLimit(&condition);
551094332d3Sopenharmony_ci        if (credList == NULL) {
552094332d3Sopenharmony_ci            LOG_ERROR("query credential failed");
553094332d3Sopenharmony_ci            return RESULT_UNKNOWN;
554094332d3Sopenharmony_ci        }
555094332d3Sopenharmony_ci        if (credList->getSize(credList) != 0) {
556094332d3Sopenharmony_ci            LOG_INFO("cache pin");
557094332d3Sopenharmony_ci            // add for reliable pin updates
558094332d3Sopenharmony_ci            credentialInfo->authType = DEFAULT_AUTH_TYPE;
559094332d3Sopenharmony_ci        }
560094332d3Sopenharmony_ci        DestroyLinkedList(credList);
561094332d3Sopenharmony_ci    }
562094332d3Sopenharmony_ci    ResultCode ret = AddCredentialToUser(user, credentialInfo);
563094332d3Sopenharmony_ci    if (ret != RESULT_SUCCESS) {
564094332d3Sopenharmony_ci        LOG_ERROR("add credential to user failed");
565094332d3Sopenharmony_ci        return ret;
566094332d3Sopenharmony_ci    }
567094332d3Sopenharmony_ci    ret = UpdateFileInfo(g_userInfoList);
568094332d3Sopenharmony_ci    if (ret != RESULT_SUCCESS) {
569094332d3Sopenharmony_ci        LOG_ERROR("updateFileInfo failed");
570094332d3Sopenharmony_ci    }
571094332d3Sopenharmony_ci    return ret;
572094332d3Sopenharmony_ci}
573094332d3Sopenharmony_ci
574094332d3Sopenharmony_ciIAM_STATIC bool MatchCredentialById(const void *data, const void *condition)
575094332d3Sopenharmony_ci{
576094332d3Sopenharmony_ci    if (data == NULL || condition == NULL) {
577094332d3Sopenharmony_ci        return false;
578094332d3Sopenharmony_ci    }
579094332d3Sopenharmony_ci    const CredentialInfoHal *credentialInfo = (const CredentialInfoHal *)data;
580094332d3Sopenharmony_ci    uint64_t credentialId = *(const uint64_t *)condition;
581094332d3Sopenharmony_ci    if (credentialInfo->credentialId == credentialId) {
582094332d3Sopenharmony_ci        return true;
583094332d3Sopenharmony_ci    }
584094332d3Sopenharmony_ci    return false;
585094332d3Sopenharmony_ci}
586094332d3Sopenharmony_ci
587094332d3Sopenharmony_ciIAM_STATIC bool MatchEnrolledInfoByType(const void *data, const void *condition)
588094332d3Sopenharmony_ci{
589094332d3Sopenharmony_ci    if (data == NULL || condition == NULL) {
590094332d3Sopenharmony_ci        return false;
591094332d3Sopenharmony_ci    }
592094332d3Sopenharmony_ci    const EnrolledInfoHal *enrolledInfo = (const EnrolledInfoHal *)data;
593094332d3Sopenharmony_ci    uint32_t authType = *(const uint32_t *)condition;
594094332d3Sopenharmony_ci    if (enrolledInfo->authType == authType) {
595094332d3Sopenharmony_ci        return true;
596094332d3Sopenharmony_ci    }
597094332d3Sopenharmony_ci    return false;
598094332d3Sopenharmony_ci}
599094332d3Sopenharmony_ci
600094332d3Sopenharmony_ciIAM_STATIC void RemoveCachePin(UserInfo *user, bool *isRemoved)
601094332d3Sopenharmony_ci{
602094332d3Sopenharmony_ci    LOG_INFO("RemoveCachePin start");
603094332d3Sopenharmony_ci    LinkedListNode *temp = user->credentialInfoList->head;
604094332d3Sopenharmony_ci    CredentialInfoHal *credentialInfoCache = NULL;
605094332d3Sopenharmony_ci    while (temp != NULL) {
606094332d3Sopenharmony_ci        CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
607094332d3Sopenharmony_ci        if (nodeData != NULL && nodeData->authType == DEFAULT_AUTH_TYPE) {
608094332d3Sopenharmony_ci            credentialInfoCache = nodeData;
609094332d3Sopenharmony_ci            break;
610094332d3Sopenharmony_ci        }
611094332d3Sopenharmony_ci        temp = temp->next;
612094332d3Sopenharmony_ci    }
613094332d3Sopenharmony_ci    if (credentialInfoCache == NULL) {
614094332d3Sopenharmony_ci        LOG_INFO("RemoveCachePin no cache pin");
615094332d3Sopenharmony_ci        *isRemoved = false;
616094332d3Sopenharmony_ci        return;
617094332d3Sopenharmony_ci    }
618094332d3Sopenharmony_ci    uint64_t credentialId = credentialInfoCache->credentialId;
619094332d3Sopenharmony_ci    ResultCode ret = (user->credentialInfoList)->remove(
620094332d3Sopenharmony_ci        user->credentialInfoList, &credentialId, MatchCredentialById, true);
621094332d3Sopenharmony_ci    if (ret != RESULT_SUCCESS) {
622094332d3Sopenharmony_ci        LOG_ERROR("remove credential failed");
623094332d3Sopenharmony_ci        *isRemoved = false;
624094332d3Sopenharmony_ci        return;
625094332d3Sopenharmony_ci    }
626094332d3Sopenharmony_ci    LOG_ERROR("remove credential success");
627094332d3Sopenharmony_ci    *isRemoved = true;
628094332d3Sopenharmony_ci}
629094332d3Sopenharmony_ci
630094332d3Sopenharmony_civoid ClearCachePin(int32_t userId)
631094332d3Sopenharmony_ci{
632094332d3Sopenharmony_ci    LOG_INFO("ClearCachePin start");
633094332d3Sopenharmony_ci    UserInfo *user = QueryUserInfo(userId);
634094332d3Sopenharmony_ci    if (user == NULL) {
635094332d3Sopenharmony_ci        LOG_ERROR("can't find this user");
636094332d3Sopenharmony_ci        return;
637094332d3Sopenharmony_ci    }
638094332d3Sopenharmony_ci
639094332d3Sopenharmony_ci    bool isRemoved = false;
640094332d3Sopenharmony_ci    RemoveCachePin(user, &isRemoved);
641094332d3Sopenharmony_ci    if (isRemoved && UpdateFileInfo(g_userInfoList) != RESULT_SUCCESS) {
642094332d3Sopenharmony_ci        LOG_ERROR("ClearCachePin save fail");
643094332d3Sopenharmony_ci        return;
644094332d3Sopenharmony_ci    }
645094332d3Sopenharmony_ci}
646094332d3Sopenharmony_ci
647094332d3Sopenharmony_ciIAM_STATIC void SwitchSubType(UserInfo *user)
648094332d3Sopenharmony_ci{
649094332d3Sopenharmony_ci    uint64_t tmpSubType = user->pinSubType;
650094332d3Sopenharmony_ci    user->pinSubType = user->cachePinSubType;
651094332d3Sopenharmony_ci    user->cachePinSubType = tmpSubType;
652094332d3Sopenharmony_ci}
653094332d3Sopenharmony_ci
654094332d3Sopenharmony_ci// add for reliable pin updates
655094332d3Sopenharmony_ciIAM_STATIC ResultCode DeletePinCredentialInfo(UserInfo *user)
656094332d3Sopenharmony_ci{
657094332d3Sopenharmony_ci    LOG_INFO("DeletePinCredentialInfo start");
658094332d3Sopenharmony_ci    LinkedListNode *temp = user->credentialInfoList->head;
659094332d3Sopenharmony_ci    CredentialInfoHal *credentialInfoOld = NULL;
660094332d3Sopenharmony_ci    CredentialInfoHal *credentialInfoCache = NULL;
661094332d3Sopenharmony_ci    while (temp != NULL) {
662094332d3Sopenharmony_ci        CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
663094332d3Sopenharmony_ci        if (nodeData != NULL && nodeData->authType == PIN_AUTH) {
664094332d3Sopenharmony_ci            credentialInfoOld = nodeData;
665094332d3Sopenharmony_ci        }
666094332d3Sopenharmony_ci        if (nodeData != NULL && nodeData->authType == DEFAULT_AUTH_TYPE) {
667094332d3Sopenharmony_ci            credentialInfoCache = nodeData;
668094332d3Sopenharmony_ci        }
669094332d3Sopenharmony_ci        temp = temp->next;
670094332d3Sopenharmony_ci    }
671094332d3Sopenharmony_ci    if (credentialInfoOld == NULL || credentialInfoCache == NULL) {
672094332d3Sopenharmony_ci        LOG_ERROR("no cache pin exist");
673094332d3Sopenharmony_ci        return RESULT_GENERAL_ERROR;
674094332d3Sopenharmony_ci    }
675094332d3Sopenharmony_ci    credentialInfoOld->authType = DEFAULT_AUTH_TYPE;
676094332d3Sopenharmony_ci    credentialInfoCache->authType = PIN_AUTH;
677094332d3Sopenharmony_ci    SwitchSubType(user);
678094332d3Sopenharmony_ci    ResultCode result = UpdateFileInfo(g_userInfoList);
679094332d3Sopenharmony_ci    if (result == RESULT_SUCCESS) {
680094332d3Sopenharmony_ci        LOG_INFO("switch cache pin success");
681094332d3Sopenharmony_ci        ClearCachePin(user->userId);
682094332d3Sopenharmony_ci        return result;
683094332d3Sopenharmony_ci    }
684094332d3Sopenharmony_ci    LOG_ERROR("switch cache pin fail");
685094332d3Sopenharmony_ci    credentialInfoOld->authType = PIN_AUTH;
686094332d3Sopenharmony_ci    credentialInfoCache->authType = DEFAULT_AUTH_TYPE;
687094332d3Sopenharmony_ci    SwitchSubType(user);
688094332d3Sopenharmony_ci    return RESULT_GENERAL_ERROR;
689094332d3Sopenharmony_ci}
690094332d3Sopenharmony_ci
691094332d3Sopenharmony_ciResultCode DeleteCredentialInfo(int32_t userId, uint64_t credentialId, CredentialInfoHal *credentialInfo)
692094332d3Sopenharmony_ci{
693094332d3Sopenharmony_ci    if (credentialInfo == NULL) {
694094332d3Sopenharmony_ci        LOG_ERROR("param is invalid");
695094332d3Sopenharmony_ci        return RESULT_BAD_PARAM;
696094332d3Sopenharmony_ci    }
697094332d3Sopenharmony_ci
698094332d3Sopenharmony_ci    UserInfo *user = QueryUserInfo(userId);
699094332d3Sopenharmony_ci    if (user == NULL) {
700094332d3Sopenharmony_ci        LOG_ERROR("can't find this user");
701094332d3Sopenharmony_ci        return RESULT_BAD_PARAM;
702094332d3Sopenharmony_ci    }
703094332d3Sopenharmony_ci
704094332d3Sopenharmony_ci    LinkedList *credentialList = user->credentialInfoList;
705094332d3Sopenharmony_ci    CredentialInfoHal *credentialQuery = QueryCredentialById(credentialId, credentialList);
706094332d3Sopenharmony_ci    if (credentialQuery == NULL) {
707094332d3Sopenharmony_ci        LOG_ERROR("credentialQuery is null");
708094332d3Sopenharmony_ci        return RESULT_UNKNOWN;
709094332d3Sopenharmony_ci    }
710094332d3Sopenharmony_ci    if (memcpy_s(credentialInfo, sizeof(CredentialInfoHal), credentialQuery, sizeof(CredentialInfoHal)) != EOK) {
711094332d3Sopenharmony_ci        LOG_ERROR("copy failed");
712094332d3Sopenharmony_ci        return RESULT_BAD_COPY;
713094332d3Sopenharmony_ci    }
714094332d3Sopenharmony_ci    if (credentialInfo->authType == PIN_AUTH) {
715094332d3Sopenharmony_ci        return DeletePinCredentialInfo(user);
716094332d3Sopenharmony_ci    }
717094332d3Sopenharmony_ci    ResultCode ret = credentialList->remove(credentialList, &credentialId, MatchCredentialById, true);
718094332d3Sopenharmony_ci    if (ret != RESULT_SUCCESS) {
719094332d3Sopenharmony_ci        LOG_ERROR("remove credential failed");
720094332d3Sopenharmony_ci        return ret;
721094332d3Sopenharmony_ci    }
722094332d3Sopenharmony_ci    if (credentialInfo->authType == DEFAULT_AUTH_TYPE) {
723094332d3Sopenharmony_ci        return UpdateFileInfo(g_userInfoList);
724094332d3Sopenharmony_ci    }
725094332d3Sopenharmony_ci    credentialQuery = QueryCredentialByAuthType(credentialInfo->authType, credentialList);
726094332d3Sopenharmony_ci    if (credentialQuery != NULL) {
727094332d3Sopenharmony_ci        return UpdateFileInfo(g_userInfoList);
728094332d3Sopenharmony_ci    }
729094332d3Sopenharmony_ci
730094332d3Sopenharmony_ci    LinkedList *enrolledInfoList = user->enrolledInfoList;
731094332d3Sopenharmony_ci    if (enrolledInfoList == NULL) {
732094332d3Sopenharmony_ci        LOG_ERROR("enrolledInfoList is null");
733094332d3Sopenharmony_ci        return RESULT_UNKNOWN;
734094332d3Sopenharmony_ci    }
735094332d3Sopenharmony_ci    ret = enrolledInfoList->remove(enrolledInfoList, &credentialInfo->authType, MatchEnrolledInfoByType, true);
736094332d3Sopenharmony_ci    if (ret != RESULT_SUCCESS) {
737094332d3Sopenharmony_ci        LOG_ERROR("remove enrolledInfo failed");
738094332d3Sopenharmony_ci        return ret;
739094332d3Sopenharmony_ci    }
740094332d3Sopenharmony_ci
741094332d3Sopenharmony_ci    return UpdateFileInfo(g_userInfoList);
742094332d3Sopenharmony_ci}
743094332d3Sopenharmony_ci
744094332d3Sopenharmony_ciIAM_STATIC CredentialInfoHal *QueryCredentialById(uint64_t credentialId, LinkedList *credentialList)
745094332d3Sopenharmony_ci{
746094332d3Sopenharmony_ci    if (credentialList == NULL) {
747094332d3Sopenharmony_ci        return NULL;
748094332d3Sopenharmony_ci    }
749094332d3Sopenharmony_ci    LinkedListNode *temp = credentialList->head;
750094332d3Sopenharmony_ci    CredentialInfoHal *credentialInfo = NULL;
751094332d3Sopenharmony_ci    while (temp != NULL) {
752094332d3Sopenharmony_ci        CredentialInfoHal *nodeData = (CredentialInfoHal *)temp->data;
753094332d3Sopenharmony_ci        if (nodeData != NULL && nodeData->credentialId == credentialId) {
754094332d3Sopenharmony_ci            credentialInfo = nodeData;
755094332d3Sopenharmony_ci            break;
756094332d3Sopenharmony_ci        }
757094332d3Sopenharmony_ci        temp = temp->next;
758094332d3Sopenharmony_ci    }
759094332d3Sopenharmony_ci    return credentialInfo;
760094332d3Sopenharmony_ci}
761094332d3Sopenharmony_ci
762094332d3Sopenharmony_ciIAM_STATIC CredentialInfoHal *QueryCredentialByAuthType(uint32_t authType, LinkedList *credentialList)
763094332d3Sopenharmony_ci{
764094332d3Sopenharmony_ci    if (credentialList == NULL) {
765094332d3Sopenharmony_ci        return NULL;
766094332d3Sopenharmony_ci    }
767094332d3Sopenharmony_ci    LinkedListNode *temp = credentialList->head;
768094332d3Sopenharmony_ci    CredentialInfoHal *credentialInfo = NULL;
769094332d3Sopenharmony_ci    while (temp != NULL) {
770094332d3Sopenharmony_ci        CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
771094332d3Sopenharmony_ci        if (nodeData != NULL && nodeData->authType == authType) {
772094332d3Sopenharmony_ci            credentialInfo = nodeData;
773094332d3Sopenharmony_ci            break;
774094332d3Sopenharmony_ci        }
775094332d3Sopenharmony_ci        temp = temp->next;
776094332d3Sopenharmony_ci    }
777094332d3Sopenharmony_ci    return credentialInfo;
778094332d3Sopenharmony_ci}
779094332d3Sopenharmony_ci
780094332d3Sopenharmony_ci// do not cotain cache pin credential
781094332d3Sopenharmony_ciIAM_STATIC bool IsCredMatch(const CredentialCondition *limit, const CredentialInfoHal *credentialInfo)
782094332d3Sopenharmony_ci{
783094332d3Sopenharmony_ci    if ((limit->conditionFactor & CREDENTIAL_CONDITION_CREDENTIAL_ID) != 0 &&
784094332d3Sopenharmony_ci        limit->credentialId != credentialInfo->credentialId) {
785094332d3Sopenharmony_ci        return false;
786094332d3Sopenharmony_ci    }
787094332d3Sopenharmony_ci    if (credentialInfo->authType == DEFAULT_AUTH_TYPE) {
788094332d3Sopenharmony_ci        if ((limit->conditionFactor & CREDENTIAL_CONDITION_NEED_CACHE_PIN) == 0) {
789094332d3Sopenharmony_ci            return false;
790094332d3Sopenharmony_ci        }
791094332d3Sopenharmony_ci    } else {
792094332d3Sopenharmony_ci        if ((limit->conditionFactor & CREDENTIAL_CONDITION_AUTH_TYPE) != 0 &&
793094332d3Sopenharmony_ci            limit->authType != credentialInfo->authType) {
794094332d3Sopenharmony_ci            return false;
795094332d3Sopenharmony_ci        }
796094332d3Sopenharmony_ci    }
797094332d3Sopenharmony_ci    if ((limit->conditionFactor & CREDENTIAL_CONDITION_TEMPLATE_ID) != 0 &&
798094332d3Sopenharmony_ci        limit->templateId != credentialInfo->templateId) {
799094332d3Sopenharmony_ci        return false;
800094332d3Sopenharmony_ci    }
801094332d3Sopenharmony_ci    if ((limit->conditionFactor & CREDENTIAL_CONDITION_SENSOR_HINT) != 0 &&
802094332d3Sopenharmony_ci        limit->executorSensorHint != INVALID_SENSOR_HINT &&
803094332d3Sopenharmony_ci        limit->executorSensorHint != credentialInfo->executorSensorHint) {
804094332d3Sopenharmony_ci        return false;
805094332d3Sopenharmony_ci    }
806094332d3Sopenharmony_ci    if ((limit->conditionFactor & CREDENTIAL_CONDITION_EXECUTOR_MATCHER) != 0 &&
807094332d3Sopenharmony_ci        limit->executorMatcher != credentialInfo->executorMatcher) {
808094332d3Sopenharmony_ci        return false;
809094332d3Sopenharmony_ci    }
810094332d3Sopenharmony_ci    return true;
811094332d3Sopenharmony_ci}
812094332d3Sopenharmony_ci
813094332d3Sopenharmony_ciIAM_STATIC bool IsUserMatch(const CredentialCondition *limit, const UserInfo *user)
814094332d3Sopenharmony_ci{
815094332d3Sopenharmony_ci    if ((limit->conditionFactor & CREDENTIAL_CONDITION_USER_ID) != 0 && limit->userId != user->userId) {
816094332d3Sopenharmony_ci        return false;
817094332d3Sopenharmony_ci    }
818094332d3Sopenharmony_ci    return true;
819094332d3Sopenharmony_ci}
820094332d3Sopenharmony_ci
821094332d3Sopenharmony_ci// do not cotain cache pin credential
822094332d3Sopenharmony_ciIAM_STATIC ResultCode TraverseCredentialList(const CredentialCondition *limit, const LinkedList *credentialList,
823094332d3Sopenharmony_ci    LinkedList *credListGet)
824094332d3Sopenharmony_ci{
825094332d3Sopenharmony_ci    if (credentialList == NULL) {
826094332d3Sopenharmony_ci        LOG_ERROR("credentialList is null");
827094332d3Sopenharmony_ci        return RESULT_GENERAL_ERROR;
828094332d3Sopenharmony_ci    }
829094332d3Sopenharmony_ci    LinkedListNode *temp = credentialList->head;
830094332d3Sopenharmony_ci    while (temp != NULL) {
831094332d3Sopenharmony_ci        CredentialInfoHal *nodeData = (CredentialInfoHal*)temp->data;
832094332d3Sopenharmony_ci        if (nodeData == NULL) {
833094332d3Sopenharmony_ci            LOG_ERROR("nodeData is null");
834094332d3Sopenharmony_ci            return RESULT_UNKNOWN;
835094332d3Sopenharmony_ci        }
836094332d3Sopenharmony_ci        if (!IsCredMatch(limit, nodeData)) {
837094332d3Sopenharmony_ci            temp = temp->next;
838094332d3Sopenharmony_ci            continue;
839094332d3Sopenharmony_ci        }
840094332d3Sopenharmony_ci        CredentialInfoHal *copy = (CredentialInfoHal *)Malloc(sizeof(CredentialInfoHal));
841094332d3Sopenharmony_ci        if (copy == NULL) {
842094332d3Sopenharmony_ci            LOG_ERROR("copy malloc failed");
843094332d3Sopenharmony_ci            return RESULT_NO_MEMORY;
844094332d3Sopenharmony_ci        }
845094332d3Sopenharmony_ci        *copy = *nodeData;
846094332d3Sopenharmony_ci        ResultCode ret = credListGet->insert(credListGet, copy);
847094332d3Sopenharmony_ci        if (ret != RESULT_SUCCESS) {
848094332d3Sopenharmony_ci            LOG_ERROR("insert failed");
849094332d3Sopenharmony_ci            Free(copy);
850094332d3Sopenharmony_ci            return ret;
851094332d3Sopenharmony_ci        }
852094332d3Sopenharmony_ci        temp = temp->next;
853094332d3Sopenharmony_ci    }
854094332d3Sopenharmony_ci    return RESULT_SUCCESS;
855094332d3Sopenharmony_ci}
856094332d3Sopenharmony_ci
857094332d3Sopenharmony_ci// do not cotain cache pin credential
858094332d3Sopenharmony_ciLinkedList *QueryCredentialLimit(const CredentialCondition *limit)
859094332d3Sopenharmony_ci{
860094332d3Sopenharmony_ci    if (limit == NULL) {
861094332d3Sopenharmony_ci        LOG_ERROR("limit is null");
862094332d3Sopenharmony_ci        return NULL;
863094332d3Sopenharmony_ci    }
864094332d3Sopenharmony_ci    if (g_userInfoList == NULL) {
865094332d3Sopenharmony_ci        LOG_ERROR("g_userInfoList is null");
866094332d3Sopenharmony_ci        return NULL;
867094332d3Sopenharmony_ci    }
868094332d3Sopenharmony_ci    LinkedList *credList = CreateLinkedList(DestroyCredentialNode);
869094332d3Sopenharmony_ci    if (credList == NULL) {
870094332d3Sopenharmony_ci        LOG_ERROR("credList is null");
871094332d3Sopenharmony_ci        return NULL;
872094332d3Sopenharmony_ci    }
873094332d3Sopenharmony_ci    LinkedListNode *temp = g_userInfoList->head;
874094332d3Sopenharmony_ci    while (temp != NULL) {
875094332d3Sopenharmony_ci        UserInfo *user = (UserInfo *)temp->data;
876094332d3Sopenharmony_ci        if (user == NULL) {
877094332d3Sopenharmony_ci            LOG_ERROR("node data is null");
878094332d3Sopenharmony_ci            DestroyLinkedList(credList);
879094332d3Sopenharmony_ci            return NULL;
880094332d3Sopenharmony_ci        }
881094332d3Sopenharmony_ci        if (IsUserMatch(limit, user)) {
882094332d3Sopenharmony_ci            ResultCode ret = TraverseCredentialList(limit, user->credentialInfoList, credList);
883094332d3Sopenharmony_ci            if (ret != RESULT_SUCCESS) {
884094332d3Sopenharmony_ci                LOG_ERROR("TraverseCredentialList failed");
885094332d3Sopenharmony_ci                DestroyLinkedList(credList);
886094332d3Sopenharmony_ci                return NULL;
887094332d3Sopenharmony_ci            }
888094332d3Sopenharmony_ci        }
889094332d3Sopenharmony_ci        temp = temp->next;
890094332d3Sopenharmony_ci    }
891094332d3Sopenharmony_ci    return credList;
892094332d3Sopenharmony_ci}
893094332d3Sopenharmony_ci
894094332d3Sopenharmony_ciResultCode QueryCredentialUserId(uint64_t credentialId, int32_t *userId)
895094332d3Sopenharmony_ci{
896094332d3Sopenharmony_ci    if (userId == NULL) {
897094332d3Sopenharmony_ci        LOG_ERROR("userId is null");
898094332d3Sopenharmony_ci        return RESULT_BAD_PARAM;
899094332d3Sopenharmony_ci    }
900094332d3Sopenharmony_ci    if (g_userInfoList == NULL) {
901094332d3Sopenharmony_ci        LOG_ERROR("g_userInfoList is null");
902094332d3Sopenharmony_ci        return RESULT_NEED_INIT;
903094332d3Sopenharmony_ci    }
904094332d3Sopenharmony_ci    LinkedList *credList = CreateLinkedList(DestroyCredentialNode);
905094332d3Sopenharmony_ci    if (credList == NULL) {
906094332d3Sopenharmony_ci        LOG_ERROR("credList is null");
907094332d3Sopenharmony_ci        return RESULT_NO_MEMORY;
908094332d3Sopenharmony_ci    }
909094332d3Sopenharmony_ci    LinkedListNode *temp = g_userInfoList->head;
910094332d3Sopenharmony_ci    CredentialCondition condition = {};
911094332d3Sopenharmony_ci    SetCredentialConditionCredentialId(&condition, credentialId);
912094332d3Sopenharmony_ci    while (temp != NULL) {
913094332d3Sopenharmony_ci        UserInfo *user = (UserInfo *)temp->data;
914094332d3Sopenharmony_ci        if (user == NULL) {
915094332d3Sopenharmony_ci            LOG_ERROR("user is null");
916094332d3Sopenharmony_ci            DestroyLinkedList(credList);
917094332d3Sopenharmony_ci            return RESULT_UNKNOWN;
918094332d3Sopenharmony_ci        }
919094332d3Sopenharmony_ci        ResultCode ret = TraverseCredentialList(&condition, user->credentialInfoList, credList);
920094332d3Sopenharmony_ci        if (ret != RESULT_SUCCESS) {
921094332d3Sopenharmony_ci            LOG_ERROR("TraverseCredentialList failed");
922094332d3Sopenharmony_ci            DestroyLinkedList(credList);
923094332d3Sopenharmony_ci            return RESULT_UNKNOWN;
924094332d3Sopenharmony_ci        }
925094332d3Sopenharmony_ci        if (credList->getSize(credList) != 0) {
926094332d3Sopenharmony_ci            DestroyLinkedList(credList);
927094332d3Sopenharmony_ci            *userId = user->userId;
928094332d3Sopenharmony_ci            return RESULT_SUCCESS;
929094332d3Sopenharmony_ci        }
930094332d3Sopenharmony_ci        temp = temp->next;
931094332d3Sopenharmony_ci    }
932094332d3Sopenharmony_ci    DestroyLinkedList(credList);
933094332d3Sopenharmony_ci    LOG_ERROR("can't find this credential");
934094332d3Sopenharmony_ci    return RESULT_NOT_FOUND;
935094332d3Sopenharmony_ci}
936094332d3Sopenharmony_ci
937094332d3Sopenharmony_ciResultCode SetPinSubType(int32_t userId, uint64_t pinSubType)
938094332d3Sopenharmony_ci{
939094332d3Sopenharmony_ci    UserInfo *user = QueryUserInfo(userId);
940094332d3Sopenharmony_ci    if (user == NULL) {
941094332d3Sopenharmony_ci        LOG_ERROR("can't find this user");
942094332d3Sopenharmony_ci        return RESULT_NOT_FOUND;
943094332d3Sopenharmony_ci    }
944094332d3Sopenharmony_ci    user->pinSubType = pinSubType;
945094332d3Sopenharmony_ci    return RESULT_SUCCESS;
946094332d3Sopenharmony_ci}
947094332d3Sopenharmony_ci
948094332d3Sopenharmony_ciResultCode GetPinSubType(int32_t userId, uint64_t *pinSubType)
949094332d3Sopenharmony_ci{
950094332d3Sopenharmony_ci    if (pinSubType == NULL) {
951094332d3Sopenharmony_ci        LOG_ERROR("pinSubType is null");
952094332d3Sopenharmony_ci        return RESULT_BAD_PARAM;
953094332d3Sopenharmony_ci    }
954094332d3Sopenharmony_ci    UserInfo *user = QueryUserInfo(userId);
955094332d3Sopenharmony_ci    if (user == NULL) {
956094332d3Sopenharmony_ci        LOG_ERROR("can't find this user");
957094332d3Sopenharmony_ci        return RESULT_NOT_FOUND;
958094332d3Sopenharmony_ci    }
959094332d3Sopenharmony_ci    *pinSubType = user->pinSubType;
960094332d3Sopenharmony_ci    return RESULT_SUCCESS;
961094332d3Sopenharmony_ci}
962094332d3Sopenharmony_ci
963094332d3Sopenharmony_civoid SetCredentialConditionCredentialId(CredentialCondition *condition, uint64_t credentialId)
964094332d3Sopenharmony_ci{
965094332d3Sopenharmony_ci    if (condition == NULL) {
966094332d3Sopenharmony_ci        LOG_ERROR("condition is null");
967094332d3Sopenharmony_ci        return;
968094332d3Sopenharmony_ci    }
969094332d3Sopenharmony_ci    condition->credentialId = credentialId;
970094332d3Sopenharmony_ci    condition->conditionFactor |= CREDENTIAL_CONDITION_CREDENTIAL_ID;
971094332d3Sopenharmony_ci}
972094332d3Sopenharmony_ci
973094332d3Sopenharmony_civoid SetCredentialConditionTemplateId(CredentialCondition *condition, uint64_t templateId)
974094332d3Sopenharmony_ci{
975094332d3Sopenharmony_ci    if (condition == NULL) {
976094332d3Sopenharmony_ci        LOG_ERROR("condition is null");
977094332d3Sopenharmony_ci        return;
978094332d3Sopenharmony_ci    }
979094332d3Sopenharmony_ci    condition->templateId = templateId;
980094332d3Sopenharmony_ci    condition->conditionFactor |= CREDENTIAL_CONDITION_TEMPLATE_ID;
981094332d3Sopenharmony_ci}
982094332d3Sopenharmony_ci
983094332d3Sopenharmony_civoid SetCredentialConditionAuthType(CredentialCondition *condition, uint32_t authType)
984094332d3Sopenharmony_ci{
985094332d3Sopenharmony_ci    if (condition == NULL) {
986094332d3Sopenharmony_ci        LOG_ERROR("condition is null");
987094332d3Sopenharmony_ci        return;
988094332d3Sopenharmony_ci    }
989094332d3Sopenharmony_ci    condition->authType = authType;
990094332d3Sopenharmony_ci    condition->conditionFactor |= CREDENTIAL_CONDITION_AUTH_TYPE;
991094332d3Sopenharmony_ci}
992094332d3Sopenharmony_ci
993094332d3Sopenharmony_civoid SetCredentialConditionExecutorSensorHint(CredentialCondition *condition, uint32_t executorSensorHint)
994094332d3Sopenharmony_ci{
995094332d3Sopenharmony_ci    if (condition == NULL) {
996094332d3Sopenharmony_ci        LOG_ERROR("condition is null");
997094332d3Sopenharmony_ci        return;
998094332d3Sopenharmony_ci    }
999094332d3Sopenharmony_ci    condition->executorSensorHint = executorSensorHint;
1000094332d3Sopenharmony_ci    condition->conditionFactor |= CREDENTIAL_CONDITION_SENSOR_HINT;
1001094332d3Sopenharmony_ci}
1002094332d3Sopenharmony_ci
1003094332d3Sopenharmony_civoid SetCredentialConditionExecutorMatcher(CredentialCondition *condition, uint32_t executorMatcher)
1004094332d3Sopenharmony_ci{
1005094332d3Sopenharmony_ci    if (condition == NULL) {
1006094332d3Sopenharmony_ci        LOG_ERROR("condition is null");
1007094332d3Sopenharmony_ci        return;
1008094332d3Sopenharmony_ci    }
1009094332d3Sopenharmony_ci    condition->executorMatcher = executorMatcher;
1010094332d3Sopenharmony_ci    condition->conditionFactor |= CREDENTIAL_CONDITION_EXECUTOR_MATCHER;
1011094332d3Sopenharmony_ci}
1012094332d3Sopenharmony_ci
1013094332d3Sopenharmony_civoid SetCredentialConditionUserId(CredentialCondition *condition, int32_t userId)
1014094332d3Sopenharmony_ci{
1015094332d3Sopenharmony_ci    if (condition == NULL) {
1016094332d3Sopenharmony_ci        LOG_ERROR("condition is null");
1017094332d3Sopenharmony_ci        return;
1018094332d3Sopenharmony_ci    }
1019094332d3Sopenharmony_ci    condition->userId = userId;
1020094332d3Sopenharmony_ci    condition->conditionFactor |= CREDENTIAL_CONDITION_USER_ID;
1021094332d3Sopenharmony_ci}
1022094332d3Sopenharmony_ci
1023094332d3Sopenharmony_civoid SetCredentiaConditionNeedCachePin(CredentialCondition *condition)
1024094332d3Sopenharmony_ci{
1025094332d3Sopenharmony_ci    if (condition == NULL) {
1026094332d3Sopenharmony_ci        LOG_ERROR("condition is null");
1027094332d3Sopenharmony_ci        return;
1028094332d3Sopenharmony_ci    }
1029094332d3Sopenharmony_ci    condition->conditionFactor |= CREDENTIAL_CONDITION_NEED_CACHE_PIN;
1030094332d3Sopenharmony_ci}
1031094332d3Sopenharmony_ci
1032094332d3Sopenharmony_ciIAM_STATIC bool IsUserValid(UserInfo *user)
1033094332d3Sopenharmony_ci{
1034094332d3Sopenharmony_ci    LinkedList *credentialInfoList = user->credentialInfoList;
1035094332d3Sopenharmony_ci    CredentialInfoHal *pinCredential = QueryCredentialByAuthType(PIN_AUTH, credentialInfoList);
1036094332d3Sopenharmony_ci    if (pinCredential == NULL) {
1037094332d3Sopenharmony_ci        LOG_INFO("user is invalid, userId: %{public}d", user->userId);
1038094332d3Sopenharmony_ci        return false;
1039094332d3Sopenharmony_ci    }
1040094332d3Sopenharmony_ci    return true;
1041094332d3Sopenharmony_ci}
1042094332d3Sopenharmony_ci
1043094332d3Sopenharmony_ciIAM_STATIC ResultCode GetInvalidUser(int32_t *invalidUserId, uint32_t maxUserCount, uint32_t *userCount,
1044094332d3Sopenharmony_ci    bool *cachePinRemoved)
1045094332d3Sopenharmony_ci{
1046094332d3Sopenharmony_ci    LOG_INFO("get invalid user start");
1047094332d3Sopenharmony_ci    if (g_userInfoList == NULL) {
1048094332d3Sopenharmony_ci        LOG_ERROR("g_userInfoList is null");
1049094332d3Sopenharmony_ci        return RESULT_GENERAL_ERROR;
1050094332d3Sopenharmony_ci    }
1051094332d3Sopenharmony_ci
1052094332d3Sopenharmony_ci    LinkedListIterator *iterator = g_userInfoList->createIterator(g_userInfoList);
1053094332d3Sopenharmony_ci    if (iterator == NULL) {
1054094332d3Sopenharmony_ci        LOG_ERROR("create iterator failed");
1055094332d3Sopenharmony_ci        return RESULT_NO_MEMORY;
1056094332d3Sopenharmony_ci    }
1057094332d3Sopenharmony_ci
1058094332d3Sopenharmony_ci    UserInfo *user = NULL;
1059094332d3Sopenharmony_ci    *userCount = 0;
1060094332d3Sopenharmony_ci    while (iterator->hasNext(iterator)) {
1061094332d3Sopenharmony_ci        user = (UserInfo *)iterator->next(iterator);
1062094332d3Sopenharmony_ci        if (user == NULL) {
1063094332d3Sopenharmony_ci            LOG_ERROR("userinfo list node is null, please check");
1064094332d3Sopenharmony_ci            continue;
1065094332d3Sopenharmony_ci        }
1066094332d3Sopenharmony_ci
1067094332d3Sopenharmony_ci        if (*userCount >= maxUserCount) {
1068094332d3Sopenharmony_ci            LOG_ERROR("too many users");
1069094332d3Sopenharmony_ci            break;
1070094332d3Sopenharmony_ci        }
1071094332d3Sopenharmony_ci
1072094332d3Sopenharmony_ci        if (!IsUserValid(user)) {
1073094332d3Sopenharmony_ci            invalidUserId[*userCount] = user->userId;
1074094332d3Sopenharmony_ci            (*userCount)++;
1075094332d3Sopenharmony_ci            continue;
1076094332d3Sopenharmony_ci        }
1077094332d3Sopenharmony_ci
1078094332d3Sopenharmony_ci        bool isRemoved = false;
1079094332d3Sopenharmony_ci        RemoveCachePin(user, &isRemoved);
1080094332d3Sopenharmony_ci        if (isRemoved) {
1081094332d3Sopenharmony_ci            *cachePinRemoved = true;
1082094332d3Sopenharmony_ci        }
1083094332d3Sopenharmony_ci    }
1084094332d3Sopenharmony_ci
1085094332d3Sopenharmony_ci    g_userInfoList->destroyIterator(iterator);
1086094332d3Sopenharmony_ci    return RESULT_SUCCESS;
1087094332d3Sopenharmony_ci}
1088094332d3Sopenharmony_ci
1089094332d3Sopenharmony_ciIAM_STATIC ResultCode ClearInvalidData(void)
1090094332d3Sopenharmony_ci{
1091094332d3Sopenharmony_ci    LOG_INFO("clear invalid user start");
1092094332d3Sopenharmony_ci    int32_t invalidUserId[MAX_USER] = {0};
1093094332d3Sopenharmony_ci    uint32_t userCount = 0;
1094094332d3Sopenharmony_ci    bool cachePinRemoved = false;
1095094332d3Sopenharmony_ci    if (GetInvalidUser(invalidUserId, MAX_USER, &userCount, &cachePinRemoved) != RESULT_SUCCESS) {
1096094332d3Sopenharmony_ci        LOG_ERROR("GetInvalidUser fail");
1097094332d3Sopenharmony_ci        return RESULT_GENERAL_ERROR;
1098094332d3Sopenharmony_ci    }
1099094332d3Sopenharmony_ci    ResultCode ret = RESULT_SUCCESS;
1100094332d3Sopenharmony_ci    for (uint32_t i = 0; i < userCount; ++i) {
1101094332d3Sopenharmony_ci        ret = DeleteUser(invalidUserId[i]);
1102094332d3Sopenharmony_ci        if (ret != RESULT_SUCCESS) {
1103094332d3Sopenharmony_ci            LOG_ERROR("delete invalid user fail, userId: %{public}d, ret: %{public}d", invalidUserId[i], ret);
1104094332d3Sopenharmony_ci            return ret;
1105094332d3Sopenharmony_ci        }
1106094332d3Sopenharmony_ci        LOG_INFO("delete invalid user success, userId: %{public}d, ret: %{public}d", invalidUserId[i], ret);
1107094332d3Sopenharmony_ci    }
1108094332d3Sopenharmony_ci
1109094332d3Sopenharmony_ci    if ((userCount != 0) || cachePinRemoved) {
1110094332d3Sopenharmony_ci        ret = UpdateFileInfo(g_userInfoList);
1111094332d3Sopenharmony_ci        if (ret != RESULT_SUCCESS) {
1112094332d3Sopenharmony_ci            LOG_ERROR("UpdateFileInfo fail, ret: %{public}d", ret);
1113094332d3Sopenharmony_ci            return ret;
1114094332d3Sopenharmony_ci        }
1115094332d3Sopenharmony_ci    }
1116094332d3Sopenharmony_ci    return RESULT_SUCCESS;
1117094332d3Sopenharmony_ci}
1118094332d3Sopenharmony_ci
1119094332d3Sopenharmony_ciResultCode GetAllExtUserInfo(UserInfoResult *userInfos, uint32_t userInfoLen, uint32_t *userInfocount)
1120094332d3Sopenharmony_ci{
1121094332d3Sopenharmony_ci    LOG_INFO("get all user info start");
1122094332d3Sopenharmony_ci    if (userInfos == NULL || userInfocount == NULL || g_userInfoList == NULL) {
1123094332d3Sopenharmony_ci        LOG_ERROR("param is null");
1124094332d3Sopenharmony_ci        return RESULT_BAD_PARAM;
1125094332d3Sopenharmony_ci    }
1126094332d3Sopenharmony_ci
1127094332d3Sopenharmony_ci    LinkedListIterator *iterator = g_userInfoList->createIterator(g_userInfoList);
1128094332d3Sopenharmony_ci    if (iterator == NULL) {
1129094332d3Sopenharmony_ci        LOG_ERROR("create iterator failed");
1130094332d3Sopenharmony_ci        return RESULT_NO_MEMORY;
1131094332d3Sopenharmony_ci    }
1132094332d3Sopenharmony_ci
1133094332d3Sopenharmony_ci    UserInfo *user = NULL;
1134094332d3Sopenharmony_ci    EnrolledInfoHal *enrolledInfoHal = NULL;
1135094332d3Sopenharmony_ci    *userInfocount = 0;
1136094332d3Sopenharmony_ci    while (iterator->hasNext(iterator)) {
1137094332d3Sopenharmony_ci        user = (UserInfo *)iterator->next(iterator);
1138094332d3Sopenharmony_ci        if (user == NULL) {
1139094332d3Sopenharmony_ci            LOG_ERROR("userinfo list node is null, please check");
1140094332d3Sopenharmony_ci            continue;
1141094332d3Sopenharmony_ci        }
1142094332d3Sopenharmony_ci
1143094332d3Sopenharmony_ci        if (*userInfocount >= userInfoLen) {
1144094332d3Sopenharmony_ci            LOG_ERROR("too many users");
1145094332d3Sopenharmony_ci            goto ERROR;
1146094332d3Sopenharmony_ci        }
1147094332d3Sopenharmony_ci
1148094332d3Sopenharmony_ci        userInfos[*userInfocount].userId = user->userId;
1149094332d3Sopenharmony_ci        userInfos[*userInfocount].secUid = user->secUid;
1150094332d3Sopenharmony_ci        userInfos[*userInfocount].pinSubType = (uint32_t)user->pinSubType;
1151094332d3Sopenharmony_ci
1152094332d3Sopenharmony_ci        ResultCode ret = GetAllEnrolledInfoFromUser(user, &enrolledInfoHal, &(userInfos[*userInfocount].enrollNum));
1153094332d3Sopenharmony_ci        if (ret != RESULT_SUCCESS) {
1154094332d3Sopenharmony_ci            LOG_ERROR("get enrolled info fail");
1155094332d3Sopenharmony_ci            goto ERROR;
1156094332d3Sopenharmony_ci        }
1157094332d3Sopenharmony_ci        if (userInfos[*userInfocount].enrollNum > MAX_ENROLL_OUTPUT) {
1158094332d3Sopenharmony_ci            LOG_ERROR("too many elements");
1159094332d3Sopenharmony_ci            free(enrolledInfoHal);
1160094332d3Sopenharmony_ci            goto ERROR;
1161094332d3Sopenharmony_ci        }
1162094332d3Sopenharmony_ci
1163094332d3Sopenharmony_ci        for (uint32_t i = 0; i < userInfos[*userInfocount].enrollNum; i++) {
1164094332d3Sopenharmony_ci            userInfos[*userInfocount].enrolledInfo[i].authType = enrolledInfoHal[i].authType;
1165094332d3Sopenharmony_ci            userInfos[*userInfocount].enrolledInfo[i].enrolledId = enrolledInfoHal[i].enrolledId;
1166094332d3Sopenharmony_ci        }
1167094332d3Sopenharmony_ci
1168094332d3Sopenharmony_ci        free(enrolledInfoHal);
1169094332d3Sopenharmony_ci        (*userInfocount)++;
1170094332d3Sopenharmony_ci    }
1171094332d3Sopenharmony_ci
1172094332d3Sopenharmony_ci    g_userInfoList->destroyIterator(iterator);
1173094332d3Sopenharmony_ci    return RESULT_SUCCESS;
1174094332d3Sopenharmony_ci
1175094332d3Sopenharmony_ciERROR:
1176094332d3Sopenharmony_ci    g_userInfoList->destroyIterator(iterator);
1177094332d3Sopenharmony_ci    return RESULT_GENERAL_ERROR;
1178094332d3Sopenharmony_ci}
1179094332d3Sopenharmony_ci
1180094332d3Sopenharmony_ciResultCode GetEnrolledState(int32_t userId, uint32_t authType, EnrolledStateHal *enrolledStateHal)
1181094332d3Sopenharmony_ci{
1182094332d3Sopenharmony_ci    LOG_INFO("get enrolled id info start, userId:%{public}d, authType:%{public}d", userId, authType);
1183094332d3Sopenharmony_ci
1184094332d3Sopenharmony_ci    UserInfo *user = QueryUserInfo(userId);
1185094332d3Sopenharmony_ci    if (user == NULL) {
1186094332d3Sopenharmony_ci        LOG_ERROR("user is null");
1187094332d3Sopenharmony_ci        return RESULT_NOT_ENROLLED;
1188094332d3Sopenharmony_ci    }
1189094332d3Sopenharmony_ci    if (user->credentialInfoList == NULL) {
1190094332d3Sopenharmony_ci        LOG_ERROR("credentialInfoList is null");
1191094332d3Sopenharmony_ci        return RESULT_NOT_ENROLLED;
1192094332d3Sopenharmony_ci    }
1193094332d3Sopenharmony_ci
1194094332d3Sopenharmony_ci    uint16_t credentialCount = 0;
1195094332d3Sopenharmony_ci    LinkedListNode *credentialInfoTemp = user->credentialInfoList->head;
1196094332d3Sopenharmony_ci    while (credentialInfoTemp != NULL) {
1197094332d3Sopenharmony_ci        CredentialInfoHal *nodeInfo = credentialInfoTemp->data;
1198094332d3Sopenharmony_ci        if (nodeInfo != NULL && nodeInfo->authType == authType) {
1199094332d3Sopenharmony_ci            ++credentialCount;
1200094332d3Sopenharmony_ci        }
1201094332d3Sopenharmony_ci        credentialInfoTemp = credentialInfoTemp->next;
1202094332d3Sopenharmony_ci    }
1203094332d3Sopenharmony_ci    if (credentialCount == 0) {
1204094332d3Sopenharmony_ci        LOG_ERROR("not enrolled");
1205094332d3Sopenharmony_ci        return RESULT_NOT_ENROLLED;
1206094332d3Sopenharmony_ci    }
1207094332d3Sopenharmony_ci    enrolledStateHal->credentialCount = credentialCount;
1208094332d3Sopenharmony_ci    if (user->enrolledInfoList == NULL) {
1209094332d3Sopenharmony_ci        LOG_ERROR("enrolledInfoList is null");
1210094332d3Sopenharmony_ci        return RESULT_NOT_ENROLLED;
1211094332d3Sopenharmony_ci    }
1212094332d3Sopenharmony_ci    LinkedListNode *enrolledInfoTemp = user->enrolledInfoList->head;
1213094332d3Sopenharmony_ci    while (enrolledInfoTemp != NULL) {
1214094332d3Sopenharmony_ci        EnrolledInfoHal *nodeInfo = enrolledInfoTemp->data;
1215094332d3Sopenharmony_ci        if (nodeInfo != NULL && nodeInfo->authType == authType) {
1216094332d3Sopenharmony_ci            enrolledStateHal->credentialDigest = nodeInfo->enrolledId;
1217094332d3Sopenharmony_ci            break;
1218094332d3Sopenharmony_ci        }
1219094332d3Sopenharmony_ci        enrolledInfoTemp = enrolledInfoTemp->next;
1220094332d3Sopenharmony_ci    }
1221094332d3Sopenharmony_ci    return RESULT_SUCCESS;
1222094332d3Sopenharmony_ci}
1223094332d3Sopenharmony_ci
1224094332d3Sopenharmony_ciIAM_STATIC ResultCode UpdateGlobalConfigArray(GlobalConfigParamHal *param, uint32_t authType)
1225094332d3Sopenharmony_ci{
1226094332d3Sopenharmony_ci    uint32_t infoIndex = 0;
1227094332d3Sopenharmony_ci    for (infoIndex = 0; infoIndex < g_globalConfigInfoNum; infoIndex++) {
1228094332d3Sopenharmony_ci        if (g_globalConfigArray[infoIndex].type == param->type &&
1229094332d3Sopenharmony_ci            g_globalConfigArray[infoIndex].authType == authType) {
1230094332d3Sopenharmony_ci            LOG_INFO("globalConfig is already exist, type:%{public}d, authType:%{public}u", param->type, authType);
1231094332d3Sopenharmony_ci            break;
1232094332d3Sopenharmony_ci        }
1233094332d3Sopenharmony_ci    }
1234094332d3Sopenharmony_ci    if (infoIndex >= MAX_GLOBAL_CONFIG_NUM) {
1235094332d3Sopenharmony_ci        LOG_ERROR("globalConfigArray is exceed limit");
1236094332d3Sopenharmony_ci        return RESULT_EXCEED_LIMIT;
1237094332d3Sopenharmony_ci    }
1238094332d3Sopenharmony_ci    memset_s(&g_globalConfigArray[infoIndex], sizeof(GlobalConfigInfo), 0, sizeof(GlobalConfigInfo));
1239094332d3Sopenharmony_ci
1240094332d3Sopenharmony_ci    switch (param->type) {
1241094332d3Sopenharmony_ci        case PIN_EXPIRED_PERIOD:
1242094332d3Sopenharmony_ci            if (authType != PIN_AUTH) {
1243094332d3Sopenharmony_ci                LOG_ERROR("bad authType:%{public}u for PIN_EXPIRED_PERIOD", authType);
1244094332d3Sopenharmony_ci                return RESULT_BAD_PARAM;
1245094332d3Sopenharmony_ci            }
1246094332d3Sopenharmony_ci            g_globalConfigArray[infoIndex].value.pinExpiredPeriod = param->value.pinExpiredPeriod;
1247094332d3Sopenharmony_ci            break;
1248094332d3Sopenharmony_ci        case ENABLE_STATUS:
1249094332d3Sopenharmony_ci            g_globalConfigArray[infoIndex].value.enableStatus = param->value.enableStatus;
1250094332d3Sopenharmony_ci            break;
1251094332d3Sopenharmony_ci        default:
1252094332d3Sopenharmony_ci            LOG_ERROR("globalConfigType not support, type:%{public}d.", param->type);
1253094332d3Sopenharmony_ci            return RESULT_BAD_PARAM;
1254094332d3Sopenharmony_ci    }
1255094332d3Sopenharmony_ci    g_globalConfigArray[infoIndex].type = param->type;
1256094332d3Sopenharmony_ci    g_globalConfigArray[infoIndex].authType = authType;
1257094332d3Sopenharmony_ci    g_globalConfigArray[infoIndex].userIdNum = param->userIdNum;
1258094332d3Sopenharmony_ci    for (uint32_t i = 0; i < param->userIdNum; i++) {
1259094332d3Sopenharmony_ci        g_globalConfigArray[infoIndex].userIds[i] = param->userIds[i];
1260094332d3Sopenharmony_ci    }
1261094332d3Sopenharmony_ci    if (infoIndex == g_globalConfigInfoNum) {
1262094332d3Sopenharmony_ci        g_globalConfigInfoNum++;
1263094332d3Sopenharmony_ci    }
1264094332d3Sopenharmony_ci    return RESULT_SUCCESS;
1265094332d3Sopenharmony_ci}
1266094332d3Sopenharmony_ci
1267094332d3Sopenharmony_ciIAM_STATIC bool CheckAuthType(uint32_t authType)
1268094332d3Sopenharmony_ci{
1269094332d3Sopenharmony_ci    if (authType != PIN_AUTH && authType != FACE_AUTH && authType != FINGER_AUTH && authType != RECOVERY_KEY) {
1270094332d3Sopenharmony_ci        LOG_ERROR("bad authType %{public}u", authType);
1271094332d3Sopenharmony_ci        return false;
1272094332d3Sopenharmony_ci    }
1273094332d3Sopenharmony_ci    return true;
1274094332d3Sopenharmony_ci}
1275094332d3Sopenharmony_ci
1276094332d3Sopenharmony_ciResultCode SaveGlobalConfigParam(GlobalConfigParamHal *param)
1277094332d3Sopenharmony_ci{
1278094332d3Sopenharmony_ci    if (param == NULL || param->userIdNum > MAX_USER || param->authTypeNum > MAX_AUTH_TYPE_LEN ||
1279094332d3Sopenharmony_ci        param->authTypeNum == 0) {
1280094332d3Sopenharmony_ci        LOG_ERROR("bad param");
1281094332d3Sopenharmony_ci        return RESULT_BAD_PARAM;
1282094332d3Sopenharmony_ci    }
1283094332d3Sopenharmony_ci    for (uint32_t i = 0; i < param->authTypeNum; i++) {
1284094332d3Sopenharmony_ci        if (!CheckAuthType(param->authTypes[i])) {
1285094332d3Sopenharmony_ci            LOG_ERROR("bad authType %{public}u", param->authTypes[i]);
1286094332d3Sopenharmony_ci            return RESULT_BAD_PARAM;
1287094332d3Sopenharmony_ci        }
1288094332d3Sopenharmony_ci        ResultCode ret = UpdateGlobalConfigArray(param, param->authTypes[i]);
1289094332d3Sopenharmony_ci        if (ret != RESULT_SUCCESS) {
1290094332d3Sopenharmony_ci            return ret;
1291094332d3Sopenharmony_ci        }
1292094332d3Sopenharmony_ci    }
1293094332d3Sopenharmony_ci
1294094332d3Sopenharmony_ci    return UpdateGlobalConfigFile(g_globalConfigArray, g_globalConfigInfoNum);
1295094332d3Sopenharmony_ci}
1296094332d3Sopenharmony_ci
1297094332d3Sopenharmony_ciIAM_STATIC ResultCode QueryPinCredential(int32_t userId, CredentialInfoHal *pinCredential)
1298094332d3Sopenharmony_ci{
1299094332d3Sopenharmony_ci    if (pinCredential == NULL) {
1300094332d3Sopenharmony_ci        LOG_ERROR("no need to get pin credential");
1301094332d3Sopenharmony_ci        return RESULT_BAD_PARAM;
1302094332d3Sopenharmony_ci    }
1303094332d3Sopenharmony_ci    CredentialCondition condition = {};
1304094332d3Sopenharmony_ci    SetCredentialConditionUserId(&condition, userId);
1305094332d3Sopenharmony_ci    SetCredentialConditionAuthType(&condition, PIN_AUTH);
1306094332d3Sopenharmony_ci    LinkedList *credList = QueryCredentialLimit(&condition);
1307094332d3Sopenharmony_ci    if (credList == NULL || credList->getSize(credList) == 0) {
1308094332d3Sopenharmony_ci        LOG_ERROR("pin credential is null");
1309094332d3Sopenharmony_ci        DestroyLinkedList(credList);
1310094332d3Sopenharmony_ci        return RESULT_NOT_ENROLLED;
1311094332d3Sopenharmony_ci    }
1312094332d3Sopenharmony_ci    if (credList->head == NULL || credList->head->data == NULL) {
1313094332d3Sopenharmony_ci        LOG_ERROR("pin credList node is invalid");
1314094332d3Sopenharmony_ci        DestroyLinkedList(credList);
1315094332d3Sopenharmony_ci        return RESULT_GENERAL_ERROR;
1316094332d3Sopenharmony_ci    }
1317094332d3Sopenharmony_ci    if (memcpy_s(pinCredential, sizeof(CredentialInfoHal), credList->head->data, sizeof(CredentialInfoHal)) != EOK) {
1318094332d3Sopenharmony_ci        LOG_ERROR("credential copy fail");
1319094332d3Sopenharmony_ci        DestroyLinkedList(credList);
1320094332d3Sopenharmony_ci        return RESULT_GENERAL_ERROR;
1321094332d3Sopenharmony_ci    }
1322094332d3Sopenharmony_ci    DestroyLinkedList(credList);
1323094332d3Sopenharmony_ci    return RESULT_SUCCESS;
1324094332d3Sopenharmony_ci}
1325094332d3Sopenharmony_ci
1326094332d3Sopenharmony_ciResultCode GetPinExpiredInfo(int32_t userId, PinExpiredInfo *expiredInfo)
1327094332d3Sopenharmony_ci{
1328094332d3Sopenharmony_ci    if (expiredInfo == NULL) {
1329094332d3Sopenharmony_ci        LOG_ERROR("bad param");
1330094332d3Sopenharmony_ci        return RESULT_BAD_PARAM;
1331094332d3Sopenharmony_ci    }
1332094332d3Sopenharmony_ci    (void)memset_s(expiredInfo, sizeof(PinExpiredInfo), 0, sizeof(PinExpiredInfo));
1333094332d3Sopenharmony_ci    for (uint32_t i = 0; i < g_globalConfigInfoNum; i++) {
1334094332d3Sopenharmony_ci        if (g_globalConfigArray[i].type == PIN_EXPIRED_PERIOD) {
1335094332d3Sopenharmony_ci            expiredInfo->pinExpiredPeriod = g_globalConfigArray[i].value.pinExpiredPeriod;
1336094332d3Sopenharmony_ci            break;
1337094332d3Sopenharmony_ci        }
1338094332d3Sopenharmony_ci    }
1339094332d3Sopenharmony_ci    if (expiredInfo->pinExpiredPeriod <= 0) {
1340094332d3Sopenharmony_ci        expiredInfo->pinExpiredPeriod = NO_CHECK_PIN_EXPIRED_PERIOD;
1341094332d3Sopenharmony_ci        LOG_INFO("no need check pinExpiredPeriod");
1342094332d3Sopenharmony_ci        return RESULT_SUCCESS;
1343094332d3Sopenharmony_ci    }
1344094332d3Sopenharmony_ci    CredentialInfoHal pinCredential = {};
1345094332d3Sopenharmony_ci    if (QueryPinCredential(userId, &pinCredential) != RESULT_SUCCESS) {
1346094332d3Sopenharmony_ci        LOG_INFO("not enrolled pin");
1347094332d3Sopenharmony_ci        return RESULT_NOT_ENROLLED;
1348094332d3Sopenharmony_ci    }
1349094332d3Sopenharmony_ci    expiredInfo->pinEnrolledSysTime = pinCredential.enrolledSysTime;
1350094332d3Sopenharmony_ci    return RESULT_SUCCESS;
1351094332d3Sopenharmony_ci}
1352094332d3Sopenharmony_ci
1353094332d3Sopenharmony_cibool GetEnableStatus(int32_t userId, uint32_t authType)
1354094332d3Sopenharmony_ci{
1355094332d3Sopenharmony_ci    for (uint32_t infoIndex = 0; infoIndex < g_globalConfigInfoNum; infoIndex++) {
1356094332d3Sopenharmony_ci        if (g_globalConfigArray[infoIndex].type != ENABLE_STATUS ||
1357094332d3Sopenharmony_ci            g_globalConfigArray[infoIndex].authType != authType) {
1358094332d3Sopenharmony_ci            continue;
1359094332d3Sopenharmony_ci        }
1360094332d3Sopenharmony_ci        LOG_INFO("enableStatus:%{public}d authType:%{public}u", g_globalConfigArray[infoIndex].value.enableStatus,
1361094332d3Sopenharmony_ci            authType);
1362094332d3Sopenharmony_ci        if (userId == INVALID_USER_ID || g_globalConfigArray[infoIndex].userIdNum == 0) {
1363094332d3Sopenharmony_ci            return g_globalConfigArray[infoIndex].value.enableStatus;
1364094332d3Sopenharmony_ci        }
1365094332d3Sopenharmony_ci        for (uint32_t i = 0; i < g_globalConfigArray[infoIndex].userIdNum; i++) {
1366094332d3Sopenharmony_ci            if (userId == g_globalConfigArray[infoIndex].userIds[i]) {
1367094332d3Sopenharmony_ci                return g_globalConfigArray[infoIndex].value.enableStatus;
1368094332d3Sopenharmony_ci            }
1369094332d3Sopenharmony_ci        }
1370094332d3Sopenharmony_ci        LOG_INFO("enableStatus is not set for userId:%{public}d", userId);
1371094332d3Sopenharmony_ci        return (!g_globalConfigArray[infoIndex].value.enableStatus);
1372094332d3Sopenharmony_ci    }
1373094332d3Sopenharmony_ci    return true;
1374094332d3Sopenharmony_ci}
1375