1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "domain_account_client.h"
17 
18 #include "account_error_no.h"
19 #include "account_log_wrapper.h"
20 #include "account_proxy.h"
21 #include "domain_account_callback_adapters.h"
22 #include "domain_account_callback_service.h"
23 #include "domain_account_plugin_service.h"
24 #include "domain_account_proxy.h"
25 #include "domain_account_status_listener.h"
26 #include "domain_account_status_listener_manager.h"
27 #include "ohos_account_kits_impl.h"
28 #include "system_ability_definition.h"
29 
30 namespace OHOS {
31 namespace AccountSA {
GetInstance()32 DomainAccountClient &DomainAccountClient::GetInstance()
33 {
34     static DomainAccountClient *instance = new (std::nothrow) DomainAccountClient();
35     return *instance;
36 }
37 
callbackFunc()38 std::function<void(int32_t, const std::string &)> callbackFunc()
39 {
40     return [](int32_t systemAbilityId, const std::string &deviceId) {
41         if (systemAbilityId == SUBSYS_ACCOUNT_SYS_ABILITY_ID_BEGIN) {
42             DomainAccountClient::GetInstance().RestoreListenerRecords();
43             DomainAccountClient::GetInstance().RestorePlugin();
44         }
45     };
46 }
47 
DomainAccountClient()48 DomainAccountClient::DomainAccountClient()
49 {
50     (void)OhosAccountKitsImpl::GetInstance().SubscribeSystemAbility(callbackFunc());
51 }
52 
RegisterPlugin(const std::shared_ptr<DomainAccountPlugin> & plugin)53 ErrCode DomainAccountClient::RegisterPlugin(const std::shared_ptr<DomainAccountPlugin> &plugin)
54 {
55     if (plugin == nullptr) {
56         ACCOUNT_LOGE("plugin is nullptr");
57         return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
58     }
59     sptr<DomainAccountPluginService> pluginService = new (std::nothrow) DomainAccountPluginService(plugin);
60     if (pluginService == nullptr) {
61         ACCOUNT_LOGE("failed to create DomainAccountPluginService");
62         return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
63     }
64     auto proxy = GetDomainAccountProxy();
65     if (proxy == nullptr) {
66         ACCOUNT_LOGE("failed to get domain account proxy");
67         return ERR_ACCOUNT_COMMON_GET_PROXY;
68     }
69     ErrCode result = proxy->RegisterPlugin(pluginService);
70     if (result == ERR_OK) {
71         pluginService_ = pluginService;
72     }
73     return result;
74 }
75 
UnregisterPlugin()76 ErrCode DomainAccountClient::UnregisterPlugin()
77 {
78     auto proxy = GetDomainAccountProxy();
79     if (proxy == nullptr) {
80         ACCOUNT_LOGE("failed to get domain account proxy");
81         return ERR_ACCOUNT_COMMON_GET_PROXY;
82     }
83     return proxy->UnregisterPlugin();
84 }
85 
AuthProxyInit(const std::shared_ptr<DomainAccountCallback> & callback,sptr<DomainAccountCallbackService> & callbackService,sptr<IDomainAccount> & proxy)86 ErrCode DomainAccountClient::AuthProxyInit(const std::shared_ptr<DomainAccountCallback> &callback,
87     sptr<DomainAccountCallbackService> &callbackService, sptr<IDomainAccount> &proxy)
88 {
89     if (callback == nullptr) {
90         ACCOUNT_LOGE("callback is nullptr");
91         return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
92     }
93     callbackService = new (std::nothrow) DomainAccountCallbackService(callback);
94     if (callbackService == nullptr) {
95         ACCOUNT_LOGE("failed to create DomainAccountCallbackService");
96         return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
97     }
98     proxy = GetDomainAccountProxy();
99     if (proxy == nullptr) {
100         ACCOUNT_LOGE("failed to get domain account proxy");
101         return ERR_ACCOUNT_COMMON_GET_PROXY;
102     }
103     return ERR_OK;
104 }
105 
GetAccessToken(const DomainAccountInfo & info,const AAFwk::WantParams & parameters,const std::shared_ptr<GetAccessTokenCallback> & callback)106 ErrCode DomainAccountClient::GetAccessToken(const DomainAccountInfo &info, const AAFwk::WantParams &parameters,
107     const std::shared_ptr<GetAccessTokenCallback> &callback)
108 {
109     if (callback == nullptr) {
110         ACCOUNT_LOGE("callback is nullptr");
111         return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
112     }
113     auto callbackPtr = std::make_shared<GetAccessTokenCallbackAdapter>(callback);
114     sptr<DomainAccountCallbackService> callbackService = new (std::nothrow) DomainAccountCallbackService(callbackPtr);
115     if (callbackService == nullptr) {
116         ACCOUNT_LOGE("failed to new callback service");
117         return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
118     }
119     auto proxy = GetDomainAccountProxy();
120     if (proxy == nullptr) {
121         ACCOUNT_LOGE("failed to get domain account proxy");
122         return ERR_ACCOUNT_COMMON_GET_PROXY;
123     }
124     return proxy->GetAccessToken(info, parameters, callbackService);
125 }
126 
HasAccount(const DomainAccountInfo & info,const std::shared_ptr<DomainAccountCallback> & callback)127 ErrCode DomainAccountClient::HasAccount(
128     const DomainAccountInfo &info, const std::shared_ptr<DomainAccountCallback> &callback)
129 {
130     if (callback == nullptr) {
131         ACCOUNT_LOGE("callback is nullptr");
132         return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
133     }
134     sptr<DomainAccountCallbackService> callbackService = new (std::nothrow) DomainAccountCallbackService(callback);
135     if (callbackService == nullptr) {
136         ACCOUNT_LOGE("failed to check domain account callback service");
137         return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
138     }
139     auto proxy = GetDomainAccountProxy();
140     if (proxy == nullptr) {
141         ACCOUNT_LOGE("failed to get domain account proxy");
142         return ERR_ACCOUNT_COMMON_GET_PROXY;
143     }
144     return proxy->HasDomainAccount(info, callbackService);
145 }
146 
Auth(const DomainAccountInfo & info,const std::vector<uint8_t> & password,const std::shared_ptr<DomainAccountCallback> & callback)147 ErrCode DomainAccountClient::Auth(const DomainAccountInfo &info, const std::vector<uint8_t> &password,
148     const std::shared_ptr<DomainAccountCallback> &callback)
149 {
150     sptr<DomainAccountCallbackService> callbackService = nullptr;
151     sptr<IDomainAccount> proxy = nullptr;
152     ErrCode result = AuthProxyInit(callback, callbackService, proxy);
153     if (result != ERR_OK) {
154         return result;
155     }
156     return proxy->Auth(info, password, callbackService);
157 }
158 
AuthUser(int32_t userId,const std::vector<uint8_t> & password,const std::shared_ptr<DomainAccountCallback> & callback)159 ErrCode DomainAccountClient::AuthUser(int32_t userId, const std::vector<uint8_t> &password,
160     const std::shared_ptr<DomainAccountCallback> &callback)
161 {
162     sptr<DomainAccountCallbackService> callbackService = nullptr;
163     sptr<IDomainAccount> proxy = nullptr;
164     ErrCode result = AuthProxyInit(callback, callbackService, proxy);
165     if (result != ERR_OK) {
166         return result;
167     }
168     return proxy->AuthUser(userId, password, callbackService);
169 }
170 
AuthWithPopup(int32_t userId,const std::shared_ptr<DomainAccountCallback> & callback)171 ErrCode DomainAccountClient::AuthWithPopup(int32_t userId, const std::shared_ptr<DomainAccountCallback> &callback)
172 {
173     sptr<DomainAccountCallbackService> callbackService = nullptr;
174     sptr<IDomainAccount> proxy = nullptr;
175     ErrCode result = AuthProxyInit(callback, callbackService, proxy);
176     if (result != ERR_OK) {
177         return result;
178     }
179     return proxy->AuthWithPopup(userId, callbackService);
180 }
181 
UpdateAccountToken(const DomainAccountInfo & info,const std::vector<uint8_t> & token)182 ErrCode DomainAccountClient::UpdateAccountToken(const DomainAccountInfo &info, const std::vector<uint8_t> &token)
183 {
184     auto proxy = GetDomainAccountProxy();
185     if (proxy == nullptr) {
186         ACCOUNT_LOGE("failed to get domain account proxy");
187         return ERR_ACCOUNT_COMMON_GET_PROXY;
188     }
189     return proxy->UpdateAccountToken(info, token);
190 }
191 
IsAuthenticationExpired(const DomainAccountInfo & info,bool & isExpired)192 ErrCode DomainAccountClient::IsAuthenticationExpired(const DomainAccountInfo &info, bool &isExpired)
193 {
194     isExpired = true;
195     auto proxy = GetDomainAccountProxy();
196     if (proxy == nullptr) {
197         ACCOUNT_LOGE("Get domain account proxy failed.");
198         return ERR_ACCOUNT_COMMON_GET_PROXY;
199     }
200     return proxy->IsAuthenticationExpired(info, isExpired);
201 }
202 
SetAccountPolicy(const DomainAccountPolicy & policy)203 ErrCode DomainAccountClient::SetAccountPolicy(const DomainAccountPolicy &policy)
204 {
205     auto proxy = GetDomainAccountProxy();
206     if (proxy == nullptr) {
207         ACCOUNT_LOGE("Get domain account proxy failed.");
208         return ERR_ACCOUNT_COMMON_GET_PROXY;
209     }
210     return proxy->SetAccountPolicy(policy);
211 }
212 
ResetDomainAccountProxy(const wptr<IRemoteObject> & remote)213 void DomainAccountClient::ResetDomainAccountProxy(const wptr<IRemoteObject>& remote)
214 {
215     std::lock_guard<std::mutex> lock(mutex_);
216     if (proxy_ == nullptr) {
217         ACCOUNT_LOGD("proxy is nullptr");
218         return;
219     }
220     auto serviceRemote = proxy_->AsObject();
221     if ((serviceRemote != nullptr) && (serviceRemote == remote.promote())) {
222         serviceRemote->RemoveDeathRecipient(deathRecipient_);
223     }
224     proxy_ = nullptr;
225     deathRecipient_ = nullptr;
226 }
227 
GetAccountStatus(const DomainAccountInfo & info,DomainAccountStatus & status)228 ErrCode DomainAccountClient::GetAccountStatus(const DomainAccountInfo &info, DomainAccountStatus &status)
229 {
230     auto proxy = GetDomainAccountProxy();
231     if (proxy == nullptr) {
232         ACCOUNT_LOGE("failed to get domain account proxy");
233         return ERR_ACCOUNT_COMMON_GET_PROXY;
234     }
235     return proxy->GetAccountStatus(info, status);
236 }
237 
GetDomainAccountInfo(const DomainAccountInfo & info,const std::shared_ptr<DomainAccountCallback> & callback)238 ErrCode DomainAccountClient::GetDomainAccountInfo(
239     const DomainAccountInfo &info, const std::shared_ptr<DomainAccountCallback> &callback)
240 {
241     if (callback == nullptr) {
242         ACCOUNT_LOGE("callback is nullptr");
243         return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
244     }
245     sptr<DomainAccountCallbackService> callbackService = new (std::nothrow) DomainAccountCallbackService(callback);
246     auto proxy = GetDomainAccountProxy();
247     if (proxy == nullptr) {
248         ACCOUNT_LOGE("failed to get domain account proxy");
249         return ERR_ACCOUNT_COMMON_GET_PROXY;
250     }
251     return proxy->GetDomainAccountInfo(info, callbackService);
252 }
253 
UpdateAccountInfo(const DomainAccountInfo & oldAccountInfo,const DomainAccountInfo & newAccountInfo)254 ErrCode DomainAccountClient::UpdateAccountInfo(
255     const DomainAccountInfo &oldAccountInfo, const DomainAccountInfo &newAccountInfo)
256 {
257     auto proxy = GetDomainAccountProxy();
258     if (proxy == nullptr) {
259         ACCOUNT_LOGE("Failed to get domain account proxy");
260         return ERR_ACCOUNT_COMMON_GET_PROXY;
261     }
262     return proxy->UpdateAccountInfo(oldAccountInfo, newAccountInfo);
263 }
264 
RegisterAccountStatusListener(const std::shared_ptr<DomainAccountStatusListener> & listener)265 ErrCode DomainAccountClient::RegisterAccountStatusListener(const std::shared_ptr<DomainAccountStatusListener> &listener)
266 {
267     if (listener == nullptr) {
268         ACCOUNT_LOGE("callback is nullptr");
269         return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
270     }
271     std::lock_guard<std::mutex> lock(recordMutex_);
272     if (listenerManager_ == nullptr) {
273         listenerManager_ = std::make_shared<DomainAccountStatusListenerManager>();
274     }
275     if (!listenerManager_->IsRecordEmpty()) {
276         listenerManager_->InsertRecord(listener);
277         return ERR_OK;
278     }
279     if (callback_ == nullptr) {
280         callback_ = new (std::nothrow) DomainAccountCallbackService(listenerManager_);
281         if (callback_ == nullptr) {
282             ACCOUNT_LOGE("failed to check domain account callback service");
283             return ERR_ACCOUNT_COMMON_INSUFFICIENT_MEMORY_ERROR;
284         }
285     }
286     auto proxy = GetDomainAccountProxy();
287     if (proxy == nullptr) {
288         ACCOUNT_LOGE("failed to get domain account proxy");
289         return ERR_ACCOUNT_COMMON_GET_PROXY;
290     }
291     ErrCode result = proxy->RegisterAccountStatusListener(callback_);
292     if (result == ERR_OK) {
293         listenerManager_->InsertRecord(listener);
294     }
295     return result;
296 }
297 
UnregisterAccountStatusListener(const std::shared_ptr<DomainAccountStatusListener> & listener)298 ErrCode DomainAccountClient::UnregisterAccountStatusListener(
299     const std::shared_ptr<DomainAccountStatusListener> &listener)
300 {
301     if (listener == nullptr) {
302         ACCOUNT_LOGE("callback is nullptr");
303         return ERR_ACCOUNT_COMMON_INVALID_PARAMETER;
304     }
305     std::lock_guard<std::mutex> lock(recordMutex_);
306     if (listenerManager_ == nullptr) {
307         ACCOUNT_LOGE("listenerManager_ is nullptr");
308         return ERR_ACCOUNT_COMMON_NULL_PTR_ERROR;
309     }
310     auto proxy = GetDomainAccountProxy();
311     if (proxy == nullptr) {
312         ACCOUNT_LOGE("failed to get domain account proxy");
313         return ERR_ACCOUNT_COMMON_GET_PROXY;
314     }
315     listenerManager_->RemoveRecord(listener);
316     if (!listenerManager_->IsRecordEmpty()) {
317         return ERR_OK;
318     }
319     ErrCode result = proxy->UnregisterAccountStatusListener(callback_);
320     if (result != ERR_OK) {
321         listenerManager_->InsertRecord(listener);
322         return result;
323     }
324     return ERR_OK;
325 }
326 
AddServerConfig(const std::string & parameters,DomainServerConfig & config)327 ErrCode DomainAccountClient::AddServerConfig(const std::string &parameters, DomainServerConfig &config)
328 {
329     auto proxy = GetDomainAccountProxy();
330     if (proxy == nullptr) {
331         ACCOUNT_LOGE("Failed to get domain account proxy.");
332         return ERR_ACCOUNT_COMMON_GET_PROXY;
333     }
334     return proxy->AddServerConfig(parameters, config);
335 }
336 
RemoveServerConfig(const std::string & configId)337 ErrCode DomainAccountClient::RemoveServerConfig(const std::string &configId)
338 {
339     auto proxy = GetDomainAccountProxy();
340     if (proxy == nullptr) {
341         ACCOUNT_LOGE("Failed to get domain account proxy.");
342         return ERR_ACCOUNT_COMMON_GET_PROXY;
343     }
344     return proxy->RemoveServerConfig(configId);
345 }
346 
GetAccountServerConfig(const DomainAccountInfo & info,DomainServerConfig & config)347 ErrCode DomainAccountClient::GetAccountServerConfig(const DomainAccountInfo &info, DomainServerConfig &config)
348 {
349     auto proxy = GetDomainAccountProxy();
350     if (proxy == nullptr) {
351         ACCOUNT_LOGE("Failed to get domain account proxy.");
352         return ERR_ACCOUNT_COMMON_GET_PROXY;
353     }
354     return proxy->GetAccountServerConfig(info, config);
355 }
356 
RestoreListenerRecords()357 void DomainAccountClient::RestoreListenerRecords()
358 {
359     if (listenerManager_ == nullptr) {
360         ACCOUNT_LOGI("listenerManager_ is nullptr");
361         return;
362     }
363     sptr<IDomainAccount> proxy = GetDomainAccountProxy();
364     if (proxy == nullptr) {
365         ACCOUNT_LOGE("proxy is nullptr");
366         return;
367     }
368     if (!listenerManager_->IsRecordEmpty()) {
369         (void)proxy->RegisterAccountStatusListener(callback_);
370     }
371 }
372 
RestorePlugin()373 void DomainAccountClient::RestorePlugin()
374 {
375     if (pluginService_ == nullptr) {
376         ACCOUNT_LOGI("pluginService_ is nullptr");
377         return;
378     }
379     sptr<IDomainAccount> proxy = GetDomainAccountProxy();
380     if (proxy == nullptr) {
381         ACCOUNT_LOGE("proxy is nullptr");
382         return;
383     }
384     (void)proxy->RegisterPlugin(pluginService_);
385 }
386 
OnRemoteDied(const wptr<IRemoteObject> & remote)387 void DomainAccountClient::DomainAccountDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
388 {
389     if (remote == nullptr) {
390         ACCOUNT_LOGE("remote is nullptr");
391         return;
392     }
393     DomainAccountClient::GetInstance().ResetDomainAccountProxy(remote);
394 }
395 
GetDomainAccountProxy()396 sptr<IDomainAccount> DomainAccountClient::GetDomainAccountProxy()
397 {
398     std::lock_guard<std::mutex> lock(mutex_);
399     if (proxy_ != nullptr) {
400         return proxy_;
401     }
402     sptr<IRemoteObject> object = OhosAccountKitsImpl::GetInstance().GetDomainAccountService();
403     if (object == nullptr) {
404         ACCOUNT_LOGE("failed to get domain account service");
405         return nullptr;
406     }
407     deathRecipient_ = new (std::nothrow) DomainAccountDeathRecipient();
408     if (deathRecipient_ == nullptr) {
409         ACCOUNT_LOGE("failed to create domain account death recipient");
410         return nullptr;
411     }
412 
413     if ((object->IsProxyObject()) && (!object->AddDeathRecipient(deathRecipient_))) {
414         ACCOUNT_LOGE("Failed to add death recipient");
415         deathRecipient_ = nullptr;
416     }
417     proxy_ = iface_cast<IDomainAccount>(object);
418     return proxy_;
419 }
420 }  // namespace AccountSA
421 }  // namespace OHOS
422