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_service_url.h" 6 7#include <string> 8 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" 21#include "url/gurl.h" 22 23namespace autofill { 24namespace { 25 26const char kProdWalletServiceUrl[] = "https://wallet.google.com/"; 27 28const char kSandboxWalletServiceUrl[] = 29 "https://wallet-web.sandbox.google.com/"; 30 31const char kSandboxWalletSecureServiceUrl[] = 32 "https://wallet-web.sandbox.google.com/"; 33 34bool IsWalletProductionEnabled() { 35 // If the command line flag exists, it takes precedence. 36 const CommandLine* command_line = CommandLine::ForCurrentProcess(); 37 std::string sandbox_enabled( 38 command_line->GetSwitchValueASCII(switches::kWalletServiceUseSandbox)); 39 if (!sandbox_enabled.empty()) 40 return sandbox_enabled != "1"; 41 42 // Default to sandbox when --reduce-security-for-testing is passed to allow 43 // rAc on http:// pages. 44 if (command_line->HasSwitch(::switches::kReduceSecurityForTesting)) 45 return false; 46 47#if defined(ENABLE_PROD_WALLET_SERVICE) 48 return true; 49#else 50 return false; 51#endif 52} 53 54GURL GetWalletHostUrl() { 55 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 56 std::string wallet_service_hostname = 57 command_line.GetSwitchValueASCII(switches::kWalletServiceUrl); 58 if (!wallet_service_hostname.empty()) 59 return GURL(wallet_service_hostname); 60 if (IsWalletProductionEnabled()) 61 return GURL(kProdWalletServiceUrl); 62 return GURL(kSandboxWalletServiceUrl); 63} 64 65GURL GetBaseWalletUrl(size_t user_index) { 66 std::string path = base::StringPrintf("online/v2/u/%" PRIuS "/", user_index); 67 return GetWalletHostUrl().Resolve(path); 68} 69 70GURL GetBaseAutocheckoutUrl(size_t user_index) { 71 return GetBaseWalletUrl(user_index).Resolve("wallet/autocheckout/v1/"); 72} 73 74GURL GetBaseSecureUrl() { 75 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 76 std::string wallet_secure_url = 77 command_line.GetSwitchValueASCII(switches::kWalletSecureServiceUrl); 78 if (!wallet_secure_url.empty()) 79 return GURL(wallet_secure_url); 80 if (IsWalletProductionEnabled()) 81 return GURL(kProdWalletServiceUrl); 82 return GURL(kSandboxWalletSecureServiceUrl); 83} 84 85GURL GetBaseEncryptedFrontendUrl(size_t user_index) { 86 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 87 GURL base_url = IsWalletProductionEnabled() || 88 command_line.HasSwitch(switches::kWalletServiceUrl) ? 89 GetWalletHostUrl() : GetBaseSecureUrl(); 90 std::string path = 91 base::StringPrintf("online-secure/v2/u/%" PRIuS "/autocheckout/v1/", 92 user_index); 93 return base_url.Resolve(path); 94} 95 96} // namespace 97 98namespace wallet { 99 100GURL GetGetWalletItemsUrl(size_t user_index) { 101 return GetBaseAutocheckoutUrl(user_index).Resolve("getWalletItemsJwtless"); 102} 103 104GURL GetGetFullWalletUrl(size_t user_index) { 105 return GetBaseEncryptedFrontendUrl(user_index) 106 .Resolve("getFullWalletJwtless?s7e=otp"); 107} 108 109GURL GetManageInstrumentsUrl(size_t user_index) { 110 std::string path = 111 base::StringPrintf("manage/w/%" PRIuS "/paymentMethods", user_index); 112 return GetBaseSecureUrl().Resolve(path); 113} 114 115GURL GetManageAddressesUrl(size_t user_index) { 116 std::string path = 117 base::StringPrintf("manage/w/%" PRIuS "/settings/addresses", user_index); 118 return GetBaseSecureUrl().Resolve(path); 119} 120 121GURL GetAcceptLegalDocumentsUrl(size_t user_index) { 122 return GetBaseAutocheckoutUrl(user_index).Resolve("acceptLegalDocument"); 123} 124 125GURL GetAuthenticateInstrumentUrl(size_t user_index) { 126 return GetBaseEncryptedFrontendUrl(user_index) 127 .Resolve("authenticateInstrument?s7e=cvn"); 128} 129 130GURL GetSaveToWalletNoEscrowUrl(size_t user_index) { 131 return GetBaseAutocheckoutUrl(user_index).Resolve("saveToWallet"); 132} 133 134GURL GetSaveToWalletUrl(size_t user_index) { 135 return GetBaseEncryptedFrontendUrl(user_index) 136 .Resolve("saveToWallet?s7e=card_number%3Bcvn"); 137} 138 139GURL GetPassiveAuthUrl(size_t user_index) { 140 return GetBaseWalletUrl(user_index) 141 .Resolve("passiveauth?isChromePayments=true"); 142} 143 144GURL GetSignInUrl() { 145 GURL url(GaiaUrls::GetInstance()->add_account_url()); 146 url = net::AppendQueryParameter(url, "nui", "1"); 147 // Prevents promos from showing (see http://crbug.com/235227). 148 url = net::AppendQueryParameter(url, "sarp", "1"); 149 url = net::AppendQueryParameter(url, 150 "continue", 151 GetSignInContinueUrl().spec()); 152 return url; 153} 154 155// The continue url portion of the sign-in URL. This URL is used as a milestone 156// to determine that the sign-in process is finished. It has to be a Google 157// domain, use https://, and do almost nothing, but otherwise it's not too 158// important what the URL actually is: it's not important that this URL has the 159// ability to generate a gdToken. 160GURL GetSignInContinueUrl() { 161 return GetPassiveAuthUrl(0); 162} 163 164bool IsSignInContinueUrl(const GURL& url, size_t* user_index) { 165 GURL final_url = GetSignInContinueUrl(); 166 if (url.scheme() != final_url.scheme() || 167 url.host() != final_url.host() || 168 url.path() != final_url.path()) { 169 return false; 170 } 171 172 *user_index = 0; 173 std::string query_str = url.query(); 174 url::Component query(0, query_str.length()); 175 url::Component key, value; 176 const char kUserIndexKey[] = "authuser"; 177 while (url::ExtractQueryKeyValue(query_str.c_str(), &query, &key, &value)) { 178 if (key.is_nonempty() && 179 query_str.substr(key.begin, key.len) == kUserIndexKey) { 180 base::StringToSizeT(query_str.substr(value.begin, value.len), user_index); 181 break; 182 } 183 } 184 185 return true; 186} 187 188bool IsSignInRelatedUrl(const GURL& url) { 189 size_t unused; 190 return url.GetOrigin() == GetSignInUrl().GetOrigin() || 191 StartsWith(base::UTF8ToUTF16(url.GetOrigin().host()), 192 base::ASCIIToUTF16("accounts."), 193 false) || 194 IsSignInContinueUrl(url, &unused); 195} 196 197bool IsUsingProd() { 198 return GetWalletHostUrl() == GURL(kProdWalletServiceUrl); 199} 200 201} // namespace wallet 202} // namespace autofill 203