Upstream version 11.40.277.0
[platform/framework/web/crosswalk.git] / src / components / autofill / content / browser / wallet / wallet_signin_helper.cc
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.
4
5 #include "components/autofill/content/browser/wallet/wallet_signin_helper.h"
6
7 #include "base/callback_helpers.h"
8 #include "base/json/json_reader.h"
9 #include "base/logging.h"
10 #include "base/rand_util.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/time/time.h"
14 #include "base/values.h"
15 #include "components/autofill/content/browser/wallet/wallet_service_url.h"
16 #include "components/autofill/content/browser/wallet/wallet_signin_helper_delegate.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "google_apis/gaia/google_service_auth_error.h"
19 #include "net/base/escape.h"
20 #include "net/cookies/canonical_cookie.h"
21 #include "net/cookies/cookie_monster.h"
22 #include "net/cookies/cookie_options.h"
23 #include "net/cookies/cookie_store.h"
24 #include "net/url_request/url_fetcher.h"
25 #include "net/url_request/url_request_context.h"
26 #include "net/url_request/url_request_context_getter.h"
27
28 namespace autofill {
29 namespace wallet {
30
31 namespace {
32
33 const char kWalletCookieName[] = "gdtoken";
34
35 // Callback for retrieving Google Wallet cookies. |callback| is passed the
36 // retrieved cookies and posted back to the UI thread. |cookies| is any Google
37 // Wallet cookies.
38 void GetGoogleCookiesCallback(
39     const base::Callback<void(const std::string&)>& callback,
40     const net::CookieList& cookies) {
41   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
42
43   // Cookies for parent domains will also be returned; we only want cookies with
44   // exact host matches. TODO(estade): really?
45   std::string host = wallet::GetPassiveAuthUrl(0).host();
46   std::string wallet_cookie;
47   for (size_t i = 0; i < cookies.size(); ++i) {
48     if (LowerCaseEqualsASCII(cookies[i].Name(), kWalletCookieName) &&
49         LowerCaseEqualsASCII(cookies[i].Domain(), host.c_str())) {
50       wallet_cookie = cookies[i].Value();
51       break;
52     }
53   }
54   content::BrowserThread::PostTask(content::BrowserThread::UI,
55                                    FROM_HERE,
56                                    base::Bind(callback, wallet_cookie));
57 }
58
59 // Gets Google Wallet cookies. Must be called on the IO thread.
60 // |request_context_getter| is a getter for the current request context.
61 // |callback| is called when retrieving cookies is completed.
62 void GetGoogleCookies(
63     scoped_refptr<net::URLRequestContextGetter> request_context_getter,
64     const base::Callback<void(const std::string&)>& callback) {
65   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
66
67   net::URLRequestContext* url_request_context =
68       request_context_getter->GetURLRequestContext();
69   net::CookieStore* cookie_store = url_request_context ?
70       url_request_context->cookie_store() : NULL;
71   net::CookieMonster* cookie_monster = cookie_store ?
72       cookie_store->GetCookieMonster() : NULL;
73   if (!cookie_monster) {
74     content::BrowserThread::PostTask(content::BrowserThread::UI,
75                                      FROM_HERE,
76                                      base::Bind(callback, std::string()));
77     return;
78   }
79
80   net::CookieOptions cookie_options;
81   cookie_options.set_include_httponly();
82   cookie_monster->GetAllCookiesForURLWithOptionsAsync(
83       wallet::GetPassiveAuthUrl(0).GetWithEmptyPath(),
84       cookie_options,
85       base::Bind(&GetGoogleCookiesCallback, callback));
86 }
87
88 }  // namespace
89
90 WalletSigninHelper::WalletSigninHelper(
91     WalletSigninHelperDelegate* delegate,
92     net::URLRequestContextGetter* getter)
93     : delegate_(delegate),
94       getter_(getter),
95       weak_ptr_factory_(this) {
96   DCHECK(delegate_);
97 }
98
99 WalletSigninHelper::~WalletSigninHelper() {
100 }
101
102 void WalletSigninHelper::StartPassiveSignin(size_t user_index) {
103   DCHECK(!url_fetcher_);
104
105   const GURL& url = wallet::GetPassiveAuthUrl(user_index);
106   url_fetcher_.reset(net::URLFetcher::Create(
107       0, url, net::URLFetcher::GET, this));
108   url_fetcher_->SetRequestContext(getter_);
109   url_fetcher_->Start();
110 }
111
112 void WalletSigninHelper::StartWalletCookieValueFetch() {
113   scoped_refptr<net::URLRequestContextGetter> request_context(getter_);
114   if (!request_context.get()) {
115     ReturnWalletCookieValue(std::string());
116     return;
117   }
118
119   base::Callback<void(const std::string&)> callback = base::Bind(
120       &WalletSigninHelper::ReturnWalletCookieValue,
121       weak_ptr_factory_.GetWeakPtr());
122
123   base::Closure task = base::Bind(&GetGoogleCookies, request_context, callback);
124   content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, task);
125 }
126
127 void WalletSigninHelper::OnServiceError(const GoogleServiceAuthError& error) {
128   delegate_->OnPassiveSigninFailure(error);
129 }
130
131 void WalletSigninHelper::OnOtherError() {
132   OnServiceError(GoogleServiceAuthError::AuthErrorNone());
133 }
134
135 void WalletSigninHelper::OnURLFetchComplete(
136     const net::URLFetcher* fetcher) {
137   DCHECK_EQ(url_fetcher_.get(), fetcher);
138   scoped_ptr<net::URLFetcher> url_fetcher(url_fetcher_.release());
139
140   if (!fetcher->GetStatus().is_success() ||
141       fetcher->GetResponseCode() < 200 ||
142       fetcher->GetResponseCode() >= 300) {
143     DVLOG(1) << "URLFetchFailure:"
144              << " r=" << fetcher->GetResponseCode()
145              << " s=" << fetcher->GetStatus().status()
146              << " e=" << fetcher->GetStatus().error();
147     OnOtherError();
148     return;
149   }
150
151   std::string data;
152   if (!fetcher->GetResponseAsString(&data)) {
153     DVLOG(1) << "failed to GetResponseAsString";
154     OnOtherError();
155     return;
156   }
157
158   if (!LowerCaseEqualsASCII(data, "yes")) {
159     OnServiceError(
160         GoogleServiceAuthError(GoogleServiceAuthError::USER_NOT_SIGNED_UP));
161     return;
162   }
163
164   delegate_->OnPassiveSigninSuccess();
165 }
166
167 void WalletSigninHelper::ReturnWalletCookieValue(
168     const std::string& cookie_value) {
169   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
170
171   delegate_->OnDidFetchWalletCookieValue(cookie_value);
172 }
173
174 }  // namespace wallet
175 }  // namespace autofill