123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850 |
- // Copyright 2015 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.
- #include "components/user_manager/known_user.h"
- #include <stddef.h>
- #include <memory>
- #include <utility>
- #include "base/json/values_util.h"
- #include "base/logging.h"
- #include "base/metrics/histogram_macros.h"
- #include "base/strings/string_piece_forward.h"
- #include "base/time/time.h"
- #include "base/values.h"
- #include "components/account_id/account_id.h"
- #include "components/prefs/pref_registry_simple.h"
- #include "components/prefs/scoped_user_pref_update.h"
- #include "components/user_manager/user_manager.h"
- #include "google_apis/gaia/gaia_auth_util.h"
- #include "third_party/abseil-cpp/absl/types/optional.h"
- namespace user_manager {
- namespace {
- // A vector pref of preferences of known users. All new preferences should be
- // placed in this list.
- const char kKnownUsers[] = "KnownUsers";
- // Known user preferences keys (stored in Local State). All keys should be
- // listed in kReservedKeys or kObsoleteKeys below.
- // Key of canonical e-mail value.
- const char kCanonicalEmail[] = "email";
- // Key of obfuscated GAIA id value.
- const char kGAIAIdKey[] = "gaia_id";
- // Key of obfuscated object guid value for Active Directory accounts.
- const char kObjGuidKey[] = "obj_guid";
- // Key of account type.
- const char kAccountTypeKey[] = "account_type";
- // Key of whether this user ID refers to a SAML user.
- const char kUsingSAMLKey[] = "using_saml";
- // Key of whether this user authenticated via SAML using the principals API.
- const char kIsUsingSAMLPrincipalsAPI[] = "using_saml_principals_api";
- // Key of Device Id.
- const char kDeviceId[] = "device_id";
- // Key of GAPS cookie.
- const char kGAPSCookie[] = "gaps_cookie";
- // Key of the reason for re-auth.
- const char kReauthReasonKey[] = "reauth_reason";
- // Key for the GaiaId migration status.
- const char kGaiaIdMigrationObsolete[] = "gaia_id_migration";
- // Key of the boolean flag telling if a minimal user home migration has been
- // attempted. This flag is not used since M88 and is only kept here to be able
- // to remove it from existing entries.
- const char kMinimalMigrationAttemptedObsolete[] = "minimal_migration_attempted";
- // Key of the boolean flag telling if user session requires policy.
- const char kProfileRequiresPolicy[] = "profile_requires_policy";
- // Key of the boolean flag telling if user is ephemeral and should be removed
- // from the local state on logout.
- const char kIsEphemeral[] = "is_ephemeral";
- // Key of the list value that stores challenge-response authentication keys.
- const char kChallengeResponseKeys[] = "challenge_response_keys";
- const char kLastOnlineSignin[] = "last_online_singin";
- const char kOfflineSigninLimitObsolete[] = "offline_signin_limit";
- const char kOfflineSigninLimit[] = "offline_signin_limit2";
- // Key of the boolean flag telling if user is enterprise managed.
- const char kIsEnterpriseManaged[] = "is_enterprise_managed";
- // Key of the name of the entity (either a domain or email address) that manages
- // the policies for this account.
- const char kAccountManager[] = "enterprise_account_manager";
- // Key of the last input method user used which is suitable for login/lock
- // screen.
- const char kLastInputMethod[] = "last_input_method";
- // Key of the PIN auto submit length.
- const char kPinAutosubmitLength[] = "pin_autosubmit_length";
- // Key for the PIN auto submit backfill needed indicator.
- const char kPinAutosubmitBackfillNeeded[] = "pin_autosubmit_backfill_needed";
- // Sync token for SAML password multi-device sync
- const char kPasswordSyncToken[] = "password_sync_token";
- // Major version in which the user completed the onboarding flow.
- const char kOnboardingCompletedVersion[] = "onboarding_completed_version";
- // Last screen shown in the onboarding flow.
- const char kPendingOnboardingScreen[] = "onboarding_screen_pending";
- // List containing all the known user preferences keys.
- const char* kReservedKeys[] = {kCanonicalEmail,
- kGAIAIdKey,
- kObjGuidKey,
- kAccountTypeKey,
- kUsingSAMLKey,
- kIsUsingSAMLPrincipalsAPI,
- kDeviceId,
- kGAPSCookie,
- kReauthReasonKey,
- kProfileRequiresPolicy,
- kIsEphemeral,
- kChallengeResponseKeys,
- kLastOnlineSignin,
- kOfflineSigninLimit,
- kIsEnterpriseManaged,
- kAccountManager,
- kLastInputMethod,
- kPinAutosubmitLength,
- kPinAutosubmitBackfillNeeded,
- kPasswordSyncToken,
- kOnboardingCompletedVersion,
- kPendingOnboardingScreen};
- // List containing all known user preference keys that used to be reserved and
- // are now obsolete.
- const char* kObsoleteKeys[] = {
- kMinimalMigrationAttemptedObsolete,
- kGaiaIdMigrationObsolete,
- kOfflineSigninLimitObsolete,
- };
- PrefService* GetLocalStateLegacy() {
- if (!UserManager::IsInitialized())
- return nullptr;
- return UserManager::Get()->GetLocalState();
- }
- // Checks if values in |dict| correspond with |account_id| identity.
- bool UserMatches(const AccountId& account_id, const base::Value& dict) {
- const std::string* account_type = dict.FindStringKey(kAccountTypeKey);
- if (account_id.GetAccountType() != AccountType::UNKNOWN && account_type &&
- account_id.GetAccountType() !=
- AccountId::StringToAccountType(*account_type)) {
- return false;
- }
- // TODO(alemate): update code once user id is really a struct.
- // TODO(https://crbug.com/1190902): If the gaia id or GUID doesn't match,
- // this function should likely be returning false even if the e-mail matches.
- switch (account_id.GetAccountType()) {
- case AccountType::GOOGLE: {
- const std::string* gaia_id = dict.FindStringKey(kGAIAIdKey);
- if (gaia_id && account_id.GetGaiaId() == *gaia_id)
- return true;
- break;
- }
- case AccountType::ACTIVE_DIRECTORY: {
- const std::string* obj_guid = dict.FindStringKey(kObjGuidKey);
- if (obj_guid && account_id.GetObjGuid() == *obj_guid)
- return true;
- break;
- }
- case AccountType::UNKNOWN: {
- }
- }
- const std::string* email = dict.FindStringKey(kCanonicalEmail);
- if (email && account_id.GetUserEmail() == *email)
- return true;
- return false;
- }
- // Fills relevant |dict| values based on |account_id|.
- // TODO(crbug.com/1287074): Consider a refactor to use base::Value::DictStorage.
- // This would require |dict| to not be modified in-place.
- void UpdateIdentity(const AccountId& account_id, base::Value& dict) {
- DCHECK(dict.is_dict());
- if (!account_id.GetUserEmail().empty())
- dict.SetStringKey(kCanonicalEmail, account_id.GetUserEmail());
- switch (account_id.GetAccountType()) {
- case AccountType::GOOGLE:
- if (!account_id.GetGaiaId().empty())
- dict.SetStringKey(kGAIAIdKey, account_id.GetGaiaId());
- break;
- case AccountType::ACTIVE_DIRECTORY:
- if (!account_id.GetObjGuid().empty())
- dict.SetStringKey(kObjGuidKey, account_id.GetObjGuid());
- break;
- case AccountType::UNKNOWN:
- return;
- }
- dict.SetStringKey(kAccountTypeKey, AccountId::AccountTypeToString(
- account_id.GetAccountType()));
- }
- } // namespace
- KnownUser::KnownUser(PrefService* local_state) : local_state_(local_state) {
- DCHECK(local_state);
- }
- KnownUser::~KnownUser() = default;
- const base::Value* KnownUser::FindPrefs(const AccountId& account_id) const {
- // UserManager is usually NULL in unit tests.
- if (account_id.GetAccountType() != AccountType::ACTIVE_DIRECTORY &&
- UserManager::IsInitialized() &&
- UserManager::Get()->IsUserNonCryptohomeDataEphemeral(account_id)) {
- return nullptr;
- }
- if (!account_id.is_valid())
- return nullptr;
- const base::Value::List& known_users =
- local_state_->GetValueList(kKnownUsers);
- for (const base::Value& element_value : known_users) {
- if (element_value.is_dict()) {
- if (UserMatches(account_id, element_value)) {
- return &element_value;
- }
- }
- }
- return nullptr;
- }
- void KnownUser::SetPath(const AccountId& account_id,
- const std::string& path,
- absl::optional<base::Value> opt_value) {
- // UserManager is usually NULL in unit tests.
- if (account_id.GetAccountType() != AccountType::ACTIVE_DIRECTORY &&
- UserManager::IsInitialized() &&
- UserManager::Get()->IsUserNonCryptohomeDataEphemeral(account_id)) {
- return;
- }
- if (!account_id.is_valid())
- return;
- ListPrefUpdate update(local_state_, kKnownUsers);
- for (base::Value& element_value : update->GetList()) {
- if (element_value.is_dict()) {
- if (UserMatches(account_id, element_value)) {
- if (opt_value.has_value())
- element_value.SetPath(path, std::move(opt_value).value());
- else
- element_value.RemovePath(path);
- UpdateIdentity(account_id, element_value);
- return;
- }
- }
- }
- if (!opt_value.has_value())
- return;
- base::Value new_dict(base::Value::Type::DICTIONARY);
- new_dict.SetPath(path, std::move(opt_value).value());
- UpdateIdentity(account_id, new_dict);
- update->Append(std::move(new_dict));
- }
- const std::string* KnownUser::FindStringPath(const AccountId& account_id,
- base::StringPiece path) const {
- const base::Value* user_pref_dict = FindPrefs(account_id);
- if (!user_pref_dict)
- return nullptr;
- return user_pref_dict->FindStringPath(path);
- }
- bool KnownUser::GetStringPrefForTest(const AccountId& account_id,
- const std::string& path,
- std::string* out_value) {
- const std::string* res = FindStringPath(account_id, path);
- if (out_value && res)
- *out_value = *res;
- return res;
- }
- void KnownUser::SetStringPref(const AccountId& account_id,
- const std::string& path,
- const std::string& in_value) {
- SetPath(account_id, path, base::Value(in_value));
- }
- absl::optional<bool> KnownUser::FindBoolPath(const AccountId& account_id,
- base::StringPiece path) const {
- const base::Value* user_pref_dict = FindPrefs(account_id);
- if (!user_pref_dict)
- return absl::nullopt;
- return user_pref_dict->FindBoolPath(path);
- }
- bool KnownUser::GetBooleanPrefForTest(const AccountId& account_id,
- const std::string& path,
- bool* out_value) {
- auto opt_val = FindBoolPath(account_id, path);
- if (out_value && opt_val.has_value())
- *out_value = opt_val.value();
- return opt_val.has_value();
- }
- void KnownUser::SetBooleanPref(const AccountId& account_id,
- const std::string& path,
- const bool in_value) {
- SetPath(account_id, path, base::Value(in_value));
- }
- absl::optional<int> KnownUser::FindIntPath(const AccountId& account_id,
- base::StringPiece path) const {
- const base::Value* user_pref_dict = FindPrefs(account_id);
- if (!user_pref_dict)
- return absl::nullopt;
- return user_pref_dict->FindIntPath(path);
- }
- bool KnownUser::GetIntegerPrefForTest(const AccountId& account_id,
- const std::string& path,
- int* out_value) {
- auto opt_val = FindIntPath(account_id, path);
- if (out_value && opt_val.has_value())
- *out_value = opt_val.value();
- return opt_val.has_value();
- }
- void KnownUser::SetIntegerPref(const AccountId& account_id,
- const std::string& path,
- const int in_value) {
- SetPath(account_id, path, base::Value(in_value));
- }
- bool KnownUser::GetPrefForTest(const AccountId& account_id,
- const std::string& path,
- const base::Value** out_value) {
- *out_value = FindPath(account_id, path);
- return *out_value != nullptr;
- }
- const base::Value* KnownUser::FindPath(const AccountId& account_id,
- const std::string& path) const {
- const base::Value* user_pref_dict = FindPrefs(account_id);
- if (!user_pref_dict)
- return nullptr;
- return user_pref_dict->FindPath(path);
- }
- void KnownUser::RemovePref(const AccountId& account_id,
- const std::string& path) {
- // Prevent removing keys that are used internally.
- for (const std::string& key : kReservedKeys)
- CHECK_NE(path, key);
- SetPath(account_id, path, absl::nullopt);
- }
- AccountId KnownUser::GetAccountId(const std::string& user_email,
- const std::string& id,
- const AccountType& account_type) {
- DCHECK((id.empty() && account_type == AccountType::UNKNOWN) ||
- (!id.empty() && account_type != AccountType::UNKNOWN));
- // In tests empty accounts are possible.
- if (user_email.empty() && id.empty() &&
- account_type == AccountType::UNKNOWN) {
- return EmptyAccountId();
- }
- AccountId result(EmptyAccountId());
- // UserManager is usually NULL in unit tests.
- if (account_type == AccountType::UNKNOWN && UserManager::IsInitialized() &&
- UserManager::Get()->GetPlatformKnownUserId(user_email, id, &result)) {
- return result;
- }
- const std::string sanitized_email =
- user_email.empty()
- ? std::string()
- : gaia::CanonicalizeEmail(gaia::SanitizeEmail(user_email));
- if (!sanitized_email.empty()) {
- const AccountId account_id(AccountId::FromUserEmail(sanitized_email));
- if (const std::string* stored_gaia_id =
- FindStringPath(account_id, kGAIAIdKey)) {
- if (!id.empty()) {
- DCHECK(account_type == AccountType::GOOGLE);
- if (id != *stored_gaia_id)
- LOG(ERROR) << "User gaia id has changed. Sync will not work.";
- }
- // gaia_id is associated with cryptohome.
- return AccountId::FromUserEmailGaiaId(sanitized_email, *stored_gaia_id);
- }
- if (const std::string* stored_obj_guid =
- FindStringPath(account_id, kObjGuidKey)) {
- if (!id.empty()) {
- DCHECK(account_type == AccountType::ACTIVE_DIRECTORY);
- if (id != *stored_obj_guid)
- LOG(ERROR) << "User object guid has changed. Sync will not work.";
- }
- // obj_guid is associated with cryptohome.
- return AccountId::AdFromUserEmailObjGuid(sanitized_email,
- *stored_obj_guid);
- }
- }
- switch (account_type) {
- case AccountType::GOOGLE:
- if (const std::string* stored_email =
- FindStringPath(AccountId::FromGaiaId(id), kCanonicalEmail)) {
- return AccountId::FromUserEmailGaiaId(*stored_email, id);
- }
- return AccountId::FromUserEmailGaiaId(sanitized_email, id);
- case AccountType::ACTIVE_DIRECTORY:
- return AccountId::AdFromUserEmailObjGuid(sanitized_email, id);
- case AccountType::UNKNOWN:
- return AccountId::FromUserEmail(sanitized_email);
- }
- NOTREACHED();
- return EmptyAccountId();
- }
- std::vector<AccountId> KnownUser::GetKnownAccountIds() {
- std::vector<AccountId> result;
- const base::Value::List& known_users =
- local_state_->GetValueList(kKnownUsers);
- for (const base::Value& element_value : known_users) {
- if (element_value.is_dict()) {
- const std::string* email = element_value.FindStringKey(kCanonicalEmail);
- const std::string* gaia_id = element_value.FindStringKey(kGAIAIdKey);
- const std::string* obj_guid = element_value.FindStringKey(kObjGuidKey);
- AccountType account_type = AccountType::GOOGLE;
- if (const std::string* account_type_string =
- element_value.FindStringKey(kAccountTypeKey)) {
- account_type = AccountId::StringToAccountType(*account_type_string);
- }
- switch (account_type) {
- case AccountType::GOOGLE:
- if (email || gaia_id) {
- result.push_back(AccountId::FromUserEmailGaiaId(
- email ? *email : std::string(),
- gaia_id ? *gaia_id : std::string()));
- }
- break;
- case AccountType::ACTIVE_DIRECTORY:
- if (email && obj_guid) {
- result.push_back(
- AccountId::AdFromUserEmailObjGuid(*email, *obj_guid));
- }
- break;
- default:
- NOTREACHED() << "Unknown account type";
- }
- }
- }
- return result;
- }
- void KnownUser::SaveKnownUser(const AccountId& account_id) {
- const bool is_ephemeral =
- UserManager::IsInitialized() &&
- UserManager::Get()->IsUserNonCryptohomeDataEphemeral(account_id);
- if (is_ephemeral &&
- account_id.GetAccountType() != AccountType::ACTIVE_DIRECTORY) {
- return;
- }
- UpdateId(account_id);
- local_state_->CommitPendingWrite();
- }
- void KnownUser::SetIsEphemeralUser(const AccountId& account_id,
- bool is_ephemeral) {
- if (account_id.GetAccountType() != AccountType::ACTIVE_DIRECTORY)
- return;
- SetBooleanPref(account_id, kIsEphemeral, is_ephemeral);
- }
- void KnownUser::UpdateId(const AccountId& account_id) {
- switch (account_id.GetAccountType()) {
- case AccountType::GOOGLE:
- SetStringPref(account_id, kGAIAIdKey, account_id.GetGaiaId());
- break;
- case AccountType::ACTIVE_DIRECTORY:
- SetStringPref(account_id, kObjGuidKey, account_id.GetObjGuid());
- break;
- case AccountType::UNKNOWN:
- return;
- }
- SetStringPref(account_id, kAccountTypeKey,
- AccountId::AccountTypeToString(account_id.GetAccountType()));
- }
- const std::string* KnownUser::FindGaiaID(const AccountId& account_id) {
- return FindStringPath(account_id, kGAIAIdKey);
- }
- void KnownUser::SetDeviceId(const AccountId& account_id,
- const std::string& device_id) {
- const std::string known_device_id = GetDeviceId(account_id);
- if (!known_device_id.empty() && device_id != known_device_id) {
- NOTREACHED() << "Trying to change device ID for known user.";
- }
- SetStringPref(account_id, kDeviceId, device_id);
- }
- std::string KnownUser::GetDeviceId(const AccountId& account_id) {
- const std::string* device_id = FindStringPath(account_id, kDeviceId);
- if (device_id)
- return *device_id;
- return std::string();
- }
- void KnownUser::SetGAPSCookie(const AccountId& account_id,
- const std::string& gaps_cookie) {
- SetStringPref(account_id, kGAPSCookie, gaps_cookie);
- }
- std::string KnownUser::GetGAPSCookie(const AccountId& account_id) {
- const std::string* gaps_cookie = FindStringPath(account_id, kGAPSCookie);
- if (gaps_cookie)
- return *gaps_cookie;
- return std::string();
- }
- void KnownUser::UpdateUsingSAML(const AccountId& account_id,
- const bool using_saml) {
- SetBooleanPref(account_id, kUsingSAMLKey, using_saml);
- }
- bool KnownUser::IsUsingSAML(const AccountId& account_id) {
- return FindBoolPath(account_id, kUsingSAMLKey).value_or(false);
- }
- void KnownUser::UpdateIsUsingSAMLPrincipalsAPI(
- const AccountId& account_id,
- bool is_using_saml_principals_api) {
- SetBooleanPref(account_id, kIsUsingSAMLPrincipalsAPI,
- is_using_saml_principals_api);
- }
- bool KnownUser::GetIsUsingSAMLPrincipalsAPI(const AccountId& account_id) {
- return FindBoolPath(account_id, kIsUsingSAMLPrincipalsAPI).value_or(false);
- }
- void KnownUser::SetProfileRequiresPolicy(const AccountId& account_id,
- ProfileRequiresPolicy required) {
- DCHECK_NE(required, ProfileRequiresPolicy::kUnknown);
- SetBooleanPref(account_id, kProfileRequiresPolicy,
- required == ProfileRequiresPolicy::kPolicyRequired);
- }
- ProfileRequiresPolicy KnownUser::GetProfileRequiresPolicy(
- const AccountId& account_id) {
- absl::optional<bool> requires_policy =
- FindBoolPath(account_id, kProfileRequiresPolicy);
- if (requires_policy.has_value()) {
- return requires_policy.value() ? ProfileRequiresPolicy::kPolicyRequired
- : ProfileRequiresPolicy::kNoPolicyRequired;
- }
- return ProfileRequiresPolicy::kUnknown;
- }
- void KnownUser::ClearProfileRequiresPolicy(const AccountId& account_id) {
- SetPath(account_id, kProfileRequiresPolicy, absl::nullopt);
- }
- void KnownUser::UpdateReauthReason(const AccountId& account_id,
- const int reauth_reason) {
- SetIntegerPref(account_id, kReauthReasonKey, reauth_reason);
- }
- absl::optional<int> KnownUser::FindReauthReason(
- const AccountId& account_id) const {
- return FindIntPath(account_id, kReauthReasonKey);
- }
- void KnownUser::SetChallengeResponseKeys(const AccountId& account_id,
- base::Value value) {
- DCHECK(value.is_list());
- SetPath(account_id, kChallengeResponseKeys, std::move(value));
- }
- base::Value KnownUser::GetChallengeResponseKeys(const AccountId& account_id) {
- const base::Value* value = FindPath(account_id, kChallengeResponseKeys);
- if (!value || !value->is_list())
- return base::Value();
- return value->Clone();
- }
- void KnownUser::SetLastOnlineSignin(const AccountId& account_id,
- base::Time time) {
- SetPath(account_id, kLastOnlineSignin, base::TimeToValue(time));
- }
- base::Time KnownUser::GetLastOnlineSignin(const AccountId& account_id) {
- const base::Value* value = FindPath(account_id, kLastOnlineSignin);
- if (!value)
- return base::Time();
- absl::optional<base::Time> time = base::ValueToTime(value);
- if (!time)
- return base::Time();
- return *time;
- }
- void KnownUser::SetOfflineSigninLimit(
- const AccountId& account_id,
- absl::optional<base::TimeDelta> time_delta) {
- if (!time_delta) {
- SetPath(account_id, kOfflineSigninLimit, absl::nullopt);
- } else {
- SetPath(account_id, kOfflineSigninLimit,
- base::TimeDeltaToValue(time_delta.value()));
- }
- }
- absl::optional<base::TimeDelta> KnownUser::GetOfflineSigninLimit(
- const AccountId& account_id) {
- return base::ValueToTimeDelta(FindPath(account_id, kOfflineSigninLimit));
- }
- void KnownUser::SetIsEnterpriseManaged(const AccountId& account_id,
- bool is_enterprise_managed) {
- SetBooleanPref(account_id, kIsEnterpriseManaged, is_enterprise_managed);
- }
- bool KnownUser::GetIsEnterpriseManaged(const AccountId& account_id) {
- return FindBoolPath(account_id, kIsEnterpriseManaged).value_or(false);
- }
- void KnownUser::SetAccountManager(const AccountId& account_id,
- const std::string& manager) {
- SetStringPref(account_id, kAccountManager, manager);
- }
- const std::string* KnownUser::GetAccountManager(const AccountId& account_id) {
- return FindStringPath(account_id, kAccountManager);
- }
- void KnownUser::SetUserLastLoginInputMethodId(
- const AccountId& account_id,
- const std::string& input_method_id) {
- SetStringPref(account_id, kLastInputMethod, input_method_id);
- }
- const std::string* KnownUser::GetUserLastInputMethodId(
- const AccountId& account_id) {
- return FindStringPath(account_id, kLastInputMethod);
- }
- void KnownUser::SetUserPinLength(const AccountId& account_id, int pin_length) {
- SetIntegerPref(account_id, kPinAutosubmitLength, pin_length);
- }
- int KnownUser::GetUserPinLength(const AccountId& account_id) {
- return FindIntPath(account_id, kPinAutosubmitLength).value_or(0);
- }
- bool KnownUser::PinAutosubmitIsBackfillNeeded(const AccountId& account_id) {
- // If the pref is not set, the pref needs to be backfilled.
- return FindBoolPath(account_id, kPinAutosubmitBackfillNeeded).value_or(true);
- }
- void KnownUser::PinAutosubmitSetBackfillNotNeeded(const AccountId& account_id) {
- SetBooleanPref(account_id, kPinAutosubmitBackfillNeeded, false);
- }
- void KnownUser::PinAutosubmitSetBackfillNeededForTests(
- const AccountId& account_id) {
- SetBooleanPref(account_id, kPinAutosubmitBackfillNeeded, true);
- }
- void KnownUser::SetPasswordSyncToken(const AccountId& account_id,
- const std::string& token) {
- SetStringPref(account_id, kPasswordSyncToken, token);
- }
- const std::string* KnownUser::GetPasswordSyncToken(
- const AccountId& account_id) const {
- return FindStringPath(account_id, kPasswordSyncToken);
- }
- void KnownUser::SetOnboardingCompletedVersion(
- const AccountId& account_id,
- const absl::optional<base::Version> version) {
- if (!version) {
- SetPath(account_id, kOnboardingCompletedVersion, absl::nullopt);
- } else {
- SetStringPref(account_id, kOnboardingCompletedVersion,
- version.value().GetString());
- }
- }
- absl::optional<base::Version> KnownUser::GetOnboardingCompletedVersion(
- const AccountId& account_id) {
- const std::string* str_version =
- FindStringPath(account_id, kOnboardingCompletedVersion);
- if (!str_version)
- return absl::nullopt;
- base::Version version = base::Version(*str_version);
- if (!version.IsValid())
- return absl::nullopt;
- return version;
- }
- void KnownUser::RemoveOnboardingCompletedVersionForTests(
- const AccountId& account_id) {
- SetPath(account_id, kOnboardingCompletedVersion, absl::nullopt);
- }
- void KnownUser::SetPendingOnboardingScreen(const AccountId& account_id,
- const std::string& screen) {
- SetStringPref(account_id, kPendingOnboardingScreen, screen);
- }
- void KnownUser::RemovePendingOnboardingScreen(const AccountId& account_id) {
- SetPath(account_id, kPendingOnboardingScreen, absl::nullopt);
- }
- std::string KnownUser::GetPendingOnboardingScreen(const AccountId& account_id) {
- if (const std::string* screen =
- FindStringPath(account_id, kPendingOnboardingScreen)) {
- return *screen;
- }
- // Return empty string if no screen is pending.
- return std::string();
- }
- bool KnownUser::UserExists(const AccountId& account_id) {
- return FindPrefs(account_id);
- }
- void KnownUser::RemovePrefs(const AccountId& account_id) {
- if (!account_id.is_valid())
- return;
- ListPrefUpdate update(local_state_, kKnownUsers);
- base::Value::List& update_list = update->GetList();
- for (auto it = update_list.begin(); it != update_list.end(); ++it) {
- if (UserMatches(account_id, *it)) {
- update_list.erase(it);
- break;
- }
- }
- }
- void KnownUser::CleanEphemeralUsers() {
- ListPrefUpdate update(local_state_, kKnownUsers);
- update->GetList().EraseIf([](const auto& value) {
- if (!value.is_dict())
- return false;
- absl::optional<bool> is_ephemeral = value.FindBoolKey(kIsEphemeral);
- return is_ephemeral && *is_ephemeral;
- });
- }
- void KnownUser::CleanObsoletePrefs() {
- ListPrefUpdate update(local_state_, kKnownUsers);
- for (base::Value& user_entry : update.Get()->GetListDeprecated()) {
- if (!user_entry.is_dict())
- continue;
- for (const std::string& key : kObsoleteKeys)
- user_entry.RemoveKey(key);
- }
- }
- // static
- void KnownUser::RegisterPrefs(PrefRegistrySimple* registry) {
- registry->RegisterListPref(kKnownUsers);
- }
- // --- Legacy interface ---
- namespace known_user {
- AccountId GetAccountId(const std::string& user_email,
- const std::string& id,
- const AccountType& account_type) {
- DCHECK((id.empty() && account_type == AccountType::UNKNOWN) ||
- (!id.empty() && account_type != AccountType::UNKNOWN));
- PrefService* local_state = GetLocalStateLegacy();
- if (local_state) {
- return KnownUser(local_state).GetAccountId(user_email, id, account_type);
- }
- // The handling of the local-state-not-initialized case is pretty complex - it
- // is KnownUser::GetAccountId with all queries assuming to return false.
- // This should be come unnecessary when all callers are migrated to the
- // KnownUser class interface (https://crbug.com/1150434) and thus responsible
- // to pass a valid |local_state| pointer.
- // In tests empty accounts are possible.
- if (user_email.empty() && id.empty() &&
- account_type == AccountType::UNKNOWN) {
- return EmptyAccountId();
- }
- AccountId result(EmptyAccountId());
- // UserManager is usually NULL in unit tests.
- if (account_type == AccountType::UNKNOWN && UserManager::IsInitialized() &&
- UserManager::Get()->GetPlatformKnownUserId(user_email, id, &result)) {
- return result;
- }
- const std::string sanitized_email =
- user_email.empty()
- ? std::string()
- : gaia::CanonicalizeEmail(gaia::SanitizeEmail(user_email));
- std::string stored_email;
- switch (account_type) {
- case AccountType::GOOGLE:
- return AccountId::FromUserEmailGaiaId(sanitized_email, id);
- case AccountType::ACTIVE_DIRECTORY:
- return AccountId::AdFromUserEmailObjGuid(sanitized_email, id);
- case AccountType::UNKNOWN:
- return AccountId::FromUserEmail(sanitized_email);
- }
- NOTREACHED();
- return EmptyAccountId();
- }
- std::vector<AccountId> GetKnownAccountIds() {
- PrefService* local_state = GetLocalStateLegacy();
- // Local State may not be initialized in tests.
- if (!local_state)
- return {};
- return KnownUser(local_state).GetKnownAccountIds();
- }
- } // namespace known_user
- } // namespace user_manager
|