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 23 namespace autofill { 24 namespace { 25 26 const char kProdWalletServiceUrl[] = "https://wallet.google.com/"; 27 28 const char kSandboxWalletServiceUrl[] = 29 "https://wallet-web.sandbox.google.com/"; 30 31 const char kSandboxWalletSecureServiceUrl[] = 32 "https://wallet-web.sandbox.google.com/"; 33 34 bool 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 54 GURL 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 65 GURL GetBaseWalletUrl(size_t user_index) { 66 std::string path = base::StringPrintf("online/v2/u/%" PRIuS "/", user_index); 67 return GetWalletHostUrl().Resolve(path); 68 } 69 70 GURL GetBaseAutocheckoutUrl(size_t user_index) { 71 return GetBaseWalletUrl(user_index).Resolve("wallet/autocheckout/v1/"); 72 } 73 74 GURL 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 85 GURL 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 98 namespace wallet { 99 100 GURL GetGetWalletItemsUrl(size_t user_index) { 101 return GetBaseAutocheckoutUrl(user_index).Resolve("getWalletItemsJwtless"); 102 } 103 104 GURL GetGetFullWalletUrl(size_t user_index) { 105 return GetBaseEncryptedFrontendUrl(user_index) 106 .Resolve("getFullWalletJwtless?s7e=otp"); 107 } 108 109 GURL 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 115 GURL 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 121 GURL GetAcceptLegalDocumentsUrl(size_t user_index) { 122 return GetBaseAutocheckoutUrl(user_index).Resolve("acceptLegalDocument"); 123 } 124 125 GURL GetAuthenticateInstrumentUrl(size_t user_index) { 126 return GetBaseEncryptedFrontendUrl(user_index) 127 .Resolve("authenticateInstrument?s7e=cvn"); 128 } 129 130 GURL GetSendStatusUrl(size_t user_index) { 131 return GetBaseAutocheckoutUrl(user_index).Resolve("reportStatus"); 132 } 133 134 GURL GetSaveToWalletNoEscrowUrl(size_t user_index) { 135 return GetBaseAutocheckoutUrl(user_index).Resolve("saveToWallet"); 136 } 137 138 GURL GetSaveToWalletUrl(size_t user_index) { 139 return GetBaseEncryptedFrontendUrl(user_index) 140 .Resolve("saveToWallet?s7e=card_number%3Bcvn"); 141 } 142 143 GURL GetPassiveAuthUrl(size_t user_index) { 144 return GetBaseWalletUrl(user_index) 145 .Resolve("passiveauth?isChromePayments=true"); 146 } 147 148 GURL GetSignInUrl() { 149 GURL url(GaiaUrls::GetInstance()->add_account_url()); 150 url = net::AppendQueryParameter(url, "nui", "1"); 151 // Prevents promos from showing (see http://crbug.com/235227). 152 url = net::AppendQueryParameter(url, "sarp", "1"); 153 url = net::AppendQueryParameter(url, 154 "continue", 155 GetSignInContinueUrl().spec()); 156 return url; 157 } 158 159 // The continue url portion of the sign-in URL. This URL is used as a milestone 160 // to determine that the sign-in process is finished. It has to be a Google 161 // domain, use https://, and do almost nothing, but otherwise it's not too 162 // important what the URL actually is: it's not important that this URL has the 163 // ability to generate a gdToken. 164 GURL GetSignInContinueUrl() { 165 return GetPassiveAuthUrl(0); 166 } 167 168 bool IsSignInContinueUrl(const GURL& url, size_t* user_index) { 169 GURL final_url = GetSignInContinueUrl(); 170 if (url.scheme() != final_url.scheme() || 171 url.host() != final_url.host() || 172 url.path() != final_url.path()) { 173 return false; 174 } 175 176 *user_index = 0; 177 std::string query_str = url.query(); 178 url::Component query(0, query_str.length()); 179 url::Component key, value; 180 const char kUserIndexKey[] = "authuser"; 181 while (url::ExtractQueryKeyValue(query_str.c_str(), &query, &key, &value)) { 182 if (key.is_nonempty() && 183 query_str.substr(key.begin, key.len) == kUserIndexKey) { 184 base::StringToSizeT(query_str.substr(value.begin, value.len), user_index); 185 break; 186 } 187 } 188 189 return true; 190 } 191 192 bool IsSignInRelatedUrl(const GURL& url) { 193 size_t unused; 194 return url.GetOrigin() == GetSignInUrl().GetOrigin() || 195 StartsWith(base::UTF8ToUTF16(url.GetOrigin().host()), 196 base::ASCIIToUTF16("accounts."), 197 false) || 198 IsSignInContinueUrl(url, &unused); 199 } 200 201 bool IsUsingProd() { 202 return GetWalletHostUrl() == GURL(kProdWalletServiceUrl); 203 } 204 205 } // namespace wallet 206 } // namespace autofill 207