[go: nahoru, domu]

blob: d30953775aa0c661a03857c1f2270f2cf00273f6 [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/login_detection/login_detection_prefs.h"
#include "base/json/values_util.h"
#include "base/time/time.h"
#include "chrome/browser/login_detection/login_detection_util.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
namespace login_detection {
namespace {
// The pref name for storing the sites where the user has signed in via OAuth.
// The effective TLD+1 is used to key the dictionary pref, and the value is the
// latest time OAuth sign-in was detected for the site. The sign-in time value
// will be used to selectively clear this signed-in list, when browsing data is
// cleared for a selected time duration. This signed-in sites list is capped to
// an allowed maximum size, after which older sites based on sign-in time are
// removed.
// TODO(rajendrant): Record metrics for the number of sites in this pref.
const char kOAuthSignedInSitesPref[] =
"login_detection.oauth_signed_in_origins";
} // namespace
namespace prefs {
void RegisterProfilePrefs(PrefRegistrySimple* registry) {
registry->RegisterDictionaryPref(kOAuthSignedInSitesPref);
}
void RemoveLoginDetectionData(PrefService* prefs) {
prefs->ClearPref(kOAuthSignedInSitesPref);
}
void SaveSiteToOAuthSignedInList(PrefService* pref_service, const GURL& url) {
ScopedDictPrefUpdate update(pref_service, kOAuthSignedInSitesPref);
base::Value::Dict& dict = update.Get();
dict.Set(GetSiteNameForURL(url), base::TimeToValue(base::Time::Now()));
// Try making space by removing sites having invalid sign-in time. This should
// not happen unless the pref is corrupt somehow.
if (dict.size() > GetOauthLoggedInSitesMaxSize()) {
std::vector<std::string> invalid_sites;
for (auto site_entry : dict) {
if (!base::ValueToTime(site_entry.second))
invalid_sites.push_back(site_entry.first);
}
for (const auto& invalid_site : invalid_sites)
dict.Remove(invalid_site);
}
// Limit the dict to its allowed max size, by removing the site entries which
// are signed-in the earliest.
while (dict.size() > GetOauthLoggedInSitesMaxSize()) {
// Holds the pair of site name, its last login time for the site that was
// least recently signed-in to be removed.
absl::optional<std::pair<std::string, base::Time>> site_entry_to_remove;
for (auto site_entry : dict) {
base::Time signin_time = *base::ValueToTime(site_entry.second);
if (!site_entry_to_remove || signin_time < site_entry_to_remove->second) {
site_entry_to_remove = std::make_pair(site_entry.first, signin_time);
}
}
dict.Remove(site_entry_to_remove->first);
}
}
bool IsSiteInOAuthSignedInList(PrefService* pref_service, const GURL& url) {
return pref_service->GetDict(kOAuthSignedInSitesPref)
.contains(GetSiteNameForURL(url));
}
std::vector<url::Origin> GetOAuthSignedInSites(PrefService* pref_service) {
std::vector<url::Origin> sites;
for (const auto site_entry : pref_service->GetDict(kOAuthSignedInSitesPref)) {
sites.push_back(url::Origin::Create(GURL(site_entry.first)));
}
return sites;
}
} // namespace prefs
} // namespace login_detection