Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 1 | // Copyright 2024 The Chromium Authors |
| 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"google_apis/api_key_cache.h" |
| 6 | |
| 7 | #include<stddef.h> |
| 8 | |
| 9 | #include<algorithm> |
| 10 | #include<memory> |
| 11 | #include<string> |
| 12 | |
| 13 | #include"base/command_line.h" |
| 14 | #include"base/environment.h" |
| 15 | #include"base/feature_list.h" |
| 16 | #include"base/features.h" |
| 17 | #include"base/logging.h" |
| 18 | #include"base/metrics/field_trial_params.h" |
| 19 | #include"base/metrics/histogram_functions.h" |
| 20 | #include"base/strings/stringize_macros.h" |
| 21 | #include"build/branding_buildflags.h" |
| 22 | #include"build/build_config.h" |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 23 | #include"google_apis/buildflags.h" |
| 24 | #include"google_apis/default_api_keys.h" |
| 25 | #include"google_apis/gaia/gaia_config.h" |
| 26 | #include"google_apis/gaia/gaia_switches.h" |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 27 | |
| 28 | #if BUILDFLAG(IS_APPLE) |
| 29 | #include"google_apis/google_api_keys_mac.h" |
| 30 | #endif |
| 31 | |
| 32 | namespace google_apis{ |
| 33 | |
| 34 | namespace{ |
Alex Ilin | a4538d9 | 2024-09-23 14:10:21 | [diff] [blame] | 35 | |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 36 | // Gets a value for a key. In priority order, this will be the value |
| 37 | // provided via: |
| 38 | // 1. Command-line switch |
| 39 | // 2. Config file |
| 40 | // 3. Environment variable |
Mihai Sardarescu | 9c16002 | 2025-01-08 10:43:59 | [diff] [blame] | 41 | // 4. On macOS and iOS, the value passed in Info.plist |
| 42 | // 5. Baked into the build. |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 43 | // |command_line_switch| may be NULL. Official Google Chrome builds will not |
| 44 | // use the value provided by an environment variable. |
Patrick Monette | 18ed4c7 | 2025-04-28 18:47:34 | [diff] [blame] | 45 | static std::stringCalculateKeyValue( |
| 46 | constchar* baked_in_value, |
| 47 | base::cstring_view environment_variable_name, |
| 48 | constchar* command_line_switch, |
| 49 | const std::string& default_if_unset, |
| 50 | base::Environment* environment, |
| 51 | base::CommandLine* command_line, |
| 52 | GaiaConfig* gaia_config, |
| 53 | bool allow_override_via_environment, |
| 54 | bool allow_unset_values){ |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 55 | std::string key_value= baked_in_value; |
| 56 | std::string temp; |
| 57 | #if BUILDFLAG(IS_APPLE) |
| 58 | // macOS and iOS can also override the API key with a value from the |
| 59 | // Info.plist. |
Alex Ilin | a4538d9 | 2024-09-23 14:10:21 | [diff] [blame] | 60 | temp=GetAPIKeyFromInfoPlist(environment_variable_name); |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 61 | if(!temp.empty()){ |
| 62 | key_value= temp; |
| 63 | VLOG(1)<<"Overriding API key "<< environment_variable_name |
| 64 | <<" with value from Info.plist."; |
| 65 | } |
| 66 | #endif |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 67 | |
| 68 | if(allow_override_via_environment){ |
| 69 | // Don't allow using the environment to override API keys for official |
| 70 | // Google Chrome builds. There have been reports of mangled environments |
| 71 | // affecting users (crbug.com/710575). |
Helmut Januschka | e6392b8 | 2025-04-16 23:55:56 | [diff] [blame] | 72 | if(auto maybe_key_value= environment->GetVar(environment_variable_name); |
| 73 | maybe_key_value.has_value()){ |
| 74 | key_value=*maybe_key_value; |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 75 | VLOG(1)<<"Overriding API key "<< environment_variable_name |
| 76 | <<" with value "<< key_value<<" from environment variable."; |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | if(gaia_config&& |
| 81 | gaia_config->GetAPIKeyIfExists(environment_variable_name,&temp)){ |
| 82 | key_value= temp; |
| 83 | VLOG(1)<<"Overriding API key "<< environment_variable_name |
| 84 | <<" with value "<< key_value<<" from gaia config."; |
| 85 | } |
| 86 | |
| 87 | if(command_line_switch&& command_line->HasSwitch(command_line_switch)){ |
| 88 | key_value= command_line->GetSwitchValueASCII(command_line_switch); |
| 89 | VLOG(1)<<"Overriding API key "<< environment_variable_name |
| 90 | <<" with value "<< key_value<<" from command-line switch."; |
| 91 | } |
| 92 | |
Alex Ilin | 857d6ffd | 2024-09-25 13:27:21 | [diff] [blame] | 93 | if(key_value==DefaultApiKeys::kUnsetApiToken){ |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 94 | // No key should be unset in an official build except the |
Alex Ilin | 857d6ffd | 2024-09-25 13:27:21 | [diff] [blame] | 95 | // GOOGLE_DEFAULT_* keys. The default keys don't trigger this |
| 96 | // check as their "unset" value is not DefaultApiKeys::kUnsetApiToken. |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 97 | CHECK(allow_unset_values); |
| 98 | if(default_if_unset.size()>0){ |
| 99 | VLOG(1)<<"Using default value \""<< default_if_unset |
| 100 | <<"\" for API key "<< environment_variable_name; |
| 101 | key_value= default_if_unset; |
| 102 | } |
| 103 | } |
| 104 | |
| 105 | // This should remain a debug-only log. |
| 106 | DVLOG(1)<<"API key "<< environment_variable_name<<"="<< key_value; |
| 107 | |
| 108 | return key_value; |
| 109 | } |
| 110 | }// namespace |
| 111 | |
Alex Ilin | a4538d9 | 2024-09-23 14:10:21 | [diff] [blame] | 112 | ApiKeyCache::ApiKeyCache(constDefaultApiKeys& default_api_keys){ |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 113 | std::unique_ptr<base::Environment> environment(base::Environment::Create()); |
| 114 | base::CommandLine* command_line= base::CommandLine::ForCurrentProcess(); |
| 115 | GaiaConfig* gaia_config=GaiaConfig::GetInstance(); |
| 116 | |
Mihai Sardarescu | 9c16002 | 2025-01-08 10:43:59 | [diff] [blame] | 117 | api_key_=CalculateKeyValue( |
| 118 | default_api_keys.google_api_key, STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY), |
| 119 | nullptr, std::string(), environment.get(), command_line, gaia_config, |
| 120 | default_api_keys.allow_override_via_environment, |
| 121 | default_api_keys.allow_unset_values); |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 122 | |
| 123 | // A special non-stable key is at the moment defined only for Android Chrome. |
| 124 | #if BUILDFLAG(IS_ANDROID) |
| 125 | api_key_non_stable_=CalculateKeyValue( |
| 126 | default_api_keys.google_api_key_android_non_stable, |
Mihai Sardarescu | 9c16002 | 2025-01-08 10:43:59 | [diff] [blame] | 127 | STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY_ANDROID_NON_STABLE),nullptr, |
| 128 | std::string(), environment.get(), command_line, gaia_config, |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 129 | default_api_keys.allow_override_via_environment, |
| 130 | default_api_keys.allow_unset_values); |
| 131 | #else |
| 132 | api_key_non_stable_= api_key_; |
| 133 | #endif |
| 134 | |
| 135 | api_key_remoting_=CalculateKeyValue( |
| 136 | default_api_keys.google_api_key_remoting, |
Mihai Sardarescu | 9c16002 | 2025-01-08 10:43:59 | [diff] [blame] | 137 | STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY_REMOTING),nullptr, std::string(), |
| 138 | environment.get(), command_line, gaia_config, |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 139 | default_api_keys.allow_override_via_environment, |
| 140 | default_api_keys.allow_unset_values); |
| 141 | |
| 142 | api_key_soda_=CalculateKeyValue( |
| 143 | default_api_keys.google_api_key_soda, |
Mihai Sardarescu | 9c16002 | 2025-01-08 10:43:59 | [diff] [blame] | 144 | STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY_SODA),nullptr, std::string(), |
| 145 | environment.get(), command_line, gaia_config, |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 146 | default_api_keys.allow_override_via_environment, |
| 147 | default_api_keys.allow_unset_values); |
| 148 | #if !BUILDFLAG(IS_ANDROID) |
| 149 | api_key_hats_=CalculateKeyValue( |
| 150 | default_api_keys.google_api_key_hats, |
Mihai Sardarescu | 9c16002 | 2025-01-08 10:43:59 | [diff] [blame] | 151 | STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY_HATS),nullptr, std::string(), |
| 152 | environment.get(), command_line, gaia_config, |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 153 | default_api_keys.allow_override_via_environment, |
| 154 | default_api_keys.allow_unset_values); |
| 155 | #endif |
| 156 | |
Georg Neis | 0c0448b | 2025-02-05 01:01:08 | [diff] [blame] | 157 | #if BUILDFLAG(IS_CHROMEOS) |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 158 | api_key_sharing_=CalculateKeyValue( |
| 159 | default_api_keys.google_api_key_sharing, |
Mihai Sardarescu | 9c16002 | 2025-01-08 10:43:59 | [diff] [blame] | 160 | STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY_SHARING),nullptr, std::string(), |
| 161 | environment.get(), command_line, gaia_config, |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 162 | default_api_keys.allow_override_via_environment, |
| 163 | default_api_keys.allow_unset_values); |
| 164 | |
| 165 | api_key_read_aloud_=CalculateKeyValue( |
| 166 | default_api_keys.google_api_key_read_aloud, |
Mihai Sardarescu | 9c16002 | 2025-01-08 10:43:59 | [diff] [blame] | 167 | STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY_READ_ALOUD),nullptr, std::string(), |
| 168 | environment.get(), command_line, gaia_config, |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 169 | default_api_keys.allow_override_via_environment, |
| 170 | default_api_keys.allow_unset_values); |
| 171 | |
| 172 | api_key_fresnel_=CalculateKeyValue( |
| 173 | default_api_keys.google_api_key_fresnel, |
Mihai Sardarescu | 9c16002 | 2025-01-08 10:43:59 | [diff] [blame] | 174 | STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY_FRESNEL),nullptr, std::string(), |
| 175 | environment.get(), command_line, gaia_config, |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 176 | default_api_keys.allow_override_via_environment, |
| 177 | default_api_keys.allow_unset_values); |
Dorian Brandon | dec8a3b | 2024-10-09 20:39:54 | [diff] [blame] | 178 | |
| 179 | api_key_boca_=CalculateKeyValue( |
| 180 | default_api_keys.google_api_key_boca, |
Mihai Sardarescu | 9c16002 | 2025-01-08 10:43:59 | [diff] [blame] | 181 | STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY_BOCA),nullptr, std::string(), |
| 182 | environment.get(), command_line, gaia_config, |
Dorian Brandon | dec8a3b | 2024-10-09 20:39:54 | [diff] [blame] | 183 | default_api_keys.allow_override_via_environment, |
| 184 | default_api_keys.allow_unset_values); |
Zauri Meshveliani | b41301a2 | 2025-03-27 20:53:57 | [diff] [blame] | 185 | |
| 186 | api_key_cros_system_geo_=CalculateKeyValue( |
| 187 | default_api_keys.google_api_key_cros_system_geo_, |
| 188 | STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY_CROS_SYSTEM_GEO),nullptr, |
| 189 | std::string(), environment.get(), command_line, gaia_config, |
| 190 | default_api_keys.allow_override_via_environment, |
| 191 | default_api_keys.allow_unset_values); |
| 192 | |
| 193 | api_key_cros_chrome_geo_=CalculateKeyValue( |
| 194 | default_api_keys.google_api_key_cros_chrome_geo_, |
| 195 | STRINGIZE_NO_EXPANSION(GOOGLE_API_KEY_CROS_CHROME_GEO),nullptr, |
| 196 | std::string(), environment.get(), command_line, gaia_config, |
| 197 | default_api_keys.allow_override_via_environment, |
| 198 | default_api_keys.allow_unset_values); |
| 199 | |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 200 | #endif |
| 201 | |
| 202 | metrics_key_=CalculateKeyValue( |
| 203 | default_api_keys.google_metrics_signing_key, |
Mihai Sardarescu | 9c16002 | 2025-01-08 10:43:59 | [diff] [blame] | 204 | STRINGIZE_NO_EXPANSION(GOOGLE_METRICS_SIGNING_KEY),nullptr, |
| 205 | std::string(), environment.get(), command_line, gaia_config, |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 206 | default_api_keys.allow_override_via_environment, |
| 207 | default_api_keys.allow_unset_values); |
| 208 | |
| 209 | std::string default_client_id=CalculateKeyValue( |
| 210 | default_api_keys.google_default_client_id, |
Mihai Sardarescu | 9c16002 | 2025-01-08 10:43:59 | [diff] [blame] | 211 | STRINGIZE_NO_EXPANSION(GOOGLE_DEFAULT_CLIENT_ID),nullptr, std::string(), |
| 212 | environment.get(), command_line, gaia_config, |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 213 | default_api_keys.allow_override_via_environment, |
| 214 | default_api_keys.allow_unset_values); |
| 215 | std::string default_client_secret=CalculateKeyValue( |
| 216 | default_api_keys.google_default_client_secret, |
Mihai Sardarescu | 9c16002 | 2025-01-08 10:43:59 | [diff] [blame] | 217 | STRINGIZE_NO_EXPANSION(GOOGLE_DEFAULT_CLIENT_SECRET),nullptr, |
| 218 | std::string(), environment.get(), command_line, gaia_config, |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 219 | default_api_keys.allow_override_via_environment, |
| 220 | default_api_keys.allow_unset_values); |
| 221 | |
| 222 | // We currently only allow overriding the baked-in values for the |
| 223 | // default OAuth2 client ID and secret using a command-line |
| 224 | // argument and gaia config, since that is useful to enable testing against |
| 225 | // staging servers, and since that was what was possible and |
| 226 | // likely practiced by the QA team before this implementation was |
| 227 | // written. |
Mihai Sardarescu | 9c16002 | 2025-01-08 10:43:59 | [diff] [blame] | 228 | client_ids_[CLIENT_MAIN]= |
| 229 | CalculateKeyValue(default_api_keys.google_client_id_main, |
| 230 | STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_MAIN), |
| 231 | ::switches::kOAuth2ClientID, default_client_id, |
| 232 | environment.get(), command_line, gaia_config, |
| 233 | default_api_keys.allow_override_via_environment, |
| 234 | default_api_keys.allow_unset_values); |
| 235 | client_secrets_[CLIENT_MAIN]= |
| 236 | CalculateKeyValue(default_api_keys.google_client_secret_main, |
| 237 | STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_MAIN), |
| 238 | ::switches::kOAuth2ClientSecret, default_client_secret, |
| 239 | environment.get(), command_line, gaia_config, |
| 240 | default_api_keys.allow_override_via_environment, |
| 241 | default_api_keys.allow_unset_values); |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 242 | |
| 243 | client_ids_[CLIENT_REMOTING]=CalculateKeyValue( |
| 244 | default_api_keys.google_client_id_remoting, |
Mihai Sardarescu | 9c16002 | 2025-01-08 10:43:59 | [diff] [blame] | 245 | STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_REMOTING),nullptr, |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 246 | default_client_id, environment.get(), command_line, gaia_config, |
| 247 | default_api_keys.allow_override_via_environment, |
| 248 | default_api_keys.allow_unset_values); |
| 249 | client_secrets_[CLIENT_REMOTING]=CalculateKeyValue( |
| 250 | default_api_keys.google_client_secret_remoting, |
Mihai Sardarescu | 9c16002 | 2025-01-08 10:43:59 | [diff] [blame] | 251 | STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_REMOTING),nullptr, |
| 252 | default_client_secret, environment.get(), command_line, gaia_config, |
| 253 | default_api_keys.allow_override_via_environment, |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 254 | default_api_keys.allow_unset_values); |
| 255 | |
| 256 | client_ids_[CLIENT_REMOTING_HOST]=CalculateKeyValue( |
| 257 | default_api_keys.google_client_id_remoting_host, |
Mihai Sardarescu | 9c16002 | 2025-01-08 10:43:59 | [diff] [blame] | 258 | STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_ID_REMOTING_HOST),nullptr, |
| 259 | default_client_id, environment.get(), command_line, gaia_config, |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 260 | default_api_keys.allow_override_via_environment, |
| 261 | default_api_keys.allow_unset_values); |
| 262 | client_secrets_[CLIENT_REMOTING_HOST]=CalculateKeyValue( |
| 263 | default_api_keys.google_client_secret_remoting_host, |
Mihai Sardarescu | 9c16002 | 2025-01-08 10:43:59 | [diff] [blame] | 264 | STRINGIZE_NO_EXPANSION(GOOGLE_CLIENT_SECRET_REMOTING_HOST),nullptr, |
| 265 | default_client_secret, environment.get(), command_line, gaia_config, |
| 266 | default_api_keys.allow_override_via_environment, |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 267 | default_api_keys.allow_unset_values); |
| 268 | } |
| 269 | |
| 270 | ApiKeyCache::~ApiKeyCache()=default; |
| 271 | |
| 272 | const std::string&ApiKeyCache::GetClientID(OAuth2Client client)const{ |
| 273 | DCHECK_LT(client, CLIENT_NUM_ITEMS); |
| 274 | return client_ids_[client]; |
| 275 | } |
| 276 | |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 277 | const std::string&ApiKeyCache::GetClientSecret(OAuth2Client client)const{ |
| 278 | DCHECK_LT(client, CLIENT_NUM_ITEMS); |
| 279 | return client_secrets_[client]; |
| 280 | } |
| 281 | |
Mihai Sardarescu | 4416597 | 2024-10-25 13:23:37 | [diff] [blame] | 282 | #if BUILDFLAG(SUPPORT_EXTERNAL_GOOGLE_API_KEY) |
| 283 | voidApiKeyCache::SetClientID(OAuth2Client client, |
| 284 | const std::string& client_id){ |
| 285 | client_ids_[client]= client_id; |
| 286 | } |
| 287 | |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 288 | voidApiKeyCache::SetClientSecret(OAuth2Client client, |
| 289 | const std::string& client_secret){ |
| 290 | client_secrets_[client]= client_secret; |
| 291 | } |
Mihai Sardarescu | 4416597 | 2024-10-25 13:23:37 | [diff] [blame] | 292 | #endif// BUILDFLAG(SUPPORT_EXTERNAL_GOOGLE_API_KEY) |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 293 | |
| 294 | boolApiKeyCache::HasAPIKeyConfigured()const{ |
Alex Ilin | 857d6ffd | 2024-09-25 13:27:21 | [diff] [blame] | 295 | return api_key_!=DefaultApiKeys::kUnsetApiToken; |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 296 | } |
| 297 | |
| 298 | boolApiKeyCache::HasOAuthClientConfigured()const{ |
Alex Ilin | 857d6ffd | 2024-09-25 13:27:21 | [diff] [blame] | 299 | auto is_unset=[](const std::string& value){ |
| 300 | return value==DefaultApiKeys::kUnsetApiToken; |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 301 | }; |
Alex Ilin | 857d6ffd | 2024-09-25 13:27:21 | [diff] [blame] | 302 | return std::ranges::none_of(client_ids_, is_unset)&& |
| 303 | std::ranges::none_of(client_secrets_, is_unset); |
Alex Ilin | af38c47 | 2024-09-23 13:59:57 | [diff] [blame] | 304 | } |
| 305 | |
| 306 | }// namespace google_apis |