• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "app_account_authenticator_session.h"
17 
18 #include "ability_manager_adapter.h"
19 #include "account_info.h"
20 #include "account_log_wrapper.h"
21 #include "app_account_authenticator_callback.h"
22 #include "app_account_authenticator_manager.h"
23 #include "app_account_common.h"
24 #include "bundle_manager_adapter.h"
25 #include "iservice_registry.h"
26 
27 namespace OHOS {
28 namespace AccountSA {
SessionClientDeathRecipient(const std::string & sessionId)29 SessionClientDeathRecipient::SessionClientDeathRecipient(const std::string &sessionId) : sessionId_(sessionId)
30 {}
31 
OnRemoteDied(const wptr<IRemoteObject> & remote)32 void SessionClientDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
33 {
34     (void)remote;
35     auto sessionMgr = AppAccountAuthenticatorSessionManager::GetInstance();
36     if (sessionMgr != nullptr) {
37         sessionMgr->CloseSession(sessionId_);
38     }
39 }
40 
SessionServerDeathRecipient(const std::string & sessionId)41 SessionServerDeathRecipient::SessionServerDeathRecipient(const std::string &sessionId) : sessionId_(sessionId)
42 {}
43 
OnRemoteDied(const wptr<IRemoteObject> & remote)44 void SessionServerDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
45 {
46     (void)remote;
47     auto sessionMgr = AppAccountAuthenticatorSessionManager::GetInstance();
48     if (sessionMgr != nullptr) {
49         sessionMgr->OnSessionServerDied(sessionId_);
50     }
51 }
52 
SessionConnection(const std::string & sessionId)53 SessionConnection::SessionConnection(const std::string &sessionId) : sessionId_(sessionId)
54 {}
55 
~SessionConnection()56 SessionConnection::~SessionConnection()
57 {}
58 
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)59 void SessionConnection::OnAbilityConnectDone(
60     const AppExecFwk::ElementName &element, const sptr<IRemoteObject> &remoteObject, int resultCode)
61 {
62     auto sessionMgr = AppAccountAuthenticatorSessionManager::GetInstance();
63     if (sessionMgr != nullptr) {
64         sessionMgr->OnSessionAbilityConnectDone(sessionId_, element, remoteObject, resultCode);
65     }
66 }
67 
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)68 void SessionConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode)
69 {
70     auto sessionMgr = AppAccountAuthenticatorSessionManager::GetInstance();
71     if (sessionMgr != nullptr) {
72         sessionMgr->OnSessionAbilityDisconnectDone(sessionId_, element, resultCode);
73     }
74 }
75 
AppAccountAuthenticatorSession(AuthenticatorAction action,const AuthenticatorSessionRequest & request)76 AppAccountAuthenticatorSession::AppAccountAuthenticatorSession(
77     AuthenticatorAction action, const AuthenticatorSessionRequest &request)
78     : action_(action), request_(request)
79 {
80     Init();
81 }
82 
~AppAccountAuthenticatorSession()83 AppAccountAuthenticatorSession::~AppAccountAuthenticatorSession()
84 {
85     if (isOpened_) {
86         Close();
87     }
88 }
89 
Init()90 void AppAccountAuthenticatorSession::Init()
91 {
92     if (isInitialized_) {
93         ACCOUNT_LOGE("session has been initialized");
94         return;
95     }
96 
97     sessionId_ = std::to_string(reinterpret_cast<int64_t>(this));
98     conn_ = new (std::nothrow) SessionConnection(sessionId_);
99     clientDeathRecipient_ = new (std::nothrow) SessionClientDeathRecipient(sessionId_);
100     serverDeathRecipient_ = new (std::nothrow) SessionServerDeathRecipient(sessionId_);
101     authenticatorCb_ = new (std::nothrow) AppAccountAuthenticatorCallback(sessionId_);
102     controlManager_ = AppAccountControlManager::GetInstance();
103     authenticatorMgr_ = AppAccountAuthenticatorManager::GetInstance();
104     if ((conn_ == nullptr) || (clientDeathRecipient_ == nullptr)
105         || (serverDeathRecipient_ == nullptr) || (authenticatorCb_ == nullptr)
106         || (controlManager_ == nullptr) || (authenticatorMgr_ == nullptr)) {
107         conn_ = nullptr;
108         clientDeathRecipient_ = nullptr;
109         serverDeathRecipient_ = nullptr;
110         authenticatorCb_ = nullptr;
111         return;
112     }
113     userId_ = request_.callerUid / UID_TRANSFORM_DIVISOR;
114     ownerUid_ = BundleManagerAdapter::GetInstance()->GetUidByBundleName(request_.owner, userId_);
115     isInitialized_ = true;
116 }
117 
Open()118 ErrCode AppAccountAuthenticatorSession::Open()
119 {
120     if (isOpened_) {
121         ACCOUNT_LOGD("session has been opened");
122         return ERR_APPACCOUNT_SERVICE_OAUTH_SERVICE_EXCEPTION;
123     }
124     if (!isInitialized_) {
125         ACCOUNT_LOGD("session has not been initialized");
126         return ERR_APPACCOUNT_SERVICE_OAUTH_SERVICE_EXCEPTION;
127     }
128     AuthenticatorInfo info;
129     ErrCode errCode = authenticatorMgr_->GetAuthenticatorInfo(request_.owner, userId_, info);
130     if (errCode != ERR_OK) {
131         ACCOUNT_LOGE("authenticator not exist, owner: %{public}s, errCode: %{public}d.",
132             request_.owner.c_str(), errCode);
133         return errCode;
134     }
135     AAFwk::Want want;
136     want.SetElementName(request_.owner, info.abilityName);
137     errCode = AbilityManagerAdapter::GetInstance()->ConnectAbility(want, conn_, nullptr, userId_);
138     if (errCode == ERR_OK) {
139         isOpened_ = true;
140     }
141     return errCode;
142 }
143 
Close()144 void AppAccountAuthenticatorSession::Close()
145 {
146     if ((authenticatorProxy_ != nullptr) && (authenticatorProxy_->AsObject() != nullptr)) {
147         authenticatorProxy_->AsObject()->RemoveDeathRecipient(serverDeathRecipient_);
148     }
149     if ((request_.callback != nullptr) && (request_.callback->AsObject() != nullptr)) {
150         request_.callback->AsObject()->RemoveDeathRecipient(clientDeathRecipient_);
151     }
152     if (isConnected_) {
153         AbilityManagerAdapter::GetInstance()->DisconnectAbility(conn_);
154     }
155     isOpened_ = false;
156 }
157 
CloseSelf() const158 void AppAccountAuthenticatorSession::CloseSelf() const
159 {
160     auto sessionManager = AppAccountAuthenticatorSessionManager::GetInstance();
161     if (sessionManager != nullptr) {
162         sessionManager->CloseSession(sessionId_);
163     }
164 }
165 
AddClientDeathRecipient()166 ErrCode AppAccountAuthenticatorSession::AddClientDeathRecipient()
167 {
168     if (!isOpened_) {
169         return ERR_APPACCOUNT_SERVICE_OAUTH_SERVICE_EXCEPTION;
170     }
171     if ((request_.callback == nullptr) || (request_.callback->AsObject() == nullptr)) {
172         return ERR_OK;
173     }
174     bool result = request_.callback->AsObject()->AddDeathRecipient(clientDeathRecipient_);
175     if (!result) {
176         return ERR_APPACCOUNT_SERVICE_OAUTH_SERVICE_EXCEPTION;
177     }
178     return ERR_OK;
179 }
180 
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)181 void AppAccountAuthenticatorSession::OnAbilityConnectDone(
182     const AppExecFwk::ElementName &element, const sptr<IRemoteObject> &remoteObject, int resultCode)
183 {
184     isConnected_ = true;
185     AAFwk::Want errResult_;
186     authenticatorProxy_ = iface_cast<IAppAccountAuthenticator>(remoteObject);
187     if ((!authenticatorProxy_) || (!authenticatorProxy_->AsObject())) {
188         ACCOUNT_LOGE("failed to cast app account authenticator proxy");
189         OnResult(ERR_JS_ACCOUNT_AUTHENTICATOR_SERVICE_EXCEPTION, errResult_);
190         return;
191     }
192     authenticatorProxy_->AsObject()->AddDeathRecipient(serverDeathRecipient_);
193     switch (action_) {
194         case ADD_ACCOUNT_IMPLICITLY:
195             resultCode = authenticatorProxy_->AddAccountImplicitly(request_.authType, request_.callerBundleName,
196                 request_.options.GetParams(), authenticatorCb_->AsObject());
197             break;
198         case AUTHENTICATE:
199             resultCode = authenticatorProxy_->Authenticate(request_.name, request_.authType, request_.callerBundleName,
200                 request_.options.GetParams(), authenticatorCb_->AsObject());
201             break;
202         case CREATE_ACCOUNT_IMPLICITLY:
203             resultCode = authenticatorProxy_->CreateAccountImplicitly(request_.createOptions,
204                 authenticatorCb_->AsObject());
205             break;
206         case AUTH:
207             resultCode = authenticatorProxy_->Auth(
208                 request_.name, request_.authType, request_.options.GetParams(), authenticatorCb_->AsObject());
209             break;
210         case VERIFY_CREDENTIAL:
211             resultCode = authenticatorProxy_->VerifyCredential(
212                 request_.name, request_.verifyCredOptions, authenticatorCb_->AsObject());
213             break;
214         case CHECK_ACCOUNT_LABELS:
215             resultCode = authenticatorProxy_->CheckAccountLabels(
216                 request_.name, request_.labels, authenticatorCb_->AsObject());
217             break;
218         case SET_AUTHENTICATOR_PROPERTIES:
219             resultCode = authenticatorProxy_->SetProperties(request_.setPropOptions, authenticatorCb_->AsObject());
220             break;
221         case IS_ACCOUNT_REMOVABLE:
222             resultCode = authenticatorProxy_->IsAccountRemovable(request_.name, authenticatorCb_->AsObject());
223             break;
224         default:
225             ACCOUNT_LOGE("unsupported action: %{public}d", action_);
226             OnResult(ERR_JS_ACCOUNT_AUTHENTICATOR_SERVICE_EXCEPTION, errResult_);
227             return;
228     }
229     if (resultCode != ERR_OK) {
230         OnResult(ERR_JS_ACCOUNT_AUTHENTICATOR_SERVICE_EXCEPTION, errResult_);
231     }
232 }
233 
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)234 void AppAccountAuthenticatorSession::OnAbilityDisconnectDone(const AppExecFwk::ElementName &element, int resultCode)
235 {
236     isConnected_ = false;
237 }
238 
OnServerDied()239 void AppAccountAuthenticatorSession::OnServerDied()
240 {
241     AAFwk::Want result;
242     OnResult(ERR_JS_ACCOUNT_AUTHENTICATOR_SERVICE_EXCEPTION, result);
243 }
244 
OnResult(int32_t resultCode,const AAFwk::Want & result) const245 int32_t AppAccountAuthenticatorSession::OnResult(int32_t resultCode, const AAFwk::Want &result) const
246 {
247     if (resultCode == ERR_JS_SUCCESS) {
248         switch (action_) {
249             case ADD_ACCOUNT_IMPLICITLY:
250                 resultCode = OnAddAccountImplicitlyDone(result);
251                 break;
252             case AUTHENTICATE:
253                 resultCode = OnAuthenticateDone(result);
254                 break;
255             default:
256                 break;
257         }
258     }
259     if ((request_.callback != nullptr) && (request_.callback->AsObject() != nullptr)) {
260         request_.callback->OnResult(resultCode, result);
261     }
262     if (isConnected_) {
263         AbilityManagerAdapter::GetInstance()->DisconnectAbility(conn_);
264     }
265     CloseSelf();
266     return resultCode;
267 }
268 
OnRequestRedirected(AAFwk::Want & newRequest) const269 int32_t AppAccountAuthenticatorSession::OnRequestRedirected(AAFwk::Want &newRequest) const
270 {
271     AAFwk::Want errResult_;
272     AppExecFwk::ElementName element = newRequest.GetElement();
273     if (element.GetBundleName() != request_.owner) {
274         ACCOUNT_LOGD("invalid response");
275         OnResult(ERR_JS_ACCOUNT_AUTHENTICATOR_SERVICE_EXCEPTION, errResult_);
276         return ERR_JS_SUCCESS;
277     }
278     if ((!request_.callback) || (!request_.callback->AsObject())) {
279         ACCOUNT_LOGD("app account callback is nullptr");
280         if (isConnected_) {
281             AbilityManagerAdapter::GetInstance()->DisconnectAbility(conn_);
282         }
283         CloseSelf();
284         return ERR_JS_SUCCESS;
285     }
286     newRequest.SetParam(Constants::KEY_ACTION, action_);
287     newRequest.SetParam(Constants::KEY_NAME, request_.name);
288     newRequest.SetParam(Constants::KEY_SESSION_ID, sessionId_);
289     newRequest.SetParam(Constants::KEY_CALLER_BUNDLE_NAME, request_.callerBundleName);
290     newRequest.SetParam(Constants::KEY_CALLER_PID, request_.callerPid);
291     newRequest.SetParam(Constants::KEY_CALLER_UID, request_.callerUid);
292     if (action_ == AUTHENTICATE || action_ == ADD_ACCOUNT_IMPLICITLY) {
293         newRequest.SetParam(Constants::KEY_AUTH_TYPE, request_.authType);
294     }
295     request_.callback->OnRequestRedirected(newRequest);
296     return ERR_JS_SUCCESS;
297 }
298 
OnRequestContinued() const299 int32_t AppAccountAuthenticatorSession::OnRequestContinued() const
300 {
301     if ((!request_.callback) || (!request_.callback->AsObject())) {
302         ACCOUNT_LOGD("app account callback is nullptr");
303         if (isConnected_) {
304             AbilityManagerAdapter::GetInstance()->DisconnectAbility(conn_);
305         }
306         CloseSelf();
307         return ERR_JS_SUCCESS;
308     }
309     request_.callback->OnRequestContinued();
310     return ERR_JS_SUCCESS;
311 }
312 
OnAuthenticateDone(const AAFwk::Want & result) const313 int32_t AppAccountAuthenticatorSession::OnAuthenticateDone(const AAFwk::Want &result) const
314 {
315     std::string name = result.GetStringParam(Constants::KEY_NAME);
316     if (name != request_.name) {
317         return ERR_JS_ACCOUNT_AUTHENTICATOR_SERVICE_EXCEPTION;
318     }
319     return ERR_OK;
320 }
321 
OnAddAccountImplicitlyDone(const AAFwk::Want & result) const322 int32_t AppAccountAuthenticatorSession::OnAddAccountImplicitlyDone(const AAFwk::Want &result) const
323 {
324     std::string name = result.GetStringParam(Constants::KEY_NAME);
325     if (name.empty()) {
326         return ERR_JS_ACCOUNT_AUTHENTICATOR_SERVICE_EXCEPTION;
327     }
328     AppAccountInfo info(name, request_.owner);
329     info.SetAppIndex(request_.appIndex);
330     AppAccountControlManager::GetInstance()->AddAccount(name, "", ownerUid_, request_.owner, info);
331     return ERR_OK;
332 }
333 
GetRequest(AuthenticatorSessionRequest & request) const334 void AppAccountAuthenticatorSession::GetRequest(AuthenticatorSessionRequest &request) const
335 {
336     request = request_;
337 }
338 
GetAuthenticatorCallback(const AuthenticatorSessionRequest & request,sptr<IRemoteObject> & callback) const339 ErrCode AppAccountAuthenticatorSession::GetAuthenticatorCallback(
340     const AuthenticatorSessionRequest &request, sptr<IRemoteObject> &callback) const
341 {
342     callback = nullptr;
343     if ((request.callerUid != ownerUid_) || (request.callerBundleName != request_.owner)) {
344         ACCOUNT_LOGE("fail to get authenticator callback for permission denied");
345         return ERR_APPACCOUNT_SERVICE_PERMISSION_DENIED;
346     }
347     if (!authenticatorCb_) {
348         ACCOUNT_LOGE("session has not been initialized");
349         return ERR_APPACCOUNT_SERVICE_OAUTH_AUTHENTICATOR_CALLBACK_NOT_EXIST;
350     }
351     callback = authenticatorCb_->AsObject();
352     return ERR_OK;
353 }
354 
GetSessionId() const355 std::string AppAccountAuthenticatorSession::GetSessionId() const
356 {
357     return sessionId_;
358 }
359 }  // namespace AccountSA
360 }  // namespace OHOS