| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/history/core/browser/web_history_service.h" | 5 #include "chrome/browser/history/web_history_service.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/json/json_reader.h" | 8 #include "base/json/json_reader.h" |
| 9 #include "base/json/json_writer.h" | 9 #include "base/json/json_writer.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| 11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
| 12 #include "base/strings/string_number_conversions.h" | 12 #include "base/strings/string_number_conversions.h" |
| 13 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
| 14 #include "base/values.h" | 14 #include "base/values.h" |
| 15 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" |
| 16 #include "chrome/browser/signin/signin_manager_factory.h" |
| 17 #include "components/signin/core/browser/profile_oauth2_token_service.h" |
| 15 #include "components/signin/core/browser/signin_manager.h" | 18 #include "components/signin/core/browser/signin_manager.h" |
| 16 #include "google_apis/gaia/gaia_urls.h" | 19 #include "google_apis/gaia/gaia_urls.h" |
| 17 #include "google_apis/gaia/google_service_auth_error.h" | 20 #include "google_apis/gaia/google_service_auth_error.h" |
| 18 #include "google_apis/gaia/oauth2_token_service.h" | 21 #include "google_apis/gaia/oauth2_token_service.h" |
| 19 #include "net/base/load_flags.h" | 22 #include "net/base/load_flags.h" |
| 20 #include "net/base/url_util.h" | 23 #include "net/base/url_util.h" |
| 21 #include "net/http/http_status_code.h" | 24 #include "net/http/http_status_code.h" |
| 22 #include "net/http/http_util.h" | 25 #include "net/http/http_util.h" |
| 23 #include "net/url_request/url_fetcher.h" | 26 #include "net/url_request/url_fetcher.h" |
| 24 #include "net/url_request/url_fetcher_delegate.h" | 27 #include "net/url_request/url_fetcher_delegate.h" |
| 25 #include "net/url_request/url_request_context_getter.h" | |
| 26 #include "url/gurl.h" | 28 #include "url/gurl.h" |
| 27 | 29 |
| 28 namespace history { | 30 namespace history { |
| 29 | 31 |
| 30 namespace { | 32 namespace { |
| 31 | 33 |
| 32 const char kHistoryOAuthScope[] = | 34 const char kHistoryOAuthScope[] = |
| 33 "https://www.googleapis.com/auth/chromesync"; | 35 "https://www.googleapis.com/auth/chromesync"; |
| 34 | 36 |
| 35 const char kHistoryQueryHistoryUrl[] = | 37 const char kHistoryQueryHistoryUrl[] = |
| (...skipping 24 matching lines...) Expand all Loading... |
| 60 int GetResponseCode() override { return response_code_; } | 62 int GetResponseCode() override { return response_code_; } |
| 61 | 63 |
| 62 // Returns the contents of the response body received from the server. | 64 // Returns the contents of the response body received from the server. |
| 63 const std::string& GetResponseBody() override { return response_body_; } | 65 const std::string& GetResponseBody() override { return response_body_; } |
| 64 | 66 |
| 65 bool IsPending() override { return is_pending_; } | 67 bool IsPending() override { return is_pending_; } |
| 66 | 68 |
| 67 private: | 69 private: |
| 68 friend class history::WebHistoryService; | 70 friend class history::WebHistoryService; |
| 69 | 71 |
| 70 RequestImpl( | 72 RequestImpl(Profile* profile, |
| 71 OAuth2TokenService* token_service, | 73 const GURL& url, |
| 72 SigninManagerBase* signin_manager, | 74 const WebHistoryService::CompletionCallback& callback) |
| 73 const scoped_refptr<net::URLRequestContextGetter>& request_context, | |
| 74 const GURL& url, | |
| 75 const WebHistoryService::CompletionCallback& callback) | |
| 76 : OAuth2TokenService::Consumer("web_history"), | 75 : OAuth2TokenService::Consumer("web_history"), |
| 77 token_service_(token_service), | 76 profile_(profile), |
| 78 signin_manager_(signin_manager), | |
| 79 url_(url), | 77 url_(url), |
| 80 response_code_(0), | 78 response_code_(0), |
| 81 auth_retry_count_(0), | 79 auth_retry_count_(0), |
| 82 callback_(callback), | 80 callback_(callback), |
| 83 is_pending_(false) {} | 81 is_pending_(false) { |
| 82 } |
| 84 | 83 |
| 85 // Tells the request to do its thang. | 84 // Tells the request to do its thang. |
| 86 void Start() override { | 85 void Start() override { |
| 87 OAuth2TokenService::ScopeSet oauth_scopes; | 86 OAuth2TokenService::ScopeSet oauth_scopes; |
| 88 oauth_scopes.insert(kHistoryOAuthScope); | 87 oauth_scopes.insert(kHistoryOAuthScope); |
| 89 | 88 |
| 90 token_request_ = token_service_->StartRequest( | 89 ProfileOAuth2TokenService* token_service = |
| 91 signin_manager_->GetAuthenticatedAccountId(), oauth_scopes, this); | 90 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); |
| 91 SigninManagerBase* signin_manager = |
| 92 SigninManagerFactory::GetForProfile(profile_); |
| 93 token_request_ = token_service->StartRequest( |
| 94 signin_manager->GetAuthenticatedAccountId(), oauth_scopes, this); |
| 92 is_pending_ = true; | 95 is_pending_ = true; |
| 93 } | 96 } |
| 94 | 97 |
| 95 // content::URLFetcherDelegate interface. | 98 // content::URLFetcherDelegate interface. |
| 96 void OnURLFetchComplete(const net::URLFetcher* source) override { | 99 void OnURLFetchComplete(const net::URLFetcher* source) override { |
| 97 DCHECK_EQ(source, url_fetcher_.get()); | 100 DCHECK_EQ(source, url_fetcher_.get()); |
| 98 response_code_ = url_fetcher_->GetResponseCode(); | 101 response_code_ = url_fetcher_->GetResponseCode(); |
| 99 | 102 |
| 100 UMA_HISTOGRAM_CUSTOM_ENUMERATION("WebHistory.OAuthTokenResponseCode", | 103 UMA_HISTOGRAM_CUSTOM_ENUMERATION("WebHistory.OAuthTokenResponseCode", |
| 101 net::HttpUtil::MapStatusCodeForHistogram(response_code_), | 104 net::HttpUtil::MapStatusCodeForHistogram(response_code_), |
| 102 net::HttpUtil::GetStatusCodesForHistogram()); | 105 net::HttpUtil::GetStatusCodesForHistogram()); |
| 103 | 106 |
| 104 // If the response code indicates that the token might not be valid, | 107 // If the response code indicates that the token might not be valid, |
| 105 // invalidate the token and try again. | 108 // invalidate the token and try again. |
| 106 if (response_code_ == net::HTTP_UNAUTHORIZED && ++auth_retry_count_ <= 1) { | 109 if (response_code_ == net::HTTP_UNAUTHORIZED && ++auth_retry_count_ <= 1) { |
| 107 OAuth2TokenService::ScopeSet oauth_scopes; | 110 OAuth2TokenService::ScopeSet oauth_scopes; |
| 108 oauth_scopes.insert(kHistoryOAuthScope); | 111 oauth_scopes.insert(kHistoryOAuthScope); |
| 109 token_service_->InvalidateToken( | 112 ProfileOAuth2TokenService* token_service = |
| 110 signin_manager_->GetAuthenticatedAccountId(), | 113 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); |
| 114 SigninManagerBase* signin_manager = |
| 115 SigninManagerFactory::GetForProfile(profile_); |
| 116 token_service->InvalidateToken( |
| 117 signin_manager->GetAuthenticatedAccountId(), |
| 111 oauth_scopes, | 118 oauth_scopes, |
| 112 access_token_); | 119 access_token_); |
| 113 | 120 |
| 114 access_token_.clear(); | 121 access_token_.clear(); |
| 115 Start(); | 122 Start(); |
| 116 return; | 123 return; |
| 117 } | 124 } |
| 118 url_fetcher_->GetResponseAsString(&response_body_); | 125 url_fetcher_->GetResponseAsString(&response_body_); |
| 119 url_fetcher_.reset(); | 126 url_fetcher_.reset(); |
| 120 is_pending_ = false; | 127 is_pending_ = false; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 149 // It is valid for the callback to delete |this|, so do not access any | 156 // It is valid for the callback to delete |this|, so do not access any |
| 150 // members below here. | 157 // members below here. |
| 151 } | 158 } |
| 152 | 159 |
| 153 // Helper for creating a new URLFetcher for the API request. | 160 // Helper for creating a new URLFetcher for the API request. |
| 154 net::URLFetcher* CreateUrlFetcher(const std::string& access_token) { | 161 net::URLFetcher* CreateUrlFetcher(const std::string& access_token) { |
| 155 net::URLFetcher::RequestType request_type = post_data_.empty() ? | 162 net::URLFetcher::RequestType request_type = post_data_.empty() ? |
| 156 net::URLFetcher::GET : net::URLFetcher::POST; | 163 net::URLFetcher::GET : net::URLFetcher::POST; |
| 157 net::URLFetcher* fetcher = net::URLFetcher::Create( | 164 net::URLFetcher* fetcher = net::URLFetcher::Create( |
| 158 url_, request_type, this); | 165 url_, request_type, this); |
| 159 fetcher->SetRequestContext(request_context_.get()); | 166 fetcher->SetRequestContext(profile_->GetRequestContext()); |
| 160 fetcher->SetMaxRetriesOn5xx(kMaxRetries); | 167 fetcher->SetMaxRetriesOn5xx(kMaxRetries); |
| 161 fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | | 168 fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | |
| 162 net::LOAD_DO_NOT_SAVE_COOKIES); | 169 net::LOAD_DO_NOT_SAVE_COOKIES); |
| 163 fetcher->AddExtraRequestHeader("Authorization: Bearer " + access_token); | 170 fetcher->AddExtraRequestHeader("Authorization: Bearer " + access_token); |
| 164 fetcher->AddExtraRequestHeader("X-Developer-Key: " + | 171 fetcher->AddExtraRequestHeader("X-Developer-Key: " + |
| 165 GaiaUrls::GetInstance()->oauth2_chrome_client_id()); | 172 GaiaUrls::GetInstance()->oauth2_chrome_client_id()); |
| 166 if (request_type == net::URLFetcher::POST) | 173 if (request_type == net::URLFetcher::POST) |
| 167 fetcher->SetUploadData(kPostDataMimeType, post_data_); | 174 fetcher->SetUploadData(kPostDataMimeType, post_data_); |
| 168 return fetcher; | 175 return fetcher; |
| 169 } | 176 } |
| 170 | 177 |
| 171 void SetPostData(const std::string& post_data) override { | 178 void SetPostData(const std::string& post_data) override { |
| 172 post_data_ = post_data; | 179 post_data_ = post_data; |
| 173 } | 180 } |
| 174 | 181 |
| 175 OAuth2TokenService* token_service_; | 182 Profile* profile_; |
| 176 SigninManagerBase* signin_manager_; | |
| 177 scoped_refptr<net::URLRequestContextGetter> request_context_; | |
| 178 | 183 |
| 179 // The URL of the API endpoint. | 184 // The URL of the API endpoint. |
| 180 GURL url_; | 185 GURL url_; |
| 181 | 186 |
| 182 // POST data to be sent with the request (may be empty). | 187 // POST data to be sent with the request (may be empty). |
| 183 std::string post_data_; | 188 std::string post_data_; |
| 184 | 189 |
| 185 // The OAuth2 access token request. | 190 // The OAuth2 access token request. |
| 186 scoped_ptr<OAuth2TokenService::Request> token_request_; | 191 scoped_ptr<OAuth2TokenService::Request> token_request_; |
| 187 | 192 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 } | 278 } |
| 274 | 279 |
| 275 } // namespace | 280 } // namespace |
| 276 | 281 |
| 277 WebHistoryService::Request::Request() { | 282 WebHistoryService::Request::Request() { |
| 278 } | 283 } |
| 279 | 284 |
| 280 WebHistoryService::Request::~Request() { | 285 WebHistoryService::Request::~Request() { |
| 281 } | 286 } |
| 282 | 287 |
| 283 WebHistoryService::WebHistoryService( | 288 WebHistoryService::WebHistoryService(Profile* profile) |
| 284 OAuth2TokenService* token_service, | 289 : profile_(profile), |
| 285 SigninManagerBase* signin_manager, | |
| 286 const scoped_refptr<net::URLRequestContextGetter>& request_context) | |
| 287 : token_service_(token_service), | |
| 288 signin_manager_(signin_manager), | |
| 289 request_context_(request_context), | |
| 290 weak_ptr_factory_(this) { | 290 weak_ptr_factory_(this) { |
| 291 } | 291 } |
| 292 | 292 |
| 293 WebHistoryService::~WebHistoryService() { | 293 WebHistoryService::~WebHistoryService() { |
| 294 STLDeleteElements(&pending_expire_requests_); | 294 STLDeleteElements(&pending_expire_requests_); |
| 295 STLDeleteElements(&pending_audio_history_requests_); | 295 STLDeleteElements(&pending_audio_history_requests_); |
| 296 } | 296 } |
| 297 | 297 |
| 298 WebHistoryService::Request* WebHistoryService::CreateRequest( | 298 WebHistoryService::Request* WebHistoryService::CreateRequest( |
| 299 const GURL& url, | 299 const GURL& url, |
| 300 const CompletionCallback& callback) { | 300 const CompletionCallback& callback) { |
| 301 return new RequestImpl(token_service_, signin_manager_, request_context_, url, | 301 return new RequestImpl(profile_, url, callback); |
| 302 callback); | |
| 303 } | 302 } |
| 304 | 303 |
| 305 // static | 304 // static |
| 306 scoped_ptr<base::DictionaryValue> WebHistoryService::ReadResponse( | 305 scoped_ptr<base::DictionaryValue> WebHistoryService::ReadResponse( |
| 307 WebHistoryService::Request* request) { | 306 WebHistoryService::Request* request) { |
| 308 scoped_ptr<base::DictionaryValue> result; | 307 scoped_ptr<base::DictionaryValue> result; |
| 309 if (request->GetResponseCode() == net::HTTP_OK) { | 308 if (request->GetResponseCode() == net::HTTP_OK) { |
| 310 base::Value* value = base::JSONReader::Read(request->GetResponseBody()); | 309 base::Value* value = base::JSONReader::Read(request->GetResponseBody()); |
| 311 if (value && value->IsType(base::Value::TYPE_DICTIONARY)) | 310 if (value && value->IsType(base::Value::TYPE_DICTIONARY)) |
| 312 result.reset(static_cast<base::DictionaryValue*>(value)); | 311 result.reset(static_cast<base::DictionaryValue*>(value)); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 330 return request.Pass(); | 329 return request.Pass(); |
| 331 } | 330 } |
| 332 | 331 |
| 333 void WebHistoryService::ExpireHistory( | 332 void WebHistoryService::ExpireHistory( |
| 334 const std::vector<ExpireHistoryArgs>& expire_list, | 333 const std::vector<ExpireHistoryArgs>& expire_list, |
| 335 const ExpireWebHistoryCallback& callback) { | 334 const ExpireWebHistoryCallback& callback) { |
| 336 base::DictionaryValue delete_request; | 335 base::DictionaryValue delete_request; |
| 337 scoped_ptr<base::ListValue> deletions(new base::ListValue); | 336 scoped_ptr<base::ListValue> deletions(new base::ListValue); |
| 338 base::Time now = base::Time::Now(); | 337 base::Time now = base::Time::Now(); |
| 339 | 338 |
| 340 for (const auto& expire : expire_list) { | 339 for (std::vector<ExpireHistoryArgs>::const_iterator it = expire_list.begin(); |
| 340 it != expire_list.end(); ++it) { |
| 341 // Convert the times to server timestamps. | 341 // Convert the times to server timestamps. |
| 342 std::string min_timestamp = ServerTimeString(expire.begin_time); | 342 std::string min_timestamp = ServerTimeString(it->begin_time); |
| 343 // TODO(dubroy): Use sane time (crbug.com/146090) here when it's available. | 343 // TODO(dubroy): Use sane time (crbug.com/146090) here when it's available. |
| 344 base::Time end_time = expire.end_time; | 344 base::Time end_time = it->end_time; |
| 345 if (end_time.is_null() || end_time > now) | 345 if (end_time.is_null() || end_time > now) |
| 346 end_time = now; | 346 end_time = now; |
| 347 std::string max_timestamp = ServerTimeString(end_time); | 347 std::string max_timestamp = ServerTimeString(end_time); |
| 348 | 348 |
| 349 for (const auto& url : expire.urls) { | 349 for (std::set<GURL>::const_iterator url_iterator = it->urls.begin(); |
| 350 url_iterator != it->urls.end(); ++url_iterator) { |
| 350 deletions->Append( | 351 deletions->Append( |
| 351 CreateDeletion(min_timestamp, max_timestamp, url)); | 352 CreateDeletion(min_timestamp, max_timestamp, *url_iterator)); |
| 352 } | 353 } |
| 353 // If no URLs were specified, delete everything in the time range. | 354 // If no URLs were specified, delete everything in the time range. |
| 354 if (expire.urls.empty()) | 355 if (it->urls.empty()) |
| 355 deletions->Append(CreateDeletion(min_timestamp, max_timestamp, GURL())); | 356 deletions->Append(CreateDeletion(min_timestamp, max_timestamp, GURL())); |
| 356 } | 357 } |
| 357 delete_request.Set("del", deletions.release()); | 358 delete_request.Set("del", deletions.release()); |
| 358 std::string post_data; | 359 std::string post_data; |
| 359 base::JSONWriter::Write(&delete_request, &post_data); | 360 base::JSONWriter::Write(&delete_request, &post_data); |
| 360 | 361 |
| 361 GURL url(kHistoryDeleteHistoryUrl); | 362 GURL url(kHistoryDeleteHistoryUrl); |
| 362 | 363 |
| 363 // Append the version info token, if it is available, to help ensure | 364 // Append the version info token, if it is available, to help ensure |
| 364 // consistency with any previous deletions. | 365 // consistency with any previous deletions. |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 bool enabled_value = false; | 470 bool enabled_value = false; |
| 470 if (success) { | 471 if (success) { |
| 471 response_value = ReadResponse(request_ptr.get()); | 472 response_value = ReadResponse(request_ptr.get()); |
| 472 if (response_value) | 473 if (response_value) |
| 473 response_value->GetBoolean("history_recording_enabled", &enabled_value); | 474 response_value->GetBoolean("history_recording_enabled", &enabled_value); |
| 474 } | 475 } |
| 475 callback.Run(success, enabled_value); | 476 callback.Run(success, enabled_value); |
| 476 } | 477 } |
| 477 | 478 |
| 478 } // namespace history | 479 } // namespace history |
| OLD | NEW |