blob: 9a15917551c0138710ea12d328d2d3b986ca5eef [file] [log] [blame]
// 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<const base::Value> 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