1c2b37d2cSopenharmony_ci/*
2c2b37d2cSopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3c2b37d2cSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4c2b37d2cSopenharmony_ci * you may not use this file except in compliance with the License.
5c2b37d2cSopenharmony_ci * You may obtain a copy of the License at
6c2b37d2cSopenharmony_ci *
7c2b37d2cSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8c2b37d2cSopenharmony_ci *
9c2b37d2cSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10c2b37d2cSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11c2b37d2cSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12c2b37d2cSopenharmony_ci * See the License for the specific language governing permissions and
13c2b37d2cSopenharmony_ci * limitations under the License.
14c2b37d2cSopenharmony_ci */
15c2b37d2cSopenharmony_ci
16c2b37d2cSopenharmony_ci#include "ohos_account_manager.h"
17c2b37d2cSopenharmony_ci#include <cerrno>
18c2b37d2cSopenharmony_ci#include <dirent.h>
19c2b37d2cSopenharmony_ci#include <dlfcn.h>
20c2b37d2cSopenharmony_ci#include <iomanip>
21c2b37d2cSopenharmony_ci#include <mbedtls/aes.h>
22c2b37d2cSopenharmony_ci#include <mbedtls/cipher.h>
23c2b37d2cSopenharmony_ci#include <mbedtls/pkcs5.h>
24c2b37d2cSopenharmony_ci#include <sys/types.h>
25c2b37d2cSopenharmony_ci#include <sstream>
26c2b37d2cSopenharmony_ci#include <string_ex.h>
27c2b37d2cSopenharmony_ci#include "accesstoken_kit.h"
28c2b37d2cSopenharmony_ci#include "account_constants.h"
29c2b37d2cSopenharmony_ci#include "account_event_provider.h"
30c2b37d2cSopenharmony_ci#include "account_event_subscribe.h"
31c2b37d2cSopenharmony_ci#include "account_helper_data.h"
32c2b37d2cSopenharmony_ci#include "account_info.h"
33c2b37d2cSopenharmony_ci#include "account_log_wrapper.h"
34c2b37d2cSopenharmony_ci#include "account_mgr_service.h"
35c2b37d2cSopenharmony_ci#include "account_permission_manager.h"
36c2b37d2cSopenharmony_ci#ifdef HAS_CES_PART
37c2b37d2cSopenharmony_ci#include "common_event_support.h"
38c2b37d2cSopenharmony_ci#endif // HAS_CES_PART
39c2b37d2cSopenharmony_ci#include "account_hisysevent_adapter.h"
40c2b37d2cSopenharmony_ci#include "distributed_account_subscribe_manager.h"
41c2b37d2cSopenharmony_ci#include "ipc_skeleton.h"
42c2b37d2cSopenharmony_ci#include "mbedtls/sha256.h"
43c2b37d2cSopenharmony_ci#include "system_ability_definition.h"
44c2b37d2cSopenharmony_ci#include "tokenid_kit.h"
45c2b37d2cSopenharmony_ci
46c2b37d2cSopenharmony_ci#ifdef HAS_CES_PART
47c2b37d2cSopenharmony_ciusing namespace OHOS::EventFwk;
48c2b37d2cSopenharmony_ci#endif // HAS_CES_PART
49c2b37d2cSopenharmony_ci
50c2b37d2cSopenharmony_cinamespace OHOS {
51c2b37d2cSopenharmony_cinamespace AccountSA {
52c2b37d2cSopenharmony_cinamespace {
53c2b37d2cSopenharmony_ciconstexpr unsigned int ITERATE_CNT = 1000;
54c2b37d2cSopenharmony_ciconstexpr std::int32_t OUTPUT_LENGTH_IN_BYTES = 32;
55c2b37d2cSopenharmony_ciconstexpr std::uint8_t TWO_BYTE_MASK = 0xF0;
56c2b37d2cSopenharmony_ciconstexpr std::int32_t MAX_RETRY_TIMES = 2; // give another chance when json file corrupted
57c2b37d2cSopenharmony_ciconstexpr std::uint32_t MAX_NAME_LENGTH = 256;
58c2b37d2cSopenharmony_ciconstexpr std::uint32_t MAX_UID_LENGTH = 512;
59c2b37d2cSopenharmony_ciconstexpr std::uint32_t HASH_LENGTH = 32;
60c2b37d2cSopenharmony_ciconstexpr std::uint32_t WIDTH_FOR_HEX = 2;
61c2b37d2cSopenharmony_ciconstexpr std::uint32_t OHOS_ACCOUNT_UDID_LENGTH = HASH_LENGTH * 2;
62c2b37d2cSopenharmony_ciconst std::string KEY_ACCOUNT_EVENT_LOGIN = "LOGIN";
63c2b37d2cSopenharmony_ciconst std::string KEY_ACCOUNT_EVENT_LOGOUT = "LOGOUT";
64c2b37d2cSopenharmony_ciconst std::string KEY_ACCOUNT_EVENT_TOKEN_INVALID = "TOKEN_INVALID";
65c2b37d2cSopenharmony_ciconst std::string KEY_ACCOUNT_EVENT_LOGOFF = "LOGOFF";
66c2b37d2cSopenharmony_cistd::string GetAccountEventStr(const std::map<std::string, std::string> &accountEventMap,
67c2b37d2cSopenharmony_ci    const std::string &eventKey, const std::string &defaultValue)
68c2b37d2cSopenharmony_ci{
69c2b37d2cSopenharmony_ci    const auto &it = accountEventMap.find(eventKey);
70c2b37d2cSopenharmony_ci    if (it != accountEventMap.end()) {
71c2b37d2cSopenharmony_ci        return it->second;
72c2b37d2cSopenharmony_ci    }
73c2b37d2cSopenharmony_ci    return defaultValue;
74c2b37d2cSopenharmony_ci}
75c2b37d2cSopenharmony_ci
76c2b37d2cSopenharmony_cibool GetCallerBundleName(std::string &bundleName)
77c2b37d2cSopenharmony_ci{
78c2b37d2cSopenharmony_ci    uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
79c2b37d2cSopenharmony_ci    Security::AccessToken::AccessTokenID tokenId = fullTokenId & TOKEN_ID_LOWMASK;
80c2b37d2cSopenharmony_ci    Security::AccessToken::ATokenTypeEnum tokenType = Security::AccessToken::AccessTokenKit::GetTokenType(tokenId);
81c2b37d2cSopenharmony_ci    if ((tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_HAP) &&
82c2b37d2cSopenharmony_ci        (!Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId))) {
83c2b37d2cSopenharmony_ci        Security::AccessToken::HapTokenInfo hapTokenInfo;
84c2b37d2cSopenharmony_ci        int result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(tokenId, hapTokenInfo);
85c2b37d2cSopenharmony_ci        if (result) {
86c2b37d2cSopenharmony_ci            ACCOUNT_LOGE("failed to get hap token info, result = %{public}d", result);
87c2b37d2cSopenharmony_ci            return false;
88c2b37d2cSopenharmony_ci        }
89c2b37d2cSopenharmony_ci        bundleName = hapTokenInfo.bundleName;
90c2b37d2cSopenharmony_ci    }
91c2b37d2cSopenharmony_ci    return true;
92c2b37d2cSopenharmony_ci}
93c2b37d2cSopenharmony_ci
94c2b37d2cSopenharmony_cistd::string ReturnOhosUdidWithSha256(const std::string &uid)
95c2b37d2cSopenharmony_ci{
96c2b37d2cSopenharmony_ci    unsigned char hash[HASH_LENGTH] = {0};
97c2b37d2cSopenharmony_ci    mbedtls_sha256_context context;
98c2b37d2cSopenharmony_ci    mbedtls_sha256_init(&context);
99c2b37d2cSopenharmony_ci    mbedtls_sha256_starts(&context, 0);
100c2b37d2cSopenharmony_ci
101c2b37d2cSopenharmony_ci    std::string plainStr = uid;
102c2b37d2cSopenharmony_ci    mbedtls_sha256_update(&context, reinterpret_cast<const unsigned char *>(plainStr.c_str()), plainStr.length());
103c2b37d2cSopenharmony_ci    mbedtls_sha256_finish(&context, hash);
104c2b37d2cSopenharmony_ci    mbedtls_sha256_free(&context);
105c2b37d2cSopenharmony_ci
106c2b37d2cSopenharmony_ci    std::stringstream ss;
107c2b37d2cSopenharmony_ci    for (std::uint32_t i = 0; i < HASH_LENGTH; ++i) {
108c2b37d2cSopenharmony_ci        ss << std::hex << std::uppercase << std::setw(WIDTH_FOR_HEX) << std::setfill('0') << std::uint16_t(hash[i]);
109c2b37d2cSopenharmony_ci    }
110c2b37d2cSopenharmony_ci    std::string ohosUidStr;
111c2b37d2cSopenharmony_ci    ss >> ohosUidStr;
112c2b37d2cSopenharmony_ci    return ohosUidStr;
113c2b37d2cSopenharmony_ci}
114c2b37d2cSopenharmony_ci
115c2b37d2cSopenharmony_cistd::string GenerateOhosUdidWithSha256(const std::string &name, const std::string &uid)
116c2b37d2cSopenharmony_ci{
117c2b37d2cSopenharmony_ci    if (name.empty() || name.length() > MAX_NAME_LENGTH) {
118c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("input name empty or too long, length %{public}zu", name.length());
119c2b37d2cSopenharmony_ci        return std::string("");
120c2b37d2cSopenharmony_ci    }
121c2b37d2cSopenharmony_ci
122c2b37d2cSopenharmony_ci    if (uid.empty() || uid.length() > MAX_UID_LENGTH) {
123c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("input uid empty or too long, length %{public}zu", uid.length());
124c2b37d2cSopenharmony_ci        return std::string("");
125c2b37d2cSopenharmony_ci    }
126c2b37d2cSopenharmony_ci
127c2b37d2cSopenharmony_ci    std::string bundleName = "";
128c2b37d2cSopenharmony_ci    if (!GetCallerBundleName(bundleName)) {
129c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("GetCallerBundleName failed");
130c2b37d2cSopenharmony_ci        return std::string("");
131c2b37d2cSopenharmony_ci    }
132c2b37d2cSopenharmony_ci    if (bundleName.empty()) {
133c2b37d2cSopenharmony_ci        return ReturnOhosUdidWithSha256(uid);
134c2b37d2cSopenharmony_ci    }
135c2b37d2cSopenharmony_ci    unsigned char newId[OUTPUT_LENGTH_IN_BYTES + 1] = {};
136c2b37d2cSopenharmony_ci    mbedtls_md_context_t md_context;
137c2b37d2cSopenharmony_ci    mbedtls_md_init(&md_context);
138c2b37d2cSopenharmony_ci    const mbedtls_md_info_t *mbedtls_sha256_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
139c2b37d2cSopenharmony_ci    int ret = mbedtls_md_setup(&md_context, mbedtls_sha256_info, 1);
140c2b37d2cSopenharmony_ci    if (ret != 0) {
141c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("mbedtls_md_setup failed");
142c2b37d2cSopenharmony_ci        mbedtls_md_free(&md_context);
143c2b37d2cSopenharmony_ci        return std::string("");
144c2b37d2cSopenharmony_ci    }
145c2b37d2cSopenharmony_ci    ret = mbedtls_pkcs5_pbkdf2_hmac(&md_context, reinterpret_cast<const unsigned char *>(uid.c_str()), uid.size(),
146c2b37d2cSopenharmony_ci        reinterpret_cast<const unsigned char *>(bundleName.c_str()), bundleName.size(), ITERATE_CNT,
147c2b37d2cSopenharmony_ci        OUTPUT_LENGTH_IN_BYTES, newId);
148c2b37d2cSopenharmony_ci    if (ret != 0) {
149c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("mbedtls_pkcs5_pbkdf2_hmac failed");
150c2b37d2cSopenharmony_ci        mbedtls_md_free(&md_context);
151c2b37d2cSopenharmony_ci        return std::string("");
152c2b37d2cSopenharmony_ci    }
153c2b37d2cSopenharmony_ci    mbedtls_md_free(&md_context);
154c2b37d2cSopenharmony_ci    std::string ohosUidStr;
155c2b37d2cSopenharmony_ci    for (int i = 0; i < OUTPUT_LENGTH_IN_BYTES; i++) {
156c2b37d2cSopenharmony_ci        if ((newId[i] & TWO_BYTE_MASK) == 0) {
157c2b37d2cSopenharmony_ci            ohosUidStr.append("0");
158c2b37d2cSopenharmony_ci        }
159c2b37d2cSopenharmony_ci        ohosUidStr.append(DexToHexString(newId[i], true));
160c2b37d2cSopenharmony_ci    }
161c2b37d2cSopenharmony_ci    return ohosUidStr;
162c2b37d2cSopenharmony_ci}
163c2b37d2cSopenharmony_ci}
164c2b37d2cSopenharmony_ci
165c2b37d2cSopenharmony_ci/**
166c2b37d2cSopenharmony_ci * Ohos account state change.
167c2b37d2cSopenharmony_ci *
168c2b37d2cSopenharmony_ci * @param name ohos account name
169c2b37d2cSopenharmony_ci * @param uid ohos account uid
170c2b37d2cSopenharmony_ci * @param eventStr ohos account state change event
171c2b37d2cSopenharmony_ci * @return true if the processing was completed, otherwise false
172c2b37d2cSopenharmony_ci */
173c2b37d2cSopenharmony_ciErrCode OhosAccountManager::OhosAccountStateChange(const std::string &name, const std::string &uid,
174c2b37d2cSopenharmony_ci    const std::string &eventStr)
175c2b37d2cSopenharmony_ci{
176c2b37d2cSopenharmony_ci    auto itFunc = eventFuncMap_.find(eventStr);
177c2b37d2cSopenharmony_ci    if (itFunc == eventFuncMap_.end()) {
178c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("invalid event: %{public}s", eventStr.c_str());
179c2b37d2cSopenharmony_ci        return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
180c2b37d2cSopenharmony_ci    }
181c2b37d2cSopenharmony_ci    OhosAccountInfo ohosAccountInfo;
182c2b37d2cSopenharmony_ci    ohosAccountInfo.name_ = name;
183c2b37d2cSopenharmony_ci    ohosAccountInfo.uid_ = uid;
184c2b37d2cSopenharmony_ci    std::int32_t userId = AccountMgrService::GetInstance().GetCallingUserID();
185c2b37d2cSopenharmony_ci    return (itFunc->second)(userId, ohosAccountInfo, eventStr);
186c2b37d2cSopenharmony_ci}
187c2b37d2cSopenharmony_ci
188c2b37d2cSopenharmony_ciErrCode OhosAccountManager::OhosAccountStateChange(
189c2b37d2cSopenharmony_ci    const int32_t userId, const OhosAccountInfo &ohosAccountInfo, const std::string &eventStr)
190c2b37d2cSopenharmony_ci{
191c2b37d2cSopenharmony_ci    auto itFunc = eventFuncMap_.find(eventStr);
192c2b37d2cSopenharmony_ci    if (itFunc == eventFuncMap_.end()) {
193c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("invalid event: %{public}s", eventStr.c_str());
194c2b37d2cSopenharmony_ci        return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
195c2b37d2cSopenharmony_ci    }
196c2b37d2cSopenharmony_ci    return (itFunc->second)(userId, ohosAccountInfo, eventStr);
197c2b37d2cSopenharmony_ci}
198c2b37d2cSopenharmony_ci
199c2b37d2cSopenharmony_ci/**
200c2b37d2cSopenharmony_ci * Clear current account information
201c2b37d2cSopenharmony_ci */
202c2b37d2cSopenharmony_cibool OhosAccountManager::ClearOhosAccount(AccountInfo &curOhosAccountInfo, std::int32_t clrStatus) const
203c2b37d2cSopenharmony_ci{
204c2b37d2cSopenharmony_ci    curOhosAccountInfo.clear(clrStatus);
205c2b37d2cSopenharmony_ci    ErrCode errCode = dataDealer_->AccountInfoToJson(curOhosAccountInfo);
206c2b37d2cSopenharmony_ci    if (errCode != ERR_OK) {
207c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("AccountInfoToJson error");
208c2b37d2cSopenharmony_ci        return false;
209c2b37d2cSopenharmony_ci    }
210c2b37d2cSopenharmony_ci    return true;
211c2b37d2cSopenharmony_ci}
212c2b37d2cSopenharmony_ci
213c2b37d2cSopenharmony_ci/**
214c2b37d2cSopenharmony_ci * Config current account config.
215c2b37d2cSopenharmony_ci *
216c2b37d2cSopenharmony_ci * @param ohosAccountInfo distribute account information.
217c2b37d2cSopenharmony_ci * @return true if success.
218c2b37d2cSopenharmony_ci */
219c2b37d2cSopenharmony_cibool OhosAccountManager::SaveOhosAccountInfo(AccountInfo &ohosAccountInfo) const
220c2b37d2cSopenharmony_ci{
221c2b37d2cSopenharmony_ci    ErrCode errCode = dataDealer_->AccountInfoToJson(ohosAccountInfo);
222c2b37d2cSopenharmony_ci    if (errCode != ERR_OK) {
223c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("AccountInfoToJson error.");
224c2b37d2cSopenharmony_ci        return false;
225c2b37d2cSopenharmony_ci    }
226c2b37d2cSopenharmony_ci    return true;
227c2b37d2cSopenharmony_ci}
228c2b37d2cSopenharmony_ci
229c2b37d2cSopenharmony_ci/**
230c2b37d2cSopenharmony_ci * Get current account information.
231c2b37d2cSopenharmony_ci *
232c2b37d2cSopenharmony_ci * @return current account information.
233c2b37d2cSopenharmony_ci */
234c2b37d2cSopenharmony_ciAccountInfo OhosAccountManager::GetCurrentOhosAccountInfo()
235c2b37d2cSopenharmony_ci{
236c2b37d2cSopenharmony_ci    std::lock_guard<std::mutex> mutexLock(mgrMutex_);
237c2b37d2cSopenharmony_ci
238c2b37d2cSopenharmony_ci    AccountInfo currOhosAccountInfo;
239c2b37d2cSopenharmony_ci    std::int32_t callingUserId = AccountMgrService::GetInstance().GetCallingUserID();
240c2b37d2cSopenharmony_ci    if (dataDealer_->AccountInfoFromJson(currOhosAccountInfo, callingUserId) != ERR_OK) {
241c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("get current ohos account info failed, callingUserId %{public}d.", callingUserId);
242c2b37d2cSopenharmony_ci        currOhosAccountInfo.clear();
243c2b37d2cSopenharmony_ci    }
244c2b37d2cSopenharmony_ci    return currOhosAccountInfo;
245c2b37d2cSopenharmony_ci}
246c2b37d2cSopenharmony_ci
247c2b37d2cSopenharmony_ciErrCode OhosAccountManager::GetAccountInfoByUserId(std::int32_t userId, AccountInfo &info)
248c2b37d2cSopenharmony_ci{
249c2b37d2cSopenharmony_ci    if (userId == 0) {
250c2b37d2cSopenharmony_ci        userId = AccountMgrService::GetInstance().GetCallingUserID();
251c2b37d2cSopenharmony_ci    }
252c2b37d2cSopenharmony_ci    std::lock_guard<std::mutex> mutexLock(mgrMutex_);
253c2b37d2cSopenharmony_ci
254c2b37d2cSopenharmony_ci    ErrCode ret = dataDealer_->AccountInfoFromJson(info, userId);
255c2b37d2cSopenharmony_ci    if (ret != ERR_OK) {
256c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("get ohos account info failed, userId %{public}d.", userId);
257c2b37d2cSopenharmony_ci        info.clear();
258c2b37d2cSopenharmony_ci        return ret;
259c2b37d2cSopenharmony_ci    }
260c2b37d2cSopenharmony_ci    return ERR_OK;
261c2b37d2cSopenharmony_ci}
262c2b37d2cSopenharmony_ci
263c2b37d2cSopenharmony_ciErrCode OhosAccountManager::SubscribeDistributedAccountEvent(const DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE type,
264c2b37d2cSopenharmony_ci    const sptr<IRemoteObject> &eventListener)
265c2b37d2cSopenharmony_ci{
266c2b37d2cSopenharmony_ci    return subscribeManager_.SubscribeDistributedAccountEvent(type, eventListener);
267c2b37d2cSopenharmony_ci}
268c2b37d2cSopenharmony_ci
269c2b37d2cSopenharmony_ciErrCode OhosAccountManager::UnsubscribeDistributedAccountEvent(const DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE type,
270c2b37d2cSopenharmony_ci    const sptr<IRemoteObject> &eventListener)
271c2b37d2cSopenharmony_ci{
272c2b37d2cSopenharmony_ci    return subscribeManager_.UnsubscribeDistributedAccountEvent(type, eventListener);
273c2b37d2cSopenharmony_ci}
274c2b37d2cSopenharmony_ci
275c2b37d2cSopenharmony_ci/**
276c2b37d2cSopenharmony_ci * Get current account state.
277c2b37d2cSopenharmony_ci *
278c2b37d2cSopenharmony_ci * @return current account state id.
279c2b37d2cSopenharmony_ci */
280c2b37d2cSopenharmony_cistd::int32_t OhosAccountManager::GetCurrentOhosAccountState()
281c2b37d2cSopenharmony_ci{
282c2b37d2cSopenharmony_ci    AccountInfo currOhosAccountInfo = GetCurrentOhosAccountInfo();
283c2b37d2cSopenharmony_ci    return currOhosAccountInfo.ohosAccountInfo_.status_;
284c2b37d2cSopenharmony_ci}
285c2b37d2cSopenharmony_ci
286c2b37d2cSopenharmony_ci/**
287c2b37d2cSopenharmony_ci * Process an account event.
288c2b37d2cSopenharmony_ci * @param curOhosAccount current ohos account info
289c2b37d2cSopenharmony_ci * @param eventStr ohos account state change event
290c2b37d2cSopenharmony_ci * @return true if the processing was completed, otherwise false
291c2b37d2cSopenharmony_ci */
292c2b37d2cSopenharmony_cibool OhosAccountManager::HandleEvent(AccountInfo &curOhosAccount, const std::string &eventStr)
293c2b37d2cSopenharmony_ci{
294c2b37d2cSopenharmony_ci    auto iter = eventMap_.find(eventStr);
295c2b37d2cSopenharmony_ci    if (iter == eventMap_.end()) {
296c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("invalid event: %{public}s", eventStr.c_str());
297c2b37d2cSopenharmony_ci        return false;
298c2b37d2cSopenharmony_ci    }
299c2b37d2cSopenharmony_ci    int event = iter->second;
300c2b37d2cSopenharmony_ci    accountState_->SetAccountState(curOhosAccount.ohosAccountInfo_.status_);
301c2b37d2cSopenharmony_ci    bool ret = accountState_->StateChangeProcess(event);
302c2b37d2cSopenharmony_ci    if (!ret) {
303c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("Handle event %{public}d failed", event);
304c2b37d2cSopenharmony_ci        return false;
305c2b37d2cSopenharmony_ci    }
306c2b37d2cSopenharmony_ci    std::int32_t newState = accountState_->GetAccountState();
307c2b37d2cSopenharmony_ci    if (newState != curOhosAccount.ohosAccountInfo_.status_) {
308c2b37d2cSopenharmony_ci        ReportOhosAccountStateChange(curOhosAccount.userId_, event, curOhosAccount.ohosAccountInfo_.status_, newState);
309c2b37d2cSopenharmony_ci        curOhosAccount.ohosAccountInfo_.status_ = newState;
310c2b37d2cSopenharmony_ci    }
311c2b37d2cSopenharmony_ci    return true;
312c2b37d2cSopenharmony_ci}
313c2b37d2cSopenharmony_ci
314c2b37d2cSopenharmony_ci/**
315c2b37d2cSopenharmony_ci * login ohos (for distributed network) account.
316c2b37d2cSopenharmony_ci *
317c2b37d2cSopenharmony_ci * @param userId target local account id.
318c2b37d2cSopenharmony_ci * @param ohosAccountInfo ohos account information
319c2b37d2cSopenharmony_ci * @param eventStr ohos account state change event
320c2b37d2cSopenharmony_ci * @return ERR_OK if the processing was completed
321c2b37d2cSopenharmony_ci */
322c2b37d2cSopenharmony_ciErrCode OhosAccountManager::LoginOhosAccount(const int32_t userId, const OhosAccountInfo &ohosAccountInfo,
323c2b37d2cSopenharmony_ci    const std::string &eventStr)
324c2b37d2cSopenharmony_ci{
325c2b37d2cSopenharmony_ci    std::lock_guard<std::mutex> mutexLock(mgrMutex_);
326c2b37d2cSopenharmony_ci
327c2b37d2cSopenharmony_ci    AccountInfo currAccountInfo;
328c2b37d2cSopenharmony_ci    ErrCode res = dataDealer_->AccountInfoFromJson(currAccountInfo, userId);
329c2b37d2cSopenharmony_ci    if (res != ERR_OK) {
330c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("get current ohos account info failed, userId %{public}d.", userId);
331c2b37d2cSopenharmony_ci        return res;
332c2b37d2cSopenharmony_ci    }
333c2b37d2cSopenharmony_ci    std::string ohosAccountUid = GenerateOhosUdidWithSha256(ohosAccountInfo.name_, ohosAccountInfo.uid_);
334c2b37d2cSopenharmony_ci    // current local user cannot be bound again when it has already been bound to an ohos account
335c2b37d2cSopenharmony_ci    if (!CheckOhosAccountCanBind(currAccountInfo, ohosAccountInfo, ohosAccountUid)) {
336c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("check can be bound failed, userId %{public}d.", userId);
337c2b37d2cSopenharmony_ci        return ERR_ACCOUNT_ZIDL_ACCOUNT_SERVICE_ERROR;
338c2b37d2cSopenharmony_ci    }
339c2b37d2cSopenharmony_ci
340c2b37d2cSopenharmony_ci#ifdef HAS_CES_PART
341c2b37d2cSopenharmony_ci    // check whether need to publish event or not
342c2b37d2cSopenharmony_ci    bool isPubLoginEvent = false;
343c2b37d2cSopenharmony_ci    if (currAccountInfo.ohosAccountInfo_.status_ != ACCOUNT_STATE_LOGIN) {
344c2b37d2cSopenharmony_ci        isPubLoginEvent = true;
345c2b37d2cSopenharmony_ci    }
346c2b37d2cSopenharmony_ci#endif // HAS_CES_PART
347c2b37d2cSopenharmony_ci    // update account status
348c2b37d2cSopenharmony_ci    if (!HandleEvent(currAccountInfo, eventStr)) {
349c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("HandleEvent %{public}s failed! userId %{public}d.", eventStr.c_str(), userId);
350c2b37d2cSopenharmony_ci        return ERR_ACCOUNT_ZIDL_ACCOUNT_SERVICE_ERROR;
351c2b37d2cSopenharmony_ci    }
352c2b37d2cSopenharmony_ci
353c2b37d2cSopenharmony_ci    // update account info
354c2b37d2cSopenharmony_ci    currAccountInfo.ohosAccountInfo_ = ohosAccountInfo;
355c2b37d2cSopenharmony_ci    currAccountInfo.ohosAccountInfo_.SetRawUid(ohosAccountInfo.uid_);
356c2b37d2cSopenharmony_ci    currAccountInfo.ohosAccountInfo_.uid_ = ohosAccountUid;
357c2b37d2cSopenharmony_ci    currAccountInfo.ohosAccountInfo_.status_ = ACCOUNT_STATE_LOGIN;
358c2b37d2cSopenharmony_ci    currAccountInfo.bindTime_ = std::time(nullptr);
359c2b37d2cSopenharmony_ci    currAccountInfo.ohosAccountInfo_.callingUid_ = IPCSkeleton::GetCallingUid();
360c2b37d2cSopenharmony_ci
361c2b37d2cSopenharmony_ci    if (!SaveOhosAccountInfo(currAccountInfo)) {
362c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("SaveOhosAccountInfo failed! userId %{public}d.", userId);
363c2b37d2cSopenharmony_ci        return ERR_ACCOUNT_ZIDL_ACCOUNT_SERVICE_ERROR;
364c2b37d2cSopenharmony_ci    }
365c2b37d2cSopenharmony_ci    subscribeManager_.Publish(userId, DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE::LOGIN);
366c2b37d2cSopenharmony_ci
367c2b37d2cSopenharmony_ci#ifdef HAS_CES_PART
368c2b37d2cSopenharmony_ci    if (!isPubLoginEvent) {
369c2b37d2cSopenharmony_ci        AccountEventProvider::EventPublish(CommonEventSupport::COMMON_EVENT_USER_INFO_UPDATED, userId, nullptr);
370c2b37d2cSopenharmony_ci        (void)CreateCommonEventSubscribe();
371c2b37d2cSopenharmony_ci        return ERR_OK;
372c2b37d2cSopenharmony_ci    }
373c2b37d2cSopenharmony_ci    AccountEventProvider::EventPublishAsUser(CommonEventSupport::COMMON_EVENT_HWID_LOGIN, userId);
374c2b37d2cSopenharmony_ci    AccountEventProvider::EventPublishAsUser(
375c2b37d2cSopenharmony_ci        CommonEventSupport::COMMON_EVENT_DISTRIBUTED_ACCOUNT_LOGIN, userId);
376c2b37d2cSopenharmony_ci#else  // HAS_CES_PART
377c2b37d2cSopenharmony_ci    ACCOUNT_LOGI("No common event part, publish nothing!");
378c2b37d2cSopenharmony_ci#endif // HAS_CES_PART
379c2b37d2cSopenharmony_ci    (void)CreateCommonEventSubscribe();
380c2b37d2cSopenharmony_ci    ACCOUNT_LOGI("LoginOhosAccount success! userId %{public}d", userId);
381c2b37d2cSopenharmony_ci    return ERR_OK;
382c2b37d2cSopenharmony_ci}
383c2b37d2cSopenharmony_ci
384c2b37d2cSopenharmony_ci/**
385c2b37d2cSopenharmony_ci * logout ohos (for distributed network) account.
386c2b37d2cSopenharmony_ci *
387c2b37d2cSopenharmony_ci * @param userId target local account id.
388c2b37d2cSopenharmony_ci * @param ohosAccountInfo ohos account information
389c2b37d2cSopenharmony_ci * @param eventStr ohos account state change event
390c2b37d2cSopenharmony_ci * @return ERR_OK if the processing was completed
391c2b37d2cSopenharmony_ci */
392c2b37d2cSopenharmony_ciErrCode OhosAccountManager::LogoutOhosAccount(
393c2b37d2cSopenharmony_ci    const int32_t userId, const OhosAccountInfo &ohosAccountInfo, const std::string &eventStr)
394c2b37d2cSopenharmony_ci{
395c2b37d2cSopenharmony_ci    std::lock_guard<std::mutex> mutexLock(mgrMutex_);
396c2b37d2cSopenharmony_ci
397c2b37d2cSopenharmony_ci    AccountInfo currentAccount;
398c2b37d2cSopenharmony_ci    if (!GetCurOhosAccountAndCheckMatch(currentAccount, ohosAccountInfo.name_,
399c2b37d2cSopenharmony_ci                                        ohosAccountInfo.uid_, userId)) {
400c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("check match failed, userId %{public}d.", userId);
401c2b37d2cSopenharmony_ci        return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
402c2b37d2cSopenharmony_ci    }
403c2b37d2cSopenharmony_ci
404c2b37d2cSopenharmony_ci    bool ret = HandleEvent(currentAccount, eventStr); // update account status
405c2b37d2cSopenharmony_ci    if (!ret) {
406c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("HandleEvent %{public}s failed, userId %{public}d.", eventStr.c_str(), userId);
407c2b37d2cSopenharmony_ci        return ERR_ACCOUNT_ZIDL_ACCOUNT_SERVICE_ERROR;
408c2b37d2cSopenharmony_ci    }
409c2b37d2cSopenharmony_ci
410c2b37d2cSopenharmony_ci    ret = ClearOhosAccount(currentAccount); // clear account info with ACCOUNT_STATE_UNBOUND
411c2b37d2cSopenharmony_ci    if (!ret) {
412c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("ClearOhosAccount failed! userId %{public}d.", userId);
413c2b37d2cSopenharmony_ci        return ERR_ACCOUNT_ZIDL_ACCOUNT_SERVICE_ERROR;
414c2b37d2cSopenharmony_ci    }
415c2b37d2cSopenharmony_ci    subscribeManager_.Publish(userId, DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE::LOGOUT);
416c2b37d2cSopenharmony_ci
417c2b37d2cSopenharmony_ci#ifdef HAS_CES_PART
418c2b37d2cSopenharmony_ci    AccountEventProvider::EventPublishAsUser(
419c2b37d2cSopenharmony_ci        EventFwk::CommonEventSupport::COMMON_EVENT_HWID_LOGOUT, userId);
420c2b37d2cSopenharmony_ci    AccountEventProvider::EventPublishAsUser(
421c2b37d2cSopenharmony_ci        EventFwk::CommonEventSupport::COMMON_EVENT_DISTRIBUTED_ACCOUNT_LOGOUT, userId);
422c2b37d2cSopenharmony_ci#else  // HAS_CES_PART
423c2b37d2cSopenharmony_ci    ACCOUNT_LOGI("No common event part! Publish nothing!");
424c2b37d2cSopenharmony_ci#endif // HAS_CES_PART
425c2b37d2cSopenharmony_ci    ACCOUNT_LOGI("LogoutOhosAccount success, userId %{public}d.", userId);
426c2b37d2cSopenharmony_ci    return ERR_OK;
427c2b37d2cSopenharmony_ci}
428c2b37d2cSopenharmony_ci
429c2b37d2cSopenharmony_ci/**
430c2b37d2cSopenharmony_ci * logoff ohos (for distributed network) account.
431c2b37d2cSopenharmony_ci *
432c2b37d2cSopenharmony_ci * @param userId target local account id.
433c2b37d2cSopenharmony_ci * @param ohosAccountInfo ohos account information
434c2b37d2cSopenharmony_ci * @param eventStr ohos account state change event
435c2b37d2cSopenharmony_ci * @return ERR_OK if the processing was completed
436c2b37d2cSopenharmony_ci */
437c2b37d2cSopenharmony_ciErrCode OhosAccountManager::LogoffOhosAccount(
438c2b37d2cSopenharmony_ci    const int32_t userId, const OhosAccountInfo &ohosAccountInfo, const std::string &eventStr)
439c2b37d2cSopenharmony_ci{
440c2b37d2cSopenharmony_ci    std::lock_guard<std::mutex> mutexLock(mgrMutex_);
441c2b37d2cSopenharmony_ci
442c2b37d2cSopenharmony_ci    AccountInfo currentAccount;
443c2b37d2cSopenharmony_ci    if (!GetCurOhosAccountAndCheckMatch(currentAccount, ohosAccountInfo.name_, ohosAccountInfo.uid_, userId)) {
444c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("check match failed, userId %{public}d.", userId);
445c2b37d2cSopenharmony_ci        return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
446c2b37d2cSopenharmony_ci    }
447c2b37d2cSopenharmony_ci
448c2b37d2cSopenharmony_ci    bool ret = HandleEvent(currentAccount, eventStr); // update account status
449c2b37d2cSopenharmony_ci    if (!ret) {
450c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("HandleEvent %{public}s failed, userId %{public}d.", eventStr.c_str(), userId);
451c2b37d2cSopenharmony_ci        return ERR_ACCOUNT_ZIDL_ACCOUNT_SERVICE_ERROR;
452c2b37d2cSopenharmony_ci    }
453c2b37d2cSopenharmony_ci
454c2b37d2cSopenharmony_ci    ret = ClearOhosAccount(currentAccount); // clear account info with ACCOUNT_STATE_UNBOUND
455c2b37d2cSopenharmony_ci    if (!ret) {
456c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("ClearOhosAccount failed, userId %{public}d.", userId);
457c2b37d2cSopenharmony_ci        return ERR_ACCOUNT_ZIDL_ACCOUNT_SERVICE_ERROR;
458c2b37d2cSopenharmony_ci    }
459c2b37d2cSopenharmony_ci    subscribeManager_.Publish(userId, DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE::LOGOFF);
460c2b37d2cSopenharmony_ci
461c2b37d2cSopenharmony_ci#ifdef HAS_CES_PART
462c2b37d2cSopenharmony_ci    AccountEventProvider::EventPublishAsUser(
463c2b37d2cSopenharmony_ci        EventFwk::CommonEventSupport::COMMON_EVENT_HWID_LOGOFF, userId);
464c2b37d2cSopenharmony_ci    AccountEventProvider::EventPublishAsUser(
465c2b37d2cSopenharmony_ci        EventFwk::CommonEventSupport::COMMON_EVENT_DISTRIBUTED_ACCOUNT_LOGOFF, userId);
466c2b37d2cSopenharmony_ci#else  // HAS_CES_PART
467c2b37d2cSopenharmony_ci    ACCOUNT_LOGI("No common event part, publish nothing for logoff!");
468c2b37d2cSopenharmony_ci#endif // HAS_CES_PART
469c2b37d2cSopenharmony_ci    ACCOUNT_LOGI("LogoffOhosAccount success, userId %{public}d.", userId);
470c2b37d2cSopenharmony_ci    return ERR_OK;
471c2b37d2cSopenharmony_ci}
472c2b37d2cSopenharmony_ci
473c2b37d2cSopenharmony_ci/**
474c2b37d2cSopenharmony_ci * Handle token_invalid event.
475c2b37d2cSopenharmony_ci *
476c2b37d2cSopenharmony_ci * @param userId target local account id.
477c2b37d2cSopenharmony_ci * @param ohosAccountInfo ohos account information
478c2b37d2cSopenharmony_ci * @param eventStr ohos account state change event
479c2b37d2cSopenharmony_ci * @return ERR_OK if the processing was completed
480c2b37d2cSopenharmony_ci */
481c2b37d2cSopenharmony_ciErrCode OhosAccountManager::HandleOhosAccountTokenInvalidEvent(
482c2b37d2cSopenharmony_ci    const int32_t userId, const OhosAccountInfo &ohosAccountInfo, const std::string &eventStr)
483c2b37d2cSopenharmony_ci{
484c2b37d2cSopenharmony_ci    std::lock_guard<std::mutex> mutexLock(mgrMutex_);
485c2b37d2cSopenharmony_ci
486c2b37d2cSopenharmony_ci    AccountInfo currentOhosAccount;
487c2b37d2cSopenharmony_ci    if (!GetCurOhosAccountAndCheckMatch(currentOhosAccount, ohosAccountInfo.name_,
488c2b37d2cSopenharmony_ci                                        ohosAccountInfo.uid_, userId)) {
489c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("check match failed, userId %{public}d.", userId);
490c2b37d2cSopenharmony_ci        return ERR_ACCOUNT_COMMON_ACCOUNT_NOT_EXIST_ERROR;
491c2b37d2cSopenharmony_ci    }
492c2b37d2cSopenharmony_ci
493c2b37d2cSopenharmony_ci    bool ret = HandleEvent(currentOhosAccount, eventStr); // update account status
494c2b37d2cSopenharmony_ci    if (!ret) {
495c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("HandleEvent %{public}s failed, userId %{public}d.", eventStr.c_str(), userId);
496c2b37d2cSopenharmony_ci        return ERR_ACCOUNT_ZIDL_ACCOUNT_SERVICE_ERROR;
497c2b37d2cSopenharmony_ci    }
498c2b37d2cSopenharmony_ci
499c2b37d2cSopenharmony_ci    ret = SaveOhosAccountInfo(currentOhosAccount);
500c2b37d2cSopenharmony_ci    if (!ret) {
501c2b37d2cSopenharmony_ci        // moving on even if failed to update account info
502c2b37d2cSopenharmony_ci        ACCOUNT_LOGW("SaveOhosAccountInfo failed, userId %{public}d.", userId);
503c2b37d2cSopenharmony_ci    }
504c2b37d2cSopenharmony_ci    subscribeManager_.Publish(userId, DISTRIBUTED_ACCOUNT_SUBSCRIBE_TYPE::TOKEN_INVALID);
505c2b37d2cSopenharmony_ci
506c2b37d2cSopenharmony_ci#ifdef HAS_CES_PART
507c2b37d2cSopenharmony_ci    AccountEventProvider::EventPublishAsUser(
508c2b37d2cSopenharmony_ci        EventFwk::CommonEventSupport::COMMON_EVENT_HWID_TOKEN_INVALID, userId);
509c2b37d2cSopenharmony_ci    AccountEventProvider::EventPublishAsUser(
510c2b37d2cSopenharmony_ci        EventFwk::CommonEventSupport::COMMON_EVENT_DISTRIBUTED_ACCOUNT_TOKEN_INVALID, userId);
511c2b37d2cSopenharmony_ci#else  // HAS_CES_PART
512c2b37d2cSopenharmony_ci    ACCOUNT_LOGI("No common event part, publish nothing for token invalid event.");
513c2b37d2cSopenharmony_ci#endif // HAS_CES_PART
514c2b37d2cSopenharmony_ci    ACCOUNT_LOGI("success, userId %{public}d.", userId);
515c2b37d2cSopenharmony_ci    return ERR_OK;
516c2b37d2cSopenharmony_ci}
517c2b37d2cSopenharmony_ci
518c2b37d2cSopenharmony_ci/**
519c2b37d2cSopenharmony_ci * Init event mapper.
520c2b37d2cSopenharmony_ci */
521c2b37d2cSopenharmony_civoid OhosAccountManager::BuildEventsMapper()
522c2b37d2cSopenharmony_ci{
523c2b37d2cSopenharmony_ci    const std::map<std::string, std::string> accountEventMap = AccountHelperData::GetAccountEventMap();
524c2b37d2cSopenharmony_ci    std::string eventLogin = GetAccountEventStr(accountEventMap, KEY_ACCOUNT_EVENT_LOGIN, OHOS_ACCOUNT_EVENT_LOGIN);
525c2b37d2cSopenharmony_ci    std::string eventLogout = GetAccountEventStr(accountEventMap, KEY_ACCOUNT_EVENT_LOGOUT, OHOS_ACCOUNT_EVENT_LOGOUT);
526c2b37d2cSopenharmony_ci    std::string eventTokenInvalid = GetAccountEventStr(accountEventMap, KEY_ACCOUNT_EVENT_TOKEN_INVALID,
527c2b37d2cSopenharmony_ci        OHOS_ACCOUNT_EVENT_TOKEN_INVALID);
528c2b37d2cSopenharmony_ci    std::string eventLogoff = GetAccountEventStr(accountEventMap, KEY_ACCOUNT_EVENT_LOGOFF, OHOS_ACCOUNT_EVENT_LOGOFF);
529c2b37d2cSopenharmony_ci
530c2b37d2cSopenharmony_ci    eventMap_.insert(std::pair<std::string, ACCOUNT_INNER_EVENT_TYPE>(eventLogin, ACCOUNT_BIND_SUCCESS_EVT));
531c2b37d2cSopenharmony_ci    eventMap_.insert(std::pair<std::string, ACCOUNT_INNER_EVENT_TYPE>(eventLogout, ACCOUNT_MANUAL_UNBOUND_EVT));
532c2b37d2cSopenharmony_ci    eventMap_.insert(std::pair<std::string, ACCOUNT_INNER_EVENT_TYPE>(eventTokenInvalid, ACCOUNT_TOKEN_EXPIRED_EVT));
533c2b37d2cSopenharmony_ci    eventMap_.insert(std::pair<std::string, ACCOUNT_INNER_EVENT_TYPE>(eventLogoff, ACCOUNT_MANUAL_LOGOFF_EVT));
534c2b37d2cSopenharmony_ci
535c2b37d2cSopenharmony_ci    eventFuncMap_.insert(std::make_pair(eventLogin,
536c2b37d2cSopenharmony_ci        [this] (const std::int32_t userId, const OhosAccountInfo &info, const std::string &eventStr) {
537c2b37d2cSopenharmony_ci        return LoginOhosAccount(userId, info, eventStr);
538c2b37d2cSopenharmony_ci    }));
539c2b37d2cSopenharmony_ci    eventFuncMap_.insert(std::make_pair(eventLogout,
540c2b37d2cSopenharmony_ci        [this] (const std::int32_t userId, const OhosAccountInfo &info, const std::string &eventStr) {
541c2b37d2cSopenharmony_ci        return LogoutOhosAccount(userId, info, eventStr);
542c2b37d2cSopenharmony_ci    }));
543c2b37d2cSopenharmony_ci    eventFuncMap_.insert(std::make_pair(eventLogoff,
544c2b37d2cSopenharmony_ci        [this] (const std::int32_t userId, const OhosAccountInfo &info, const std::string &eventStr) {
545c2b37d2cSopenharmony_ci        return LogoffOhosAccount(userId, info, eventStr);
546c2b37d2cSopenharmony_ci    }));
547c2b37d2cSopenharmony_ci    eventFuncMap_.insert(std::make_pair(eventTokenInvalid,
548c2b37d2cSopenharmony_ci        [this] (const std::int32_t userId, const OhosAccountInfo &info, const std::string &eventStr) {
549c2b37d2cSopenharmony_ci        return HandleOhosAccountTokenInvalidEvent(userId, info, eventStr);
550c2b37d2cSopenharmony_ci    }));
551c2b37d2cSopenharmony_ci}
552c2b37d2cSopenharmony_ci
553c2b37d2cSopenharmony_ciOhosAccountManager &OhosAccountManager::GetInstance()
554c2b37d2cSopenharmony_ci{
555c2b37d2cSopenharmony_ci    static OhosAccountManager *instance = new (std::nothrow) OhosAccountManager();
556c2b37d2cSopenharmony_ci    return *instance;
557c2b37d2cSopenharmony_ci}
558c2b37d2cSopenharmony_ci
559c2b37d2cSopenharmony_ciOhosAccountManager::OhosAccountManager() : subscribeManager_(DistributedAccountSubscribeManager::GetInstance())
560c2b37d2cSopenharmony_ci{
561c2b37d2cSopenharmony_ci    accountState_ = std::make_unique<AccountStateMachine>();
562c2b37d2cSopenharmony_ci    dataDealer_ = std::make_unique<OhosAccountDataDeal>(ACCOUNT_CFG_DIR_ROOT_PATH);
563c2b37d2cSopenharmony_ci    BuildEventsMapper();
564c2b37d2cSopenharmony_ci}
565c2b37d2cSopenharmony_ci
566c2b37d2cSopenharmony_ci/**
567c2b37d2cSopenharmony_ci * Init ohos account manager.
568c2b37d2cSopenharmony_ci *
569c2b37d2cSopenharmony_ci */
570c2b37d2cSopenharmony_cibool OhosAccountManager::OnInitialize()
571c2b37d2cSopenharmony_ci{
572c2b37d2cSopenharmony_ci    std::lock_guard<std::mutex> mutexLock(mgrMutex_);
573c2b37d2cSopenharmony_ci    if (isInit_) {
574c2b37d2cSopenharmony_ci        return true;
575c2b37d2cSopenharmony_ci    }
576c2b37d2cSopenharmony_ci
577c2b37d2cSopenharmony_ci    std::int32_t tryTimes = 0;
578c2b37d2cSopenharmony_ci    while (tryTimes < MAX_RETRY_TIMES) {
579c2b37d2cSopenharmony_ci        tryTimes++;
580c2b37d2cSopenharmony_ci        ErrCode errCode = dataDealer_->Init(DEVICE_ACCOUNT_OWNER);
581c2b37d2cSopenharmony_ci        if (errCode == ERR_OK) {
582c2b37d2cSopenharmony_ci            break;
583c2b37d2cSopenharmony_ci        }
584c2b37d2cSopenharmony_ci
585c2b37d2cSopenharmony_ci        // when json file corrupted, have it another try
586c2b37d2cSopenharmony_ci        if ((tryTimes == MAX_RETRY_TIMES) || (errCode != ERR_ACCOUNT_DATADEAL_JSON_FILE_CORRUPTION)) {
587c2b37d2cSopenharmony_ci            ACCOUNT_LOGE("parse json file failed: %{public}d, tryTime: %{public}d", errCode, tryTimes);
588c2b37d2cSopenharmony_ci            eventMap_.clear();
589c2b37d2cSopenharmony_ci            eventFuncMap_.clear();
590c2b37d2cSopenharmony_ci            return false;
591c2b37d2cSopenharmony_ci        }
592c2b37d2cSopenharmony_ci    }
593c2b37d2cSopenharmony_ci    isInit_ = true;
594c2b37d2cSopenharmony_ci    return true;
595c2b37d2cSopenharmony_ci}
596c2b37d2cSopenharmony_ci
597c2b37d2cSopenharmony_ci#ifdef HAS_CES_PART
598c2b37d2cSopenharmony_cibool OhosAccountManager::CreateCommonEventSubscribe()
599c2b37d2cSopenharmony_ci{
600c2b37d2cSopenharmony_ci    if (accountEventSubscribe_ == nullptr) {
601c2b37d2cSopenharmony_ci        AccountCommonEventCallback callback = {
602c2b37d2cSopenharmony_ci            [this](int32_t userId) { this->OnPackageRemoved(userId); } };
603c2b37d2cSopenharmony_ci        accountEventSubscribe_ = std::make_shared<AccountEventSubscriber>(callback);
604c2b37d2cSopenharmony_ci        if (!accountEventSubscribe_->CreateEventSubscribe()) {
605c2b37d2cSopenharmony_ci            ACCOUNT_LOGE("CreateEventSubscribe is failed");
606c2b37d2cSopenharmony_ci            return false;
607c2b37d2cSopenharmony_ci        }
608c2b37d2cSopenharmony_ci    }
609c2b37d2cSopenharmony_ci    return true;
610c2b37d2cSopenharmony_ci}
611c2b37d2cSopenharmony_ci
612c2b37d2cSopenharmony_civoid OhosAccountManager::OnPackageRemoved(const std::int32_t callingUid)
613c2b37d2cSopenharmony_ci{
614c2b37d2cSopenharmony_ci    std::vector<OsAccountInfo> osAccountInfos;
615c2b37d2cSopenharmony_ci    (void)IInnerOsAccountManager::GetInstance().QueryAllCreatedOsAccounts(osAccountInfos);
616c2b37d2cSopenharmony_ci    for (const auto &info : osAccountInfos) {
617c2b37d2cSopenharmony_ci        AccountInfo accountInfo;
618c2b37d2cSopenharmony_ci        (void)GetAccountInfoByUserId(info.GetLocalId(), accountInfo);
619c2b37d2cSopenharmony_ci        if (accountInfo.ohosAccountInfo_.callingUid_ == callingUid) {
620c2b37d2cSopenharmony_ci            (void)ClearOhosAccount(accountInfo);
621c2b37d2cSopenharmony_ci            AccountEventProvider::EventPublishAsUser(
622c2b37d2cSopenharmony_ci                EventFwk::CommonEventSupport::COMMON_EVENT_HWID_LOGOUT, info.GetLocalId());
623c2b37d2cSopenharmony_ci            AccountEventProvider::EventPublishAsUser(
624c2b37d2cSopenharmony_ci                EventFwk::CommonEventSupport::COMMON_EVENT_DISTRIBUTED_ACCOUNT_LOGOUT, info.GetLocalId());
625c2b37d2cSopenharmony_ci        }
626c2b37d2cSopenharmony_ci    }
627c2b37d2cSopenharmony_ci}
628c2b37d2cSopenharmony_ci#endif // HAS_CES_PART
629c2b37d2cSopenharmony_ci
630c2b37d2cSopenharmony_ci/**
631c2b37d2cSopenharmony_ci * Handle device account switch event.
632c2b37d2cSopenharmony_ci *
633c2b37d2cSopenharmony_ci * @param None
634c2b37d2cSopenharmony_ci * @return None
635c2b37d2cSopenharmony_ci */
636c2b37d2cSopenharmony_civoid OhosAccountManager::HandleDevAccountSwitchEvent()
637c2b37d2cSopenharmony_ci{
638c2b37d2cSopenharmony_ci    std::lock_guard<std::mutex> mutexLock(mgrMutex_);
639c2b37d2cSopenharmony_ci    eventMap_.clear();
640c2b37d2cSopenharmony_ci    eventFuncMap_.clear();
641c2b37d2cSopenharmony_ci
642c2b37d2cSopenharmony_ci    // Re-Init
643c2b37d2cSopenharmony_ci    if (!OnInitialize()) {
644c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("Handle dev Account SwitchEvent failed");
645c2b37d2cSopenharmony_ci    }
646c2b37d2cSopenharmony_ci}
647c2b37d2cSopenharmony_ci
648c2b37d2cSopenharmony_cibool OhosAccountManager::CheckOhosAccountCanBind(const AccountInfo &currAccountInfo,
649c2b37d2cSopenharmony_ci    const OhosAccountInfo &newOhosAccountInfo, const std::string &newOhosUid) const
650c2b37d2cSopenharmony_ci{
651c2b37d2cSopenharmony_ci    if (newOhosUid.length() != OHOS_ACCOUNT_UDID_LENGTH) {
652c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("newOhosUid invalid length, %{public}s.", newOhosUid.c_str());
653c2b37d2cSopenharmony_ci        return false;
654c2b37d2cSopenharmony_ci    }
655c2b37d2cSopenharmony_ci
656c2b37d2cSopenharmony_ci    // check if current account has been bound or not
657c2b37d2cSopenharmony_ci    if ((currAccountInfo.ohosAccountInfo_.status_ == ACCOUNT_STATE_LOGIN) &&
658c2b37d2cSopenharmony_ci        ((currAccountInfo.ohosAccountInfo_.uid_ != newOhosUid) ||
659c2b37d2cSopenharmony_ci        (currAccountInfo.ohosAccountInfo_.name_ != newOhosAccountInfo.name_))) {
660c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("current account has already been bounded. callingUserId %{public}d.",
661c2b37d2cSopenharmony_ci            AccountMgrService::GetInstance().GetCallingUserID());
662c2b37d2cSopenharmony_ci        return false;
663c2b37d2cSopenharmony_ci    }
664c2b37d2cSopenharmony_ci
665c2b37d2cSopenharmony_ci    // check whether newOhosUid has been already bound to another account or not
666c2b37d2cSopenharmony_ci    DIR* rootDir = opendir(ACCOUNT_CFG_DIR_ROOT_PATH.c_str());
667c2b37d2cSopenharmony_ci    if (rootDir == nullptr) {
668c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("cannot open dir %{public}s, err %{public}d.", ACCOUNT_CFG_DIR_ROOT_PATH.c_str(), errno);
669c2b37d2cSopenharmony_ci        return false;
670c2b37d2cSopenharmony_ci    }
671c2b37d2cSopenharmony_ci    struct dirent* curDir = nullptr;
672c2b37d2cSopenharmony_ci    while ((curDir = readdir(rootDir)) != nullptr) {
673c2b37d2cSopenharmony_ci        std::string curDirName(curDir->d_name);
674c2b37d2cSopenharmony_ci        if (curDirName == "." || curDirName == ".." || curDir->d_type != DT_DIR) {
675c2b37d2cSopenharmony_ci            continue;
676c2b37d2cSopenharmony_ci        }
677c2b37d2cSopenharmony_ci
678c2b37d2cSopenharmony_ci        AccountInfo curInfo;
679c2b37d2cSopenharmony_ci        std::stringstream sstream;
680c2b37d2cSopenharmony_ci        sstream << curDirName;
681c2b37d2cSopenharmony_ci        std::int32_t userId = -1;
682c2b37d2cSopenharmony_ci        sstream >> userId;
683c2b37d2cSopenharmony_ci        if (dataDealer_->AccountInfoFromJson(curInfo, userId) != ERR_OK) {
684c2b37d2cSopenharmony_ci            ACCOUNT_LOGI("get ohos account info from user %{public}s failed.", curDirName.c_str());
685c2b37d2cSopenharmony_ci            continue;
686c2b37d2cSopenharmony_ci        }
687c2b37d2cSopenharmony_ci
688c2b37d2cSopenharmony_ci        if (curInfo.ohosAccountInfo_.status_ != ACCOUNT_STATE_LOGIN) {
689c2b37d2cSopenharmony_ci            continue; // account not bind, skip check
690c2b37d2cSopenharmony_ci        }
691c2b37d2cSopenharmony_ci    }
692c2b37d2cSopenharmony_ci
693c2b37d2cSopenharmony_ci    (void)closedir(rootDir);
694c2b37d2cSopenharmony_ci    return true;
695c2b37d2cSopenharmony_ci}
696c2b37d2cSopenharmony_ci
697c2b37d2cSopenharmony_cibool OhosAccountManager::GetCurOhosAccountAndCheckMatch(AccountInfo &curAccountInfo,
698c2b37d2cSopenharmony_ci                                                        const std::string &inputName,
699c2b37d2cSopenharmony_ci                                                        const std::string &inputUid,
700c2b37d2cSopenharmony_ci                                                        const std::int32_t callingUserId) const
701c2b37d2cSopenharmony_ci{
702c2b37d2cSopenharmony_ci    if (dataDealer_->AccountInfoFromJson(curAccountInfo, callingUserId) != ERR_OK) {
703c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("cannot read from config, inputName %{public}s.", inputName.c_str());
704c2b37d2cSopenharmony_ci        return false;
705c2b37d2cSopenharmony_ci    }
706c2b37d2cSopenharmony_ci
707c2b37d2cSopenharmony_ci    std::string ohosAccountUid = GenerateOhosUdidWithSha256(inputName, inputUid);
708c2b37d2cSopenharmony_ci    if (inputName != curAccountInfo.ohosAccountInfo_.name_ ||
709c2b37d2cSopenharmony_ci        ohosAccountUid != curAccountInfo.ohosAccountInfo_.uid_) {
710c2b37d2cSopenharmony_ci        ACCOUNT_LOGE("account name %{public}s or ohosAccountUid %{public}s mismatch, calling user %{public}d.",
711c2b37d2cSopenharmony_ci            inputName.c_str(), ohosAccountUid.c_str(), callingUserId);
712c2b37d2cSopenharmony_ci        return false;
713c2b37d2cSopenharmony_ci    }
714c2b37d2cSopenharmony_ci    return true;
715c2b37d2cSopenharmony_ci}
716c2b37d2cSopenharmony_ci} // namespace AccountSA
717c2b37d2cSopenharmony_ci} // namespace OHOS
718