| // Copyright 2014 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef COMPONENTS_USER_MANAGER_USER_MANAGER_H_ |
| #define COMPONENTS_USER_MANAGER_USER_MANAGER_H_ |
| |
| #include <string> |
| |
| #include "base/functional/callback_forward.h" |
| #include "base/scoped_observation_traits.h" |
| #include "components/user_manager/include_exclude_account_id_filter.h" |
| #include "components/user_manager/user.h" |
| #include "components/user_manager/user_manager_export.h" |
| #include "components/user_manager/user_type.h" |
| |
| class AccountId; |
| class PrefService; |
| |
| namespace user_manager { |
| |
| class MultiUserSignInPolicyController; |
| |
| namespace internal { |
| class ScopedUserManagerImpl; |
| } // namespace internal |
| |
| enum class UserRemovalReason : int32_t { |
| UNKNOWN = 0, |
| LOCAL_USER_INITIATED = 1, |
| REMOTE_ADMIN_INITIATED = 2, |
| LOCAL_USER_INITIATED_ON_REQUIRED_UPDATE = 3, |
| DEVICE_EPHEMERAL_USERS_ENABLED = 4, |
| GAIA_REMOVED = 5, |
| MISCONFIGURED_USER = 6, |
| }; |
| |
| // Interface for UserManagerBase - that provides base implementation for |
| // Chrome OS user management. Typical features: |
| // * Get list of all know users (who have logged into this Chrome OS device) |
| // * Keep track for logged in/LRU users, active user in multi-user session. |
| // * Find/modify users, store user meta-data such as display name/email. |
| class USER_MANAGER_EXPORT UserManager { |
| public: |
| using EphemeralModeConfig = IncludeExcludeAccountIdFilter; |
| |
| // Interface that observers of UserManager must implement in order |
| // to receive notification when local state preferences is changed |
| class Observer { |
| public: |
| // Called when the local state preferences is changed. |
| virtual void LocalStateChanged(UserManager* user_manager); |
| |
| // Called when the user list is loaded. |
| virtual void OnUserListLoaded(); |
| |
| // Called when the device local user list is updated. |
| virtual void OnDeviceLocalUserListUpdated(); |
| |
| // Called when the user is logged in. |
| virtual void OnUserLoggedIn(const User& user); |
| |
| // Called when the image of the given user is changed. |
| virtual void OnUserImageChanged(const User& user); |
| |
| // Called when the user image enterprise state of the given user is changed. |
| virtual void OnUserImageIsEnterpriseManagedChanged( |
| const User& user, |
| bool is_enterprise_managed); |
| |
| // Called when the Profile instance for the user is created. |
| virtual void OnUserProfileCreated(const User& user); |
| |
| // Called when the profile image download for the given user fails or |
| // user has the default profile image or no porfile image at all. |
| virtual void OnUserProfileImageUpdateFailed(const User& user); |
| |
| // Called when the profile image for the given user is downloaded. |
| // |profile_image| contains the downloaded profile image. |
| virtual void OnUserProfileImageUpdated(const User& user, |
| const gfx::ImageSkia& profile_image); |
| |
| // Called when any of the device cros settings which are responsible for |
| // user sign in are changed. |
| virtual void OnUsersSignInConstraintsChanged(); |
| |
| // Called when the user affiliation is updated. |
| virtual void OnUserAffiliationUpdated(const User& user); |
| |
| // Called just before a user of the device will be removed. |
| virtual void OnUserToBeRemoved(const AccountId& account_id); |
| |
| // Called just after a user of the device has been removed. |
| virtual void OnUserRemoved(const AccountId& account_id, |
| UserRemovalReason reason); |
| |
| // Called when the first user that is not allowed in the session is |
| // detected. |
| virtual void OnUserNotAllowed(const std::string& user_email); |
| |
| protected: |
| virtual ~Observer(); |
| }; |
| |
| // TODO(xiyuan): Refactor and move this observer out of UserManager. |
| // Observer interface that defines methods used to notify on user session / |
| // active user state changes. Default implementation is empty. |
| class UserSessionStateObserver { |
| public: |
| // Called when active user has changed. |
| virtual void ActiveUserChanged(User* active_user); |
| |
| // Called when login state is updated. |
| // This looks very similar to ActiveUserChanged, so consider to merge |
| // in the future. |
| virtual void OnLoginStateUpdated(const User* active_user, |
| bool is_current_user_owner); |
| |
| // Called when another user got added to the existing session. |
| virtual void UserAddedToSession(const User* added_user); |
| |
| protected: |
| virtual ~UserSessionStateObserver(); |
| }; |
| |
| // Data retrieved from user account. |
| class UserAccountData { |
| public: |
| UserAccountData(const std::u16string& display_name, |
| const std::u16string& given_name, |
| const std::string& locale); |
| |
| UserAccountData(const UserAccountData&) = delete; |
| UserAccountData& operator=(const UserAccountData&) = delete; |
| |
| ~UserAccountData(); |
| const std::u16string& display_name() const { return display_name_; } |
| const std::u16string& given_name() const { return given_name_; } |
| const std::string& locale() const { return locale_; } |
| |
| private: |
| const std::u16string display_name_; |
| const std::u16string given_name_; |
| const std::string locale_; |
| }; |
| |
| // Initializes UserManager instance to this. Normally should be called right |
| // after creation so that user_manager::UserManager::Get() doesn't fail. |
| // Tests could call this method if they are replacing existing UserManager |
| // instance with their own test instance. |
| virtual void Initialize(); |
| |
| // Checks whether the UserManager instance has been created already. |
| // This method is not thread-safe and must be called from the main UI thread. |
| static bool IsInitialized(); |
| |
| // Shuts down the UserManager. After this method has been called, the |
| // singleton has unregistered itself as an observer but remains available so |
| // that other classes can access it during their shutdown. This method is not |
| // thread-safe and must be called from the main UI thread. |
| virtual void Shutdown() = 0; |
| |
| // Sets UserManager instance to NULL. Always call Shutdown() first. |
| // This method is not thread-safe and must be called from the main UI thread. |
| void Destroy(); |
| |
| // Returns UserManager instance or will crash if it is |NULL| (has either not |
| // been created yet or is already destroyed). This method is not thread-safe |
| // and must be called from the main UI thread. |
| static UserManager* Get(); |
| |
| virtual ~UserManager(); |
| |
| // Returns a list of users who have logged into this device previously. This |
| // is sorted by last login date with the most recent user at the beginning. |
| virtual const UserList& GetUsers() const = 0; |
| |
| // Returns list of users allowed for logging in into multi-profile session. |
| // Users that have a policy that prevents them from being added to the |
| // multi-profile session will still be part of this list as long as they |
| // are regular users (i.e. not a public session/supervised etc.). |
| // Returns an empty list in case when primary user is not a regular one or |
| // has a policy that prohibits it to be part of multi-profile session. |
| virtual UserList GetUsersAllowedForMultiProfile() const = 0; |
| |
| // Returns users allowed on login screen in the given `users` list. |
| virtual UserList FindLoginAllowedUsersFrom(const UserList& users) const = 0; |
| |
| // Returns a list of users who are currently logged in. |
| virtual const UserList& GetLoggedInUsers() const = 0; |
| |
| // Returns a list of users who are currently logged in in the LRU order - |
| // so the active user is the first one in the list. If there is no user logged |
| // in, the current user will be returned. |
| virtual const UserList& GetLRULoggedInUsers() const = 0; |
| |
| // Returns a list of users who can unlock the device. |
| // This list is based on policy and whether user is able to do unlock. |
| // Policy: |
| // * If user has primary-only policy then it is the only user in unlock users. |
| // * Otherwise all users with unrestricted policy are added to this list. |
| // All users that are unable to perform unlock are excluded from this list. |
| virtual UserList GetUnlockUsers() const = 0; |
| |
| // Returns account Id of the owner user. Returns an empty Id if there is |
| // no owner for the device. |
| virtual const AccountId& GetOwnerAccountId() const = 0; |
| |
| // Provides the caller with account Id of the Owner user once it is loaded. |
| // Would provide empty account id if there is no owner on the device (e.g. |
| // if device is enterprise-owned). |
| virtual void GetOwnerAccountIdAsync( |
| base::OnceCallback<void(const AccountId&)> callback) const = 0; |
| |
| // Returns account Id of the user that was active in the previous session. |
| virtual const AccountId& GetLastSessionActiveAccountId() const = 0; |
| |
| // Indicates that a user with the given |account_id| has just logged in. The |
| // persistent list is updated accordingly if the user is not ephemeral. |
| // |browser_restart| is true when reloading Chrome after crash to distinguish |
| // from normal sign in flow. |
| // |username_hash| is used to identify homedir mount point. |
| virtual void UserLoggedIn(const AccountId& account_id, |
| const std::string& username_hash, |
| bool browser_restart, |
| bool is_child) = 0; |
| |
| // Called when the Profile instance for a user identified by `account_id` |
| // is created. `prefs` should be the one that is owned by Profile. |
| // The 'prefs' must be kept alive until OnUserProfileWillBeDestroyed |
| // for the user is called. |
| // Returns whether actually the prefs are used or not. |
| virtual bool OnUserProfileCreated(const AccountId& account_id, |
| PrefService* prefs) = 0; |
| |
| // Called just before the Profile for a user identified by `account_id` |
| // will be destroyed. |
| virtual void OnUserProfileWillBeDestroyed(const AccountId& account_id) = 0; |
| |
| // Switches to active user identified by |account_id|. User has to be logged |
| // in. |
| virtual void SwitchActiveUser(const AccountId& account_id) = 0; |
| |
| // Switches to the last active user (called after crash happens and session |
| // restore has completed). |
| virtual void SwitchToLastActiveUser() = 0; |
| |
| // Invoked by session manager to inform session start. |
| virtual void OnSessionStarted() = 0; |
| |
| // Removes the user from the device while providing a reason for enterprise |
| // reporting. Note, it will verify that the given user isn't the owner, so |
| // calling this method for the owner will take no effect. |
| // This removes the user from the list synchronously, so the following |
| // function calls should have updated users. However, actual deletion of |
| // a user from a device has more tasks to complete, such as deletion of |
| // cryptohome data, which are asynchronous operations. Currently, there's |
| // no support to observe the completion of such tasks. |
| virtual void RemoveUser(const AccountId& account_id, |
| UserRemovalReason reason) = 0; |
| |
| // Removes the user from the persistent list only. Also removes the user's |
| // picture. |
| virtual void RemoveUserFromList(const AccountId& account_id) = 0; |
| |
| // Removes the user from persistent list, without triggering user removal |
| // notification. |
| // Used to re-create user in Password changed flow when user can not |
| // remember old password and decides to delete existing user directory and |
| // re-create it. |
| // TODO(b/270040728): Remove this method once internal architecture allows |
| // better solution. |
| virtual void RemoveUserFromListForRecreation(const AccountId& account_id) = 0; |
| |
| // Removes the user from the device in case when user's cryptohome is lost |
| // for some reason to ensure that user is correctly re-created. |
| // Does not trigger user removal notification. |
| // This method is similar to `RemoveUserFromListForRecreation`, but is |
| // triggered at different stage of login process, and when absence of user |
| // directory is not anticipated by the flow. This removes the user from the |
| // list synchronously, so the following function calls should have updated |
| // users. |
| virtual void CleanStaleUserInformationFor(const AccountId& account_id) = 0; |
| |
| // Returns true if a user with the given account id is found in the persistent |
| // list or currently logged in as ephemeral. |
| virtual bool IsKnownUser(const AccountId& account_id) const = 0; |
| |
| // Returns the user with the given account id if found in the persistent |
| // list or currently logged in as ephemeral. Returns |NULL| otherwise. |
| virtual const User* FindUser(const AccountId& account_id) const = 0; |
| |
| // Returns the user with the given account id if found in the persistent |
| // list or currently logged in as ephemeral. Returns |NULL| otherwise. |
| // Same as FindUser but returns non-const pointer to User object. |
| virtual User* FindUserAndModify(const AccountId& account_id) = 0; |
| |
| // Returns the logged-in user that is currently active within this session. |
| // There could be multiple users logged in at the the same but for now |
| // we support only one of them being active. |
| virtual const User* GetActiveUser() const = 0; |
| virtual User* GetActiveUser() = 0; |
| |
| // Returns the primary user of the current session. It is recorded for the |
| // first signed-in user and does not change thereafter. |
| virtual const User* GetPrimaryUser() const = 0; |
| |
| // Saves user's oauth token status in local state preferences. |
| virtual void SaveUserOAuthStatus( |
| const AccountId& account_id, |
| User::OAuthTokenStatus oauth_token_status) = 0; |
| |
| // Saves a flag indicating whether online authentication against GAIA should |
| // be enforced during the user's next sign-in. |
| virtual void SaveForceOnlineSignin(const AccountId& account_id, |
| bool force_online_signin) = 0; |
| |
| // Saves user's displayed name in local state preferences. |
| // Ignored If there is no such user. |
| virtual void SaveUserDisplayName(const AccountId& account_id, |
| const std::u16string& display_name) = 0; |
| |
| // Updates data upon User Account download. |
| virtual void UpdateUserAccountData(const AccountId& account_id, |
| const UserAccountData& account_data) = 0; |
| |
| // Saves user's displayed (non-canonical) email in local state preferences. |
| // Ignored If there is no such user. |
| virtual void SaveUserDisplayEmail(const AccountId& account_id, |
| const std::string& display_email) = 0; |
| |
| // Returns stored user type or UserType::kRegular by default. |
| virtual UserType GetUserType(const AccountId& account_id) = 0; |
| |
| // Saves user's type for |user| into local state preferences. |
| virtual void SaveUserType(const User* user) = 0; |
| |
| // Returns the email of the owner user stored in local state. Can return |
| // nullopt if no user attempted to take ownership so far (e.g. there were |
| // only guest sessions or it's a managed device). This is a secondary / backup |
| // mechanism to determine the owner user, prefer relying on device policies or |
| // possession of the private key when possible. |
| virtual std::optional<std::string> GetOwnerEmail() = 0; |
| |
| // Records the identity of the owner user. In the current implementation |
| // always stores the email. |
| virtual void RecordOwner(const AccountId& owner) = 0; |
| |
| // Returns true if the given |user| is the device owner. |
| virtual bool IsOwnerUser(const User* user) const = 0; |
| |
| // Returns true if the given |user| is the primary user. |
| virtual bool IsPrimaryUser(const User* user) const = 0; |
| |
| // Returns true if the given |user| is an ephemeral user. |
| virtual bool IsEphemeralUser(const User* user) const = 0; |
| |
| // Returns true if current user is an owner. |
| virtual bool IsCurrentUserOwner() const = 0; |
| |
| // Returns true if current user is not existing one (hasn't signed in before). |
| virtual bool IsCurrentUserNew() const = 0; |
| |
| // This method updates "User was added to the device in this session and is |
| // not full initialized yet" flag. |
| virtual void SetIsCurrentUserNew(bool is_new) = 0; |
| |
| // Returns true if data stored or cached for the current user outside that |
| // user's cryptohome (wallpaper, avatar, OAuth token status, display name, |
| // display email) is ephemeral. |
| virtual bool IsCurrentUserNonCryptohomeDataEphemeral() const = 0; |
| |
| // Returns true if data stored or cached for the current user inside that |
| // user's cryptohome is ephemeral. |
| virtual bool IsCurrentUserCryptohomeDataEphemeral() const = 0; |
| |
| // Returns true if at least one user has signed in. |
| virtual bool IsUserLoggedIn() const = 0; |
| |
| // Returns true if we're logged in as a user with gaia account. |
| virtual bool IsLoggedInAsUserWithGaiaAccount() const = 0; |
| |
| // Returns true if we're logged in as a child user. |
| virtual bool IsLoggedInAsChildUser() const = 0; |
| |
| // Returns true if we're logged in as a managed guest session. |
| virtual bool IsLoggedInAsManagedGuestSession() const = 0; |
| |
| // Returns true if we're logged in as a Guest. |
| virtual bool IsLoggedInAsGuest() const = 0; |
| |
| // Returns true if we're logged in as a kiosk app. |
| virtual bool IsLoggedInAsKioskApp() const = 0; |
| |
| // Returns true if we're logged in as an ARC kiosk app. |
| virtual bool IsLoggedInAsArcKioskApp() const = 0; |
| |
| // Returns true if we're logged in as a Web kiosk app. |
| virtual bool IsLoggedInAsWebKioskApp() const = 0; |
| |
| // Returns true if we're logged in as chrome, ARC or Web kiosk app. |
| virtual bool IsLoggedInAsAnyKioskApp() const = 0; |
| |
| // Returns true if we're logged in as the stub user used for testing on Linux. |
| virtual bool IsLoggedInAsStub() const = 0; |
| |
| // Returns true if data stored or cached for the user with the given |
| // |account_id| |
| // address outside that user's cryptohome (wallpaper, avatar, OAuth token |
| // status, display name, display email) is to be treated as ephemeral. |
| virtual bool IsUserNonCryptohomeDataEphemeral( |
| const AccountId& account_id) const = 0; |
| |
| virtual bool IsUserCryptohomeDataEphemeral( |
| const AccountId& account_id) const = 0; |
| |
| // Returns true if device is enterprise managed. |
| virtual bool IsEnterpriseManaged() const = 0; |
| |
| virtual void AddObserver(Observer* obs) = 0; |
| virtual void RemoveObserver(Observer* obs) = 0; |
| |
| virtual void AddSessionStateObserver(UserSessionStateObserver* obs) = 0; |
| virtual void RemoveSessionStateObserver(UserSessionStateObserver* obs) = 0; |
| |
| virtual void NotifyLocalStateChanged() = 0; |
| virtual void NotifyUserImageChanged(const User& user) = 0; |
| virtual void NotifyUserImageIsEnterpriseManagedChanged( |
| const User& user, |
| bool is_enterprise_managed) = 0; |
| virtual void NotifyUserProfileImageUpdateFailed(const User& user) = 0; |
| virtual void NotifyUserProfileImageUpdated( |
| const User& user, |
| const gfx::ImageSkia& profile_image) = 0; |
| virtual void NotifyUsersSignInConstraintsChanged() = 0; |
| virtual void NotifyUserAffiliationUpdated(const User& user) = 0; |
| virtual void NotifyUserToBeRemoved(const AccountId& account_id) = 0; |
| virtual void NotifyUserRemoved(const AccountId& account_id, |
| UserRemovalReason reason) = 0; |
| virtual void NotifyUserNotAllowed(const std::string& user_email) = 0; |
| |
| // Returns true if guest user is allowed. |
| virtual bool IsGuestSessionAllowed() const = 0; |
| |
| // Returns true if the |user|, which has a GAIA account is allowed according |
| // to device settings and policies. |
| // Accept only users who has gaia account. |
| virtual bool IsGaiaUserAllowed(const User& user) const = 0; |
| |
| // Returns true if |user| is allowed depending on device policies. |
| // Accepted user types: UserType::kRegular, UserType::kGuest, |
| // UserType::kChild. |
| virtual bool IsUserAllowed(const User& user) const = 0; |
| |
| // Explicitly non-ephemeral accounts are Owner account (on consumer-owned |
| // devices) and Stub accounts (used in tests). |
| // |
| // Explicitly ephemeral accounts are Guest and Managed Guest sessions. |
| // |
| // In all other cases the ephemeral status of account depends on set of |
| // policies. |
| virtual bool IsEphemeralAccountId(const AccountId& account_id) const = 0; |
| |
| // Returns "Local State" PrefService instance. |
| virtual PrefService* GetLocalState() const = 0; |
| |
| // Returns true if this is first exec after boot. |
| virtual bool IsFirstExecAfterBoot() const = 0; |
| |
| // Actually removes cryptohome. |
| virtual void AsyncRemoveCryptohome(const AccountId& account_id) const = 0; |
| |
| // Returns true if |account_id| is deprecated supervised. |
| // TODO(crbug/1155729): Check it is not used anymore and remove it. |
| virtual bool IsDeprecatedSupervisedAccountId( |
| const AccountId& account_id) const = 0; |
| |
| virtual bool IsDeviceLocalAccountMarkedForRemoval( |
| const AccountId& account_id) const = 0; |
| |
| // Sets affiliation status for the user identified with `account_id` |
| // to `is_affiliated`. |
| virtual void SetUserAffiliated(const AccountId& account_id, |
| bool is_affiliated) = 0; |
| |
| // Returns true when the browser has crashed and restarted during the current |
| // user's session. |
| virtual bool HasBrowserRestarted() const = 0; |
| |
| // Returns true if |image_index| is a valid default user image index. |
| virtual bool IsValidDefaultUserImageId(int image_index) const = 0; |
| |
| // Returns the instance of multi user sign-in policy controller. |
| virtual MultiUserSignInPolicyController* |
| GetMultiUserSignInPolicyController() = 0; |
| |
| UserType CalculateUserType(const AccountId& account_id, |
| const User* user, |
| bool browser_restart, |
| bool is_child) const; |
| |
| protected: |
| // Sets UserManager instance. |
| static void SetInstance(UserManager* user_manager); |
| |
| // Pointer to the existing UserManager instance (if any). |
| // Usually is set by calling Initialize(), reset by calling Destroy(). |
| // Not owned since specific implementation of UserManager should decide on its |
| // own appropriate owner. For src/chrome implementation such place is |
| // g_browser_process->platform_part(). |
| static UserManager* instance; |
| |
| private: |
| friend class internal::ScopedUserManagerImpl; |
| |
| // Same as Get() but doesn't won't crash is current instance is NULL. |
| static UserManager* GetForTesting(); |
| |
| // Sets UserManager instance to the given |user_manager|. |
| // Returns the previous value of the instance. |
| static UserManager* SetForTesting(UserManager* user_manager); |
| }; |
| |
| } // namespace user_manager |
| |
| namespace base { |
| |
| template <> |
| struct ScopedObservationTraits< |
| user_manager::UserManager, |
| user_manager::UserManager::UserSessionStateObserver> { |
| static void AddObserver( |
| user_manager::UserManager* source, |
| user_manager::UserManager::UserSessionStateObserver* observer) { |
| source->AddSessionStateObserver(observer); |
| } |
| static void RemoveObserver( |
| user_manager::UserManager* source, |
| user_manager::UserManager::UserSessionStateObserver* observer) { |
| source->RemoveSessionStateObserver(observer); |
| } |
| }; |
| |
| } // namespace base |
| |
| #endif // COMPONENTS_USER_MANAGER_USER_MANAGER_H_ |