1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/json/json_reader.h"
6 #include "base/strings/string_number_conversions.h"
7 #include "base/strings/stringprintf.h"
8 #include "base/values.h"
9 #include "chrome/browser/local_discovery/cloud_print_base_api_flow.h"
10 #include "chrome/common/cloud_print/cloud_print_constants.h"
11 #include "google_apis/gaia/google_service_auth_error.h"
12 #include "net/base/load_flags.h"
13 #include "net/base/url_util.h"
14 #include "net/http/http_status_code.h"
15 #include "net/url_request/url_request_status.h"
17 namespace local_discovery
{
20 const char kCloudPrintOAuthHeaderFormat
[] = "Authorization: Bearer %s";
21 const char kXSRFURLParameterKey
[] = "xsrf";
22 const char kUserURLParameterKey
[] = "user";
25 CloudPrintBaseApiFlow::CloudPrintBaseApiFlow(
26 net::URLRequestContextGetter
* request_context
,
27 OAuth2TokenService
* token_service
,
28 const std::string
& account_id
,
29 const GURL
& automated_claim_url
,
31 : OAuth2TokenService::Consumer("cloud_print"),
32 request_context_(request_context
),
33 token_service_(token_service
),
34 account_id_(account_id
),
35 user_index_(kAccountIndexUseOAuth2
),
36 url_(automated_claim_url
),
40 CloudPrintBaseApiFlow::CloudPrintBaseApiFlow(
41 net::URLRequestContextGetter
* request_context
,
43 const std::string
& xsrf_token
,
44 const GURL
& automated_claim_url
,
46 : OAuth2TokenService::Consumer("cloud_print"),
47 request_context_(request_context
),
50 user_index_(user_index
),
51 xsrf_token_(xsrf_token
),
52 url_(automated_claim_url
),
56 CloudPrintBaseApiFlow::CloudPrintBaseApiFlow(
57 net::URLRequestContextGetter
* request_context
,
59 const GURL
& automated_claim_url
,
61 : OAuth2TokenService::Consumer("cloud_print"),
62 request_context_(request_context
),
65 user_index_(user_index
),
66 url_(automated_claim_url
),
70 CloudPrintBaseApiFlow::~CloudPrintBaseApiFlow() {
73 void CloudPrintBaseApiFlow::Start() {
75 OAuth2TokenService::ScopeSet oauth_scopes
;
76 oauth_scopes
.insert(cloud_print::kCloudPrintAuth
);
77 oauth_request_
= token_service_
->StartRequest(account_id_
,
81 GURL cookie_url
= url_
;
83 if (!xsrf_token_
.empty()) {
84 cookie_url
= net::AppendQueryParameter(cookie_url
,
89 cookie_url
= net::AppendQueryParameter(cookie_url
,
91 base::IntToString(user_index_
));
93 CreateRequest(cookie_url
);
95 url_fetcher_
->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES
);
97 url_fetcher_
->Start();
101 void CloudPrintBaseApiFlow::OnGetTokenSuccess(
102 const OAuth2TokenService::Request
* request
,
103 const std::string
& access_token
,
104 const base::Time
& expiration_time
) {
107 std::string authorization_header
=
108 base::StringPrintf(kCloudPrintOAuthHeaderFormat
, access_token
.c_str());
110 url_fetcher_
->AddExtraRequestHeader(authorization_header
);
111 url_fetcher_
->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES
|
112 net::LOAD_DO_NOT_SEND_COOKIES
);
113 url_fetcher_
->Start();
116 void CloudPrintBaseApiFlow::OnGetTokenFailure(
117 const OAuth2TokenService::Request
* request
,
118 const GoogleServiceAuthError
& error
) {
119 delegate_
->OnCloudPrintAPIFlowError(this, ERROR_TOKEN
);
122 void CloudPrintBaseApiFlow::CreateRequest(const GURL
& url
) {
123 url_fetcher_
.reset(net::URLFetcher::Create(url
,
124 net::URLFetcher::GET
,
127 url_fetcher_
->SetRequestContext(request_context_
.get());
129 url_fetcher_
->AddExtraRequestHeader(
130 cloud_print::kChromeCloudPrintProxyHeader
);
133 void CloudPrintBaseApiFlow::OnURLFetchComplete(
134 const net::URLFetcher
* source
) {
135 // TODO(noamsml): Error logging.
137 // TODO(noamsml): Extract this and PrivetURLFetcher::OnURLFetchComplete into
138 // one helper method.
139 std::string response_str
;
141 if (source
->GetStatus().status() != net::URLRequestStatus::SUCCESS
||
142 !source
->GetResponseAsString(&response_str
)) {
143 delegate_
->OnCloudPrintAPIFlowError(this, ERROR_NETWORK
);
147 if (source
->GetResponseCode() != net::HTTP_OK
) {
148 delegate_
->OnCloudPrintAPIFlowError(this, ERROR_HTTP_CODE
);
152 base::JSONReader reader
;
153 scoped_ptr
<const base::Value
> value(reader
.Read(response_str
));
154 const base::DictionaryValue
* dictionary_value
= NULL
;
156 if (!value
|| !value
->GetAsDictionary(&dictionary_value
)) {
157 delegate_
->OnCloudPrintAPIFlowError(this, ERROR_MALFORMED_RESPONSE
);
161 delegate_
->OnCloudPrintAPIFlowComplete(this, dictionary_value
);
164 } // namespace local_discovery