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