1 // Copyright 2015 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "buffet/buffet_config.h"
16 
17 #include <set>
18 
19 #include <base/bind.h>
20 #include <brillo/data_encoding.h>
21 #include <gtest/gtest.h>
22 
23 namespace buffet {
24 
TEST(BuffetConfigTest,LoadConfig)25 TEST(BuffetConfigTest, LoadConfig) {
26   brillo::KeyValueStore config_store;
27   config_store.SetString("client_id", "conf_client_id");
28   config_store.SetString("client_secret", "conf_client_secret");
29   config_store.SetString("api_key", "conf_api_key");
30   config_store.SetString("oauth_url", "conf_oauth_url");
31   config_store.SetString("service_url", "conf_service_url");
32   config_store.SetString("oem_name", "conf_oem_name");
33   config_store.SetString("model_name", "conf_model_name");
34   config_store.SetString("model_id", "ABCDE");
35   config_store.SetString("polling_period_ms", "12345");
36   config_store.SetString("backup_polling_period_ms", "6589");
37   config_store.SetBoolean("wifi_auto_setup_enabled", false);
38   config_store.SetBoolean("ble_setup_enabled", true);
39   config_store.SetString("pairing_modes", "pinCode,embeddedCode");
40   config_store.SetString("embedded_code", "567");
41   config_store.SetString("name", "conf_name");
42   config_store.SetString("description", "conf_description");
43   config_store.SetString("location", "conf_location");
44   config_store.SetString("local_anonymous_access_role", "user");
45   config_store.SetBoolean("local_pairing_enabled", false);
46   config_store.SetBoolean("local_discovery_enabled", false);
47 
48   // Following will be ignored.
49   config_store.SetString("device_kind", "conf_device_kind");
50   config_store.SetString("device_id", "conf_device_id");
51   config_store.SetString("refresh_token", "conf_refresh_token");
52   config_store.SetString("robot_account", "conf_robot_account");
53   config_store.SetString("last_configured_ssid", "conf_last_configured_ssid");
54 
55   weave::Settings settings;
56   BuffetConfig config{{}};
57   EXPECT_TRUE(config.LoadDefaults(config_store, &settings));
58 
59   EXPECT_EQ("conf_client_id", settings.client_id);
60   EXPECT_EQ("conf_client_secret", settings.client_secret);
61   EXPECT_EQ("conf_api_key", settings.api_key);
62   EXPECT_EQ("conf_oauth_url", settings.oauth_url);
63   EXPECT_EQ("conf_service_url", settings.service_url);
64   EXPECT_EQ("conf_oem_name", settings.oem_name);
65   EXPECT_EQ("conf_model_name", settings.model_name);
66   EXPECT_EQ("ABCDE", settings.model_id);
67   EXPECT_FALSE(settings.wifi_auto_setup_enabled);
68   std::set<weave::PairingType> pairing_types{weave::PairingType::kPinCode,
69                                              weave::PairingType::kEmbeddedCode};
70   EXPECT_EQ(pairing_types, settings.pairing_modes);
71   EXPECT_EQ("567", settings.embedded_code);
72   EXPECT_EQ("conf_name", settings.name);
73   EXPECT_EQ("conf_description", settings.description);
74   EXPECT_EQ("conf_location", settings.location);
75   EXPECT_EQ(weave::AuthScope::kUser, settings.local_anonymous_access_role);
76   EXPECT_FALSE(settings.local_pairing_enabled);
77   EXPECT_FALSE(settings.local_discovery_enabled);
78 }
79 
80 class BuffetConfigTestWithFakes : public testing::Test,
81                                   public BuffetConfig::FileIO,
82                                   public Encryptor {
83  public:
SetUp()84   void SetUp() {
85     BuffetConfig::Options config_options;
86     config_options.settings = base::FilePath{"settings_file"};
87     config_.reset(new BuffetConfig{config_options});
88     config_->SetEncryptor(this);
89     config_->SetFileIO(this);
90   };
91 
92   // buffet::Encryptor methods.
EncryptWithAuthentication(const std::string & plaintext,std::string * ciphertext)93   bool EncryptWithAuthentication(const std::string& plaintext,
94                                  std::string* ciphertext) override {
95     *ciphertext = brillo::data_encoding::Base64Encode(plaintext);
96     return encryptor_result_;
97   };
DecryptWithAuthentication(const std::string & ciphertext,std::string * plaintext)98   bool DecryptWithAuthentication(const std::string& ciphertext,
99                                  std::string* plaintext) override {
100     return encryptor_result_ &&
101            brillo::data_encoding::Base64Decode(ciphertext, plaintext);
102   };
103 
104   // buffet::BuffetConfig::FileIO methods.
ReadFile(const base::FilePath & path,std::string * content)105   bool ReadFile(const base::FilePath& path, std::string* content) override {
106     if (fake_file_content_.count(path.value()) == 0) {
107       return false;
108     }
109     *content = fake_file_content_[path.value()];
110     return io_result_;
111   };
WriteFile(const base::FilePath & path,const std::string & content)112   bool WriteFile(const base::FilePath& path,
113                  const std::string& content) override {
114     if (io_result_) {
115       fake_file_content_[path.value()] = content;
116     }
117     return io_result_;
118   };
119 
120  protected:
121   std::map<std::string, std::string> fake_file_content_;
122   bool encryptor_result_ = true;
123   bool io_result_ = true;
124   std::unique_ptr<BuffetConfig> config_;
125 };
126 
TEST_F(BuffetConfigTestWithFakes,EncryptionEnabled)127 TEST_F(BuffetConfigTestWithFakes, EncryptionEnabled) {
128   config_->SaveSettings("config", "test", {});
129   ASSERT_NE("test", fake_file_content_["settings_file.config"]);
130   ASSERT_EQ("test", config_->LoadSettings("config"));
131 }
132 
TEST_F(BuffetConfigTestWithFakes,EncryptionFailure)133 TEST_F(BuffetConfigTestWithFakes, EncryptionFailure) {
134   config_->SaveSettings("config", "test", {});
135   ASSERT_FALSE(fake_file_content_["settings_file.config"].empty());
136   encryptor_result_ = false;
137   config_->SaveSettings("config", "test2", {});
138   // Encryption fails -> file cleared.
139   ASSERT_TRUE(fake_file_content_["settings_file.config"].empty());
140 }
141 
TEST_F(BuffetConfigTestWithFakes,DecryptionFailure)142 TEST_F(BuffetConfigTestWithFakes, DecryptionFailure) {
143   config_->SaveSettings("config", "test", {});
144   ASSERT_FALSE(fake_file_content_["settings_file.config"].empty());
145   encryptor_result_ = false;
146   // Decryption fails -> empty settings loaded.
147   ASSERT_TRUE(config_->LoadSettings("config").empty());
148 }
149 
TEST_F(BuffetConfigTestWithFakes,SettingsIOFailure)150 TEST_F(BuffetConfigTestWithFakes, SettingsIOFailure) {
151   config_->SaveSettings("config", "test", {});
152   std::string original = fake_file_content_["settings_file.config"];
153   ASSERT_FALSE(original.empty());
154   io_result_ = false;
155   ASSERT_TRUE(config_->LoadSettings("config").empty());
156   config_->SaveSettings("config2", "test", {});
157   ASSERT_EQ(original, fake_file_content_["settings_file.config"]);
158 }
159 
160 }  // namespace buffet
161