blob: d2c0c226a41209bfe756a76e2bc29957dcc3d3f0 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROMEOS_LOGIN_AUTH_LOGIN_PERFORMER_H_
#define CHROMEOS_LOGIN_AUTH_LOGIN_PERFORMER_H_
#include <memory>
#include <string>
#include "base/callback.h"
#include "base/component_export.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "chromeos/login/auth/auth_status_consumer.h"
#include "chromeos/login/auth/authenticator.h"
#include "chromeos/login/auth/extended_authenticator.h"
#include "chromeos/login/auth/user_context.h"
#include "components/user_manager/user_type.h"
#include "google_apis/gaia/google_service_auth_error.h"
class AccountId;
namespace base {
class SequencedTaskRunner;
}
namespace network {
class SharedURLLoaderFactory;
}
namespace chromeos {
// This class encapsulates sign in operations.
// Sign in is performed in a way that offline auth is executed first.
// Once offline auth is OK - user homedir is mounted, UI is launched.
// At this point LoginPerformer |delegate_| is destroyed and it releases
// LP instance ownership. LP waits for online login result.
// If auth is succeeded, cookie fetcher is executed, LP instance deletes itself.
//
// If |delegate_| is not NULL it will handle error messages, password input.
class COMPONENT_EXPORT(CHROMEOS_LOGIN_AUTH) LoginPerformer
: public AuthStatusConsumer {
public:
enum class AuthorizationMode {
// Authorization performed internally by Chrome.
kInternal,
// Authorization performed by an external service (e.g., Gaia, or Active
// Directory).
kExternal
};
// Delegate class to get notifications from the LoginPerformer.
class Delegate : public AuthStatusConsumer {
public:
~Delegate() override {}
virtual void AllowlistCheckFailed(const std::string& email) = 0;
virtual void PolicyLoadFailed() = 0;
};
LoginPerformer(scoped_refptr<base::SequencedTaskRunner> task_runner,
Delegate* delegate);
~LoginPerformer() override;
// Performs a login for |user_context|.
// If auth_mode is |kExternal|, there are no further auth checks, |kInternal|
// will perform auth checks.
void PerformLogin(const UserContext& user_context,
AuthorizationMode auth_mode);
// Performs actions to prepare guest mode login.
void LoginOffTheRecord();
// Performs public session login with a given |user_context|.
void LoginAsPublicSession(const UserContext& user_context);
// Performs a login into the kiosk mode account with |app_account_id|.
void LoginAsKioskAccount(const AccountId& app_account_id,
bool use_guest_mount);
// Performs a login into the ARC kiosk mode account with |arc_app_account_id|.
void LoginAsArcKioskAccount(const AccountId& arc_app_account_id);
// Performs a login into the Web kiosk mode account with |web_app_account_id|.
void LoginAsWebKioskAccount(const AccountId& web_app_account_id);
// AuthStatusConsumer implementation:
void OnAuthFailure(const AuthFailure& error) override;
void OnAuthSuccess(const UserContext& user_context) override;
void OnOffTheRecordAuthSuccess() override;
void OnPasswordChangeDetected(const UserContext& user_context) override;
void OnOldEncryptionDetected(const UserContext& user_context,
bool has_incomplete_migration) override;
// Migrates cryptohome using |old_password| specified.
void RecoverEncryptedData(const std::string& old_password);
// Reinitializes cryptohome with the new password.
void ResyncEncryptedData();
// Returns latest auth error.
const GoogleServiceAuthError& error() const {
return last_login_failure_.error();
}
// True if password change has been detected.
bool password_changed() { return password_changed_; }
// Number of times we've been called with OnPasswordChangeDetected().
// If user enters incorrect old password, same LoginPerformer instance will
// be called so callback count makes it possible to distinguish initial
// "password changed detected" event from further attempts to enter old
// password for cryptohome migration (when > 1).
int password_changed_callback_count() {
return password_changed_callback_count_;
}
void set_delegate(Delegate* delegate) { delegate_ = delegate; }
AuthorizationMode auth_mode() const { return auth_mode_; }
// Check if user is allowed to sign in on device. |wildcard_match| will
// contain additional information whether this user is explicitly listed or
// not (may be relevant for external-based sign-in). |user_type| will be used
// to check if the user is allowed because of the user type, pass
// base::nullopt if user type is not known.
virtual bool IsUserAllowlisted(
const AccountId& account_id,
bool* wildcard_match,
const base::Optional<user_manager::UserType>& user_type) = 0;
protected:
// Platform-dependant methods to be implemented by concrete class.
// Run trusted check for a platform. If trusted check have to be performed
// asynchronously, |false| will be returned, and either delegate's
// PolicyLoadFailed() or |callback| will be called upon actual check.
virtual bool RunTrustedCheck(base::OnceClosure callback) = 0;
// This method should run addional online check if user can sign in on device.
// Either |success_callback| or |failure_callback| should be called upon this
// check.
virtual void RunOnlineAllowlistCheck(const AccountId& account_id,
bool wildcard_match,
const std::string& refresh_token,
base::OnceClosure success_callback,
base::OnceClosure failure_callback) = 0;
// Set up sign-in flow for Easy Unlock.
virtual void SetupEasyUnlockUserFlow(const AccountId& account_id) = 0;
// Run policy check for |account_id|. If something is wrong, delegate's
// PolicyLoadFailed is called.
virtual bool CheckPolicyForUser(const AccountId& account_id) = 0;
// Gets the SharedURLLoaderFactory used for sign in.
virtual scoped_refptr<network::SharedURLLoaderFactory>
GetSigninURLLoaderFactory() = 0;
// Create authenticator implementation.
virtual scoped_refptr<Authenticator> CreateAuthenticator() = 0;
void set_authenticator(scoped_refptr<Authenticator> authenticator);
// Notifications receiver.
Delegate* delegate_;
private:
// Starts login completion of externally authenticated user.
void StartLoginCompletion();
// Starts authentication.
void StartAuthentication();
void NotifyAllowlistCheckFailure();
// Makes sure that authenticator is created.
void EnsureAuthenticator();
void EnsureExtendedAuthenticator();
// Actual implementantion of PeformLogin that is run after trusted values
// check.
void DoPerformLogin(const UserContext& user_context,
AuthorizationMode auth_mode);
scoped_refptr<base::SequencedTaskRunner> task_runner_;
// Used for logging in.
scoped_refptr<Authenticator> authenticator_;
// Used for logging in.
scoped_refptr<ExtendedAuthenticator> extended_authenticator_;
// Represents last login failure that was encountered when communicating to
// sign-in server. AuthFailure.LoginFailureNone() by default.
AuthFailure last_login_failure_;
// User credentials for the current login attempt.
UserContext user_context_;
// True if password change has been detected.
// Once correct password is entered homedir migration is executed.
bool password_changed_ = false;
int password_changed_callback_count_ = 0;
// Authorization mode type.
AuthorizationMode auth_mode_ = AuthorizationMode::kInternal;
base::WeakPtrFactory<LoginPerformer> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(LoginPerformer);
};
} // namespace chromeos
// TODO(https://crbug.com/1164001): remove when the //chrome/browser/chromeos
// source code migration is finished.
namespace ash {
using ::chromeos::LoginPerformer;
}
#endif // CHROMEOS_LOGIN_AUTH_LOGIN_PERFORMER_H_