Commit 87303639 authored by manukh's avatar manukh Committed by Commit Bot

[omnibox] Expire search session token on cookie or cache deletion.

Moves session token management from the SearchProvider to
TemplateURLService.

Bug: 10664653
Change-Id: I48be94dbed74b7a3ca4e8c45a0d81687c2a2dea0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2519837Reviewed-by: default avatarChristian Dullweber <dullweber@chromium.org>
Reviewed-by: default avatarJustin Donnelly <jdonnelly@chromium.org>
Commit-Queue: manuk hovanesian <manukh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#825363}
parent 9d2e4b70
...@@ -3670,7 +3670,8 @@ TEST_F(SearchProviderTest, SuggestQueryUsesToken) { ...@@ -3670,7 +3670,8 @@ TEST_F(SearchProviderTest, SuggestQueryUsesToken) {
// And the URL matches what we expected. // And the URL matches what we expected.
TemplateURLRef::SearchTermsArgs search_terms_args(term); TemplateURLRef::SearchTermsArgs search_terms_args(term);
search_terms_args.session_token = provider_->current_token_; search_terms_args.session_token =
provider_->client()->GetTemplateURLService()->GetSessionToken();
std::string expected_url( std::string expected_url(
default_t_url_->suggestions_url_ref().ReplaceSearchTerms( default_t_url_->suggestions_url_ref().ReplaceSearchTerms(
search_terms_args, turl_model->search_terms_data())); search_terms_args, turl_model->search_terms_data()));
...@@ -3683,36 +3684,6 @@ TEST_F(SearchProviderTest, SuggestQueryUsesToken) { ...@@ -3683,36 +3684,6 @@ TEST_F(SearchProviderTest, SuggestQueryUsesToken) {
RunTillProviderDone(); RunTillProviderDone();
} }
TEST_F(SearchProviderTest, SessionToken) {
// Subsequent calls always get the same token.
std::string token = provider_->GetSessionToken();
std::string token2 = provider_->GetSessionToken();
EXPECT_EQ(token, token2);
EXPECT_FALSE(token.empty());
// Calls do not regenerate a token.
provider_->current_token_ = "PRE-EXISTING TOKEN";
token = provider_->GetSessionToken();
EXPECT_EQ(token, "PRE-EXISTING TOKEN");
// ... unless the token has expired.
provider_->current_token_.clear();
const base::TimeDelta kSmallDelta = base::TimeDelta::FromMilliseconds(1);
provider_->token_expiration_time_ = base::TimeTicks::Now() - kSmallDelta;
token = provider_->GetSessionToken();
EXPECT_FALSE(token.empty());
EXPECT_EQ(token, provider_->current_token_);
// The expiration time is always updated.
provider_->GetSessionToken();
base::TimeTicks expiration_time_1 = provider_->token_expiration_time_;
base::PlatformThread::Sleep(kSmallDelta);
provider_->GetSessionToken();
base::TimeTicks expiration_time_2 = provider_->token_expiration_time_;
EXPECT_GT(expiration_time_2, expiration_time_1);
EXPECT_GE(expiration_time_2, expiration_time_1 + kSmallDelta);
}
TEST_F(SearchProviderTest, AnswersCache) { TEST_F(SearchProviderTest, AnswersCache) {
AutocompleteResult result; AutocompleteResult result;
ACMatches matches; ACMatches matches;
......
...@@ -1104,13 +1104,13 @@ void ChromeBrowsingDataRemoverDelegate::RemoveEmbedderData( ...@@ -1104,13 +1104,13 @@ void ChromeBrowsingDataRemoverDelegate::RemoveEmbedderData(
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// Zero suggest and Search prefetch. // Zero suggest, Search prefetch, and search session token.
// Remove omnibox zero-suggest cache results and Search Prefetch cached // Remove omnibox zero-suggest cache results and Search Prefetch cached
// results, we only delete when the default search engine is in the filter. // results only when their respective URLs are in the filter.
if ((remove_mask & (content::BrowsingDataRemover::DATA_TYPE_CACHE | if ((remove_mask & (content::BrowsingDataRemover::DATA_TYPE_CACHE |
content::BrowsingDataRemover::DATA_TYPE_COOKIES))) { content::BrowsingDataRemover::DATA_TYPE_COOKIES))) {
// If there is no template service or DSE, clear the caches. // If there is no template service or DSE, clear the caches.
bool should_clear_zero_suggest = true; bool should_clear_zero_suggest_and_session_token = true;
bool should_clear_search_prefetch = true; bool should_clear_search_prefetch = true;
auto* template_url_service = auto* template_url_service =
...@@ -1122,7 +1122,7 @@ void ChromeBrowsingDataRemoverDelegate::RemoveEmbedderData( ...@@ -1122,7 +1122,7 @@ void ChromeBrowsingDataRemoverDelegate::RemoveEmbedderData(
// The suggest URL is used for zero suggest. // The suggest URL is used for zero suggest.
GURL suggest_url( GURL suggest_url(
template_url_service->GetDefaultSearchProvider()->suggestions_url()); template_url_service->GetDefaultSearchProvider()->suggestions_url());
should_clear_zero_suggest = should_clear_zero_suggest_and_session_token =
nullable_filter.is_null() || nullable_filter.Run(suggest_url); nullable_filter.is_null() || nullable_filter.Run(suggest_url);
// The search URL is used for search prefetch. // The search URL is used for search prefetch.
...@@ -1131,7 +1131,7 @@ void ChromeBrowsingDataRemoverDelegate::RemoveEmbedderData( ...@@ -1131,7 +1131,7 @@ void ChromeBrowsingDataRemoverDelegate::RemoveEmbedderData(
nullable_filter.is_null() || nullable_filter.Run(search_url); nullable_filter.is_null() || nullable_filter.Run(search_url);
} }
if (should_clear_zero_suggest) if (should_clear_zero_suggest_and_session_token)
prefs->SetString(omnibox::kZeroSuggestCachedResults, std::string()); prefs->SetString(omnibox::kZeroSuggestCachedResults, std::string());
// |search_prefetch_service| is null if |profile_| is off the record. // |search_prefetch_service| is null if |profile_| is off the record.
...@@ -1139,6 +1139,9 @@ void ChromeBrowsingDataRemoverDelegate::RemoveEmbedderData( ...@@ -1139,6 +1139,9 @@ void ChromeBrowsingDataRemoverDelegate::RemoveEmbedderData(
SearchPrefetchServiceFactory::GetForProfile(profile_); SearchPrefetchServiceFactory::GetForProfile(profile_);
if (should_clear_search_prefetch && search_prefetch_service) if (should_clear_search_prefetch && search_prefetch_service)
search_prefetch_service->ClearPrefetches(); search_prefetch_service->ClearPrefetches();
if (should_clear_zero_suggest_and_session_token && template_url_service)
template_url_service->ClearSessionToken();
} }
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
......
...@@ -900,7 +900,8 @@ std::unique_ptr<network::SimpleURLLoader> SearchProvider::CreateSuggestLoader( ...@@ -900,7 +900,8 @@ std::unique_ptr<network::SimpleURLLoader> SearchProvider::CreateSuggestLoader(
search_term_args.cursor_position = input.cursor_position(); search_term_args.cursor_position = input.cursor_position();
search_term_args.page_classification = input.current_page_classification(); search_term_args.page_classification = input.current_page_classification();
// Session token and prefetch data required for answers. // Session token and prefetch data required for answers.
search_term_args.session_token = GetSessionToken(); search_term_args.session_token =
client()->GetTemplateURLService()->GetSessionToken();
if (!prefetch_data_.full_query_text.empty()) { if (!prefetch_data_.full_query_text.empty()) {
search_term_args.prefetch_query = search_term_args.prefetch_query =
base::UTF16ToUTF8(prefetch_data_.full_query_text); base::UTF16ToUTF8(prefetch_data_.full_query_text);
...@@ -931,14 +932,13 @@ std::unique_ptr<network::SimpleURLLoader> SearchProvider::CreateSuggestLoader( ...@@ -931,14 +932,13 @@ std::unique_ptr<network::SimpleURLLoader> SearchProvider::CreateSuggestLoader(
return nullptr; return nullptr;
// Send the current page URL if user setting and URL requirements are met. // Send the current page URL if user setting and URL requirements are met.
TemplateURLService* template_url_service = client()->GetTemplateURLService();
if (CanSendURL(input.current_url(), suggest_url, template_url, if (CanSendURL(input.current_url(), suggest_url, template_url,
input.current_page_classification(), input.current_page_classification(), search_terms_data,
template_url_service->search_terms_data(), client(), true)) { client(), true)) {
search_term_args.current_page_url = input.current_url().spec(); search_term_args.current_page_url = input.current_url().spec();
// Create the suggest URL again with the current page URL. // Create the suggest URL again with the current page URL.
suggest_url = GURL(template_url->suggestions_url_ref().ReplaceSearchTerms( suggest_url = GURL(template_url->suggestions_url_ref().ReplaceSearchTerms(
search_term_args, template_url_service->search_terms_data())); search_term_args, search_terms_data));
} }
LogOmniboxSuggestRequest(REQUEST_SENT); LogOmniboxSuggestRequest(REQUEST_SENT);
...@@ -1556,26 +1556,6 @@ void SearchProvider::UpdateDone() { ...@@ -1556,26 +1556,6 @@ void SearchProvider::UpdateDone() {
done_ = !timer_.IsRunning() && !default_loader_ && !keyword_loader_; done_ = !timer_.IsRunning() && !default_loader_ && !keyword_loader_;
} }
std::string SearchProvider::GetSessionToken() {
base::TimeTicks current_time(base::TimeTicks::Now());
// Renew token if it expired.
if (current_time > token_expiration_time_) {
const size_t kTokenBytes = 12;
std::string raw_data;
base::RandBytes(base::WriteInto(&raw_data, kTokenBytes + 1), kTokenBytes);
base::Base64Encode(raw_data, &current_token_);
// Make the base64 encoded value URL and filename safe(see RFC 3548).
std::replace(current_token_.begin(), current_token_.end(), '+', '-');
std::replace(current_token_.begin(), current_token_.end(), '/', '_');
}
// Extend expiration time another 60 seconds.
token_expiration_time_ = current_time + base::TimeDelta::FromSeconds(60);
return current_token_;
}
AnswersQueryData SearchProvider::FindAnswersPrefetchData() { AnswersQueryData SearchProvider::FindAnswersPrefetchData() {
// Retrieve the top entry from scored history results. // Retrieve the top entry from scored history results.
MatchMap map; MatchMap map;
......
...@@ -99,7 +99,6 @@ class SearchProvider : public BaseSearchProvider, ...@@ -99,7 +99,6 @@ class SearchProvider : public BaseSearchProvider,
FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, SuggestRelevanceExperiment); FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, SuggestRelevanceExperiment);
FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, TestDeleteMatch); FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, TestDeleteMatch);
FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, SuggestQueryUsesToken); FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, SuggestQueryUsesToken);
FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, SessionToken);
FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, AnswersCache); FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, AnswersCache);
FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, RemoveExtraAnswers); FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, RemoveExtraAnswers);
FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, DoesNotProvideOnFocus); FRIEND_TEST_ALL_PREFIXES(SearchProviderTest, DoesNotProvideOnFocus);
...@@ -374,9 +373,6 @@ class SearchProvider : public BaseSearchProvider, ...@@ -374,9 +373,6 @@ class SearchProvider : public BaseSearchProvider,
// Updates the value of |done_| from the internal state. // Updates the value of |done_| from the internal state.
void UpdateDone(); void UpdateDone();
// Obtains a session token, regenerating if necessary.
std::string GetSessionToken();
// Answers prefetch handling - finds the previously displayed answer matching // Answers prefetch handling - finds the previously displayed answer matching
// the current top-scoring history result. If there is a previous answer, // the current top-scoring history result. If there is a previous answer,
// returns the query data associated with it. Otherwise, returns an empty // returns the query data associated with it. Otherwise, returns an empty
...@@ -428,10 +424,6 @@ class SearchProvider : public BaseSearchProvider, ...@@ -428,10 +424,6 @@ class SearchProvider : public BaseSearchProvider,
// The top navigation suggestion, left blank/invalid if none. // The top navigation suggestion, left blank/invalid if none.
GURL top_navigation_suggestion_; GURL top_navigation_suggestion_;
// Session token management.
std::string current_token_;
base::TimeTicks token_expiration_time_;
// Answers prefetch management. // Answers prefetch management.
AnswersCache answers_cache_; // Cache for last answers seen. AnswersCache answers_cache_; // Cache for last answers seen.
AnswersQueryData prefetch_data_; // Data to use for query prefetching. AnswersQueryData prefetch_data_; // Data to use for query prefetching.
......
...@@ -152,6 +152,7 @@ source_set("unit_tests") { ...@@ -152,6 +152,7 @@ source_set("unit_tests") {
"search_host_to_urls_map_unittest.cc", "search_host_to_urls_map_unittest.cc",
"template_url_data_unittest.cc", "template_url_data_unittest.cc",
"template_url_prepopulate_data_unittest.cc", "template_url_prepopulate_data_unittest.cc",
"template_url_service_unittest.cc",
"template_url_service_util_unittest.cc", "template_url_service_util_unittest.cc",
"template_url_unittest.cc", "template_url_unittest.cc",
] ]
......
...@@ -7,11 +7,14 @@ ...@@ -7,11 +7,14 @@
#include <algorithm> #include <algorithm>
#include "base/auto_reset.h" #include "base/auto_reset.h"
#include "base/base64.h"
#include "base/base64url.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/callback.h" #include "base/callback.h"
#include "base/debug/crash_logging.h" #include "base/debug/crash_logging.h"
#include "base/format_macros.h" #include "base/format_macros.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/rand_util.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/strings/string_split.h" #include "base/strings/string_split.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
...@@ -1260,6 +1263,27 @@ void TemplateURLService::ProcessTemplateURLChange( ...@@ -1260,6 +1263,27 @@ void TemplateURLService::ProcessTemplateURLChange(
sync_processor_->ProcessSyncChanges(FROM_HERE, changes); sync_processor_->ProcessSyncChanges(FROM_HERE, changes);
} }
std::string TemplateURLService::GetSessionToken() {
base::TimeTicks current_time(base::TimeTicks::Now());
// Renew token if it expired.
if (current_time > token_expiration_time_) {
const size_t kTokenBytes = 12;
std::string raw_data;
base::RandBytes(base::WriteInto(&raw_data, kTokenBytes + 1), kTokenBytes);
base::Base64UrlEncode(raw_data,
base::Base64UrlEncodePolicy::INCLUDE_PADDING,
&current_token_);
}
// Extend expiration time another 60 seconds.
token_expiration_time_ = current_time + base::TimeDelta::FromSeconds(60);
return current_token_;
}
void TemplateURLService::ClearSessionToken() {
token_expiration_time_ = base::TimeTicks();
}
// static // static
syncer::SyncData TemplateURLService::CreateSyncDataFromTemplateURL( syncer::SyncData TemplateURLService::CreateSyncDataFromTemplateURL(
const TemplateURL& turl) { const TemplateURL& turl) {
......
...@@ -400,6 +400,13 @@ class TemplateURLService : public WebDataServiceConsumer, ...@@ -400,6 +400,13 @@ class TemplateURLService : public WebDataServiceConsumer,
return *search_terms_data_; return *search_terms_data_;
} }
// Obtains a session token, regenerating if necessary.
std::string GetSessionToken();
// Clears the session token. Should be called when the user clears browsing
// data.
void ClearSessionToken();
// Returns a SyncData with a sync representation of the search engine data // Returns a SyncData with a sync representation of the search engine data
// from |turl|. // from |turl|.
static syncer::SyncData CreateSyncDataFromTemplateURL( static syncer::SyncData CreateSyncDataFromTemplateURL(
...@@ -455,6 +462,7 @@ class TemplateURLService : public WebDataServiceConsumer, ...@@ -455,6 +462,7 @@ class TemplateURLService : public WebDataServiceConsumer,
FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, PreSyncDeletes); FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, PreSyncDeletes);
FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, MergeInSyncTemplateURL); FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceSyncTest, MergeInSyncTemplateURL);
FRIEND_TEST_ALL_PREFIXES(LocationBarModelTest, GoogleBaseURL); FRIEND_TEST_ALL_PREFIXES(LocationBarModelTest, GoogleBaseURL);
FRIEND_TEST_ALL_PREFIXES(TemplateURLServiceUnitTest, SessionToken);
friend class InstantUnitTestBase; friend class InstantUnitTestBase;
friend class Scoper; friend class Scoper;
...@@ -847,6 +855,10 @@ class TemplateURLService : public WebDataServiceConsumer, ...@@ -847,6 +855,10 @@ class TemplateURLService : public WebDataServiceConsumer,
// but if no model mutation occurs, the deferred notification can be skipped. // but if no model mutation occurs, the deferred notification can be skipped.
bool model_mutated_notification_pending_ = false; bool model_mutated_notification_pending_ = false;
// Session token management.
std::string current_token_;
base::TimeTicks token_expiration_time_;
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
// Manage and fetch the java object that wraps this TemplateURLService on // Manage and fetch the java object that wraps this TemplateURLService on
// android. // android.
......
// 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.
#include <stddef.h>
#include <memory>
#include "components/search_engines/template_url_service.h"
#include "testing/gtest/include/gtest/gtest.h"
class TemplateURLServiceUnitTest : public testing::Test {
public:
TemplateURLServiceUnitTest()
: template_url_service_(/*initializers=*/nullptr, /*count=*/0) {}
TemplateURLService& template_url_service() { return template_url_service_; }
private:
TemplateURLService template_url_service_;
};
TEST_F(TemplateURLServiceUnitTest, SessionToken) {
// Subsequent calls always get the same token.
std::string token = template_url_service().GetSessionToken();
std::string token2 = template_url_service().GetSessionToken();
EXPECT_EQ(token, token2);
EXPECT_FALSE(token.empty());
// Calls do not regenerate a token.
template_url_service().current_token_ = "PRE-EXISTING TOKEN";
token = template_url_service().GetSessionToken();
EXPECT_EQ(token, "PRE-EXISTING TOKEN");
// ... unless the token has expired.
template_url_service().current_token_.clear();
const base::TimeDelta kSmallDelta = base::TimeDelta::FromMilliseconds(1);
template_url_service().token_expiration_time_ =
base::TimeTicks::Now() - kSmallDelta;
token = template_url_service().GetSessionToken();
EXPECT_FALSE(token.empty());
EXPECT_EQ(token, template_url_service().current_token_);
// ... or cleared.
template_url_service().current_token_.clear();
template_url_service().ClearSessionToken();
token = template_url_service().GetSessionToken();
EXPECT_FALSE(token.empty());
EXPECT_EQ(token, template_url_service().current_token_);
// The expiration time is always updated.
template_url_service().GetSessionToken();
base::TimeTicks expiration_time_1 =
template_url_service().token_expiration_time_;
base::PlatformThread::Sleep(kSmallDelta);
template_url_service().GetSessionToken();
base::TimeTicks expiration_time_2 =
template_url_service().token_expiration_time_;
EXPECT_GT(expiration_time_2, expiration_time_1);
EXPECT_GE(expiration_time_2, expiration_time_1 + kSmallDelta);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment