summaryrefslogtreecommitdiffstats
path: root/chrome/browser/local_discovery/gcd_api_flow_impl.cc
blob: d4abd9329625f8e3803afba8d5ec475a324cb5dc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// 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 "chrome/browser/local_discovery/gcd_api_flow_impl.h"

#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/gcd_constants.h"
#include "chrome/common/cloud_print/cloud_print_constants.h"
#include "components/cloud_devices/common/cloud_devices_urls.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 {

GCDApiFlowImpl::GCDApiFlowImpl(net::URLRequestContextGetter* request_context,
                               OAuth2TokenService* token_service,
                               const std::string& account_id)
    : OAuth2TokenService::Consumer("cloud_print"),
      request_context_(request_context),
      token_service_(token_service),
      account_id_(account_id) {
}

GCDApiFlowImpl::~GCDApiFlowImpl() {
}

void GCDApiFlowImpl::Start(scoped_ptr<Request> request) {
  request_ = request.Pass();
  OAuth2TokenService::ScopeSet oauth_scopes;
  oauth_scopes.insert(request_->GetOAuthScope());
  oauth_request_ =
      token_service_->StartRequest(account_id_, oauth_scopes, this);
}

void GCDApiFlowImpl::OnGetTokenSuccess(
    const OAuth2TokenService::Request* request,
    const std::string& access_token,
    const base::Time& expiration_time) {
  CreateRequest(request_->GetURL());

  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 GCDApiFlowImpl::OnGetTokenFailure(
    const OAuth2TokenService::Request* request,
    const GoogleServiceAuthError& error) {
  request_->OnGCDAPIFlowError(ERROR_TOKEN);
}

void GCDApiFlowImpl::CreateRequest(const GURL& url) {
  net::URLFetcher::RequestType request_type = request_->GetRequestType();

  url_fetcher_.reset(net::URLFetcher::Create(url, request_type, this));

  if (request_type != net::URLFetcher::GET) {
    std::string upload_type;
    std::string upload_data;
    request_->GetUploadData(&upload_type, &upload_data);
    url_fetcher_->SetUploadData(upload_type, upload_data);
  }

  url_fetcher_->SetRequestContext(request_context_.get());

  std::vector<std::string> extra_headers = request_->GetExtraRequestHeaders();
  for (size_t i = 0; i < extra_headers.size(); ++i)
    url_fetcher_->AddExtraRequestHeader(extra_headers[i]);
}

void GCDApiFlowImpl::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)) {
    request_->OnGCDAPIFlowError(ERROR_NETWORK);
    return;
  }

  if (source->GetResponseCode() != net::HTTP_OK) {
    request_->OnGCDAPIFlowError(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)) {
    request_->OnGCDAPIFlowError(ERROR_MALFORMED_RESPONSE);
    return;
  }

  request_->OnGCDAPIFlowComplete(*dictionary_value);
}

}  // namespace local_discovery