1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #define LOG_TAG "AccountDelegateNormalImpl"
16
17 #include "account_delegate_normal_impl.h"
18 #include <algorithm>
19 #include <endian.h>
20 #include <list>
21 #include <regex>
22 #include <thread>
23 #include <unistd.h>
24 #include "accesstoken_kit.h"
25 #include "log_print.h"
26 #include "ohos_account_kits.h"
27 #include "os_account_manager.h"
28
29 namespace OHOS {
30 namespace DistributedKv {
31 using namespace OHOS::EventFwk;
32 using namespace OHOS::AAFwk;
33 using namespace OHOS::DistributedData;
34 using namespace Security::AccessToken;
35 __attribute__((used)) static bool g_isInit = AccountDelegateNormalImpl::Init();
36
GetCurrentAccountId() const37 std::string AccountDelegateNormalImpl::GetCurrentAccountId() const
38 {
39 ZLOGD("start");
40 auto ohosAccountInfo = AccountSA::OhosAccountKits::GetInstance().QueryOhosAccountInfo();
41 if (!ohosAccountInfo.first) {
42 ZLOGE("get ohosAccountInfo from OhosAccountKits is null, return default");
43 return AccountSA::DEFAULT_OHOS_ACCOUNT_UID;
44 }
45 if (ohosAccountInfo.second.uid_.empty()) {
46 ZLOGE("get ohosAccountInfo from OhosAccountKits is null, return default");
47 return AccountSA::DEFAULT_OHOS_ACCOUNT_UID;
48 }
49
50 return Sha256AccountId(ohosAccountInfo.second.uid_);
51 }
52
GetUserByToken(uint32_t tokenId) const53 int32_t AccountDelegateNormalImpl::GetUserByToken(uint32_t tokenId) const
54 {
55 auto type = AccessTokenKit::GetTokenTypeFlag(tokenId);
56 if (type == TOKEN_NATIVE || type == TOKEN_SHELL) {
57 return 0;
58 }
59
60 HapTokenInfo tokenInfo;
61 auto result = AccessTokenKit::GetHapTokenInfo(tokenId, tokenInfo);
62 if (result != RET_SUCCESS) {
63 ZLOGE("token:0x%{public}x, result:%{public}d", tokenId, result);
64 return -1;
65 }
66 return tokenInfo.userID;
67 }
68
QueryUsers(std::vector<int> & users)69 bool AccountDelegateNormalImpl::QueryUsers(std::vector<int> &users)
70 {
71 users = {0}; // default user
72 return AccountSA::OsAccountManager::QueryActiveOsAccountIds(users) == 0;
73 }
74
QueryForegroundUsers(std::vector<int> & users)75 bool AccountDelegateNormalImpl::QueryForegroundUsers(std::vector<int> &users)
76 {
77 std::vector<AccountSA::ForegroundOsAccount> accounts;
78 if (AccountSA::OsAccountManager::GetForegroundOsAccounts(accounts) != 0) {
79 return false;
80 }
81 for (auto &account : accounts) {
82 users.push_back(account.localId);
83 }
84 return true;
85 }
86
IsLoginAccount()87 bool AccountDelegateNormalImpl::IsLoginAccount()
88 {
89 return GetCurrentAccountId() != AccountSA::DEFAULT_OHOS_ACCOUNT_UID;
90 }
91
IsVerified(int userId)92 bool AccountDelegateNormalImpl::IsVerified(int userId)
93 {
94 auto [success, res] = userStatus_.Find(userId);
95 if (success && res) {
96 return true;
97 }
98 auto status = AccountSA::OsAccountManager::IsOsAccountVerified(userId, res);
99 if (status == 0) {
100 userStatus_.InsertOrAssign(userId, res);
101 }
102 return status == 0 && res;
103 }
104
SubscribeAccountEvent()105 void AccountDelegateNormalImpl::SubscribeAccountEvent()
106 {
107 ZLOGI("Subscribe account event listener start.");
108 if (eventSubscriber_ == nullptr) {
109 MatchingSkills matchingSkills;
110 matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_REMOVED);
111 matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_SWITCHED);
112 matchingSkills.AddEvent(CommonEventSupport::COMMON_EVENT_USER_UNLOCKED);
113 CommonEventSubscribeInfo info(matchingSkills);
114 eventSubscriber_ = std::make_shared<EventSubscriber>(info);
115 eventSubscriber_->SetEventCallback([this](AccountEventInfo& account) {
116 UpdateUserStatus(account);
117 account.harmonyAccountId = GetCurrentAccountId();
118 NotifyAccountChanged(account);
119 });
120 }
121 executors_->Execute(GetTask(0));
122 }
123
UpdateUserStatus(const AccountEventInfo & account)124 void AccountDelegateNormalImpl::UpdateUserStatus(const AccountEventInfo& account)
125 {
126 uint32_t status = static_cast<uint32_t>(account.status);
127 switch (status) {
128 case static_cast<uint32_t>(AccountStatus::DEVICE_ACCOUNT_DELETE):
129 userStatus_.Erase(atoi(account.userId.c_str()));
130 break;
131 case static_cast<uint32_t>(AccountStatus::DEVICE_ACCOUNT_UNLOCKED):
132 userStatus_.InsertOrAssign(atoi(account.userId.c_str()), true);
133 break;
134 default:
135 break;
136 }
137 }
138
GetTask(uint32_t retry)139 ExecutorPool::Task AccountDelegateNormalImpl::GetTask(uint32_t retry)
140 {
141 return [this, retry] {
142 auto result = CommonEventManager::SubscribeCommonEvent(eventSubscriber_);
143 if (result) {
144 ZLOGI("success to register subscriber.");
145 return;
146 }
147 ZLOGD("fail to register subscriber, error:%{public}d, time:%{public}d", result, retry);
148
149 if (retry + 1 > MAX_RETRY_TIME) {
150 ZLOGE("fail to register subscriber!");
151 return;
152 }
153 executors_->Schedule(std::chrono::seconds(RETRY_WAIT_TIME_S), GetTask(retry + 1));
154 };
155 }
156
~AccountDelegateNormalImpl()157 AccountDelegateNormalImpl::~AccountDelegateNormalImpl()
158 {
159 ZLOGD("destruct");
160 auto res = CommonEventManager::UnSubscribeCommonEvent(eventSubscriber_);
161 if (!res) {
162 ZLOGW("unregister account event fail res:%d", res);
163 }
164 }
165
UnsubscribeAccountEvent()166 void AccountDelegateNormalImpl::UnsubscribeAccountEvent()
167 {
168 auto res = CommonEventManager::UnSubscribeCommonEvent(eventSubscriber_);
169 if (!res) {
170 ZLOGW("unregister account event fail res:%d", res);
171 }
172 }
173
Sha256AccountId(const std::string & plainText) const174 std::string AccountDelegateNormalImpl::Sha256AccountId(const std::string &plainText) const
175 {
176 std::regex pattern("^[0-9]+$");
177 if (!std::regex_match(plainText, pattern)) {
178 return plainText;
179 }
180
181 int64_t plain;
182 std::string::size_type int64MaxLen(std::to_string(INT64_MAX).size());
183 // plain text length must be less than INT64_MAX string.
184 plain = atoll(plainText.c_str());
185 if (plain == 0) {
186 return plainText;
187 }
188 if (plain == INT64_MAX) {
189 plain = atoll(plainText.substr(plainText.size() - int64MaxLen + 1, int64MaxLen - 1).c_str());
190 }
191
192 auto plainVal = htobe64(plain);
193 return DoHash(static_cast<void *>(&plainVal), sizeof(plainVal), true);
194 }
195
BindExecutor(std::shared_ptr<ExecutorPool> executors)196 void AccountDelegateNormalImpl::BindExecutor(std::shared_ptr<ExecutorPool> executors)
197 {
198 executors_ = executors;
199 }
200
GetUnencryptedAccountId(int32_t userId) const201 std::string AccountDelegateNormalImpl::GetUnencryptedAccountId(int32_t userId) const
202 {
203 AccountSA::OhosAccountInfo info;
204 auto ret = AccountSA::OhosAccountKits::GetInstance().GetOhosAccountInfoByUserId(userId, info);
205 if (ret != ERR_OK) {
206 ZLOGE("GetUnencryptedAccountId failed: %{public}d", ret);
207 return "";
208 }
209 return Sha256AccountId(info.GetRawUid());
210 }
211
QueryForegroundUserId(int & foregroundUserId)212 bool AccountDelegateNormalImpl::QueryForegroundUserId(int &foregroundUserId)
213 {
214 int32_t status = AccountSA::OsAccountManager::GetForegroundOsAccountLocalId(foregroundUserId);
215 if (status != ERR_OK) {
216 ZLOGE("GetForegroundOsAccountLocalId failed, status: %{public}d", status);
217 return false;
218 }
219 return true;
220 }
221
Init()222 bool AccountDelegateNormalImpl::Init()
223 {
224 static AccountDelegateNormalImpl normalAccountDelegate;
225 static std::once_flag onceFlag;
226 std::call_once(onceFlag, [&]() { AccountDelegate::RegisterAccountInstance(&normalAccountDelegate); });
227 return true;
228 }
229 } // namespace DistributedKv
230 } // namespace OHOS