buffet: Rework buffet configuration
Manufacturer supplied fields will come from the buffet configuration
file with good defaults provided by buffet itself. This includes
a few default values for user supplied fields.
User supplied and other per device instance state will be stored in
a state file as before.
Keeping these fields separate greatly simplifies reasoning about
adding configuration settings to buffet.
BUG=brillo:658
TEST=unittests, tendo_experimental passes
CQ-DEPEND=CL:262292
Change-Id: Ib74721b9c99d11c189042aa78cc43a076072de32
Reviewed-on: https://chromium-review.googlesource.com/262296
Tested-by: Christopher Wiley <wiley@chromium.org>
Reviewed-by: Alex Vakulenko <avakulenko@chromium.org>
Reviewed-by: Anton Muhin <antonm@chromium.org>
Commit-Queue: Christopher Wiley <wiley@chromium.org>
diff --git a/buffet/device_registration_info.cc b/buffet/device_registration_info.cc
index 380d75a..3f7e17c 100644
--- a/buffet/device_registration_info.cc
+++ b/buffet/device_registration_info.cc
@@ -36,22 +36,12 @@
namespace storage_keys {
// Persistent keys
-const char kClientId[] = "client_id";
-const char kClientSecret[] = "client_secret";
-const char kApiKey[] = "api_key";
const char kRefreshToken[] = "refresh_token";
const char kDeviceId[] = "device_id";
-const char kOAuthURL[] = "oauth_url";
-const char kServiceURL[] = "service_url";
const char kRobotAccount[] = "robot_account";
-// Transient keys
-const char kDeviceKind[] = "device_kind";
-const char kName[] = "name";
const char kDisplayName[] = "display_name";
const char kDescription[] = "description";
const char kLocation[] = "location";
-const char kModelId[] = "model_id";
-
} // namespace storage_keys
} // namespace buffet
@@ -133,7 +123,7 @@
DeviceRegistrationInfo::DeviceRegistrationInfo(
const std::shared_ptr<CommandManager>& command_manager,
const std::shared_ptr<StateManager>& state_manager,
- std::unique_ptr<chromeos::KeyValueStore> config_store,
+ std::unique_ptr<const BuffetConfig> config,
const std::shared_ptr<chromeos::http::Transport>& transport,
const std::shared_ptr<StorageInterface>& state_store,
const base::Closure& on_status_changed)
@@ -141,7 +131,7 @@
storage_{state_store},
command_manager_{command_manager},
state_manager_{state_manager},
- config_store_{std::move(config_store)},
+ config_{std::move(config)},
on_status_changed_{on_status_changed} {
}
@@ -155,20 +145,21 @@
std::string DeviceRegistrationInfo::GetServiceURL(
const std::string& subpath,
const chromeos::data_encoding::WebParamList& params) const {
- return BuildURL(service_url_, {subpath}, params);
+ return BuildURL(config_->service_url(), {subpath}, params);
}
std::string DeviceRegistrationInfo::GetDeviceURL(
const std::string& subpath,
const chromeos::data_encoding::WebParamList& params) const {
CHECK(!device_id_.empty()) << "Must have a valid device ID";
- return BuildURL(service_url_, {"devices", device_id_, subpath}, params);
+ return BuildURL(config_->service_url(),
+ {"devices", device_id_, subpath}, params);
}
std::string DeviceRegistrationInfo::GetOAuthURL(
const std::string& subpath,
const chromeos::data_encoding::WebParamList& params) const {
- return BuildURL(oauth_url_, {subpath}, params);
+ return BuildURL(config_->oauth_url(), {subpath}, params);
}
const std::string& DeviceRegistrationInfo::GetDeviceId() const {
@@ -187,60 +178,22 @@
// Get the values into temp variables first to make sure we can get
// all the data correctly before changing the state of this object.
- std::string client_id;
- if (!dict->GetString(storage_keys::kClientId, &client_id))
- return false;
- std::string client_secret;
- if (!dict->GetString(storage_keys::kClientSecret, &client_secret))
- return false;
- std::string api_key;
- if (!dict->GetString(storage_keys::kApiKey, &api_key))
- return false;
std::string refresh_token;
- if (!dict->GetString(storage_keys::kRefreshToken, &refresh_token))
- return false;
std::string device_id;
- if (!dict->GetString(storage_keys::kDeviceId, &device_id))
- return false;
- std::string oauth_url;
- if (!dict->GetString(storage_keys::kOAuthURL, &oauth_url))
- return false;
- std::string service_url;
- if (!dict->GetString(storage_keys::kServiceURL, &service_url))
- return false;
std::string device_robot_account;
- if (!dict->GetString(storage_keys::kRobotAccount, &device_robot_account))
- return false;
- std::string device_kind;
- if (!dict->GetString(storage_keys::kDeviceKind, &device_kind))
- return false;
- std::string name;
- if (!dict->GetString(storage_keys::kName, &name))
- return false;
std::string display_name;
- if (!dict->GetString(storage_keys::kDisplayName, &display_name))
- return false;
std::string description;
- if (!dict->GetString(storage_keys::kDescription, &description))
- return false;
std::string location;
- if (!dict->GetString(storage_keys::kLocation, &location))
+ if (!dict->GetString(storage_keys::kRefreshToken, &refresh_token) ||
+ !dict->GetString(storage_keys::kDeviceId, &device_id) ||
+ !dict->GetString(storage_keys::kRobotAccount, &device_robot_account) ||
+ !dict->GetString(storage_keys::kDisplayName, &display_name) ||
+ !dict->GetString(storage_keys::kDescription, &description) ||
+ !dict->GetString(storage_keys::kLocation, &location)) {
return false;
-
- // Temporarily tolerate missing modelId. Older registrations will not have a
- // modelId in their state files.
- // TODO(vitalybuka): Add result check back. Should be safe starting Mar 2015.
- dict->GetString(storage_keys::kModelId, &model_id_);
-
- client_id_ = client_id;
- client_secret_ = client_secret;
- api_key_ = api_key;
+ }
refresh_token_ = refresh_token;
- oauth_url_ = oauth_url;
- service_url_ = service_url;
device_robot_account_ = device_robot_account;
- device_kind_ = device_kind;
- name_ = name;
display_name_ = display_name;
description_ = description;
location_ = location;
@@ -262,20 +215,12 @@
bool DeviceRegistrationInfo::Save() const {
base::DictionaryValue dict;
- dict.SetString(storage_keys::kClientId, client_id_);
- dict.SetString(storage_keys::kClientSecret, client_secret_);
- dict.SetString(storage_keys::kApiKey, api_key_);
dict.SetString(storage_keys::kRefreshToken, refresh_token_);
dict.SetString(storage_keys::kDeviceId, device_id_);
- dict.SetString(storage_keys::kOAuthURL, oauth_url_);
- dict.SetString(storage_keys::kServiceURL, service_url_);
dict.SetString(storage_keys::kRobotAccount, device_robot_account_);
- dict.SetString(storage_keys::kDeviceKind, device_kind_);
- dict.SetString(storage_keys::kName, name_);
dict.SetString(storage_keys::kDisplayName, display_name_);
dict.SetString(storage_keys::kDescription, description_);
dict.SetString(storage_keys::kLocation, location_);
- dict.SetString(storage_keys::kModelId, model_id_);
return storage_->Save(&dict);
}
@@ -362,8 +307,8 @@
LOG(INFO) << "Refreshing access token.";
auto response = chromeos::http::PostFormDataAndBlock(GetOAuthURL("token"), {
{"refresh_token", refresh_token_},
- {"client_id", client_id_},
- {"client_secret", client_secret_},
+ {"client_id", config_->client_id()},
+ {"client_secret", config_->client_secret()},
{"grant_type", "refresh_token"},
}, {}, transport_, error);
if (!response)
@@ -449,16 +394,16 @@
std::unique_ptr<base::DictionaryValue> resource{new base::DictionaryValue};
if (!device_id_.empty())
resource->SetString("id", device_id_);
- resource->SetString("deviceKind", device_kind_);
- resource->SetString("name", name_);
+ resource->SetString("deviceKind", config_->device_kind());
+ resource->SetString("name", config_->name());
if (!display_name_.empty())
resource->SetString("displayName", display_name_);
if (!description_.empty())
resource->SetString("description", description_);
if (!location_.empty())
resource->SetString("location", location_);
- if (!model_id_.empty())
- resource->SetString("modelManifestId", model_id_);
+ if (!config_->model_id().empty())
+ resource->SetString("modelManifestId", config_->model_id());
resource->SetString("channel.supportedType", "xmpp");
resource->Set("commandDefs", commands.release());
resource->Set("state", state.release());
@@ -488,27 +433,41 @@
return json;
}
+namespace {
+
+bool GetWithDefault(const std::map<std::string, std::string>& source,
+ const std::string& key,
+ const std::string& default_value,
+ std::string* output) {
+ auto it = source.find(key);
+ if (it == source.end()) {
+ *output = default_value;
+ return false;
+ }
+ *output = it->second;
+ return true;
+}
+
+} // namespace
+
std::string DeviceRegistrationInfo::RegisterDevice(
const std::map<std::string, std::string>& params,
chromeos::ErrorPtr* error) {
std::string ticket_id;
- if (!GetParamValue(params, "ticket_id", &ticket_id, error) ||
- !GetParamValue(params, storage_keys::kClientId, &client_id_, error) ||
- !GetParamValue(params, storage_keys::kClientSecret, &client_secret_,
- error) ||
- !GetParamValue(params, storage_keys::kApiKey, &api_key_, error) ||
- !GetParamValue(params, storage_keys::kDeviceKind, &device_kind_, error) ||
- !GetParamValue(params, storage_keys::kName, &name_, error) ||
- !GetParamValue(params, storage_keys::kDisplayName, &display_name_,
- error) ||
- !GetParamValue(params, storage_keys::kDescription, &description_,
- error) ||
- !GetParamValue(params, storage_keys::kLocation, &location_, error) ||
- !GetParamValue(params, storage_keys::kModelId, &model_id_, error) ||
- !GetParamValue(params, storage_keys::kOAuthURL, &oauth_url_, error) ||
- !GetParamValue(params, storage_keys::kServiceURL, &service_url_, error)) {
+ if (!GetWithDefault(params, "ticket_id", "", &ticket_id)) {
+ chromeos::Error::AddTo(error, FROM_HERE, kErrorDomainBuffet,
+ "missing_parameter",
+ "Need ticket_id parameter for RegisterDevice().");
return std::string();
}
+ // These fields are optional, and will default to values from the manufacturer
+ // supplied config.
+ GetWithDefault(params, storage_keys::kDisplayName,
+ config_->default_display_name(), &display_name_);
+ GetWithDefault(params, storage_keys::kDescription,
+ config_->default_description(), &description_);
+ GetWithDefault(params, storage_keys::kLocation,
+ config_->default_location(), &location_);
std::unique_ptr<base::DictionaryValue> device_draft =
BuildDeviceResource(error);
@@ -517,11 +476,11 @@
base::DictionaryValue req_json;
req_json.SetString("id", ticket_id);
- req_json.SetString("oauthClientId", client_id_);
+ req_json.SetString("oauthClientId", config_->client_id());
req_json.Set("deviceDraft", device_draft.release());
auto url = GetServiceURL("registrationTickets/" + ticket_id,
- {{"key", api_key_}});
+ {{"key", config_->api_key()}});
std::unique_ptr<chromeos::http::Response> response =
chromeos::http::PatchJsonAndBlock(url, &req_json, {}, transport_, error);
auto json_resp = chromeos::http::ParseJsonResponse(response.get(), nullptr,
@@ -534,7 +493,7 @@
}
url = GetServiceURL("registrationTickets/" + ticket_id +
- "/finalize?key=" + api_key_);
+ "/finalize?key=" + config_->api_key());
response = chromeos::http::SendRequestWithNoDataAndBlock(
chromeos::http::request_type::kPost, url, {}, transport_, error);
if (!response)
@@ -562,8 +521,8 @@
// Now get access_token and refresh_token
response = chromeos::http::PostFormDataAndBlock(GetOAuthURL("token"), {
{"code", auth_code},
- {"client_id", client_id_},
- {"client_secret", client_secret_},
+ {"client_id", config_->client_id()},
+ {"client_secret", config_->client_secret()},
{"redirect_uri", "oob"},
{"scope", "https://www.googleapis.com/auth/clouddevices"},
{"grant_type", "authorization_code"}
@@ -971,28 +930,6 @@
base::Bind(&IgnoreCloudResult), base::Bind(&IgnoreCloudError));
}
-bool DeviceRegistrationInfo::GetParamValue(
- const std::map<std::string, std::string>& params,
- const std::string& param_name,
- std::string* param_value,
- chromeos::ErrorPtr* error) {
- auto p = params.find(param_name);
- if (p != params.end()) {
- *param_value = p->second;
- return true;
- }
-
- bool default_was_set = config_store_->GetString(param_name, param_value);
- if (default_was_set)
- return true;
-
- chromeos::Error::AddToPrintf(error, FROM_HERE, kErrorDomainBuffet,
- "missing_parameter",
- "Parameter %s not specified",
- param_name.c_str());
- return false;
-}
-
void DeviceRegistrationInfo::SetRegistrationStatus(
RegistrationStatus new_status) {
if (new_status == registration_status_)