gaia_config.cc 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. // Copyright 2020 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. #include "google_apis/gaia/gaia_config.h"
  5. #include "base/command_line.h"
  6. #include "base/files/file_util.h"
  7. #include "base/json/json_reader.h"
  8. #include "base/json/json_writer.h"
  9. #include "base/logging.h"
  10. #include "base/memory/ptr_util.h"
  11. #include "base/no_destructor.h"
  12. #include "base/strings/string_piece.h"
  13. #include "base/threading/thread_restrictions.h"
  14. #include "google_apis/gaia/gaia_switches.h"
  15. #include "google_apis/google_api_keys.h"
  16. #include "third_party/abseil-cpp/absl/types/optional.h"
  17. #include "url/gurl.h"
  18. // static
  19. GaiaConfig* GaiaConfig::GetInstance() {
  20. return GetGlobalConfig()->get();
  21. }
  22. GaiaConfig::GaiaConfig(base::Value parsed_config)
  23. : parsed_config_(std::move(parsed_config)) {}
  24. GaiaConfig::~GaiaConfig() = default;
  25. bool GaiaConfig::GetURLIfExists(base::StringPiece key, GURL* out_url) {
  26. const base::Value* urls = parsed_config_.FindDictKey("urls");
  27. if (!urls)
  28. return false;
  29. const base::Value* url_config = urls->FindDictKey(key);
  30. if (!url_config)
  31. return false;
  32. const std::string* url_string = url_config->FindStringKey("url");
  33. if (!url_string) {
  34. LOG(ERROR) << "Incorrect format of \"" << key
  35. << "\" gaia config key. A key should contain {\"url\": "
  36. "\"https://...\"} dictionary.";
  37. return false;
  38. }
  39. GURL url = GURL(*url_string);
  40. if (!url.is_valid()) {
  41. LOG(ERROR) << "Invalid URL at \"" << key << "\" URL key";
  42. return false;
  43. }
  44. *out_url = url;
  45. return true;
  46. }
  47. bool GaiaConfig::GetAPIKeyIfExists(base::StringPiece key,
  48. std::string* out_api_key) {
  49. const base::Value* api_keys = parsed_config_.FindDictKey("api_keys");
  50. if (!api_keys)
  51. return false;
  52. const std::string* api_key = api_keys->FindStringKey(key);
  53. if (!api_key)
  54. return false;
  55. *out_api_key = *api_key;
  56. return true;
  57. }
  58. void GaiaConfig::SerializeContentsToCommandLineSwitch(
  59. base::CommandLine* command_line) const {
  60. std::string config_contents;
  61. base::JSONWriter::Write(parsed_config_, &config_contents);
  62. command_line->AppendSwitchASCII(switches::kGaiaConfigContents,
  63. config_contents);
  64. }
  65. // static
  66. std::unique_ptr<GaiaConfig> GaiaConfig::CreateFromCommandLineForTesting(
  67. const base::CommandLine* command_line) {
  68. return ReadConfigFromCommandLineSwitches(command_line);
  69. }
  70. // static
  71. void GaiaConfig::ResetInstanceForTesting() {
  72. *GetGlobalConfig() =
  73. ReadConfigFromCommandLineSwitches(base::CommandLine::ForCurrentProcess());
  74. }
  75. // static
  76. std::unique_ptr<GaiaConfig>* GaiaConfig::GetGlobalConfig() {
  77. static base::NoDestructor<std::unique_ptr<GaiaConfig>> config(
  78. ReadConfigFromCommandLineSwitches(
  79. base::CommandLine::ForCurrentProcess()));
  80. return config.get();
  81. }
  82. // static
  83. std::unique_ptr<GaiaConfig> GaiaConfig::ReadConfigFromString(
  84. const std::string& config_contents) {
  85. absl::optional<base::Value> dict = base::JSONReader::Read(config_contents);
  86. if (!dict || !dict->is_dict()) {
  87. LOG(FATAL) << "Couldn't parse Gaia config file";
  88. return nullptr;
  89. }
  90. return std::make_unique<GaiaConfig>(std::move(dict.value()));
  91. }
  92. // static
  93. std::unique_ptr<GaiaConfig> GaiaConfig::ReadConfigFromDisk(
  94. const base::FilePath& config_path) {
  95. // Blocking is okay here because this code is executed only when the
  96. // --gaia-config command line flag is specified. --gaia-config is only used
  97. // for development.
  98. base::ScopedAllowBlocking scoped_allow_blocking;
  99. std::string config_contents;
  100. if (!base::ReadFileToString(config_path, &config_contents)) {
  101. LOG(FATAL) << "Couldn't read Gaia config file " << config_path;
  102. return nullptr;
  103. }
  104. return ReadConfigFromString(config_contents);
  105. }
  106. // static
  107. std::unique_ptr<GaiaConfig> GaiaConfig::ReadConfigFromCommandLineSwitches(
  108. const base::CommandLine* command_line) {
  109. if (command_line->HasSwitch(switches::kGaiaConfigPath) &&
  110. command_line->HasSwitch(switches::kGaiaConfigContents)) {
  111. LOG(FATAL) << "Either a Gaia config file path or a config file contents "
  112. "can be provided; "
  113. << "not both";
  114. return nullptr;
  115. }
  116. if (command_line->HasSwitch(switches::kGaiaConfigContents)) {
  117. return ReadConfigFromString(
  118. command_line->GetSwitchValueASCII(switches::kGaiaConfigContents));
  119. }
  120. if (command_line->HasSwitch(switches::kGaiaConfigPath)) {
  121. return ReadConfigFromDisk(
  122. command_line->GetSwitchValuePath(switches::kGaiaConfigPath));
  123. }
  124. return nullptr;
  125. }