1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
|
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMEOS_ASH_COMPONENTS_OSAUTH_IMPL_AUTH_HUB_ATTEMPT_HANDLER_H_
#define CHROMEOS_ASH_COMPONENTS_OSAUTH_IMPL_AUTH_HUB_ATTEMPT_HANDLER_H_
#include <optional>
#include "base/callback_list.h"
#include "base/component_export.h"
#include "base/containers/flat_map.h"
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "chromeos/ash/components/osauth/impl/auth_hub_common.h"
#include "chromeos/ash/components/osauth/public/auth_factor_engine.h"
#include "chromeos/ash/components/osauth/public/auth_factor_status_consumer.h"
#include "chromeos/ash/components/osauth/public/common_types.h"
namespace ash {
// This class handles all post-initialization interaction with
// `AuthFactorEngine`s during single authentication flow (specified by
// AuthAttemptVector).
// It combines events from individual `AuthFactorEngine`s, calculates
// resulting factor's status, and notifies `AuthFactorStatusConsumer`
// upon all changes.
// This class also enables/disables `AuthFactorEngine`s according to
// their status/parallel authentication attempts; it also tracks
// overall authentication success.
//
// This class is re-created every time owning `AuthHub` starts new,
// user authentication attempt.
class COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_OSAUTH) AuthHubAttemptHandler
: public AuthFactorEngine::FactorEngineObserver,
public AuthHubConnector {
public:
// Interface to interact with owning AuthHub:
class COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_OSAUTH) Owner {
public:
virtual ~Owner();
virtual void UpdateFactorUiCache(const AuthAttemptVector& attempt,
AuthFactorsSet configured_factors) = 0;
virtual void OnAuthenticationSuccess(const AuthAttemptVector& attempt,
AshAuthFactor factor) = 0;
virtual void OnFactorAttemptFailed(const AuthAttemptVector& attempt,
AshAuthFactor factor) = 0;
};
AuthHubAttemptHandler(Owner* owner,
const AuthAttemptVector& attempt,
const AuthEnginesMap& engines,
AuthFactorsSet expected_factors);
~AuthHubAttemptHandler() override;
AuthHubConnector* GetConnector();
void SetConsumer(raw_ptr<AuthFactorStatusConsumer> consumer);
// Returns true if there is an ongoing factor attempt.
bool HasOngoingAttempt() const;
// Waits for the result of ongoing factor attempt, and calls
// `callback`, without re-enabling engines.
void PrepareForShutdown(base::OnceClosure callback);
// This method is called by owning AuthHub once VectorLifecycle
// starts all auth engines.
// This method notifies StatusConsumer about finalized factors list,
// notifies Owner if cache needs to be updated,
// and enables all applicable factors to handle authentication attempts.
void OnFactorsChecked(AuthFactorsSet available_factors,
AuthFactorsSet failed_factors);
// AuthFactorEngine::FactorEngineObserver:
void OnFactorPresenceChecked(AshAuthFactor factor,
bool factor_present) override;
void OnFactorAttempt(AshAuthFactor factor) override;
void OnFactorAttemptResult(AshAuthFactor factor, bool success) override;
void OnPolicyChanged(AshAuthFactor factor) override;
void OnLockoutChanged(AshAuthFactor factor) override;
void OnFactorSpecificRestrictionsChanged(AshAuthFactor factor) override;
void OnCriticalError(AshAuthFactor factor) override;
void OnFactorCustomSignal(AshAuthFactor factor) override;
// AuthHubConnector:
AuthFactorEngine* GetEngine(AshAuthFactor factor) override;
private:
// See also a comment for `AuthFactorState`.
struct FactorAttemptState {
// Factor is considered failed, no updates / auth attempts
// should happen for the factor.
bool engine_failed = false;
// Reasons for disabling factor:
bool disabled_by_policy = false;
bool locked_out = false;
bool factor_specific_restricted = false;
// Up-to date usage value for the engine, might not be propagated to
// engine yet.
AuthFactorEngine::UsageAllowed intended_usage =
AuthFactorEngine::UsageAllowed::kDisabled;
// Latest value propagated to the engine.
AuthFactorEngine::UsageAllowed engine_usage =
AuthFactorEngine::UsageAllowed::kDisabled;
// Up-to date state of the factor, might be not reported to
// `AuthFactorStatusConsumer` yet.
AuthFactorState internal_state = AuthFactorState::kCheckingForPresence;
// Latest value reported to 'AuthFactorStatusConsumer'.
AuthFactorState reported_state = AuthFactorState::kCheckingForPresence;
};
void FillAllStatusValues(AshAuthFactor factor, FactorAttemptState& state);
void CalculateFactorState(AshAuthFactor factor, FactorAttemptState& state);
void PropagateEnginesEnabledStatus();
void PropagateStatusUpdates();
void UpdateAllFactorStates();
// TODO(b/271248452): Those `raw_ptr`s are currently dangling due to a problem
// with the destruction order. Something causes those ptrs to be freed before
// the execution reaches the destruction of this class. Likely a higher level
// component in the ownership graph has the objects pointed to below and the
// current class as downstream dependencies.
raw_ptr<Owner, DanglingUntriaged> owner_;
raw_ptr<AuthFactorStatusConsumer, DanglingUntriaged> status_consumer_;
AuthAttemptVector attempt_;
AuthEnginesMap engines_;
AuthFactorsSet initial_factors_;
AuthFactorsSet available_factors_;
base::flat_map<AshAuthFactor, FactorAttemptState> factor_state_;
std::optional<AshAuthFactor> ongoing_attempt_factor_;
bool authenticated_ = false;
bool shutting_down_ = false;
base::OnceCallbackList<void(void)> shutdown_callbacks_;
base::WeakPtrFactory<AuthHubAttemptHandler> weak_factory_{this};
};
} // namespace ash
#endif // CHROMEOS_ASH_COMPONENTS_OSAUTH_IMPL_AUTH_HUB_ATTEMPT_HANDLER_H_
|