diff options
author | Vitaly Buka <vitalybuka@google.com> | 2016-02-10 22:16:23 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2016-02-10 22:16:23 +0000 |
commit | 33d175c7d46bc610c6f714f08a2ed102895aea34 (patch) | |
tree | 918f5eb89c3cd09e6d8df3ddd4587fbec6bd05aa | |
parent | ac8b1afad20f51e11b2f06848e0d7f514aca5246 (diff) | |
parent | 6326ae9bf09db60ced8d228343c2113f504c7fe4 (diff) | |
download | libweave-brillo-m10-dev.tar.gz |
Merge master into aosp-masterbrillo-m10-releasebrillo-m10-dev
am: 6326ae9bf0
* commit '6326ae9bf09db60ced8d228343c2113f504c7fe4':
Replace ' in json constants with "
Implement privet properties for changing cloud print endpoints
Replace URL with Url in identifiers
Enable support of endpoints override.
-rw-r--r-- | examples/daemon/common/daemon.h | 44 | ||||
-rw-r--r-- | examples/daemon/light/light.cc | 2 | ||||
-rw-r--r-- | examples/daemon/lock/lock.cc | 2 | ||||
-rw-r--r-- | examples/provider/file_config_store.cc | 1 | ||||
-rw-r--r-- | include/weave/device.h | 27 | ||||
-rw-r--r-- | include/weave/settings.h | 1 | ||||
-rw-r--r-- | include/weave/test/mock_device.h | 2 | ||||
-rw-r--r-- | src/config.cc | 90 | ||||
-rw-r--r-- | src/config.h | 3 | ||||
-rw-r--r-- | src/device_manager.cc | 4 | ||||
-rw-r--r-- | src/device_manager.h | 2 | ||||
-rw-r--r-- | src/device_registration_info.cc | 147 | ||||
-rw-r--r-- | src/device_registration_info.h | 24 | ||||
-rw-r--r-- | src/device_registration_info_unittest.cc | 196 | ||||
-rw-r--r-- | src/privet/cloud_delegate.cc | 27 | ||||
-rw-r--r-- | src/privet/cloud_delegate.h | 9 | ||||
-rw-r--r-- | src/privet/mock_delegates.h | 9 | ||||
-rw-r--r-- | src/privet/privet_handler.cc | 49 | ||||
-rw-r--r-- | src/privet/privet_handler_unittest.cc | 642 | ||||
-rw-r--r-- | src/weave_unittest.cc | 6 |
20 files changed, 761 insertions, 526 deletions
diff --git a/examples/daemon/common/daemon.h b/examples/daemon/common/daemon.h index 985c5e5..0b3c25a 100644 --- a/examples/daemon/common/daemon.h +++ b/examples/daemon/common/daemon.h @@ -19,10 +19,11 @@ class Daemon { public: struct Options { - bool force_bootstrapping_{false}; - bool disable_privet_{false}; - std::string registration_ticket_; - std::string model_id_{"AAAAA"}; + bool force_bootstrapping{false}; + bool disable_privet{false}; + std::string registration_ticket; + std::string model_id{"AAAAA"}; + std::string service_url; static void ShowUsage(const std::string& name) { LOG(ERROR) << "\nUsage: " << name << " <option(s)>" @@ -30,8 +31,10 @@ class Daemon { << "\t-h,--help Show this help message\n" << "\t--v=LEVEL Logging level\n" << "\t-b,--bootstrapping Force WiFi bootstrapping\n" - << "\t--registration_ticket=TICKET Register device with the " - "given ticket\n" + << "\t-r,--registration_ticket=TICKET Register device with " + "the given ticket\n" + << "\t-s,--staging Use staging server. Use " + "only with -r.\n" << "\t--disable_privet Disable local privet\n"; } @@ -41,15 +44,19 @@ class Daemon { if (arg == "-h" || arg == "--help") { return false; } else if (arg == "-b" || arg == "--bootstrapping") { - force_bootstrapping_ = true; + force_bootstrapping = true; + } else if (arg == "-s" || arg == "--staging") { + service_url = + "https://www-googleapis-staging.sandbox.google.com/weave/v1/"; } else if (arg == "--disable_privet") { - disable_privet_ = true; - } else if (arg.find("--registration_ticket") != std::string::npos) { + disable_privet = true; + } else if (arg.find("--registration_ticket=") != std::string::npos || + arg.find("-r=") != std::string::npos) { auto pos = arg.find("="); if (pos == std::string::npos) { return false; } - registration_ticket_ = arg.substr(pos + 1); + registration_ticket = arg.substr(pos + 1); } else if (arg.find("--v") != std::string::npos) { auto pos = arg.find("="); if (pos == std::string::npos) { @@ -66,14 +73,13 @@ class Daemon { Daemon(const Options& opts) : task_runner_{new weave::examples::EventTaskRunner}, - config_store_{ - new weave::examples::FileConfigStore(opts.model_id_, - task_runner_.get())}, + config_store_{new weave::examples::FileConfigStore(opts.model_id, + task_runner_.get())}, http_client_{new weave::examples::CurlHttpClient(task_runner_.get())}, network_{new weave::examples::EventNetworkImpl(task_runner_.get())}, bluetooth_{new weave::examples::BluetoothImpl} { - if (!opts.disable_privet_) { - network_->SetSimulateOffline(opts.force_bootstrapping_); + if (!opts.disable_privet) { + network_->SetSimulateOffline(opts.force_bootstrapping); dns_sd_.reset(new weave::examples::AvahiClient); http_server_.reset( @@ -87,9 +93,11 @@ class Daemon { dns_sd_.get(), http_server_.get(), wifi_.get(), bluetooth_.get()); - if (!opts.registration_ticket_.empty()) { - device_->Register(opts.registration_ticket_, - base::Bind(&OnRegisterDeviceDone, device_.get())); + if (!opts.registration_ticket.empty()) { + weave::RegistrationData data; + data.ticket_id = opts.registration_ticket; + data.service_url = opts.service_url; + device_->Register(data, base::Bind(&OnRegisterDeviceDone, device_.get())); } } diff --git a/examples/daemon/light/light.cc b/examples/daemon/light/light.cc index a78231f..4cbf9b4 100644 --- a/examples/daemon/light/light.cc +++ b/examples/daemon/light/light.cc @@ -304,7 +304,7 @@ class LightHandler { int main(int argc, char** argv) { Daemon::Options opts; - opts.model_id_ = "AIAAA"; + opts.model_id = "AIAAA"; if (!opts.Parse(argc, argv)) { Daemon::Options::ShowUsage(argv[0]); return 1; diff --git a/examples/daemon/lock/lock.cc b/examples/daemon/lock/lock.cc index fcc6ad7..a2da9cf 100644 --- a/examples/daemon/lock/lock.cc +++ b/examples/daemon/lock/lock.cc @@ -134,7 +134,7 @@ class LockHandler { int main(int argc, char** argv) { Daemon::Options opts; - opts.model_id_ = "AOAAA"; + opts.model_id = "AOAAA"; if (!opts.Parse(argc, argv)) { Daemon::Options::ShowUsage(argv[0]); return 1; diff --git a/examples/provider/file_config_store.cc b/examples/provider/file_config_store.cc index b215023..af3f047 100644 --- a/examples/provider/file_config_store.cc +++ b/examples/provider/file_config_store.cc @@ -48,6 +48,7 @@ bool FileConfigStore::LoadDefaults(Settings* settings) { settings->model_id = model_id_; settings->pairing_modes = {PairingType::kEmbeddedCode}; settings->embedded_code = "0000"; + settings->allow_endpoints_override = true; // Keys owners: // avakulenko@google.com diff --git a/include/weave/device.h b/include/weave/device.h index 05e3b78..9a29574 100644 --- a/include/weave/device.h +++ b/include/weave/device.h @@ -31,6 +31,31 @@ enum class GcdState { kInvalidCredentials, // Our registration has been revoked. }; +struct RegistrationData { + explicit RegistrationData(const std::string& ticket = {}) + : ticket_id{ticket} {} + + std::string ticket_id; + + std::string oauth_url; + std::string client_id; + std::string client_secret; + std::string api_key; + std::string service_url; + std::string xmpp_endpoint; +}; + +inline bool operator==(const RegistrationData& l, const RegistrationData& r) { + return l.ticket_id == r.ticket_id && l.oauth_url == r.oauth_url && + l.client_id == r.client_id && l.client_secret == r.client_secret && + l.api_key == r.api_key && l.service_url == r.service_url && + l.xmpp_endpoint == r.xmpp_endpoint; +} + +inline bool operator!=(const RegistrationData& l, const RegistrationData& r) { + return !(l == r); +} + class Device { public: virtual ~Device() {} @@ -141,7 +166,7 @@ class Device { // Registers the device. // This is testing method and should not be used by applications. - virtual void Register(const std::string& ticket_id, + virtual void Register(const RegistrationData& registration_data, const DoneCallback& callback) = 0; // Handler should display pin code to the user. diff --git a/include/weave/settings.h b/include/weave/settings.h index 7cb798d..2ba619c 100644 --- a/include/weave/settings.h +++ b/include/weave/settings.h @@ -71,6 +71,7 @@ struct Settings { // Internal options to tweak some library functionality. External code should // avoid using them. + bool allow_endpoints_override{false}; bool wifi_auto_setup_enabled{true}; std::string test_privet_ssid; }; diff --git a/include/weave/test/mock_device.h b/include/weave/test/mock_device.h index 2f380e0..8e75d44 100644 --- a/include/weave/test/mock_device.h +++ b/include/weave/test/mock_device.h @@ -63,7 +63,7 @@ class MockDevice : public Device { MOCK_METHOD1(AddGcdStateChangedCallback, void(const GcdStateChangedCallback& callback)); MOCK_METHOD2(Register, - void(const std::string& ticket_id, + void(const RegistrationData& registration_data, const DoneCallback& callback)); MOCK_METHOD2(AddPairingChangedCallbacks, void(const PairingBeginCallback& begin_callback, diff --git a/src/config.cc b/src/config.cc index 21a1c1f..cd28de9 100644 --- a/src/config.cc +++ b/src/config.cc @@ -31,8 +31,8 @@ const char kVersion[] = "version"; const char kClientId[] = "client_id"; const char kClientSecret[] = "client_secret"; const char kApiKey[] = "api_key"; -const char kOAuthURL[] = "oauth_url"; -const char kServiceURL[] = "service_url"; +const char kOAuthUrl[] = "oauth_url"; +const char kServiceUrl[] = "service_url"; const char kXmppEndpoint[] = "xmpp_endpoint"; const char kName[] = "name"; const char kDescription[] = "description"; @@ -67,7 +67,7 @@ void MigrateFromV0(base::DictionaryValue* dict) { dict->Set(config_keys::kCloudId, std::move(tmp)); } -Config::Settings CreateDefaultSettings() { +Config::Settings CreateDefaultSettings(provider::ConfigStore* config_store) { Config::Settings result; result.oauth_url = "https://accounts.google.com/o/oauth2/"; result.service_url = kWeaveUrl; @@ -75,6 +75,36 @@ Config::Settings CreateDefaultSettings() { result.local_anonymous_access_role = AuthScope::kViewer; result.pairing_modes.insert(PairingType::kPinCode); result.device_id = base::GenerateGUID(); + + if (!config_store) + return result; + + // Crash on any mistakes in defaults. + CHECK(config_store->LoadDefaults(&result)); + + CHECK(!result.client_id.empty()); + CHECK(!result.client_secret.empty()); + CHECK(!result.api_key.empty()); + CHECK(!result.oauth_url.empty()); + CHECK(!result.service_url.empty()); + CHECK(!result.xmpp_endpoint.empty()); + CHECK(!result.oem_name.empty()); + CHECK(!result.model_name.empty()); + CHECK(!result.model_id.empty()); + CHECK(!result.name.empty()); + CHECK(!result.device_id.empty()); + CHECK_EQ(result.embedded_code.empty(), + (result.pairing_modes.find(PairingType::kEmbeddedCode) == + result.pairing_modes.end())); + + // Values below will be generated at runtime. + CHECK(result.cloud_id.empty()); + CHECK(result.refresh_token.empty()); + CHECK(result.robot_account.empty()); + CHECK(result.last_configured_ssid.empty()); + CHECK(result.secret.empty()); + CHECK(result.root_client_token_owner == RootClientTokenOwner::kNone); + return result; } @@ -91,8 +121,12 @@ LIBWEAVE_EXPORT EnumToStringMap<RootClientTokenOwner>::EnumToStringMap() : EnumToStringMap(kRootClientTokenOwnerMap) {} Config::Config(provider::ConfigStore* config_store) - : settings_{CreateDefaultSettings()}, config_store_{config_store} { - Load(); + : defaults_{CreateDefaultSettings(config_store)}, + settings_{defaults_}, + config_store_{config_store} { + Transaction change{this}; + change.save_ = false; + change.LoadState(); } void Config::AddOnChangedCallback(const OnChangedCallback& callback) { @@ -105,42 +139,8 @@ const Config::Settings& Config::GetSettings() const { return settings_; } -void Config::Load() { - Transaction change{this}; - change.save_ = false; - - settings_ = CreateDefaultSettings(); - - if (!config_store_) - return; - - // Crash on any mistakes in defaults. - CHECK(config_store_->LoadDefaults(&settings_)); - - CHECK(!settings_.client_id.empty()); - CHECK(!settings_.client_secret.empty()); - CHECK(!settings_.api_key.empty()); - CHECK(!settings_.oauth_url.empty()); - CHECK(!settings_.service_url.empty()); - CHECK(!settings_.xmpp_endpoint.empty()); - CHECK(!settings_.oem_name.empty()); - CHECK(!settings_.model_name.empty()); - CHECK(!settings_.model_id.empty()); - CHECK(!settings_.name.empty()); - CHECK(!settings_.device_id.empty()); - CHECK_EQ(settings_.embedded_code.empty(), - (settings_.pairing_modes.find(PairingType::kEmbeddedCode) == - settings_.pairing_modes.end())); - - // Values below will be generated at runtime. - CHECK(settings_.cloud_id.empty()); - CHECK(settings_.refresh_token.empty()); - CHECK(settings_.robot_account.empty()); - CHECK(settings_.last_configured_ssid.empty()); - CHECK(settings_.secret.empty()); - CHECK(settings_.root_client_token_owner == RootClientTokenOwner::kNone); - - change.LoadState(); +const Config::Settings& Config::GetDefaults() const { + return defaults_; } void Config::Transaction::LoadState() { @@ -185,10 +185,10 @@ void Config::Transaction::LoadState() { if (dict->GetString(config_keys::kApiKey, &tmp)) set_api_key(tmp); - if (dict->GetString(config_keys::kOAuthURL, &tmp)) + if (dict->GetString(config_keys::kOAuthUrl, &tmp)) set_oauth_url(tmp); - if (dict->GetString(config_keys::kServiceURL, &tmp)) { + if (dict->GetString(config_keys::kServiceUrl, &tmp)) { if (tmp == kDeprecatedUrl) tmp = kWeaveUrl; set_service_url(tmp); @@ -255,8 +255,8 @@ void Config::Save() { dict.SetString(config_keys::kClientId, settings_.client_id); dict.SetString(config_keys::kClientSecret, settings_.client_secret); dict.SetString(config_keys::kApiKey, settings_.api_key); - dict.SetString(config_keys::kOAuthURL, settings_.oauth_url); - dict.SetString(config_keys::kServiceURL, settings_.service_url); + dict.SetString(config_keys::kOAuthUrl, settings_.oauth_url); + dict.SetString(config_keys::kServiceUrl, settings_.service_url); dict.SetString(config_keys::kXmppEndpoint, settings_.xmpp_endpoint); dict.SetString(config_keys::kRefreshToken, settings_.refresh_token); dict.SetString(config_keys::kCloudId, settings_.cloud_id); diff --git a/src/config.h b/src/config.h index 8e0a8f3..692d9c5 100644 --- a/src/config.h +++ b/src/config.h @@ -45,6 +45,7 @@ class Config final { void AddOnChangedCallback(const OnChangedCallback& callback); const Config::Settings& GetSettings() const; + const Config::Settings& GetDefaults() const; // Allows editing of config. Makes sure that callbacks were called and changes // were saved. @@ -121,9 +122,9 @@ class Config final { }; private: - void Load(); void Save(); + const Settings defaults_; Settings settings_; provider::ConfigStore* config_store_{nullptr}; std::vector<OnChangedCallback> on_changed_; diff --git a/src/device_manager.cc b/src/device_manager.cc index deb5404..4c0d3ee 100644 --- a/src/device_manager.cc +++ b/src/device_manager.cc @@ -262,9 +262,9 @@ const base::DictionaryValue& DeviceManager::GetState() const { return component_manager_->GetLegacyState(); } -void DeviceManager::Register(const std::string& ticket_id, +void DeviceManager::Register(const RegistrationData& registration_data, const DoneCallback& callback) { - device_info_->RegisterDevice(ticket_id, callback); + device_info_->RegisterDevice(registration_data, callback); } void DeviceManager::AddPairingChangedCallbacks( diff --git a/src/device_manager.h b/src/device_manager.h index d77bacc..f0ad464 100644 --- a/src/device_manager.h +++ b/src/device_manager.h @@ -69,7 +69,7 @@ class DeviceManager final : public Device { ErrorPtr* error) override; Command* FindCommand(const std::string& id) override; void AddStateChangedCallback(const base::Closure& callback) override; - void Register(const std::string& ticket_id, + void Register(const RegistrationData& registration_data, const DoneCallback& callback) override; GcdState GetGcdState() const override; void AddGcdStateChangedCallback( diff --git a/src/device_registration_info.cc b/src/device_registration_info.cc index 0dc1f54..3ae1321 100644 --- a/src/device_registration_info.cc +++ b/src/device_registration_info.cc @@ -28,6 +28,7 @@ #include "src/json_error_codes.h" #include "src/notification/xmpp_channel.h" #include "src/privet/auth_manager.h" +#include "src/privet/constants.h" #include "src/string_utils.h" #include "src/utils.h" @@ -90,7 +91,7 @@ std::string AppendQueryParams(const std::string& url, return url + '?' + WebParamsEncode(params); } -std::string BuildURL(const std::string& url, +std::string BuildUrl(const std::string& url, const std::string& subpath, const WebParamList& params) { std::string result = url; @@ -271,24 +272,24 @@ DeviceRegistrationInfo::DeviceRegistrationInfo( DeviceRegistrationInfo::~DeviceRegistrationInfo() = default; -std::string DeviceRegistrationInfo::GetServiceURL( +std::string DeviceRegistrationInfo::GetServiceUrl( const std::string& subpath, const WebParamList& params) const { - return BuildURL(GetSettings().service_url, subpath, params); + return BuildUrl(GetSettings().service_url, subpath, params); } -std::string DeviceRegistrationInfo::GetDeviceURL( +std::string DeviceRegistrationInfo::GetDeviceUrl( const std::string& subpath, const WebParamList& params) const { CHECK(!GetSettings().cloud_id.empty()) << "Must have a valid device ID"; - return BuildURL(GetSettings().service_url, - "devices/" + GetSettings().cloud_id + "/" + subpath, params); + return GetServiceUrl("devices/" + GetSettings().cloud_id + "/" + subpath, + params); } -std::string DeviceRegistrationInfo::GetOAuthURL( +std::string DeviceRegistrationInfo::GetOAuthUrl( const std::string& subpath, const WebParamList& params) const { - return BuildURL(GetSettings().oauth_url, subpath, params); + return BuildUrl(GetSettings().oauth_url, subpath, params); } void DeviceRegistrationInfo::Start() { @@ -375,7 +376,7 @@ void DeviceRegistrationInfo::RefreshAccessToken(const DoneCallback& callback) { return; } - RequestSender sender{HttpClient::Method::kPost, GetOAuthURL("token"), + RequestSender sender{HttpClient::Method::kPost, GetOAuthUrl("token"), http_client_}; sender.SetFormData({ {"refresh_token", GetSettings().refresh_token}, @@ -506,7 +507,7 @@ void DeviceRegistrationInfo::GetDeviceInfo( ErrorPtr error; if (!VerifyRegistrationCredentials(&error)) return callback.Run({}, std::move(error)); - DoCloudRequest(HttpClient::Method::kGet, GetDeviceURL(), nullptr, callback); + DoCloudRequest(HttpClient::Method::kGet, GetDeviceUrl(), nullptr, callback); } void DeviceRegistrationInfo::RegisterDeviceError(const DoneCallback& callback, @@ -515,8 +516,47 @@ void DeviceRegistrationInfo::RegisterDeviceError(const DoneCallback& callback, base::Bind(callback, base::Passed(&error)), {}); } -void DeviceRegistrationInfo::RegisterDevice(const std::string& ticket_id, +void DeviceRegistrationInfo::RegisterDevice(RegistrationData registration_data, const DoneCallback& callback) { + if (!GetSettings().allow_endpoints_override && + registration_data != RegistrationData{registration_data.ticket_id}) { + ErrorPtr error; + Error::AddTo(&error, FROM_HERE, privet::errors::kInvalidParams, + "Endpoint change is not permitted"); + return RegisterDeviceError(callback, std::move(error)); + } + + // Reset OAuth to defaults, if device was unregistered values can be + // customized. These muse be replaced all together. + if (registration_data.oauth_url.empty() || + registration_data.client_id.empty() || + registration_data.client_secret.empty() || + registration_data.api_key.empty()) { + registration_data.oauth_url = GetDefaults().oauth_url; + registration_data.client_id = GetDefaults().client_id; + registration_data.client_secret = GetDefaults().client_secret; + registration_data.api_key = GetDefaults().api_key; + } + + // Reset Server URL to default, if device was unregistered value can be + // customized. + if (registration_data.service_url.empty()) + registration_data.service_url = GetDefaults().service_url; + + // Reset XMPP to default, if device was unregistered value can be + // customized. + if (registration_data.xmpp_endpoint.empty()) + registration_data.xmpp_endpoint = GetDefaults().xmpp_endpoint; + + VLOG(1) << "RegisterDevice: " + << "ticket_id: " << registration_data.ticket_id + << ", oauth_url: " << registration_data.oauth_url + << ", client_id: " << registration_data.client_id + << ", client_secret: " << registration_data.client_secret + << ", api_key: " << registration_data.api_key + << ", service_url: " << registration_data.service_url + << ", xmpp_endpoint: " << registration_data.xmpp_endpoint; + if (HaveRegistrationCredentials()) { ErrorPtr error; Error::AddTo(&error, FROM_HERE, kErrorAlreayRegistered, @@ -528,21 +568,23 @@ void DeviceRegistrationInfo::RegisterDevice(const std::string& ticket_id, CHECK(device_draft); base::DictionaryValue req_json; - req_json.SetString("id", ticket_id); - req_json.SetString("oauthClientId", GetSettings().client_id); + req_json.SetString("id", registration_data.ticket_id); + req_json.SetString("oauthClientId", registration_data.client_id); req_json.Set("deviceDraft", device_draft.release()); - auto url = GetServiceURL("registrationTickets/" + ticket_id, - {{"key", GetSettings().api_key}}); + auto url = BuildUrl(registration_data.service_url, + "registrationTickets/" + registration_data.ticket_id, + {{"key", registration_data.api_key}}); RequestSender sender{HttpClient::Method::kPatch, url, http_client_}; sender.SetJsonData(req_json); sender.Send(base::Bind(&DeviceRegistrationInfo::RegisterDeviceOnTicketSent, - weak_factory_.GetWeakPtr(), ticket_id, callback)); + weak_factory_.GetWeakPtr(), registration_data, + callback)); } void DeviceRegistrationInfo::RegisterDeviceOnTicketSent( - const std::string& ticket_id, + const RegistrationData& registration_data, const DoneCallback& callback, std::unique_ptr<provider::HttpClient::Response> response, ErrorPtr error) { @@ -557,15 +599,17 @@ void DeviceRegistrationInfo::RegisterDeviceOnTicketSent( return RegisterDeviceError(callback, std::move(error)); } - std::string url = - GetServiceURL("registrationTickets/" + ticket_id + "/finalize", - {{"key", GetSettings().api_key}}); + std::string url = BuildUrl( + registration_data.service_url, + "registrationTickets/" + registration_data.ticket_id + "/finalize", + {{"key", registration_data.api_key}}); RequestSender{HttpClient::Method::kPost, url, http_client_}.Send( base::Bind(&DeviceRegistrationInfo::RegisterDeviceOnTicketFinalized, - weak_factory_.GetWeakPtr(), callback)); + weak_factory_.GetWeakPtr(), registration_data, callback)); } void DeviceRegistrationInfo::RegisterDeviceOnTicketFinalized( + const RegistrationData& registration_data, const DoneCallback& callback, std::unique_ptr<provider::HttpClient::Response> response, ErrorPtr error) { @@ -595,19 +639,21 @@ void DeviceRegistrationInfo::RegisterDeviceOnTicketFinalized( UpdateDeviceInfoTimestamp(*device_draft_response); // Now get access_token and refresh_token - RequestSender sender2{HttpClient::Method::kPost, GetOAuthURL("token"), + RequestSender sender2{HttpClient::Method::kPost, + BuildUrl(registration_data.oauth_url, "token", {}), http_client_}; sender2.SetFormData({{"code", auth_code}, - {"client_id", GetSettings().client_id}, - {"client_secret", GetSettings().client_secret}, + {"client_id", registration_data.client_id}, + {"client_secret", registration_data.client_secret}, {"redirect_uri", "oob"}, {"grant_type", "authorization_code"}}); sender2.Send(base::Bind(&DeviceRegistrationInfo::RegisterDeviceOnAuthCodeSent, - weak_factory_.GetWeakPtr(), cloud_id, robot_account, - callback)); + weak_factory_.GetWeakPtr(), registration_data, + cloud_id, robot_account, callback)); } void DeviceRegistrationInfo::RegisterDeviceOnAuthCodeSent( + const RegistrationData& registration_data, const std::string& cloud_id, const std::string& robot_account, const DoneCallback& callback, @@ -631,9 +677,18 @@ void DeviceRegistrationInfo::RegisterDeviceOnAuthCodeSent( base::Time::Now() + base::TimeDelta::FromSeconds(expires_in); Config::Transaction change{config_}; + change.set_cloud_id(cloud_id); change.set_robot_account(robot_account); change.set_refresh_token(refresh_token); + + change.set_oauth_url(registration_data.oauth_url); + change.set_client_id(registration_data.client_id); + change.set_client_secret(registration_data.client_secret); + change.set_api_key(registration_data.api_key); + change.set_service_url(registration_data.service_url); + change.set_xmpp_endpoint(registration_data.xmpp_endpoint); + change.Commit(); task_runner_->PostDelayedTask(FROM_HERE, base::Bind(callback, nullptr), {}); @@ -828,40 +883,12 @@ void DeviceRegistrationInfo::UpdateBaseConfig(AuthScope anonymous_access_role, change.set_local_pairing_enabled(local_pairing_enabled); } -bool DeviceRegistrationInfo::UpdateServiceConfig( - const std::string& client_id, - const std::string& client_secret, - const std::string& api_key, - const std::string& oauth_url, - const std::string& service_url, - const std::string& xmpp_endpoint, - ErrorPtr* error) { - if (HaveRegistrationCredentials()) { - return Error::AddTo(error, FROM_HERE, kErrorAlreayRegistered, - "Unable to change config for registered device"); - } - Config::Transaction change{config_}; - if (!client_id.empty()) - change.set_client_id(client_id); - if (!client_secret.empty()) - change.set_client_secret(client_secret); - if (!api_key.empty()) - change.set_api_key(api_key); - if (!oauth_url.empty()) - change.set_oauth_url(oauth_url); - if (!service_url.empty()) - change.set_service_url(service_url); - if (!xmpp_endpoint.empty()) - change.set_xmpp_endpoint(xmpp_endpoint); - return true; -} - void DeviceRegistrationInfo::UpdateCommand( const std::string& command_id, const base::DictionaryValue& command_patch, const DoneCallback& callback) { DoCloudRequest(HttpClient::Method::kPatch, - GetServiceURL("commands/" + command_id), &command_patch, + GetServiceUrl("commands/" + command_id), &command_patch, base::Bind(&IgnoreCloudResultWithCallback, callback)); } @@ -915,7 +942,7 @@ void DeviceRegistrationInfo::StartQueuedUpdateDeviceResource() { BuildDeviceResource(); CHECK(device_resource); - std::string url = GetDeviceURL( + std::string url = GetDeviceUrl( {}, {{"lastUpdateTimeMs", last_device_resource_updated_timestamp_}}); DoCloudRequest(HttpClient::Method::kPut, url, device_resource.get(), @@ -951,7 +978,7 @@ void DeviceRegistrationInfo::SendAuthInfo() { std::unique_ptr<base::DictionaryValue> root{new base::DictionaryValue}; root->Set("localAuthInfo", auth.release()); - std::string url = GetDeviceURL("upsertLocalAuthInfo", {}); + std::string url = GetDeviceUrl("upsertLocalAuthInfo", {}); DoCloudRequest(HttpClient::Method::kPost, url, root.get(), base::Bind(&DeviceRegistrationInfo::OnSendAuthInfoDone, AsWeakPtr(), token)); @@ -1058,7 +1085,7 @@ void DeviceRegistrationInfo::FetchCommands( fetch_commands_request_queued_ = false; DoCloudRequest( HttpClient::Method::kGet, - GetServiceURL("commands/queue", + GetServiceUrl("commands/queue", {{"deviceId", GetSettings().cloud_id}, {"reason", reason}}), nullptr, base::Bind(&DeviceRegistrationInfo::OnFetchCommandsDone, AsWeakPtr(), callback)); @@ -1106,7 +1133,7 @@ void DeviceRegistrationInfo::ProcessInitialCommandList( cmd_copy->SetString("state", "aborted"); // TODO(wiley) We could consider handling this error case more gracefully. DoCloudRequest(HttpClient::Method::kPut, - GetServiceURL("commands/" + command_id), cmd_copy.get(), + GetServiceUrl("commands/" + command_id), cmd_copy.get(), base::Bind(&IgnoreCloudResult)); } else { // Normal command, publish it to local clients. @@ -1184,7 +1211,7 @@ void DeviceRegistrationInfo::PublishStateUpdates() { body.Set("patches", patches.release()); device_state_update_pending_ = true; - DoCloudRequest(HttpClient::Method::kPost, GetDeviceURL("patchState"), &body, + DoCloudRequest(HttpClient::Method::kPost, GetDeviceUrl("patchState"), &body, base::Bind(&DeviceRegistrationInfo::OnPublishStateDone, AsWeakPtr(), snapshot.update_id)); } diff --git a/src/device_registration_info.h b/src/device_registration_info.h index a296258..a488bae 100644 --- a/src/device_registration_info.h +++ b/src/device_registration_info.h @@ -64,7 +64,8 @@ class DeviceRegistrationInfo : public NotificationDelegate, void AddGcdStateChangedCallback( const Device::GcdStateChangedCallback& callback); - void RegisterDevice(const std::string& ticket_id, + + void RegisterDevice(RegistrationData registration_data, const DoneCallback& callback); void UpdateDeviceInfo(const std::string& name, @@ -73,13 +74,6 @@ class DeviceRegistrationInfo : public NotificationDelegate, void UpdateBaseConfig(AuthScope anonymous_access_role, bool local_discovery_enabled, bool local_pairing_enabled); - bool UpdateServiceConfig(const std::string& client_id, - const std::string& client_secret, - const std::string& api_key, - const std::string& oauth_url, - const std::string& service_url, - const std::string& xmpp_endpoint, - ErrorPtr* error); void GetDeviceInfo(const CloudRequestDoneCallback& callback); @@ -90,21 +84,21 @@ class DeviceRegistrationInfo : public NotificationDelegate, // WebParamsEncode() and appended to URL as a query // string. // So, calling: - // GetServiceURL("ticket", {{"key","apiKey"}}) + // GetServiceUrl("ticket", {{"key","apiKey"}}) // will return something like: // https://www.googleapis.com/weave/v1/ticket?key=apiKey - std::string GetServiceURL(const std::string& subpath = {}, + std::string GetServiceUrl(const std::string& subpath = {}, const WebParamList& params = {}) const; // Returns a service URL to access the registered device on GCD server. // The base URL used to construct the full URL looks like this: // https://www.googleapis.com/weave/v1/devices/<cloud_id>/ - std::string GetDeviceURL(const std::string& subpath = {}, + std::string GetDeviceUrl(const std::string& subpath = {}, const WebParamList& params = {}) const; // Similar to GetServiceURL, GetOAuthURL() returns a URL of OAuth 2.0 server. // The base URL used is https://accounts.google.com/o/oauth2/. - std::string GetOAuthURL(const std::string& subpath = {}, + std::string GetOAuthUrl(const std::string& subpath = {}, const WebParamList& params = {}) const; // Starts GCD device if credentials available. @@ -124,6 +118,8 @@ class DeviceRegistrationInfo : public NotificationDelegate, private: friend class DeviceRegistrationInfoTest; + const Config::Settings& GetDefaults() const { return config_->GetDefaults(); } + base::WeakPtr<DeviceRegistrationInfo> AsWeakPtr() { return weak_factory_.GetWeakPtr(); } @@ -276,15 +272,17 @@ class DeviceRegistrationInfo : public NotificationDelegate, void RegisterDeviceError(const DoneCallback& callback, ErrorPtr error); void RegisterDeviceOnTicketSent( - const std::string& ticket_id, + const RegistrationData& registration_data, const DoneCallback& callback, std::unique_ptr<provider::HttpClient::Response> response, ErrorPtr error); void RegisterDeviceOnTicketFinalized( + const RegistrationData& registration_data, const DoneCallback& callback, std::unique_ptr<provider::HttpClient::Response> response, ErrorPtr error); void RegisterDeviceOnAuthCodeSent( + const RegistrationData& registration_data, const std::string& cloud_id, const std::string& robot_account, const DoneCallback& callback, diff --git a/src/device_registration_info_unittest.cc b/src/device_registration_info_unittest.cc index bbc167e..adc5175 100644 --- a/src/device_registration_info_unittest.cc +++ b/src/device_registration_info_unittest.cc @@ -45,8 +45,8 @@ namespace { namespace test_data { const char kXmppEndpoint[] = "xmpp.server.com:1234"; -const char kServiceURL[] = "http://gcd.server.com/"; -const char kOAuthURL[] = "http://oauth.server.com/"; +const char kServiceUrl[] = "http://gcd.server.com/"; +const char kOAuthUrl[] = "http://oauth.server.com/"; const char kApiKey[] = "GOadRdTf9FERf0k4w6EFOof56fUJ3kFDdFL3d7f"; const char kClientId[] = "123543821385-sfjkjshdkjhfk234sdfsdfkskd" @@ -127,12 +127,12 @@ class DeviceRegistrationInfoTest : public ::testing::Test { void SetUp() override { EXPECT_CALL(clock_, Now()) .WillRepeatedly(Return(base::Time::FromTimeT(1450000000))); - ReloadDefaults(); + ReloadDefaults(true); } - void ReloadDefaults() { + void ReloadDefaults(bool allow_endpoints_override) { EXPECT_CALL(config_store_, LoadDefaults(_)) - .WillOnce(Invoke([](Settings* settings) { + .WillOnce(Invoke([allow_endpoints_override](Settings* settings) { settings->client_id = test_data::kClientId; settings->client_secret = test_data::kClientSecret; settings->api_key = test_data::kApiKey; @@ -143,9 +143,10 @@ class DeviceRegistrationInfoTest : public ::testing::Test { settings->location = "Kitchen"; settings->local_anonymous_access_role = AuthScope::kViewer; settings->model_id = "AAAAA"; - settings->oauth_url = test_data::kOAuthURL; - settings->service_url = test_data::kServiceURL; + settings->oauth_url = test_data::kOAuthUrl; + settings->service_url = test_data::kServiceUrl; settings->xmpp_endpoint = test_data::kXmppEndpoint; + settings->allow_endpoints_override = allow_endpoints_override; return true; })); config_.reset(new Config{&config_store_}); @@ -155,7 +156,7 @@ class DeviceRegistrationInfoTest : public ::testing::Test { dev_reg_->Start(); } - void ReloadSettings(bool registered = true) { + void ReloadSettings(bool registered, bool allow_endpoints_override) { base::DictionaryValue dict; dict.SetInteger("version", 1); if (registered) { @@ -168,7 +169,7 @@ class DeviceRegistrationInfoTest : public ::testing::Test { base::JSONWriter::WriteWithOptions( dict, base::JSONWriter::OPTIONS_PRETTY_PRINT, &json_string); EXPECT_CALL(config_store_, LoadSettings()).WillOnce(Return(json_string)); - ReloadDefaults(); + ReloadDefaults(allow_endpoints_override); } void PublishCommands(const base::ListValue& commands) { @@ -196,6 +197,9 @@ class DeviceRegistrationInfoTest : public ::testing::Test { return dev_reg_->HaveRegistrationCredentials(); } + void RegisterDevice(const RegistrationData registration_data, + const RegistrationData& expected_data); + provider::test::FakeTaskRunner task_runner_; provider::test::MockConfigStore config_store_; StrictMock<MockHttpClient> http_client_; @@ -213,31 +217,31 @@ class DeviceRegistrationInfoTest : public ::testing::Test { ComponentManagerImpl component_manager_{&task_runner_}; }; -TEST_F(DeviceRegistrationInfoTest, GetServiceURL) { - EXPECT_EQ(test_data::kServiceURL, dev_reg_->GetServiceURL()); - std::string url = test_data::kServiceURL; +TEST_F(DeviceRegistrationInfoTest, GetServiceUrl) { + EXPECT_EQ(test_data::kServiceUrl, dev_reg_->GetServiceUrl()); + std::string url = test_data::kServiceUrl; url += "registrationTickets"; - EXPECT_EQ(url, dev_reg_->GetServiceURL("registrationTickets")); + EXPECT_EQ(url, dev_reg_->GetServiceUrl("registrationTickets")); url += "?key="; url += test_data::kApiKey; - EXPECT_EQ(url, dev_reg_->GetServiceURL("registrationTickets", + EXPECT_EQ(url, dev_reg_->GetServiceUrl("registrationTickets", {{"key", test_data::kApiKey}})); url += "&restart=true"; - EXPECT_EQ(url, dev_reg_->GetServiceURL( + EXPECT_EQ(url, dev_reg_->GetServiceUrl( "registrationTickets", { {"key", test_data::kApiKey}, {"restart", "true"}, })); } -TEST_F(DeviceRegistrationInfoTest, GetOAuthURL) { - EXPECT_EQ(test_data::kOAuthURL, dev_reg_->GetOAuthURL()); - std::string url = test_data::kOAuthURL; +TEST_F(DeviceRegistrationInfoTest, GetOAuthUrl) { + EXPECT_EQ(test_data::kOAuthUrl, dev_reg_->GetOAuthUrl()); + std::string url = test_data::kOAuthUrl; url += "auth?redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&"; url += "response_type=code&"; url += "client_id="; url += test_data::kClientId; - EXPECT_EQ(url, dev_reg_->GetOAuthURL( + EXPECT_EQ(url, dev_reg_->GetOAuthUrl( "auth", {{"redirect_uri", "urn:ietf:wg:oauth:2.0:oob"}, {"response_type", "code"}, {"client_id", test_data::kClientId}})); @@ -245,11 +249,11 @@ TEST_F(DeviceRegistrationInfoTest, GetOAuthURL) { TEST_F(DeviceRegistrationInfoTest, HaveRegistrationCredentials) { EXPECT_FALSE(HaveRegistrationCredentials()); - ReloadSettings(); + ReloadSettings(true, false); EXPECT_CALL( http_client_, - SendRequest(HttpClient::Method::kPost, dev_reg_->GetOAuthURL("token"), + SendRequest(HttpClient::Method::kPost, dev_reg_->GetOAuthUrl("token"), HttpClient::Headers{GetFormHeader()}, _, _)) .WillOnce(WithArgs<3, 4>( Invoke([](const std::string& data, @@ -287,12 +291,12 @@ TEST_F(DeviceRegistrationInfoTest, HaveRegistrationCredentials) { } TEST_F(DeviceRegistrationInfoTest, CheckAuthenticationFailure) { - ReloadSettings(); + ReloadSettings(true, false); EXPECT_EQ(GcdState::kConnecting, GetGcdState()); EXPECT_CALL( http_client_, - SendRequest(HttpClient::Method::kPost, dev_reg_->GetOAuthURL("token"), + SendRequest(HttpClient::Method::kPost, dev_reg_->GetOAuthUrl("token"), HttpClient::Headers{GetFormHeader()}, _, _)) .WillOnce(WithArgs<3, 4>( Invoke([](const std::string& data, @@ -316,12 +320,12 @@ TEST_F(DeviceRegistrationInfoTest, CheckAuthenticationFailure) { } TEST_F(DeviceRegistrationInfoTest, CheckDeregistration) { - ReloadSettings(); + ReloadSettings(true, false); EXPECT_EQ(GcdState::kConnecting, GetGcdState()); EXPECT_CALL( http_client_, - SendRequest(HttpClient::Method::kPost, dev_reg_->GetOAuthURL("token"), + SendRequest(HttpClient::Method::kPost, dev_reg_->GetOAuthUrl("token"), HttpClient::Headers{GetFormHeader()}, _, _)) .WillOnce(WithArgs<3, 4>( Invoke([](const std::string& data, @@ -346,12 +350,12 @@ TEST_F(DeviceRegistrationInfoTest, CheckDeregistration) { } TEST_F(DeviceRegistrationInfoTest, GetDeviceInfo) { - ReloadSettings(); + ReloadSettings(true, false); SetAccessToken(); EXPECT_CALL( http_client_, - SendRequest(HttpClient::Method::kGet, dev_reg_->GetDeviceURL(), + SendRequest(HttpClient::Method::kGet, dev_reg_->GetDeviceUrl(), HttpClient::Headers{GetAuthHeader(), GetJsonHeader()}, _, _)) .WillOnce(WithArgs<3, 4>( Invoke([](const std::string& data, @@ -377,9 +381,32 @@ TEST_F(DeviceRegistrationInfoTest, GetDeviceInfo) { EXPECT_TRUE(succeeded); } -TEST_F(DeviceRegistrationInfoTest, RegisterDevice) { - ReloadSettings(false); +TEST_F(DeviceRegistrationInfoTest, ReRegisterDevice) { + ReloadSettings(true, false); + + bool done = false; + dev_reg_->RegisterDevice(RegistrationData{test_data::kClaimTicketId}, + base::Bind([this, &done](ErrorPtr error) { + EXPECT_TRUE(error->HasError("already_registered")); + done = true; + task_runner_.Break(); + EXPECT_EQ(GcdState::kConnecting, GetGcdState()); + + // Validate the device info saved to storage... + EXPECT_EQ(test_data::kCloudId, + dev_reg_->GetSettings().cloud_id); + EXPECT_EQ(test_data::kRefreshToken, + dev_reg_->GetSettings().refresh_token); + EXPECT_EQ(test_data::kRobotAccountEmail, + dev_reg_->GetSettings().robot_account); + })); + task_runner_.Run(); + EXPECT_TRUE(done); +} +void DeviceRegistrationInfoTest::RegisterDevice( + const RegistrationData registration_data, + const RegistrationData& expected_data) { auto json_traits = CreateDictionaryValue(R"({ 'base': { 'commands': { @@ -408,25 +435,25 @@ TEST_F(DeviceRegistrationInfoTest, RegisterDevice) { EXPECT_TRUE(component_manager_.SetStateProperty( "comp", "base.firmwareVersion", ver, nullptr)); - std::string ticket_url = dev_reg_->GetServiceURL("registrationTickets/") + - test_data::kClaimTicketId; + std::string ticket_url = expected_data.service_url + "registrationTickets/" + + expected_data.ticket_id; EXPECT_CALL(http_client_, SendRequest(HttpClient::Method::kPatch, - ticket_url + "?key=" + test_data::kApiKey, + ticket_url + "?key=" + expected_data.api_key, HttpClient::Headers{GetJsonHeader()}, _, _)) - .WillOnce(WithArgs<3, 4>( - Invoke([](const std::string& data, - const HttpClient::SendRequestCallback& callback) { + .WillOnce(WithArgs<3, 4>(Invoke( + [&expected_data](const std::string& data, + const HttpClient::SendRequestCallback& callback) { auto json = test::CreateDictionaryValue(data); EXPECT_NE(nullptr, json.get()); std::string value; EXPECT_TRUE(json->GetString("id", &value)); - EXPECT_EQ(test_data::kClaimTicketId, value); + EXPECT_EQ(expected_data.ticket_id, value); EXPECT_TRUE( json->GetString("deviceDraft.channel.supportedType", &value)); EXPECT_EQ("pull", value); EXPECT_TRUE(json->GetString("oauthClientId", &value)); - EXPECT_EQ(test_data::kClientId, value); + EXPECT_EQ(expected_data.client_id, value); EXPECT_TRUE(json->GetString("deviceDraft.description", &value)); EXPECT_EQ("Easy to clean", value); EXPECT_TRUE(json->GetString("deviceDraft.location", &value)); @@ -489,7 +516,7 @@ TEST_F(DeviceRegistrationInfoTest, RegisterDevice) { EXPECT_CALL(http_client_, SendRequest(HttpClient::Method::kPost, - ticket_url + "/finalize?key=" + test_data::kApiKey, + ticket_url + "/finalize?key=" + expected_data.api_key, HttpClient::Headers{}, _, _)) .WillOnce(WithArgs<4>( Invoke([](const HttpClient::SendRequestCallback& callback) { @@ -509,15 +536,15 @@ TEST_F(DeviceRegistrationInfoTest, RegisterDevice) { EXPECT_CALL( http_client_, - SendRequest(HttpClient::Method::kPost, dev_reg_->GetOAuthURL("token"), + SendRequest(HttpClient::Method::kPost, expected_data.oauth_url + "token", HttpClient::Headers{GetFormHeader()}, _, _)) - .WillOnce(WithArgs<3, 4>(Invoke([]( + .WillOnce(WithArgs<3, 4>(Invoke([&expected_data]( const std::string& data, const HttpClient::SendRequestCallback& callback) { EXPECT_EQ("authorization_code", GetFormField(data, "grant_type")); EXPECT_EQ(test_data::kRobotAccountAuthCode, GetFormField(data, "code")); - EXPECT_EQ(test_data::kClientId, GetFormField(data, "client_id")); - EXPECT_EQ(test_data::kClientSecret, + EXPECT_EQ(expected_data.client_id, GetFormField(data, "client_id")); + EXPECT_EQ(expected_data.client_secret, GetFormField(data, "client_secret")); EXPECT_EQ("oob", GetFormField(data, "redirect_uri")); @@ -532,7 +559,9 @@ TEST_F(DeviceRegistrationInfoTest, RegisterDevice) { EXPECT_CALL( http_client_, - SendRequest(HttpClient::Method::kPost, HasSubstr("upsertLocalAuthInfo"), + SendRequest(HttpClient::Method::kPost, + expected_data.service_url + "devices/" + test_data::kCloudId + + "/upsertLocalAuthInfo", HttpClient::Headers{GetAuthHeader(), GetJsonHeader()}, _, _)) .WillOnce(WithArgs<3, 4>( Invoke([](const std::string& data, @@ -546,10 +575,12 @@ TEST_F(DeviceRegistrationInfoTest, RegisterDevice) { bool done = false; dev_reg_->RegisterDevice( - test_data::kClaimTicketId, base::Bind([this, &done](ErrorPtr error) { - EXPECT_FALSE(error); + registration_data, + base::Bind([this, &done, &expected_data](ErrorPtr error) { done = true; task_runner_.Break(); + + EXPECT_FALSE(error); EXPECT_EQ(GcdState::kConnecting, GetGcdState()); // Validate the device info saved to storage... @@ -558,29 +589,66 @@ TEST_F(DeviceRegistrationInfoTest, RegisterDevice) { dev_reg_->GetSettings().refresh_token); EXPECT_EQ(test_data::kRobotAccountEmail, dev_reg_->GetSettings().robot_account); + EXPECT_EQ(expected_data.oauth_url, dev_reg_->GetSettings().oauth_url); + EXPECT_EQ(expected_data.client_id, dev_reg_->GetSettings().client_id); + EXPECT_EQ(expected_data.client_secret, + dev_reg_->GetSettings().client_secret); + EXPECT_EQ(expected_data.api_key, dev_reg_->GetSettings().api_key); + EXPECT_EQ(expected_data.service_url, + dev_reg_->GetSettings().service_url); + EXPECT_EQ(expected_data.xmpp_endpoint, + dev_reg_->GetSettings().xmpp_endpoint); })); task_runner_.Run(); EXPECT_TRUE(done); } -TEST_F(DeviceRegistrationInfoTest, ReRegisterDevice) { - ReloadSettings(); +TEST_F(DeviceRegistrationInfoTest, RegisterDevice) { + ReloadSettings(false, true); + + RegistrationData registration_data; + registration_data.ticket_id = "test_ticked_id"; + registration_data.oauth_url = "https://test.oauth/"; + registration_data.client_id = "test_client_id"; + registration_data.client_secret = "test_client_secret"; + registration_data.api_key = "test_api_key"; + registration_data.service_url = "https://test.service/"; + registration_data.xmpp_endpoint = "test.xmpp:1234"; + + RegisterDevice(registration_data, registration_data); +} - bool done = false; - dev_reg_->RegisterDevice( - test_data::kClaimTicketId, base::Bind([this, &done](ErrorPtr error) { - EXPECT_TRUE(error->HasError("already_registered")); - done = true; - task_runner_.Break(); - EXPECT_EQ(GcdState::kConnecting, GetGcdState()); +TEST_F(DeviceRegistrationInfoTest, RegisterDeviceWithDefaultEndpoints) { + ReloadSettings(false, true); - // Validate the device info saved to storage... - EXPECT_EQ(test_data::kCloudId, dev_reg_->GetSettings().cloud_id); - EXPECT_EQ(test_data::kRefreshToken, - dev_reg_->GetSettings().refresh_token); - EXPECT_EQ(test_data::kRobotAccountEmail, - dev_reg_->GetSettings().robot_account); - })); + RegistrationData registration_data; + registration_data.ticket_id = "test_ticked_id"; + + RegistrationData expected_data = registration_data; + expected_data.oauth_url = test_data::kOAuthUrl; + expected_data.client_id = test_data::kClientId; + expected_data.client_secret = test_data::kClientSecret; + expected_data.api_key = test_data::kApiKey; + expected_data.service_url = test_data::kServiceUrl; + expected_data.xmpp_endpoint = test_data::kXmppEndpoint; + + RegisterDevice(registration_data, expected_data); +} + +TEST_F(DeviceRegistrationInfoTest, RegisterDeviceEndpointsOverrideNotAllowed) { + ReloadSettings(false, false); + + RegistrationData registration_data; + registration_data.ticket_id = "test_ticked_id"; + registration_data.service_url = "https://test.service/"; + + bool done = false; + dev_reg_->RegisterDevice(registration_data, + base::Bind([this, &done](ErrorPtr error) { + done = true; + task_runner_.Break(); + EXPECT_TRUE(error->HasError("invalidParams")); + })); task_runner_.Run(); EXPECT_TRUE(done); } @@ -590,7 +658,7 @@ TEST_F(DeviceRegistrationInfoTest, OOBRegistrationStatus) { // unregistered, depending on whether or not we've found credentials. EXPECT_EQ(GcdState::kUnconfigured, GetGcdState()); // Put some credentials into our state, make sure we call that offline. - ReloadSettings(); + ReloadSettings(true, false); EXPECT_EQ(GcdState::kConnecting, GetGcdState()); } @@ -600,7 +668,7 @@ class DeviceRegistrationInfoUpdateCommandTest void SetUp() override { DeviceRegistrationInfoTest::SetUp(); - ReloadSettings(); + ReloadSettings(true, false); SetAccessToken(); auto json_traits = CreateDictionaryValue(R"({ @@ -619,7 +687,7 @@ class DeviceRegistrationInfoUpdateCommandTest EXPECT_TRUE( component_manager_.AddComponent("", "comp", {"robot"}, nullptr)); - command_url_ = dev_reg_->GetServiceURL("commands/1234"); + command_url_ = dev_reg_->GetServiceUrl("commands/1234"); auto commands_json = CreateValue(R"([{ 'name':'robot._jump', diff --git a/src/privet/cloud_delegate.cc b/src/privet/cloud_delegate.cc index 49fceaa..0b4400f 100644 --- a/src/privet/cloud_delegate.cc +++ b/src/privet/cloud_delegate.cc @@ -12,6 +12,7 @@ #include <base/memory/weak_ptr.h> #include <base/values.h> #include <weave/error.h> +#include <weave/device.h> #include <weave/provider/task_runner.h> #include "src/backoff_entry.h" @@ -109,15 +110,13 @@ class CloudDelegateImpl : public CloudDelegate { const SetupState& GetSetupState() const override { return setup_state_; } - bool Setup(const std::string& ticket_id, - const std::string& user, + bool Setup(const RegistrationData& registration_data, ErrorPtr* error) override { - VLOG(1) << "GCD Setup started. ticket_id: " << ticket_id - << ", user:" << user; + VLOG(1) << "GCD Setup started. "; // Set (or reset) the retry counter, since we are starting a new // registration process. registation_retry_count_ = kMaxDeviceRegistrationRetries; - ticket_id_ = ticket_id; + registration_data_ = registration_data; if (setup_state_.IsStatusEqual(SetupState::kInProgress)) { // Another registration is in progress. In case it fails, we will use // the new ticket ID when retrying the request. @@ -140,6 +139,18 @@ class CloudDelegateImpl : public CloudDelegate { : ""; } + std::string GetOAuthUrl() const override { + return device_->GetSettings().oauth_url; + } + + std::string GetServiceUrl() const override { + return device_->GetSettings().service_url; + } + + std::string GetXmppEndpoint() const override { + return device_->GetSettings().xmpp_endpoint; + } + const base::DictionaryValue& GetLegacyCommandDef() const override { return component_manager_->GetLegacyCommandDefinitions(); } @@ -273,7 +284,7 @@ class CloudDelegateImpl : public CloudDelegate { return; } - device_->RegisterDevice(ticket_id_, + device_->RegisterDevice(registration_data_, base::Bind(&CloudDelegateImpl::RegisterDeviceDone, setup_weak_factory_.GetWeakPtr())); } @@ -337,8 +348,8 @@ class CloudDelegateImpl : public CloudDelegate { // State of the current or last setup. SetupState setup_state_{SetupState::kNone}; - // Ticket ID for registering the device. - std::string ticket_id_; + // Registration data for current registration process. + RegistrationData registration_data_; // Number of remaining retries for device registration process. int registation_retry_count_{0}; diff --git a/src/privet/cloud_delegate.h b/src/privet/cloud_delegate.h index 9f053d8..37ed723 100644 --- a/src/privet/cloud_delegate.h +++ b/src/privet/cloud_delegate.h @@ -12,6 +12,7 @@ #include <base/callback.h> #include <base/memory/ref_counted.h> #include <base/observer_list.h> +#include <weave/device.h> #include "src/privet/privet_types.h" #include "src/privet/security_delegate.h" @@ -88,13 +89,17 @@ class CloudDelegate { virtual const SetupState& GetSetupState() const = 0; // Starts GCD setup. - virtual bool Setup(const std::string& ticket_id, - const std::string& user, + virtual bool Setup(const RegistrationData& registration_data, ErrorPtr* error) = 0; // Returns cloud id if the registered device or empty string if unregistered. virtual std::string GetCloudId() const = 0; + // Returns currently active cloud endponts. + virtual std::string GetOAuthUrl() const = 0; + virtual std::string GetServiceUrl() const = 0; + virtual std::string GetXmppEndpoint() const = 0; + // Returns dictionary with device state (for legacy APIs). virtual const base::DictionaryValue& GetLegacyState() const = 0; diff --git a/src/privet/mock_delegates.h b/src/privet/mock_delegates.h index c2e9a89..108e450 100644 --- a/src/privet/mock_delegates.h +++ b/src/privet/mock_delegates.h @@ -183,8 +183,11 @@ class MockCloudDelegate : public CloudDelegate { MOCK_CONST_METHOD0(GetAnonymousMaxScope, AuthScope()); MOCK_CONST_METHOD0(GetConnectionState, const ConnectionState&()); MOCK_CONST_METHOD0(GetSetupState, const SetupState&()); - MOCK_METHOD3(Setup, bool(const std::string&, const std::string&, ErrorPtr*)); + MOCK_METHOD2(Setup, bool(const RegistrationData&, ErrorPtr*)); MOCK_CONST_METHOD0(GetCloudId, std::string()); + MOCK_CONST_METHOD0(GetOAuthUrl, std::string()); + MOCK_CONST_METHOD0(GetServiceUrl, std::string()); + MOCK_CONST_METHOD0(GetXmppEndpoint, std::string()); MOCK_CONST_METHOD0(GetLegacyState, const base::DictionaryValue&()); MOCK_CONST_METHOD0(GetLegacyCommandDef, const base::DictionaryValue&()); MOCK_CONST_METHOD0(GetComponents, const base::DictionaryValue&()); @@ -208,6 +211,10 @@ class MockCloudDelegate : public CloudDelegate { MockCloudDelegate() { EXPECT_CALL(*this, GetDeviceId()).WillRepeatedly(Return("TestId")); + EXPECT_CALL(*this, GetOAuthUrl()).WillRepeatedly(Return("https://oauths/")); + EXPECT_CALL(*this, GetServiceUrl()) + .WillRepeatedly(Return("https://service/")); + EXPECT_CALL(*this, GetXmppEndpoint()).WillRepeatedly(Return("xmpp:678")); EXPECT_CALL(*this, GetModelId()).WillRepeatedly(Return("ABMID")); EXPECT_CALL(*this, GetName()).WillRepeatedly(Return("TestDevice")); EXPECT_CALL(*this, GetDescription()).WillRepeatedly(Return("")); diff --git a/src/privet/privet_handler.cc b/src/privet/privet_handler.cc index e8b1c77..05b6e0a 100644 --- a/src/privet/privet_handler.cc +++ b/src/privet/privet_handler.cc @@ -14,6 +14,7 @@ #include <base/location.h> #include <base/strings/stringprintf.h> #include <base/values.h> +#include <weave/device.h> #include <weave/enum_to_string.h> #include <weave/provider/task_runner.h> @@ -98,6 +99,19 @@ const char kSetupStartSsidKey[] = "ssid"; const char kSetupStartPassKey[] = "passphrase"; const char kSetupStartTicketIdKey[] = "ticketId"; const char kSetupStartUserKey[] = "user"; +const char kSetupStartClientIdKey[] = "client_id"; +const char kSetupStartClientSecretKey[] = "client_secret"; +const char kSetupStartApiKeyKey[] = "api_key"; +const char kSetupStartOAuthUrlKey[] = "oauth_url"; +const char kSetupStartServiceUrlKey[] = "service_url"; +const char kSetupStartXmppEndpointKey[] = "xmpp_endpoint"; + +std::string oauth_url; +std::string client_id; +std::string client_secret; +std::string api_key; +std::string service_url; +std::string xmpp_endpoint; const char kFingerprintKey[] = "fingerprint"; const char kStateKey[] = "state"; @@ -285,10 +299,17 @@ std::unique_ptr<base::DictionaryValue> CreateWifiSection( return result; } +void SetGcdProperties(const CloudDelegate& cloud, base::DictionaryValue* dict) { + dict->SetString(kInfoIdKey, cloud.GetCloudId()); + dict->SetString(kSetupStartOAuthUrlKey, cloud.GetOAuthUrl()); + dict->SetString(kSetupStartServiceUrlKey, cloud.GetServiceUrl()); + dict->SetString(kSetupStartXmppEndpointKey, cloud.GetXmppEndpoint()); +} + std::unique_ptr<base::DictionaryValue> CreateGcdSection( const CloudDelegate& cloud) { std::unique_ptr<base::DictionaryValue> gcd(new base::DictionaryValue()); - gcd->SetString(kInfoIdKey, cloud.GetCloudId()); + SetGcdProperties(cloud, gcd.get()); SetStateProperties(cloud.GetConnectionState(), gcd.get()); return gcd; } @@ -756,7 +777,7 @@ void PrivetHandler::HandleSetupStart(const base::DictionaryValue& input, std::string ssid; std::string passphrase; - std::string ticket; + RegistrationData registration_data; std::string user; const base::DictionaryValue* wifi = nullptr; @@ -785,14 +806,26 @@ void PrivetHandler::HandleSetupStart(const base::DictionaryValue& input, "Only owner can register device"); return ReturnError(*error, callback); } - registration->GetString(kSetupStartTicketIdKey, &ticket); - if (ticket.empty()) { + registration->GetString(kSetupStartTicketIdKey, + ®istration_data.ticket_id); + if (registration_data.ticket_id.empty()) { ErrorPtr error; Error::AddToPrintf(&error, FROM_HERE, errors::kInvalidParams, kInvalidParamValueFormat, kSetupStartTicketIdKey, ""); return ReturnError(*error, callback); } registration->GetString(kSetupStartUserKey, &user); + registration->GetString(kSetupStartClientIdKey, + ®istration_data.client_id); + registration->GetString(kSetupStartClientSecretKey, + ®istration_data.client_secret); + registration->GetString(kSetupStartApiKeyKey, ®istration_data.api_key); + registration->GetString(kSetupStartOAuthUrlKey, + ®istration_data.oauth_url); + registration->GetString(kSetupStartServiceUrlKey, + ®istration_data.service_url); + registration->GetString(kSetupStartXmppEndpointKey, + ®istration_data.xmpp_endpoint); } cloud_->UpdateDeviceInfo(name, description, location); @@ -801,7 +834,8 @@ void PrivetHandler::HandleSetupStart(const base::DictionaryValue& input, if (!ssid.empty() && !wifi_->ConfigureCredentials(ssid, passphrase, &error)) return ReturnError(*error, callback); - if (!ticket.empty() && !cloud_->Setup(ticket, user, &error)) + if (!registration_data.ticket_id.empty() && + !cloud_->Setup(registration_data, &error)) return ReturnError(*error, callback); ReplyWithSetupStatus(callback); @@ -822,8 +856,9 @@ void PrivetHandler::ReplyWithSetupStatus( base::DictionaryValue* gcd = new base::DictionaryValue; output.Set(kGcdKey, gcd); SetStateProperties(state, gcd); - if (state.IsStatusEqual(SetupState::kSuccess)) - gcd->SetString(kInfoIdKey, cloud_->GetCloudId()); + if (state.IsStatusEqual(SetupState::kSuccess)) { + SetGcdProperties(*cloud_, gcd); + } } if (wifi_) { diff --git a/src/privet/privet_handler_unittest.cc b/src/privet/privet_handler_unittest.cc index 20f5aa0..3c72242 100644 --- a/src/privet/privet_handler_unittest.cc +++ b/src/privet/privet_handler_unittest.cc @@ -15,6 +15,7 @@ #include <base/values.h> #include <gmock/gmock.h> #include <gtest/gtest.h> +#include <weave/device.h> #include <weave/test/unittest_utils.h> #include "src/privet/constants.h" @@ -36,15 +37,13 @@ namespace { void LoadTestJson(const std::string& test_json, base::DictionaryValue* dictionary) { - std::string json = test_json; - base::ReplaceChars(json, "'", "\"", &json); int error = 0; std::string message; std::unique_ptr<base::Value> value( - base::JSONReader::ReadAndReturnError(json, base::JSON_PARSE_RFC, &error, - &message) + base::JSONReader::ReadAndReturnError(test_json, base::JSON_PARSE_RFC, + &error, &message) .release()); - EXPECT_TRUE(value.get()) << "\nError: " << message << "\n" << json; + EXPECT_TRUE(value.get()) << "\nError: " << message << "\n" << test_json; base::DictionaryValue* dictionary_ptr = nullptr; if (value->GetAsDictionary(&dictionary_ptr)) dictionary->MergeDictionary(dictionary_ptr); @@ -58,7 +57,7 @@ struct CodeWithReason { }; std::ostream& operator<<(std::ostream& stream, const CodeWithReason& error) { - return stream << "{" << error.code << ", " << error.reason << "}"; + return stream << R"({" << error.code << ", " << error.reason << "})"; } bool IsEqualError(const CodeWithReason& expected, @@ -134,12 +133,11 @@ class PrivetHandlerTest : public testing::Test { EXPECT_CALL(cloud_, GetCloudId()).WillRepeatedly(Return("")); EXPECT_CALL(cloud_, GetConnectionState()) .WillRepeatedly(ReturnRef(gcd_disabled_state_)); - auto set_error = [](const std::string&, const std::string&, - ErrorPtr* error) { + auto set_error = [](ErrorPtr* error) { Error::AddTo(error, FROM_HERE, "setupUnavailable", ""); }; - EXPECT_CALL(cloud_, Setup(_, _, _)) - .WillRepeatedly(DoAll(Invoke(set_error), Return(false))); + EXPECT_CALL(cloud_, Setup(_, _)) + .WillRepeatedly(DoAll(WithArgs<1>(Invoke(set_error)), Return(false))); } test::MockClock clock_; @@ -219,37 +217,40 @@ TEST_F(PrivetHandlerTest, InfoMinimal) { .WillRepeatedly(Return(std::set<AuthType>{})); const char kExpected[] = R"({ - 'version': '3.0', - 'id': 'TestId', - 'name': 'TestDevice', - 'services': [ "developmentBoard" ], - 'modelManifestId': "ABMID", - 'basicModelManifest': { - 'uiDeviceKind': 'developmentBoard', - 'oemName': 'Chromium', - 'modelName': 'Brillo' + "version": "3.0", + "id": "TestId", + "name": "TestDevice", + "services": [ "developmentBoard" ], + "modelManifestId": "ABMID", + "basicModelManifest": { + "uiDeviceKind": "developmentBoard", + "oemName": "Chromium", + "modelName": "Brillo" }, - 'endpoints': { - 'httpPort': 0, - 'httpUpdatesPort': 0, - 'httpsPort': 0, - 'httpsUpdatesPort': 0 + "endpoints": { + "httpPort": 0, + "httpUpdatesPort": 0, + "httpsPort": 0, + "httpsUpdatesPort": 0 }, - 'authentication': { - 'anonymousMaxScope': 'user', - 'mode': [ + "authentication": { + "anonymousMaxScope": "user", + "mode": [ ], - 'pairing': [ + "pairing": [ ], - 'crypto': [ + "crypto": [ ] }, - 'gcd': { - 'id': '', - 'status': 'disabled' + "gcd": { + "id": "", + "oauth_url": "https://oauths/", + "service_url": "https://service/", + "status": "disabled", + "xmpp_endpoint": "xmpp:678" }, - 'time': 1410000001000.0, - 'sessionId': 'SessionId' + "time": 1410000001000.0, + "sessionId": "SessionId" })"; EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/info", "{}")); } @@ -266,85 +267,89 @@ TEST_F(PrivetHandlerTest, Info) { .WillRepeatedly(Return("Test_device.BBABCLAprv")); const char kExpected[] = R"({ - 'version': '3.0', - 'id': 'TestId', - 'name': 'TestDevice', - 'description': 'TestDescription', - 'location': 'TestLocation', - 'services': [ "developmentBoard" ], - 'modelManifestId': "ABMID", - 'basicModelManifest': { - 'uiDeviceKind': 'developmentBoard', - 'oemName': 'Chromium', - 'modelName': 'Brillo' + "version": "3.0", + "id": "TestId", + "name": "TestDevice", + "description": "TestDescription", + "location": "TestLocation", + "services": [ "developmentBoard" ], + "modelManifestId": "ABMID", + "basicModelManifest": { + "uiDeviceKind": "developmentBoard", + "oemName": "Chromium", + "modelName": "Brillo" }, - 'endpoints': { - 'httpPort': 80, - 'httpUpdatesPort': 10080, - 'httpsPort': 443, - 'httpsUpdatesPort': 10443 + "endpoints": { + "httpPort": 80, + "httpUpdatesPort": 10080, + "httpsPort": 443, + "httpsUpdatesPort": 10443 }, - 'authentication': { - 'anonymousMaxScope': 'none', - 'mode': [ - 'anonymous', - 'pairing', - 'local' + "authentication": { + "anonymousMaxScope": "none", + "mode": [ + "anonymous", + "pairing", + "local" ], - 'pairing': [ - 'pinCode', - 'embeddedCode' + "pairing": [ + "pinCode", + "embeddedCode" ], - 'crypto': [ - 'p224_spake2' + "crypto": [ + "p224_spake2" ] }, - 'wifi': { - 'capabilities': [ - '2.4GHz' + "wifi": { + "capabilities": [ + "2.4GHz" ], - 'ssid': 'TestSsid', - 'hostedSsid': 'Test_device.BBABCLAprv', - 'status': 'offline' + "ssid": "TestSsid", + "hostedSsid": "Test_device.BBABCLAprv", + "status": "offline" }, - 'gcd': { - 'id': 'TestCloudId', - 'status': 'online' + "gcd": { + "id": "TestCloudId", + "oauth_url": "https://oauths/", + "service_url": "https://service/", + "status": "online", + "xmpp_endpoint": "xmpp:678" }, - 'time': 1410000001000.0, - 'sessionId': 'SessionId' + "time": 1410000001000.0, + "sessionId": "SessionId" })"; EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/info", "{}")); } TEST_F(PrivetHandlerTest, PairingStartInvalidParams) { - EXPECT_PRED2(IsEqualError, CodeWithReason(400, "invalidParams"), - HandleRequest("/privet/v3/pairing/start", - "{'pairing':'embeddedCode','crypto':'crypto'}")); + EXPECT_PRED2( + IsEqualError, CodeWithReason(400, "invalidParams"), + HandleRequest("/privet/v3/pairing/start", + R"({"pairing":"embeddedCode","crypto":"crypto"})")); EXPECT_PRED2(IsEqualError, CodeWithReason(400, "invalidParams"), HandleRequest("/privet/v3/pairing/start", - "{'pairing':'code','crypto':'p224_spake2'}")); + R"({"pairing":"code","crypto":"p224_spake2"})")); } TEST_F(PrivetHandlerTest, PairingStart) { EXPECT_JSON_EQ( - "{'deviceCommitment': 'testCommitment', 'sessionId': 'testSession'}", + R"({"deviceCommitment": "testCommitment", "sessionId": "testSession"})", HandleRequest("/privet/v3/pairing/start", - "{'pairing': 'embeddedCode', 'crypto': 'p224_spake2'}")); + R"({"pairing": "embeddedCode", "crypto": "p224_spake2"})")); } TEST_F(PrivetHandlerTest, PairingConfirm) { EXPECT_JSON_EQ( - "{'certFingerprint':'testFingerprint','certSignature':'testSignature'}", + R"({"certFingerprint":"testFingerprint","certSignature":"testSignature"})", HandleRequest( "/privet/v3/pairing/confirm", - "{'sessionId':'testSession','clientCommitment':'testCommitment'}")); + R"({"sessionId":"testSession","clientCommitment":"testCommitment"})")); } TEST_F(PrivetHandlerTest, PairingCancel) { EXPECT_JSON_EQ("{}", HandleRequest("/privet/v3/pairing/cancel", - "{'sessionId': 'testSession'}")); + R"({"sessionId": "testSession"})")); } TEST_F(PrivetHandlerTest, AuthErrorNoType) { @@ -354,25 +359,26 @@ TEST_F(PrivetHandlerTest, AuthErrorNoType) { TEST_F(PrivetHandlerTest, AuthErrorInvalidType) { EXPECT_PRED2(IsEqualError, CodeWithReason(400, "invalidAuthMode"), - HandleRequest("/privet/v3/auth", "{'mode':'unknown'}")); + HandleRequest("/privet/v3/auth", R"({"mode":"unknown"})")); } TEST_F(PrivetHandlerTest, AuthErrorNoScope) { EXPECT_PRED2(IsEqualError, CodeWithReason(400, "invalidRequestedScope"), - HandleRequest("/privet/v3/auth", "{'mode':'anonymous'}")); + HandleRequest("/privet/v3/auth", R"({"mode":"anonymous"})")); } TEST_F(PrivetHandlerTest, AuthErrorInvalidScope) { EXPECT_PRED2( IsEqualError, CodeWithReason(400, "invalidRequestedScope"), HandleRequest("/privet/v3/auth", - "{'mode':'anonymous','requestedScope':'unknown'}")); + R"({"mode":"anonymous","requestedScope":"unknown"})")); } TEST_F(PrivetHandlerTest, AuthErrorAccessDenied) { - EXPECT_PRED2(IsEqualError, CodeWithReason(403, "accessDenied"), - HandleRequest("/privet/v3/auth", - "{'mode':'anonymous','requestedScope':'owner'}")); + EXPECT_PRED2( + IsEqualError, CodeWithReason(403, "accessDenied"), + HandleRequest("/privet/v3/auth", + R"({"mode":"anonymous","requestedScope":"owner"})")); } TEST_F(PrivetHandlerTest, AuthErrorInvalidAuthCode) { @@ -382,9 +388,9 @@ TEST_F(PrivetHandlerTest, AuthErrorInvalidAuthCode) { EXPECT_CALL(security_, CreateAccessToken(_, "testToken", _, _, _, _, _)) .WillRepeatedly(WithArgs<6>(Invoke(set_error))); const char kInput[] = R"({ - 'mode': 'pairing', - 'requestedScope': 'user', - 'authCode': 'testToken' + "mode": "pairing", + "requestedScope": "user", + "authCode": "testToken" })"; EXPECT_PRED2(IsEqualError, CodeWithReason(403, "invalidAuthCode"), HandleRequest("/privet/v3/auth", kInput)); @@ -392,14 +398,15 @@ TEST_F(PrivetHandlerTest, AuthErrorInvalidAuthCode) { TEST_F(PrivetHandlerTest, AuthAnonymous) { const char kExpected[] = R"({ - 'accessToken': 'GuestAccessToken', - 'expiresIn': 15, - 'scope': 'viewer', - 'tokenType': 'Privet' + "accessToken": "GuestAccessToken", + "expiresIn": 15, + "scope": "viewer", + "tokenType": "Privet" })"; - EXPECT_JSON_EQ(kExpected, - HandleRequest("/privet/v3/auth", - "{'mode':'anonymous','requestedScope':'auto'}")); + EXPECT_JSON_EQ( + kExpected, + HandleRequest("/privet/v3/auth", + R"({"mode":"anonymous","requestedScope":"auto"})")); } TEST_F(PrivetHandlerTest, AuthPairing) { @@ -409,15 +416,15 @@ TEST_F(PrivetHandlerTest, AuthPairing) { SetArgPointee<5>(base::TimeDelta::FromSeconds(15)), Return(true))); const char kInput[] = R"({ - 'mode': 'pairing', - 'requestedScope': 'owner', - 'authCode': 'testToken' + "mode": "pairing", + "requestedScope": "owner", + "authCode": "testToken" })"; const char kExpected[] = R"({ - 'accessToken': 'OwnerAccessToken', - 'expiresIn': 15, - 'scope': 'owner', - 'tokenType': 'Privet' + "accessToken": "OwnerAccessToken", + "expiresIn": 15, + "scope": "owner", + "tokenType": "Privet" })"; EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/v3/auth", kInput)); } @@ -429,15 +436,15 @@ TEST_F(PrivetHandlerTest, AuthLocalAuto) { SetArgPointee<5>(base::TimeDelta::FromSeconds(15)), Return(true))); const char kInput[] = R"({ - 'mode': 'local', - 'requestedScope': 'auto', - 'authCode': 'localAuthToken' + "mode": "local", + "requestedScope": "auto", + "authCode": "localAuthToken" })"; const char kExpected[] = R"({ - 'accessToken': 'UserAccessToken', - 'expiresIn': 15, - 'scope': 'user', - 'tokenType': 'Privet' + "accessToken": "UserAccessToken", + "expiresIn": 15, + "scope": "user", + "tokenType": "Privet" })"; EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/v3/auth", kInput)); } @@ -449,15 +456,15 @@ TEST_F(PrivetHandlerTest, AuthLocal) { SetArgPointee<5>(base::TimeDelta::FromSeconds(15)), Return(true))); const char kInput[] = R"({ - 'mode': 'local', - 'requestedScope': 'manager', - 'authCode': 'localAuthToken' + "mode": "local", + "requestedScope": "manager", + "authCode": "localAuthToken" })"; const char kExpected[] = R"({ - 'accessToken': 'ManagerAccessToken', - 'expiresIn': 15, - 'scope': 'manager', - 'tokenType': 'Privet' + "accessToken": "ManagerAccessToken", + "expiresIn": 15, + "scope": "manager", + "tokenType": "Privet" })"; EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/v3/auth", kInput)); } @@ -469,9 +476,9 @@ TEST_F(PrivetHandlerTest, AuthLocalHighScope) { SetArgPointee<5>(base::TimeDelta::FromSeconds(1)), Return(true))); const char kInput[] = R"({ - 'mode': 'local', - 'requestedScope': 'manager', - 'authCode': 'localAuthToken' + "mode": "local", + "requestedScope": "manager", + "authCode": "localAuthToken" })"; EXPECT_PRED2(IsEqualError, CodeWithReason(403, "accessDenied"), HandleRequest("/privet/v3/auth", kInput)); @@ -500,9 +507,9 @@ TEST_F(PrivetHandlerSetupTest, StatusWifi) { wifi_.setup_state_ = SetupState{SetupState::kSuccess}; const char kExpected[] = R"({ - 'wifi': { - 'ssid': 'TestSsid', - 'status': 'success' + "wifi": { + "ssid": "TestSsid", + "status": "success" } })"; EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/v3/setup/status", "{}")); @@ -514,10 +521,10 @@ TEST_F(PrivetHandlerSetupTest, StatusWifiError) { wifi_.setup_state_ = SetupState{std::move(error)}; const char kExpected[] = R"({ - 'wifi': { - 'status': 'error', - 'error': { - 'code': 'invalidPassphrase' + "wifi": { + "status": "error", + "error": { + "code": "invalidPassphrase" } } })"; @@ -530,9 +537,12 @@ TEST_F(PrivetHandlerSetupTest, StatusGcd) { cloud_.setup_state_ = SetupState{SetupState::kSuccess}; const char kExpected[] = R"({ - 'gcd': { - 'id': 'TestCloudId', - 'status': 'success' + "gcd": { + "id": "TestCloudId", + "oauth_url": "https://oauths/", + "service_url": "https://service/", + "status": "success", + "xmpp_endpoint": "xmpp:678" } })"; EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/v3/setup/status", "{}")); @@ -544,10 +554,10 @@ TEST_F(PrivetHandlerSetupTest, StatusGcdError) { cloud_.setup_state_ = SetupState{std::move(error)}; const char kExpected[] = R"({ - 'gcd': { - 'status': 'error', - 'error': { - 'code': 'invalidTicket' + "gcd": { + "status": "error", + "error": { + "code": "invalidTicket" } } })"; @@ -561,25 +571,25 @@ TEST_F(PrivetHandlerSetupTest, SetupNameDescriptionLocation) { UpdateDeviceInfo("testName", "testDescription", "testLocation")) .Times(1); const char kInput[] = R"({ - 'name': 'testName', - 'description': 'testDescription', - 'location': 'testLocation' + "name": "testName", + "description": "testDescription", + "location": "testLocation" })"; EXPECT_JSON_EQ("{}", HandleRequest("/privet/v3/setup/start", kInput)); } TEST_F(PrivetHandlerSetupTest, InvalidParams) { const char kInputWifi[] = R"({ - 'wifi': { - 'ssid': '' + "wifi": { + "ssid": "" } })"; EXPECT_PRED2(IsEqualError, CodeWithReason(400, "invalidParams"), HandleRequest("/privet/v3/setup/start", kInputWifi)); const char kInputRegistration[] = R"({ - 'gcd': { - 'ticketId': '' + "gcd": { + "ticketId": "" } })"; EXPECT_PRED2(IsEqualError, CodeWithReason(400, "invalidParams"), @@ -589,14 +599,14 @@ TEST_F(PrivetHandlerSetupTest, InvalidParams) { TEST_F(PrivetHandlerSetupTest, WifiSetupUnavailable) { SetNoWifiAndGcd(); EXPECT_PRED2(IsEqualError, CodeWithReason(400, "setupUnavailable"), - HandleRequest("/privet/v3/setup/start", "{'wifi': {}}")); + HandleRequest("/privet/v3/setup/start", R"({"wifi": {}})")); } TEST_F(PrivetHandlerSetupTest, WifiSetup) { const char kInput[] = R"({ - 'wifi': { - 'ssid': 'testSsid', - 'passphrase': 'testPass' + "wifi": { + "ssid": "testSsid", + "passphrase": "testPass" } })"; auto set_error = [](const std::string&, const std::string&, ErrorPtr* error) { @@ -607,8 +617,8 @@ TEST_F(PrivetHandlerSetupTest, WifiSetup) { HandleRequest("/privet/v3/setup/start", kInput)); const char kExpected[] = R"({ - 'wifi': { - 'status': 'inProgress' + "wifi": { + "status": "inProgress" } })"; wifi_.setup_state_ = SetupState{SetupState::kInProgress}; @@ -620,9 +630,9 @@ TEST_F(PrivetHandlerSetupTest, WifiSetup) { TEST_F(PrivetHandlerSetupTest, GcdSetupUnavailable) { SetNoWifiAndGcd(); const char kInput[] = R"({ - 'gcd': { - 'ticketId': 'testTicket', - 'user': 'testUser' + "gcd": { + "ticketId": "testTicket", + "user": "testUser" } })"; @@ -632,39 +642,74 @@ TEST_F(PrivetHandlerSetupTest, GcdSetupUnavailable) { TEST_F(PrivetHandlerSetupTest, GcdSetup) { const char kInput[] = R"({ - 'gcd': { - 'ticketId': 'testTicket', - 'user': 'testUser' + "gcd": { + "ticketId": "testTicket", + "user": "testUser" } })"; - auto set_error = [](const std::string&, const std::string&, ErrorPtr* error) { + auto set_error = [](ErrorPtr* error) { return Error::AddTo(error, FROM_HERE, "deviceBusy", ""); }; - EXPECT_CALL(cloud_, Setup(_, _, _)).WillOnce(Invoke(set_error)); + EXPECT_CALL(cloud_, Setup(_, _)).WillOnce(WithArgs<1>(Invoke(set_error))); EXPECT_PRED2(IsEqualError, CodeWithReason(503, "deviceBusy"), HandleRequest("/privet/v3/setup/start", kInput)); const char kExpected[] = R"({ - 'gcd': { - 'status': 'inProgress' + "gcd": { + "status": "inProgress" } })"; cloud_.setup_state_ = SetupState{SetupState::kInProgress}; - EXPECT_CALL(cloud_, Setup("testTicket", "testUser", _)) + EXPECT_CALL(cloud_, Setup(RegistrationData{"testTicket"}, _)) .WillOnce(Return(true)); EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/v3/setup/start", kInput)); } +TEST_F(PrivetHandlerSetupTest, GcdSetupWithEndpoints) { + const char kInput[] = R"({ + "gcd": { + "api_key": "test_api_key", + "client_id": "test_client_id", + "client_secret": "test_client_secret", + "oauth_url": "https://oauths/", + "service_url": "https://service/", + "status": "success", + "xmpp_endpoint": "xmpp:678", + "ticketId": "testTicket", + "user": "testUser" + } + })"; + + const char kExpected[] = R"({ + "gcd": { + "status": "inProgress" + } + })"; + cloud_.setup_state_ = SetupState{SetupState::kInProgress}; + + RegistrationData expected_reg_data; + expected_reg_data.ticket_id = "testTicket"; + expected_reg_data.oauth_url = "https://oauths/"; + expected_reg_data.client_id = "test_client_id"; + expected_reg_data.client_secret = "test_client_secret"; + expected_reg_data.api_key = "test_api_key"; + expected_reg_data.service_url = "https://service/"; + expected_reg_data.xmpp_endpoint = "xmpp:678"; + + EXPECT_CALL(cloud_, Setup(expected_reg_data, _)).WillOnce(Return(true)); + EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/v3/setup/start", kInput)); +} + TEST_F(PrivetHandlerSetupTest, GcdSetupAsMaster) { EXPECT_CALL(security_, ParseAccessToken(_, _, _)) .WillRepeatedly(DoAll( SetArgPointee<1>(UserInfo{AuthScope::kManager, TestUserId{"1"}}), Return(true))); const char kInput[] = R"({ - 'gcd': { - 'ticketId': 'testTicket', - 'user': 'testUser' + "gcd": { + "ticketId": "testTicket", + "user": "testUser" } })"; @@ -673,59 +718,59 @@ TEST_F(PrivetHandlerSetupTest, GcdSetupAsMaster) { } TEST_F(PrivetHandlerTestWithAuth, ClaimAccessControl) { - EXPECT_JSON_EQ("{'clientToken': 'RootClientAuthToken'}", + EXPECT_JSON_EQ(R"({"clientToken": "RootClientAuthToken"})", HandleRequest("/privet/v3/accessControl/claim", "{}")); } TEST_F(PrivetHandlerTestWithAuth, ConfirmAccessControl) { EXPECT_JSON_EQ("{}", HandleRequest("/privet/v3/accessControl/confirm", - "{'clientToken': 'DerivedClientAuthToken'}")); + R"({"clientToken": "DerivedClientAuthToken"})")); } TEST_F(PrivetHandlerTestWithAuth, State) { - EXPECT_JSON_EQ("{'state': {'test': {}}, 'fingerprint': '1'}", + EXPECT_JSON_EQ(R"({"state": {"test": {}}, "fingerprint": "1"})", HandleRequest("/privet/v3/state", "{}")); cloud_.NotifyOnStateChanged(); - EXPECT_JSON_EQ("{'state': {'test': {}}, 'fingerprint': '2'}", + EXPECT_JSON_EQ(R"({"state": {"test": {}}, "fingerprint": "2"})", HandleRequest("/privet/v3/state", "{}")); } TEST_F(PrivetHandlerTestWithAuth, CommandsDefs) { - EXPECT_JSON_EQ("{'commands': {'test':{}}, 'fingerprint': '1'}", + EXPECT_JSON_EQ(R"({"commands": {"test":{}}, "fingerprint": "1"})", HandleRequest("/privet/v3/commandDefs", "{}")); cloud_.NotifyOnTraitDefsChanged(); - EXPECT_JSON_EQ("{'commands': {'test':{}}, 'fingerprint': '2'}", + EXPECT_JSON_EQ(R"({"commands": {"test":{}}, "fingerprint": "2"})", HandleRequest("/privet/v3/commandDefs", "{}")); } TEST_F(PrivetHandlerTestWithAuth, Traits) { - EXPECT_JSON_EQ("{'traits': {'test': {}}, 'fingerprint': '1'}", + EXPECT_JSON_EQ(R"({"traits": {"test": {}}, "fingerprint": "1"})", HandleRequest("/privet/v3/traits", "{}")); cloud_.NotifyOnTraitDefsChanged(); - EXPECT_JSON_EQ("{'traits': {'test': {}}, 'fingerprint': '2'}", + EXPECT_JSON_EQ(R"({"traits": {"test": {}}, "fingerprint": "2"})", HandleRequest("/privet/v3/traits", "{}")); } TEST_F(PrivetHandlerTestWithAuth, Components) { - EXPECT_JSON_EQ("{'components': {'test': {}}, 'fingerprint': '1'}", + EXPECT_JSON_EQ(R"({"components": {"test": {}}, "fingerprint": "1"})", HandleRequest("/privet/v3/components", "{}")); cloud_.NotifyOnComponentTreeChanged(); - EXPECT_JSON_EQ("{'components': {'test': {}}, 'fingerprint': '2'}", + EXPECT_JSON_EQ(R"({"components": {"test": {}}, "fingerprint": "2"})", HandleRequest("/privet/v3/components", "{}")); // State change will also change the components fingerprint. cloud_.NotifyOnStateChanged(); - EXPECT_JSON_EQ("{'components': {'test': {}}, 'fingerprint': '3'}", + EXPECT_JSON_EQ(R"({"components": {"test": {}}, "fingerprint": "3"})", HandleRequest("/privet/v3/components", "{}")); } @@ -770,7 +815,7 @@ TEST_F(PrivetHandlerTestWithAuth, ComponentsWithFiltersAndPaths) { "fingerprint": "1" })"; EXPECT_JSON_EQ(kExpected1, HandleRequest("/privet/v3/components", - "{'filter':['state']}")); + R"({"filter":["state"]})")); const char kExpected2[] = R"({ "components": { @@ -781,7 +826,7 @@ TEST_F(PrivetHandlerTestWithAuth, ComponentsWithFiltersAndPaths) { "fingerprint": "1" })"; EXPECT_JSON_EQ(kExpected2, HandleRequest("/privet/v3/components", - "{'filter':['traits']}")); + R"({"filter":["traits"]})")); const char kExpected3[] = R"({ "components": { @@ -799,7 +844,7 @@ TEST_F(PrivetHandlerTestWithAuth, ComponentsWithFiltersAndPaths) { "fingerprint": "1" })"; EXPECT_JSON_EQ(kExpected3, HandleRequest("/privet/v3/components", - "{'filter':['components']}")); + R"({"filter":["components"]})")); const char kExpected4[] = R"({ "components": { @@ -827,9 +872,10 @@ TEST_F(PrivetHandlerTestWithAuth, ComponentsWithFiltersAndPaths) { }, "fingerprint": "1" })"; - EXPECT_JSON_EQ(kExpected4, - HandleRequest("/privet/v3/components", - "{'filter':['traits', 'components', 'state']}")); + EXPECT_JSON_EQ( + kExpected4, + HandleRequest("/privet/v3/components", + R"({"filter":["traits", "components", "state"]})")); const base::DictionaryValue* comp2 = nullptr; ASSERT_TRUE(components.GetDictionary("comp1.components.comp2", &comp2)); @@ -852,7 +898,7 @@ TEST_F(PrivetHandlerTestWithAuth, ComponentsWithFiltersAndPaths) { kExpected5, HandleRequest( "/privet/v3/components", - "{'path':'comp1.comp2', 'filter':['traits', 'components']}")); + R"({"path":"comp1.comp2", "filter":["traits", "components"]})")); auto error_handler = [](ErrorPtr* error) -> const base::DictionaryValue* { return Error::AddTo(error, FROM_HERE, "componentNotFound", ""); @@ -863,36 +909,36 @@ TEST_F(PrivetHandlerTestWithAuth, ComponentsWithFiltersAndPaths) { EXPECT_PRED2( IsEqualError, CodeWithReason(500, "componentNotFound"), HandleRequest("/privet/v3/components", - "{'path':'comp7', 'filter':['traits', 'components']}")); + R"({"path":"comp7", "filter":["traits", "components"]})")); } TEST_F(PrivetHandlerTestWithAuth, CommandsExecute) { - const char kInput[] = "{'name': 'test'}"; + const char kInput[] = R"({"name": "test"})"; base::DictionaryValue command; LoadTestJson(kInput, &command); - LoadTestJson("{'id':'5'}", &command); + LoadTestJson(R"({"id":"5"})", &command); EXPECT_CALL(cloud_, AddCommand(_, _, _)) .WillOnce(WithArgs<2>(Invoke( [&command](const CloudDelegate::CommandDoneCallback& callback) { callback.Run(command, nullptr); }))); - EXPECT_JSON_EQ("{'name':'test', 'id':'5'}", + EXPECT_JSON_EQ(R"({"name":"test", "id":"5"})", HandleRequest("/privet/v3/commands/execute", kInput)); } TEST_F(PrivetHandlerTestWithAuth, CommandsStatus) { - const char kInput[] = "{'id': '5'}"; + const char kInput[] = R"({"id": "5"})"; base::DictionaryValue command; LoadTestJson(kInput, &command); - LoadTestJson("{'name':'test'}", &command); + LoadTestJson(R"({"name":"test"})", &command); EXPECT_CALL(cloud_, GetCommand(_, _, _)) .WillOnce(WithArgs<2>(Invoke( [&command](const CloudDelegate::CommandDoneCallback& callback) { callback.Run(command, nullptr); }))); - EXPECT_JSON_EQ("{'name':'test', 'id':'5'}", + EXPECT_JSON_EQ(R"({"name":"test", "id":"5"})", HandleRequest("/privet/v3/commands/status", kInput)); ErrorPtr error; @@ -904,11 +950,11 @@ TEST_F(PrivetHandlerTestWithAuth, CommandsStatus) { }))); EXPECT_PRED2(IsEqualError, CodeWithReason(404, "notFound"), - HandleRequest("/privet/v3/commands/status", "{'id': '15'}")); + HandleRequest("/privet/v3/commands/status", R"({"id": "15"})")); } TEST_F(PrivetHandlerTestWithAuth, CommandsCancel) { - const char kExpected[] = "{'id': '5', 'name':'test', 'state':'cancelled'}"; + const char kExpected[] = R"({"id": "5", "name":"test", "state":"cancelled"})"; base::DictionaryValue command; LoadTestJson(kExpected, &command); EXPECT_CALL(cloud_, CancelCommand(_, _, _)) @@ -918,7 +964,7 @@ TEST_F(PrivetHandlerTestWithAuth, CommandsCancel) { }))); EXPECT_JSON_EQ(kExpected, - HandleRequest("/privet/v3/commands/cancel", "{'id': '8'}")); + HandleRequest("/privet/v3/commands/cancel", R"({"id": "8"})")); ErrorPtr error; Error::AddTo(&error, FROM_HERE, "notFound", ""); @@ -929,14 +975,14 @@ TEST_F(PrivetHandlerTestWithAuth, CommandsCancel) { }))); EXPECT_PRED2(IsEqualError, CodeWithReason(404, "notFound"), - HandleRequest("/privet/v3/commands/cancel", "{'id': '11'}")); + HandleRequest("/privet/v3/commands/cancel", R"({"id": "11"})")); } TEST_F(PrivetHandlerTestWithAuth, CommandsList) { const char kExpected[] = R"({ - 'commands' : [ - {'id':'5', 'state':'cancelled'}, - {'id':'15', 'state':'inProgress'} + "commands" : [ + {"id":"5", "state":"cancelled"}, + {"id":"15", "state":"inProgress"} ]})"; base::DictionaryValue commands; @@ -961,10 +1007,10 @@ TEST_F(PrivetHandlerCheckForUpdatesTest, NoInput) { cloud_.NotifyOnStateChanged(); const char kInput[] = "{}"; const char kExpected[] = R"({ - 'commandsFingerprint': '2', - 'stateFingerprint': '2', - 'traitsFingerprint': '2', - 'componentsFingerprint': '3' + "commandsFingerprint": "2", + "stateFingerprint": "2", + "traitsFingerprint": "2", + "componentsFingerprint": "3" })"; EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/v3/checkForUpdates", kInput)); @@ -978,16 +1024,16 @@ TEST_F(PrivetHandlerCheckForUpdatesTest, AlreadyChanged) { cloud_.NotifyOnComponentTreeChanged(); cloud_.NotifyOnStateChanged(); const char kInput[] = R"({ - 'commandsFingerprint': '1', - 'stateFingerprint': '1', - 'traitsFingerprint': '1', - 'componentsFingerprint': '1' + "commandsFingerprint": "1", + "stateFingerprint": "1", + "traitsFingerprint": "1", + "componentsFingerprint": "1" })"; const char kExpected[] = R"({ - 'commandsFingerprint': '2', - 'stateFingerprint': '2', - 'traitsFingerprint': '2', - 'componentsFingerprint': '3' + "commandsFingerprint": "2", + "stateFingerprint": "2", + "traitsFingerprint": "2", + "componentsFingerprint": "3" })"; EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/v3/checkForUpdates", kInput)); @@ -998,20 +1044,20 @@ TEST_F(PrivetHandlerCheckForUpdatesTest, LongPollCommands) { EXPECT_CALL(device_, GetHttpRequestTimeout()) .WillOnce(Return(base::TimeDelta::Max())); const char kInput[] = R"({ - 'commandsFingerprint': '1', - 'stateFingerprint': '1', - 'traitsFingerprint': '1', - 'componentsFingerprint': '1' + "commandsFingerprint": "1", + "stateFingerprint": "1", + "traitsFingerprint": "1", + "componentsFingerprint": "1" })"; EXPECT_JSON_EQ("{}", HandleRequest("/privet/v3/checkForUpdates", kInput)); EXPECT_EQ(0, GetResponseCount()); cloud_.NotifyOnTraitDefsChanged(); EXPECT_EQ(1, GetResponseCount()); const char kExpected[] = R"({ - 'commandsFingerprint': '2', - 'stateFingerprint': '1', - 'traitsFingerprint': '2', - 'componentsFingerprint': '1' + "commandsFingerprint": "2", + "stateFingerprint": "1", + "traitsFingerprint": "2", + "componentsFingerprint": "1" })"; EXPECT_JSON_EQ(kExpected, GetResponse()); } @@ -1020,20 +1066,20 @@ TEST_F(PrivetHandlerCheckForUpdatesTest, LongPollTraits) { EXPECT_CALL(device_, GetHttpRequestTimeout()) .WillOnce(Return(base::TimeDelta::Max())); const char kInput[] = R"({ - 'commandsFingerprint': '1', - 'stateFingerprint': '1', - 'traitsFingerprint': '1', - 'componentsFingerprint': '1' + "commandsFingerprint": "1", + "stateFingerprint": "1", + "traitsFingerprint": "1", + "componentsFingerprint": "1" })"; EXPECT_JSON_EQ("{}", HandleRequest("/privet/v3/checkForUpdates", kInput)); EXPECT_EQ(0, GetResponseCount()); cloud_.NotifyOnTraitDefsChanged(); EXPECT_EQ(1, GetResponseCount()); const char kExpected[] = R"({ - 'commandsFingerprint': '2', - 'stateFingerprint': '1', - 'traitsFingerprint': '2', - 'componentsFingerprint': '1' + "commandsFingerprint": "2", + "stateFingerprint": "1", + "traitsFingerprint": "2", + "componentsFingerprint": "1" })"; EXPECT_JSON_EQ(kExpected, GetResponse()); } @@ -1042,20 +1088,20 @@ TEST_F(PrivetHandlerCheckForUpdatesTest, LongPollState) { EXPECT_CALL(device_, GetHttpRequestTimeout()) .WillOnce(Return(base::TimeDelta::Max())); const char kInput[] = R"({ - 'commandsFingerprint': '1', - 'stateFingerprint': '1', - 'traitsFingerprint': '1', - 'componentsFingerprint': '1' + "commandsFingerprint": "1", + "stateFingerprint": "1", + "traitsFingerprint": "1", + "componentsFingerprint": "1" })"; EXPECT_JSON_EQ("{}", HandleRequest("/privet/v3/checkForUpdates", kInput)); EXPECT_EQ(0, GetResponseCount()); cloud_.NotifyOnStateChanged(); EXPECT_EQ(1, GetResponseCount()); const char kExpected[] = R"({ - 'commandsFingerprint': '1', - 'stateFingerprint': '2', - 'traitsFingerprint': '1', - 'componentsFingerprint': '2' + "commandsFingerprint": "1", + "stateFingerprint": "2", + "traitsFingerprint": "1", + "componentsFingerprint": "2" })"; EXPECT_JSON_EQ(kExpected, GetResponse()); } @@ -1064,20 +1110,20 @@ TEST_F(PrivetHandlerCheckForUpdatesTest, LongPollComponents) { EXPECT_CALL(device_, GetHttpRequestTimeout()) .WillOnce(Return(base::TimeDelta::Max())); const char kInput[] = R"({ - 'commandsFingerprint': '1', - 'stateFingerprint': '1', - 'traitsFingerprint': '1', - 'componentsFingerprint': '1' + "commandsFingerprint": "1", + "stateFingerprint": "1", + "traitsFingerprint": "1", + "componentsFingerprint": "1" })"; EXPECT_JSON_EQ("{}", HandleRequest("/privet/v3/checkForUpdates", kInput)); EXPECT_EQ(0, GetResponseCount()); cloud_.NotifyOnComponentTreeChanged(); EXPECT_EQ(1, GetResponseCount()); const char kExpected[] = R"({ - 'commandsFingerprint': '1', - 'stateFingerprint': '1', - 'traitsFingerprint': '1', - 'componentsFingerprint': '2' + "commandsFingerprint": "1", + "stateFingerprint": "1", + "traitsFingerprint": "1", + "componentsFingerprint": "2" })"; EXPECT_JSON_EQ(kExpected, GetResponse()); } @@ -1086,8 +1132,8 @@ TEST_F(PrivetHandlerCheckForUpdatesTest, LongPollIgnoreTraits) { EXPECT_CALL(device_, GetHttpRequestTimeout()) .WillOnce(Return(base::TimeDelta::Max())); const char kInput[] = R"({ - 'stateFingerprint': '1', - 'componentsFingerprint': '1' + "stateFingerprint": "1", + "componentsFingerprint": "1" })"; EXPECT_JSON_EQ("{}", HandleRequest("/privet/v3/checkForUpdates", kInput)); EXPECT_EQ(0, GetResponseCount()); @@ -1096,10 +1142,10 @@ TEST_F(PrivetHandlerCheckForUpdatesTest, LongPollIgnoreTraits) { cloud_.NotifyOnComponentTreeChanged(); EXPECT_EQ(1, GetResponseCount()); const char kExpected[] = R"({ - 'commandsFingerprint': '2', - 'stateFingerprint': '1', - 'traitsFingerprint': '2', - 'componentsFingerprint': '2' + "commandsFingerprint": "2", + "stateFingerprint": "1", + "traitsFingerprint": "2", + "componentsFingerprint": "2" })"; EXPECT_JSON_EQ(kExpected, GetResponse()); } @@ -1108,8 +1154,8 @@ TEST_F(PrivetHandlerCheckForUpdatesTest, LongPollIgnoreState) { EXPECT_CALL(device_, GetHttpRequestTimeout()) .WillOnce(Return(base::TimeDelta::Max())); const char kInput[] = R"({ - 'commandsFingerprint': '1', - 'traitsFingerprint': '1' + "commandsFingerprint": "1", + "traitsFingerprint": "1" })"; EXPECT_JSON_EQ("{}", HandleRequest("/privet/v3/checkForUpdates", kInput)); EXPECT_EQ(0, GetResponseCount()); @@ -1120,10 +1166,10 @@ TEST_F(PrivetHandlerCheckForUpdatesTest, LongPollIgnoreState) { cloud_.NotifyOnTraitDefsChanged(); EXPECT_EQ(1, GetResponseCount()); const char kExpected[] = R"({ - 'commandsFingerprint': '2', - 'stateFingerprint': '2', - 'traitsFingerprint': '2', - 'componentsFingerprint': '3' + "commandsFingerprint": "2", + "stateFingerprint": "2", + "traitsFingerprint": "2", + "componentsFingerprint": "3" })"; EXPECT_JSON_EQ(kExpected, GetResponse()); } @@ -1132,17 +1178,17 @@ TEST_F(PrivetHandlerCheckForUpdatesTest, InstantTimeout) { EXPECT_CALL(device_, GetHttpRequestTimeout()) .WillOnce(Return(base::TimeDelta::Max())); const char kInput[] = R"({ - 'commandsFingerprint': '1', - 'stateFingerprint': '1', - 'traitsFingerprint': '1', - 'componentsFingerprint': '1', - 'waitTimeout': 0 + "commandsFingerprint": "1", + "stateFingerprint": "1", + "traitsFingerprint": "1", + "componentsFingerprint": "1", + "waitTimeout": 0 })"; const char kExpected[] = R"({ - 'commandsFingerprint': '1', - 'stateFingerprint': '1', - 'traitsFingerprint': '1', - 'componentsFingerprint': '1' + "commandsFingerprint": "1", + "stateFingerprint": "1", + "traitsFingerprint": "1", + "componentsFingerprint": "1" })"; EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/v3/checkForUpdates", kInput)); @@ -1152,11 +1198,11 @@ TEST_F(PrivetHandlerCheckForUpdatesTest, UserTimeout) { EXPECT_CALL(device_, GetHttpRequestTimeout()) .WillOnce(Return(base::TimeDelta::Max())); const char kInput[] = R"({ - 'commandsFingerprint': '1', - 'stateFingerprint': '1', - 'traitsFingerprint': '1', - 'componentsFingerprint': '1', - 'waitTimeout': 3 + "commandsFingerprint": "1", + "stateFingerprint": "1", + "traitsFingerprint": "1", + "componentsFingerprint": "1", + "waitTimeout": 3 })"; base::Closure callback; EXPECT_CALL(device_, PostDelayedTask(_, _, base::TimeDelta::FromSeconds(3))) @@ -1166,10 +1212,10 @@ TEST_F(PrivetHandlerCheckForUpdatesTest, UserTimeout) { callback.Run(); EXPECT_EQ(1, GetResponseCount()); const char kExpected[] = R"({ - 'commandsFingerprint': '1', - 'stateFingerprint': '1', - 'traitsFingerprint': '1', - 'componentsFingerprint': '1' + "commandsFingerprint": "1", + "stateFingerprint": "1", + "traitsFingerprint": "1", + "componentsFingerprint": "1" })"; EXPECT_JSON_EQ(kExpected, GetResponse()); } @@ -1178,10 +1224,10 @@ TEST_F(PrivetHandlerCheckForUpdatesTest, ServerTimeout) { EXPECT_CALL(device_, GetHttpRequestTimeout()) .WillOnce(Return(base::TimeDelta::FromMinutes(1))); const char kInput[] = R"({ - 'commandsFingerprint': '1', - 'stateFingerprint': '1', - 'traitsFingerprint': '1', - 'componentsFingerprint': '1' + "commandsFingerprint": "1", + "stateFingerprint": "1", + "traitsFingerprint": "1", + "componentsFingerprint": "1" })"; base::Closure callback; EXPECT_CALL(device_, PostDelayedTask(_, _, base::TimeDelta::FromSeconds(50))) @@ -1191,10 +1237,10 @@ TEST_F(PrivetHandlerCheckForUpdatesTest, ServerTimeout) { callback.Run(); EXPECT_EQ(1, GetResponseCount()); const char kExpected[] = R"({ - 'commandsFingerprint': '1', - 'stateFingerprint': '1', - 'traitsFingerprint': '1', - 'componentsFingerprint': '1' + "commandsFingerprint": "1", + "stateFingerprint": "1", + "traitsFingerprint": "1", + "componentsFingerprint": "1" })"; EXPECT_JSON_EQ(kExpected, GetResponse()); } @@ -1203,10 +1249,10 @@ TEST_F(PrivetHandlerCheckForUpdatesTest, VeryShortServerTimeout) { EXPECT_CALL(device_, GetHttpRequestTimeout()) .WillOnce(Return(base::TimeDelta::FromSeconds(5))); const char kInput[] = R"({ - 'commandsFingerprint': '1', - 'stateFingerprint': '1', - 'traitsFingerprint': '1', - 'componentsFingerprint': '1' + "commandsFingerprint": "1", + "stateFingerprint": "1", + "traitsFingerprint": "1", + "componentsFingerprint": "1" })"; EXPECT_JSON_EQ(kInput, HandleRequest("/privet/v3/checkForUpdates", kInput)); EXPECT_EQ(1, GetResponseCount()); @@ -1216,11 +1262,11 @@ TEST_F(PrivetHandlerCheckForUpdatesTest, ServerAndUserTimeout) { EXPECT_CALL(device_, GetHttpRequestTimeout()) .WillOnce(Return(base::TimeDelta::FromMinutes(1))); const char kInput[] = R"({ - 'commandsFingerprint': '1', - 'stateFingerprint': '1', - 'traitsFingerprint': '1', - 'componentsFingerprint': '1', - 'waitTimeout': 10 + "commandsFingerprint": "1", + "stateFingerprint": "1", + "traitsFingerprint": "1", + "componentsFingerprint": "1", + "waitTimeout": 10 })"; base::Closure callback; EXPECT_CALL(device_, PostDelayedTask(_, _, base::TimeDelta::FromSeconds(10))) @@ -1230,10 +1276,10 @@ TEST_F(PrivetHandlerCheckForUpdatesTest, ServerAndUserTimeout) { callback.Run(); EXPECT_EQ(1, GetResponseCount()); const char kExpected[] = R"({ - 'commandsFingerprint': '1', - 'stateFingerprint': '1', - 'traitsFingerprint': '1', - 'componentsFingerprint': '1' + "commandsFingerprint": "1", + "stateFingerprint": "1", + "traitsFingerprint": "1", + "componentsFingerprint": "1" })"; EXPECT_JSON_EQ(kExpected, GetResponse()); } @@ -1242,11 +1288,11 @@ TEST_F(PrivetHandlerCheckForUpdatesTest, ChangeBeforeTimeout) { EXPECT_CALL(device_, GetHttpRequestTimeout()) .WillOnce(Return(base::TimeDelta::Max())); const char kInput[] = R"({ - 'commandsFingerprint': '1', - 'stateFingerprint': '1', - 'traitsFingerprint': '1', - 'componentsFingerprint': '1', - 'waitTimeout': 10 + "commandsFingerprint": "1", + "stateFingerprint": "1", + "traitsFingerprint": "1", + "componentsFingerprint": "1", + "waitTimeout": 10 })"; base::Closure callback; EXPECT_CALL(device_, PostDelayedTask(_, _, base::TimeDelta::FromSeconds(10))) @@ -1256,10 +1302,10 @@ TEST_F(PrivetHandlerCheckForUpdatesTest, ChangeBeforeTimeout) { cloud_.NotifyOnTraitDefsChanged(); EXPECT_EQ(1, GetResponseCount()); const char kExpected[] = R"({ - 'commandsFingerprint': '2', - 'stateFingerprint': '1', - 'traitsFingerprint': '2', - 'componentsFingerprint': '1' + "commandsFingerprint": "2", + "stateFingerprint": "1", + "traitsFingerprint": "2", + "componentsFingerprint": "1" })"; EXPECT_JSON_EQ(kExpected, GetResponse()); callback.Run(); diff --git a/src/weave_unittest.cc b/src/weave_unittest.cc index b300f57..452ac78 100644 --- a/src/weave_unittest.cc +++ b/src/weave_unittest.cc @@ -421,7 +421,8 @@ TEST_F(WeaveBasicTest, Register) { InitDnsSdPublishing(true, "DB"); bool done = false; - device_->Register("TICKET_ID", base::Bind([this, &done](ErrorPtr error) { + device_->Register(RegistrationData{"TICKET_ID"}, + base::Bind([this, &done](ErrorPtr error) { EXPECT_FALSE(error); done = true; task_runner_.Break(); @@ -431,7 +432,8 @@ TEST_F(WeaveBasicTest, Register) { EXPECT_TRUE(done); done = false; - device_->Register("TICKET_ID2", base::Bind([this, &done](ErrorPtr error) { + device_->Register(RegistrationData{"TICKET_ID2"}, + base::Bind([this, &done](ErrorPtr error) { EXPECT_TRUE(error->HasError("already_registered")); done = true; task_runner_.Break(); |