| // Copyright 2024 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef ASH_AUTH_ACTIVE_SESSION_AUTH_CONTROLLER_IMPL_H_ |
| #define ASH_AUTH_ACTIVE_SESSION_AUTH_CONTROLLER_IMPL_H_ |
| |
| #include <memory> |
| #include <string> |
| #include <string_view> |
| |
| #include "ash/ash_export.h" |
| #include "ash/auth/active_session_auth_metrics_recorder.h" |
| #include "ash/auth/views/active_session_auth_view.h" |
| #include "ash/auth/views/auth_common.h" |
| #include "ash/public/cpp/auth/active_session_auth_controller.h" |
| #include "ash/public/cpp/auth/active_session_fingerprint_client.h" |
| #include "ash/public/cpp/in_session_auth_token_provider.h" |
| #include "ash/public/cpp/session/session_observer.h" |
| #include "base/memory/raw_ptr.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/scoped_observation.h" |
| #include "chromeos/ash/components/cryptohome/auth_factor.h" |
| #include "chromeos/ash/components/dbus/userdataauth/userdataauth_client.h" |
| #include "chromeos/ash/components/login/auth/auth_factor_editor.h" |
| #include "chromeos/ash/components/login/auth/auth_performer.h" |
| #include "chromeos/ash/components/osauth/public/common_types.h" |
| #include "chromeos/ash/components/osauth/public/request/auth_request.h" |
| #include "components/account_id/account_id.h" |
| #include "ui/aura/window.h" |
| #include "ui/views/view_observer.h" |
| #include "ui/views/widget/widget.h" |
| |
| namespace ash { |
| |
| // ActiveSessionAuthControllerImpl is responsible for : |
| // - Initialize the ActiveSessionAuthView and control this view. |
| // - Create and manage a widget to show the ActiveSessionAuthView. |
| // - Listening to the ActiveSessionAuthView observers and call auth performer if |
| // authentication is requested on the UI. |
| // - Call the callback with the authentication result. |
| class ASH_EXPORT ActiveSessionAuthControllerImpl |
| : public ActiveSessionAuthController, |
| public ActiveSessionAuthView::Observer, |
| public UserDataAuthClient::AuthFactorStatusUpdateObserver, |
| public SessionObserver, |
| public views::ViewObserver { |
| public: |
| class TestApi { |
| public: |
| explicit TestApi(ActiveSessionAuthControllerImpl* controller); |
| ~TestApi(); |
| TestApi(const TestApi&) = delete; |
| TestApi& operator=(const TestApi&) = delete; |
| |
| // Returns the known-to-be-available factors that `ActiveSessionAuthView` |
| // was rendered with. |
| AuthFactorSet GetAvailableFactors() const; |
| |
| // Simulates submitting the `password` to cryptohome as if the user |
| // manually entered it. |
| void SubmitPassword(const std::string& password); |
| |
| // Simulates submitting the `pin` to cryptohome as if the user |
| // manually entered it. |
| void SubmitPin(const std::string& pin); |
| |
| void SetPinStatus(std::unique_ptr<cryptohome::PinStatus> pin_status); |
| |
| std::u16string_view GetPinStatusMessage() const; |
| |
| void Close(); |
| |
| private: |
| const raw_ptr<ActiveSessionAuthControllerImpl> controller_; |
| }; |
| |
| ActiveSessionAuthControllerImpl(); |
| ActiveSessionAuthControllerImpl(const ActiveSessionAuthControllerImpl&) = |
| delete; |
| ActiveSessionAuthControllerImpl& operator=( |
| const ActiveSessionAuthControllerImpl&) = delete; |
| |
| ~ActiveSessionAuthControllerImpl() override; |
| |
| // ActiveSessionAuthController: |
| bool ShowAuthDialog(std::unique_ptr<AuthRequest> auth_request) override; |
| bool IsShown() const override; |
| void SetFingerprintClient(ActiveSessionFingerprintClient* fp_client) override; |
| |
| // SessionObserver: |
| void OnSessionStateChanged(session_manager::SessionState state) override; |
| |
| // views::ViewObserver: |
| void OnViewPreferredSizeChanged(views::View* observed_view) override; |
| |
| // ActiveSessionAuthView::Observer: |
| void OnPasswordSubmit(std::u16string_view password) override; |
| void OnPinSubmit(std::u16string_view pin) override; |
| void OnClose() override; |
| |
| // UserDataAuthClient::AuthFactorStatusUpdateObserver: |
| void OnAuthFactorStatusUpdate( |
| const user_data_auth::AuthFactorStatusUpdate& update) override; |
| |
| // Actions: |
| void MoveToTheCenter(); |
| |
| // The closing process is divided into two functions to accommodate |
| // fingerprint authentication. If fingerprint authentication is active, |
| // we must terminate it asynchronously. This requires a second function |
| // (callback/ CompleteClose) to complete the closing procedure. |
| void StartClose(); |
| void CompleteClose(std::unique_ptr<UserContext> user_context, |
| std::optional<AuthenticationError> authentication_error); |
| |
| // Fingerprint actions: |
| void OnFingerprintScan(const FingerprintAuthScanResult scan_result); |
| void OnFingerprintSuccess( |
| std::unique_ptr<UserContext> user_context, |
| std::optional<AuthenticationError> authentication_error); |
| void OnFingerprintTerminated( |
| std::unique_ptr<UserContext> user_context, |
| std::optional<AuthenticationError> authentication_error); |
| void OnFingerprintAnimationFinished(); |
| |
| // Tracks the authentication flow for the active session. |
| enum class ActiveSessionAuthState { |
| kOnIdle, // Initial state, waiting for request. |
| kWaitForInit, // Waiting session start. |
| kInitialized, // Session started, ready for user input. |
| kPasswordAuthStarted, // User submitted password, awaiting verification. |
| kPasswordAuthSucceeded, // Successful password authentication. |
| kPinAuthStarted, // User submitted PIN, awaiting verification. |
| kPinAuthSucceeded, // Successful PIN authentication. |
| kFingerprintAuthSucceeded, // Successful fingerprint authentication. |
| kFingerprintAuthSucceededWaiting, // Successful fingerprint scan but |
| // password/PIN auth is already in |
| // progress, awaiting callback to get |
| // back user_context to start the |
| // authentication. |
| kCloseRequested, // Close requested while we are waiting password/PIN |
| // authentication callback. |
| kAuthNotAvailable, // No authentication factors are available. |
| // Note: On authentication failure, the state reverts to kInitialized. |
| }; |
| |
| private: |
| class FingerprintAuthTracker; |
| friend class FingerprintAuthTracker; |
| |
| using AuthFactorsReadyCallback = |
| base::OnceCallback<void(std::unique_ptr<UserContext>)>; |
| |
| // Helper functions for handling the readiness of authentication factors, |
| // particularly focusing on fingerprint authentication setup and its |
| // integration into the overall authentication flow. |
| void MaybePrepareFingerprint(AuthFactorsReadyCallback on_auth_factors_ready); |
| void OnFingerprintReady( |
| AuthFactorsReadyCallback on_auth_factors_ready, |
| std::unique_ptr<UserContext> user_context, |
| std::optional<AuthenticationError> authentication_error); |
| void AuthFactorsAreReady(std::unique_ptr<UserContext> user_context); |
| |
| // Set the state of the class, if it necessary disable/enable the input area |
| // of the UI. Validates the transitions. |
| void SetState(ActiveSessionAuthState state); |
| |
| bool IsPreInitializedState() const; |
| bool IsSucceedState() const; |
| |
| // Internal methods for authentication. |
| void OnAuthSessionStarted( |
| bool user_exists, |
| std::unique_ptr<UserContext> user_context, |
| std::optional<AuthenticationError> authentication_error); |
| void OnAuthComplete(AuthInputType input_type, |
| std::unique_ptr<UserContext> user_context, |
| std::optional<AuthenticationError> authentication_error); |
| |
| void HandleFingerprintAuthSuccess(); |
| void NotifySuccess(const AuthProofToken& token, base::TimeDelta timeout); |
| void ProcessAuthFactorStatusUpdate( |
| const user_data_auth::AuthFactorStatusUpdate& update); |
| |
| // Initialize the UI after we retrieve the available auth factors from |
| // cryptohome. |
| void InitUi(); |
| |
| std::unique_ptr<views::Widget> widget_; |
| |
| base::ScopedObservation<views::View, ViewObserver> contents_view_observer_{ |
| this}; |
| base::ScopedObservation<SessionControllerImpl, SessionObserver> |
| session_controller_observation_{this}; |
| |
| raw_ptr<ActiveSessionAuthView> contents_view_ = nullptr; |
| |
| AccountId account_id_; |
| std::u16string title_; |
| std::u16string description_; |
| |
| std::string auth_session_broadcast_id_; |
| std::u16string pin_status_message_; |
| |
| std::unique_ptr<AuthFactorEditor> auth_factor_editor_; |
| std::unique_ptr<AuthPerformer> auth_performer_; |
| |
| std::unique_ptr<UserContext> user_context_; |
| |
| AuthFactorSet available_factors_; |
| ActiveSessionAuthState state_ = ActiveSessionAuthState::kOnIdle; |
| |
| std::unique_ptr<AuthRequest> auth_request_; |
| |
| bool fingerprint_animation_finished_ = false; |
| bool fingerprint_authentication_finished_ = false; |
| |
| raw_ptr<ActiveSessionFingerprintClient> fp_client_; |
| std::unique_ptr<FingerprintAuthTracker> fp_auth_tracker_; |
| |
| ActiveSessionAuthMetricsRecorder uma_recorder_; |
| |
| base::WeakPtrFactory<ActiveSessionAuthControllerImpl> weak_ptr_factory_{this}; |
| }; |
| |
| } // namespace ash |
| |
| #endif // ASH_AUTH_ACTIVE_SESSION_AUTH_CONTROLLER_IMPL_H_ |