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