// Copyright 2013 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 "base/json/json_reader.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" #include "base/values.h" #include "chrome/browser/local_discovery/cloud_print_base_api_flow.h" #include "chrome/common/cloud_print/cloud_print_constants.h" #include "google_apis/gaia/google_service_auth_error.h" #include "net/base/load_flags.h" #include "net/base/url_util.h" #include "net/http/http_status_code.h" #include "net/url_request/url_request_status.h" namespace local_discovery { namespace { const char kCloudPrintOAuthHeaderFormat[] = "Authorization: Bearer %s"; const char kXSRFURLParameterKey[] = "xsrf"; const char kUserURLParameterKey[] = "user"; } CloudPrintBaseApiFlow::CloudPrintBaseApiFlow( net::URLRequestContextGetter* request_context, OAuth2TokenService* token_service, const std::string& account_id, const GURL& automated_claim_url, Delegate* delegate) : request_context_(request_context), token_service_(token_service), account_id_(account_id), user_index_(kAccountIndexUseOAuth2), url_(automated_claim_url), delegate_(delegate) { } CloudPrintBaseApiFlow::CloudPrintBaseApiFlow( net::URLRequestContextGetter* request_context, int user_index, const std::string& xsrf_token, const GURL& automated_claim_url, Delegate* delegate) : request_context_(request_context), token_service_(NULL), account_id_(""), user_index_(user_index), xsrf_token_(xsrf_token), url_(automated_claim_url), delegate_(delegate) { } CloudPrintBaseApiFlow::CloudPrintBaseApiFlow( net::URLRequestContextGetter* request_context, int user_index, const GURL& automated_claim_url, Delegate* delegate) : request_context_(request_context), token_service_(NULL), account_id_(""), user_index_(user_index), url_(automated_claim_url), delegate_(delegate) { } CloudPrintBaseApiFlow::~CloudPrintBaseApiFlow() { } void CloudPrintBaseApiFlow::Start() { if (UseOAuth2()) { OAuth2TokenService::ScopeSet oauth_scopes; oauth_scopes.insert(cloud_print::kCloudPrintAuth); oauth_request_ = token_service_->StartRequest(account_id_, oauth_scopes, this); } else { GURL cookie_url = url_; if (!xsrf_token_.empty()) { cookie_url = net::AppendQueryParameter(cookie_url, kXSRFURLParameterKey, xsrf_token_); } cookie_url = net::AppendQueryParameter(cookie_url, kUserURLParameterKey, base::IntToString(user_index_)); CreateRequest(cookie_url); url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES); url_fetcher_->Start(); } } void CloudPrintBaseApiFlow::OnGetTokenSuccess( const OAuth2TokenService::Request* request, const std::string& access_token, const base::Time& expiration_time) { CreateRequest(url_); std::string authorization_header = base::StringPrintf(kCloudPrintOAuthHeaderFormat, access_token.c_str()); url_fetcher_->AddExtraRequestHeader(authorization_header); url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_COOKIES); url_fetcher_->Start(); } void CloudPrintBaseApiFlow::OnGetTokenFailure( const OAuth2TokenService::Request* request, const GoogleServiceAuthError& error) { delegate_->OnCloudPrintAPIFlowError(this, ERROR_TOKEN); } void CloudPrintBaseApiFlow::CreateRequest(const GURL& url) { url_fetcher_.reset(net::URLFetcher::Create(url, net::URLFetcher::GET, this)); url_fetcher_->SetRequestContext(request_context_.get()); url_fetcher_->AddExtraRequestHeader( cloud_print::kChromeCloudPrintProxyHeader); } void CloudPrintBaseApiFlow::OnURLFetchComplete( const net::URLFetcher* source) { // TODO(noamsml): Error logging. // TODO(noamsml): Extract this and PrivetURLFetcher::OnURLFetchComplete into // one helper method. std::string response_str; if (source->GetStatus().status() != net::URLRequestStatus::SUCCESS || !source->GetResponseAsString(&response_str)) { delegate_->OnCloudPrintAPIFlowError(this, ERROR_NETWORK); return; } if (source->GetResponseCode() != net::HTTP_OK) { delegate_->OnCloudPrintAPIFlowError(this, ERROR_HTTP_CODE); return; } base::JSONReader reader; scoped_ptr value(reader.Read(response_str)); const base::DictionaryValue* dictionary_value = NULL; if (!value || !value->GetAsDictionary(&dictionary_value)) { delegate_->OnCloudPrintAPIFlowError(this, ERROR_MALFORMED_RESPONSE); return; } delegate_->OnCloudPrintAPIFlowComplete(this, dictionary_value); } } // namespace local_discovery