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