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 "components/autofill/content/browser/wallet/wallet_service_url.h"
9 #include "base/command_line.h"
10 #include "base/format_macros.h"
11 #include "base/metrics/field_trial.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_util.h"
14 #include "base/strings/stringprintf.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "components/autofill/core/common/autofill_switches.h"
17 #include "content/public/common/content_switches.h"
18 #include "content/public/common/url_constants.h"
19 #include "google_apis/gaia/gaia_urls.h"
20 #include "net/base/url_util.h"
26 const char kProdWalletServiceUrl
[] = "https://wallet.google.com/";
28 const char kSandboxWalletServiceUrl
[] =
29 "https://wallet-web.sandbox.google.com/";
31 const char kSandboxWalletSecureServiceUrl
[] =
32 "https://wallet-web.sandbox.google.com/";
34 bool IsWalletProductionEnabled() {
35 // If the command line flag exists, it takes precedence.
36 const base::CommandLine
* command_line
=
37 base::CommandLine::ForCurrentProcess();
38 std::string
sandbox_enabled(
39 command_line
->GetSwitchValueASCII(switches::kWalletServiceUseSandbox
));
40 if (!sandbox_enabled
.empty())
41 return sandbox_enabled
!= "1";
43 // Default to sandbox when --reduce-security-for-testing is passed to allow
44 // rAc on http:// pages.
45 if (command_line
->HasSwitch(::switches::kReduceSecurityForTesting
))
48 #if defined(ENABLE_PROD_WALLET_SERVICE)
55 GURL
GetWalletHostUrl() {
56 const base::CommandLine
& command_line
=
57 *base::CommandLine::ForCurrentProcess();
58 std::string wallet_service_hostname
=
59 command_line
.GetSwitchValueASCII(switches::kWalletServiceUrl
);
60 if (!wallet_service_hostname
.empty())
61 return GURL(wallet_service_hostname
);
62 if (IsWalletProductionEnabled())
63 return GURL(kProdWalletServiceUrl
);
64 return GURL(kSandboxWalletServiceUrl
);
67 GURL
GetBaseWalletUrl(size_t user_index
) {
68 std::string path
= base::StringPrintf("online/v2/u/%" PRIuS
"/", user_index
);
69 return GetWalletHostUrl().Resolve(path
);
72 GURL
GetBaseAutocheckoutUrl(size_t user_index
) {
73 return GetBaseWalletUrl(user_index
).Resolve("wallet/autocheckout/v1/");
76 GURL
GetBaseSecureUrl() {
77 const base::CommandLine
& command_line
=
78 *base::CommandLine::ForCurrentProcess();
79 std::string wallet_secure_url
=
80 command_line
.GetSwitchValueASCII(switches::kWalletSecureServiceUrl
);
81 if (!wallet_secure_url
.empty())
82 return GURL(wallet_secure_url
);
83 if (IsWalletProductionEnabled())
84 return GURL(kProdWalletServiceUrl
);
85 return GURL(kSandboxWalletSecureServiceUrl
);
88 GURL
GetBaseEncryptedFrontendUrl(size_t user_index
) {
89 const base::CommandLine
& command_line
=
90 *base::CommandLine::ForCurrentProcess();
91 GURL base_url
= IsWalletProductionEnabled() ||
92 command_line
.HasSwitch(switches::kWalletServiceUrl
) ?
93 GetWalletHostUrl() : GetBaseSecureUrl();
95 base::StringPrintf("online-secure/v2/u/%" PRIuS
"/autocheckout/v1/",
97 return base_url
.Resolve(path
);
104 GURL
GetGetWalletItemsUrl(size_t user_index
) {
105 return GetBaseAutocheckoutUrl(user_index
).Resolve("getWalletItemsJwtless");
108 GURL
GetGetFullWalletUrl(size_t user_index
) {
109 return GetBaseEncryptedFrontendUrl(user_index
)
110 .Resolve("getFullWalletJwtless?s7e=otp");
113 GURL
GetManageInstrumentsUrl(size_t user_index
) {
115 base::StringPrintf("manage/w/%" PRIuS
"/paymentMethods", user_index
);
116 return GetBaseSecureUrl().Resolve(path
);
119 GURL
GetManageAddressesUrl(size_t user_index
) {
121 base::StringPrintf("manage/w/%" PRIuS
"/settings/addresses", user_index
);
122 return GetBaseSecureUrl().Resolve(path
);
125 GURL
GetPrivacyNoticeUrl() {
126 return GetWalletHostUrl().Resolve("legaldocument?family=0.privacynotice");
129 GURL
GetAcceptLegalDocumentsUrl(size_t user_index
) {
130 return GetBaseAutocheckoutUrl(user_index
).Resolve("acceptLegalDocument");
133 GURL
GetAuthenticateInstrumentUrl(size_t user_index
) {
134 return GetBaseEncryptedFrontendUrl(user_index
)
135 .Resolve("authenticateInstrument?s7e=cvn");
138 GURL
GetSaveToWalletNoEscrowUrl(size_t user_index
) {
139 return GetBaseAutocheckoutUrl(user_index
).Resolve("saveToWallet");
142 GURL
GetSaveToWalletUrl(size_t user_index
) {
143 return GetBaseEncryptedFrontendUrl(user_index
)
144 .Resolve("saveToWallet?s7e=card_number%3Bcvn");
147 GURL
GetPassiveAuthUrl(size_t user_index
) {
148 return GetBaseWalletUrl(user_index
)
149 .Resolve("passiveauth?isChromePayments=true");
152 GURL
GetAddAccountUrl() {
153 GURL
url(GaiaUrls::GetInstance()->add_account_url());
154 url
= net::AppendQueryParameter(url
, "nui", "1");
155 // Prevents promos from showing (see http://crbug.com/235227).
156 url
= net::AppendQueryParameter(url
, "sarp", "1");
157 url
= net::AppendQueryParameter(url
,
159 GetSignInContinueUrl().spec());
163 GURL
GetSignInUrl(size_t user_index
) {
164 GURL
url(GaiaUrls::GetInstance()->service_login_url());
165 url
= net::AppendQueryParameter(
166 url
, "authuser", base::SizeTToString(user_index
));
167 // Prevents promos from showing (see http://crbug.com/235227).
168 url
= net::AppendQueryParameter(url
, "sarp", "1");
170 net::AppendQueryParameter(url
, "continue", GetSignInContinueUrl().spec());
174 // The continue url portion of the sign-in URL. This URL is used as a milestone
175 // to determine that the sign-in process is finished. It has to be a Google
176 // domain, use https://, and do almost nothing, but otherwise it's not too
177 // important what the URL actually is: it's not important that this URL has the
178 // ability to generate a gdToken.
179 GURL
GetSignInContinueUrl() {
180 return GetPassiveAuthUrl(0);
183 bool IsSignInContinueUrl(const GURL
& url
, size_t* user_index
) {
184 GURL final_url
= GetSignInContinueUrl();
185 if (url
.scheme() != final_url
.scheme() ||
186 url
.host() != final_url
.host() ||
187 url
.path() != final_url
.path()) {
192 std::string query_str
= url
.query();
193 url::Component
query(0, query_str
.length());
194 url::Component key
, value
;
195 const char kUserIndexKey
[] = "authuser";
196 while (url::ExtractQueryKeyValue(query_str
.c_str(), &query
, &key
, &value
)) {
197 if (key
.is_nonempty() &&
198 query_str
.substr(key
.begin
, key
.len
) == kUserIndexKey
) {
199 base::StringToSizeT(query_str
.substr(value
.begin
, value
.len
), user_index
);
207 bool IsSignInRelatedUrl(const GURL
& url
) {
209 // Origins are host names which are canonicalized, so case-sensitive is OK.
210 GURL origin
= url
.GetOrigin();
211 return origin
== GetAddAccountUrl().GetOrigin() ||
212 base::StartsWith(origin
.host(), "accounts.",
213 base::CompareCase::SENSITIVE
) ||
214 IsSignInContinueUrl(url
, &unused
);
218 return GetWalletHostUrl() == GURL(kProdWalletServiceUrl
);
221 } // namespace wallet
222 } // namespace autofill