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 
16 #include "app_account_authenticator_session_manager.h"
17 
18 #include "account_log_wrapper.h"
19 #include "app_account_authenticator_session.h"
20 #include "app_account_check_labels_session.h"
21 #include "app_mgr_constants.h"
22 #include "iservice_registry.h"
23 #include "system_ability_definition.h"
24 
25 namespace OHOS {
26 namespace AccountSA {
27 namespace {
28 constexpr size_t SESSION_MAX_NUM = 256;
29 }
30 
SessionAppStateObserver()31 SessionAppStateObserver::SessionAppStateObserver()
32 {}
33 
OnAbilityStateChanged(const AppExecFwk::AbilityStateData & abilityStateData)34 void SessionAppStateObserver::OnAbilityStateChanged(const AppExecFwk::AbilityStateData &abilityStateData)
35 {
36     AppAccountAuthenticatorSessionManager::GetInstance().OnAbilityStateChanged(abilityStateData);
37 }
38 
~AppAccountAuthenticatorSessionManager()39 AppAccountAuthenticatorSessionManager::~AppAccountAuthenticatorSessionManager()
40 {
41     UnregisterApplicationStateObserver();
42     sessionMap_.clear();
43     abilitySessions_.clear();
44 }
45 
GetInstance()46 AppAccountAuthenticatorSessionManager &AppAccountAuthenticatorSessionManager::GetInstance()
47 {
48     static AppAccountAuthenticatorSessionManager instance;
49     return instance;
50 }
51 
RegisterApplicationStateObserver()52 void AppAccountAuthenticatorSessionManager::RegisterApplicationStateObserver()
53 {
54     if (appStateObserver_ != nullptr) {
55         return;
56     }
57     appStateObserver_ = new (std::nothrow) SessionAppStateObserver();
58     if (appStateObserver_ == nullptr) {
59         ACCOUNT_LOGE("failed to create SessionAppStateObserver instance");
60         return;
61     }
62     sptr<ISystemAbilityManager> samgrClient = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
63     if (samgrClient == nullptr) {
64         ACCOUNT_LOGE("failed to system ability manager");
65         return;
66     }
67     iAppMgr_ = iface_cast<AppExecFwk::IAppMgr>(samgrClient->GetSystemAbility(APP_MGR_SERVICE_ID));
68     if (iAppMgr_ == nullptr) {
69         appStateObserver_ = nullptr;
70         ACCOUNT_LOGE("failed to get ability manager service");
71         return;
72     }
73     iAppMgr_->RegisterApplicationStateObserver(appStateObserver_);
74 }
75 
UnregisterApplicationStateObserver()76 void AppAccountAuthenticatorSessionManager::UnregisterApplicationStateObserver()
77 {
78     if (iAppMgr_) {
79         iAppMgr_->UnregisterApplicationStateObserver(appStateObserver_);
80     }
81     iAppMgr_ = nullptr;
82     appStateObserver_ = nullptr;
83 }
84 
AddAccountImplicitly(const AuthenticatorSessionRequest & request)85 ErrCode AppAccountAuthenticatorSessionManager::AddAccountImplicitly(const AuthenticatorSessionRequest &request)
86 {
87     auto session = std::make_shared<AppAccountAuthenticatorSession>(ADD_ACCOUNT_IMPLICITLY, request);
88     return OpenSession(session);
89 }
90 
CreateAccountImplicitly(const AuthenticatorSessionRequest & request)91 ErrCode AppAccountAuthenticatorSessionManager::CreateAccountImplicitly(const AuthenticatorSessionRequest &request)
92 {
93     auto session = std::make_shared<AppAccountAuthenticatorSession>(CREATE_ACCOUNT_IMPLICITLY, request);
94     return OpenSession(session);
95 }
96 
Authenticate(const AuthenticatorSessionRequest & request)97 ErrCode AppAccountAuthenticatorSessionManager::Authenticate(const AuthenticatorSessionRequest &request)
98 {
99     auto session = std::make_shared<AppAccountAuthenticatorSession>(AUTHENTICATE, request);
100     return OpenSession(session);
101 }
102 
Auth(const AuthenticatorSessionRequest & request)103 ErrCode AppAccountAuthenticatorSessionManager::Auth(const AuthenticatorSessionRequest &request)
104 {
105     auto session = std::make_shared<AppAccountAuthenticatorSession>(AUTH, request);
106     return OpenSession(session);
107 }
108 
VerifyCredential(const AuthenticatorSessionRequest & request)109 ErrCode AppAccountAuthenticatorSessionManager::VerifyCredential(const AuthenticatorSessionRequest &request)
110 {
111     auto session = std::make_shared<AppAccountAuthenticatorSession>(VERIFY_CREDENTIAL, request);
112     return OpenSession(session);
113 }
114 
CheckAccountLabels(const AuthenticatorSessionRequest & request)115 ErrCode AppAccountAuthenticatorSessionManager::CheckAccountLabels(const AuthenticatorSessionRequest &request)
116 {
117     auto session = std::make_shared<AppAccountAuthenticatorSession>(CHECK_ACCOUNT_LABELS, request);
118     return OpenSession(session);
119 }
120 
IsAccountRemovable(const AuthenticatorSessionRequest & request)121 ErrCode AppAccountAuthenticatorSessionManager::IsAccountRemovable(const AuthenticatorSessionRequest &request)
122 {
123     auto session = std::make_shared<AppAccountAuthenticatorSession>(IS_ACCOUNT_REMOVABLE, request);
124     return OpenSession(session);
125 }
126 
SelectAccountsByOptions(const std::vector<AppAccountInfo> accounts,const AuthenticatorSessionRequest & request)127 ErrCode AppAccountAuthenticatorSessionManager::SelectAccountsByOptions(
128     const std::vector<AppAccountInfo> accounts, const AuthenticatorSessionRequest &request)
129 {
130     auto session = std::make_shared<AppAccountCheckLabelsSession>(accounts, request);
131     OpenSession(session);
132     return session->CheckLabels();
133 }
134 
SetAuthenticatorProperties(const AuthenticatorSessionRequest & request)135 ErrCode AppAccountAuthenticatorSessionManager::SetAuthenticatorProperties(const AuthenticatorSessionRequest &request)
136 {
137     auto session = std::make_shared<AppAccountAuthenticatorSession>(SET_AUTHENTICATOR_PROPERTIES, request);
138     return OpenSession(session);
139 }
140 
OpenSession(const std::shared_ptr<AppAccountAuthenticatorSession> & session)141 ErrCode AppAccountAuthenticatorSessionManager::OpenSession(
142     const std::shared_ptr<AppAccountAuthenticatorSession> &session)
143 {
144     if (session == nullptr) {
145         ACCOUNT_LOGE("failed to create AppAccountAuthenticatorSession");
146         return ERR_APPACCOUNT_SERVICE_OAUTH_SERVICE_EXCEPTION;
147     }
148     std::string sessionId = session->GetSessionId();
149     ErrCode result = ERR_OK;
150     {
151         std::lock_guard<std::mutex> lock(mutex_);
152         if (sessionMap_.size() == SESSION_MAX_NUM) {
153             ACCOUNT_LOGD("app account mgr service is busy");
154             return ERR_APPACCOUNT_SERVICE_OAUTH_BUSY;
155         }
156         result = session->Open();
157         if (result != ERR_OK) {
158             ACCOUNT_LOGE("failed to open session, result: %{public}d.", result);
159             return result;
160         }
161         if (sessionMap_.size() == 0) {
162             RegisterApplicationStateObserver();
163         }
164         sessionMap_.emplace(sessionId, session);
165         AuthenticatorSessionRequest request;
166         session->GetRequest(request);
167         std::string key = request.callerAbilityName + std::to_string(request.callerUid);
168         auto it = abilitySessions_.find(key);
169         if (it != abilitySessions_.end()) {
170             it->second.emplace(sessionId);
171         } else {
172             std::set<std::string> sessionSet;
173             sessionSet.emplace(sessionId);
174             abilitySessions_.emplace(key, sessionSet);
175         }
176     }
177     session->AddClientDeathRecipient();
178     return ERR_OK;
179 }
180 
GetSession(const std::string & sessionId)181 std::shared_ptr<AppAccountAuthenticatorSession> AppAccountAuthenticatorSessionManager::GetSession(
182     const std::string &sessionId)
183 {
184     std::lock_guard<std::mutex> lock(mutex_);
185     auto it = sessionMap_.find(sessionId);
186     if (it == sessionMap_.end()) {
187         return nullptr;
188     }
189     return it->second;
190 }
191 
GetAuthenticatorCallback(const AuthenticatorSessionRequest & request,sptr<IRemoteObject> & callback)192 ErrCode AppAccountAuthenticatorSessionManager::GetAuthenticatorCallback(
193     const AuthenticatorSessionRequest &request, sptr<IRemoteObject> &callback)
194 {
195     callback = nullptr;
196     std::lock_guard<std::mutex> lock(mutex_);
197     auto it = sessionMap_.find(request.sessionId);
198     if ((it == sessionMap_.end()) || (it->second == nullptr)) {
199         ACCOUNT_LOGE("failed to find a session by id=%{private}s.", request.sessionId.c_str());
200         return ERR_APPACCOUNT_SERVICE_OAUTH_SESSION_NOT_EXIST;
201     }
202     return it->second->GetAuthenticatorCallback(request, callback);
203 }
204 
OnAbilityStateChanged(const AppExecFwk::AbilityStateData & abilityStateData)205 void AppAccountAuthenticatorSessionManager::OnAbilityStateChanged(const AppExecFwk::AbilityStateData &abilityStateData)
206 {
207     if (abilityStateData.abilityState != static_cast<int32_t>(AppExecFwk::AbilityState::ABILITY_STATE_TERMINATED)) {
208         return;
209     }
210     std::string key = abilityStateData.abilityName + std::to_string(abilityStateData.uid);
211     std::lock_guard<std::mutex> lock(mutex_);
212     auto it = abilitySessions_.find(key);
213     if (it == abilitySessions_.end()) {
214         return;
215     }
216     for (auto sessionId : it->second) {
217         auto sessionIt = sessionMap_.find(sessionId);
218         if (sessionIt != sessionMap_.end()) {
219             ACCOUNT_LOGI("session{id=%{private}s} will be cleared", sessionId.c_str());
220             sessionMap_.erase(sessionIt);
221         }
222     }
223     abilitySessions_.erase(it);
224 }
225 
OnSessionServerDied(const std::string & sessionId)226 void AppAccountAuthenticatorSessionManager::OnSessionServerDied(const std::string &sessionId)
227 {
228     auto session = GetSession(sessionId);
229     if (session != nullptr) {
230         session->OnServerDied();
231     }
232 }
233 
OnSessionAbilityConnectDone(const std::string & sessionId,const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int32_t resultCode)234 void AppAccountAuthenticatorSessionManager::OnSessionAbilityConnectDone(const std::string &sessionId,
235     const AppExecFwk::ElementName &element, const sptr<IRemoteObject> &remoteObject, int32_t resultCode)
236 {
237     auto session = GetSession(sessionId);
238     if (session != nullptr) {
239         session->OnAbilityConnectDone(element, remoteObject, resultCode);
240     }
241 }
242 
OnSessionAbilityDisconnectDone(const std::string & sessionId,const AppExecFwk::ElementName & element,int resultCode)243 void AppAccountAuthenticatorSessionManager::OnSessionAbilityDisconnectDone(
244     const std::string &sessionId, const AppExecFwk::ElementName &element, int resultCode)
245 {
246     auto session = GetSession(sessionId);
247     if (session != nullptr) {
248         session->OnAbilityDisconnectDone(element, resultCode);
249     }
250 }
251 
OnSessionResult(const std::string & sessionId,int32_t resultCode,const AAFwk::Want & result)252 void AppAccountAuthenticatorSessionManager::OnSessionResult(
253     const std::string &sessionId, int32_t resultCode, const AAFwk::Want &result)
254 {
255     auto session = GetSession(sessionId);
256     if (session != nullptr) {
257         session->OnResult(resultCode, result);
258     }
259 }
260 
OnSessionRequestRedirected(const std::string & sessionId,AAFwk::Want & request)261 void AppAccountAuthenticatorSessionManager::OnSessionRequestRedirected(
262     const std::string &sessionId, AAFwk::Want &request)
263 {
264     auto session = GetSession(sessionId);
265     if (session != nullptr) {
266         session->OnRequestRedirected(request);
267     }
268 }
269 
OnSessionRequestContinued(const std::string & sessionId)270 void AppAccountAuthenticatorSessionManager::OnSessionRequestContinued(const std::string &sessionId)
271 {
272     auto session = GetSession(sessionId);
273     if (session != nullptr) {
274         session->OnRequestContinued();
275     }
276 }
277 
CloseSession(const std::string & sessionId)278 void AppAccountAuthenticatorSessionManager::CloseSession(const std::string &sessionId)
279 {
280     std::lock_guard<std::mutex> lock(mutex_);
281     auto it = sessionMap_.find(sessionId);
282     if (it == sessionMap_.end()) {
283         ACCOUNT_LOGI("session not exist, sessionId=%{private}s", sessionId.c_str());
284         return;
285     }
286     AuthenticatorSessionRequest request;
287     it->second->GetRequest(request);
288     std::string key = request.callerAbilityName + std::to_string(request.callerUid);
289     auto asIt = abilitySessions_.find(key);
290     if (asIt != abilitySessions_.end()) {
291         asIt->second.erase(sessionId);
292     }
293     sessionMap_.erase(it);
294     if (sessionMap_.size() == 0) {
295         iAppMgr_->UnregisterApplicationStateObserver(appStateObserver_);
296     }
297 }
298 }  // namespace AccountSA
299 }  // namespace OHOS
300