1 // Copyright 2015 The Weave Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef LIBWEAVE_SRC_CONFIG_H_
6 #define LIBWEAVE_SRC_CONFIG_H_
7 
8 #include <set>
9 #include <string>
10 #include <vector>
11 
12 #include <base/callback.h>
13 #include <base/gtest_prod_util.h>
14 #include <weave/error.h>
15 #include <weave/provider/config_store.h>
16 
17 #include "src/privet/privet_types.h"
18 
19 namespace weave {
20 
21 class StorageInterface;
22 
23 enum class RootClientTokenOwner {
24   // Keep order as it's used with order comparison operators.
25   kNone,
26   kClient,
27   kCloud,
28 };
29 
30 // Handles reading buffet config and state files.
31 class Config final {
32  public:
33   struct Settings : public weave::Settings {
34     std::string refresh_token;
35     std::string robot_account;
36     std::string last_configured_ssid;
37     std::vector<uint8_t> secret;
38     RootClientTokenOwner root_client_token_owner{RootClientTokenOwner::kNone};
39   };
40 
41   using OnChangedCallback = base::Callback<void(const weave::Settings&)>;
42   ~Config() = default;
43 
44   explicit Config(provider::ConfigStore* config_store);
45 
46   void AddOnChangedCallback(const OnChangedCallback& callback);
47   const Config::Settings& GetSettings() const;
48 
49   // Allows editing of config. Makes sure that callbacks were called and changes
50   // were saved.
51   // User can commit changes by calling Commit method or by destroying the
52   // object.
53   class Transaction final {
54    public:
Transaction(Config * config)55     explicit Transaction(Config* config)
56         : config_(config), settings_(&config->settings_) {
57       CHECK(config_);
58     }
59 
60     ~Transaction();
61 
set_client_id(const std::string & id)62     void set_client_id(const std::string& id) { settings_->client_id = id; }
set_client_secret(const std::string & secret)63     void set_client_secret(const std::string& secret) {
64       settings_->client_secret = secret;
65     }
set_api_key(const std::string & key)66     void set_api_key(const std::string& key) { settings_->api_key = key; }
set_oauth_url(const std::string & url)67     void set_oauth_url(const std::string& url) { settings_->oauth_url = url; }
set_service_url(const std::string & url)68     void set_service_url(const std::string& url) {
69       settings_->service_url = url;
70     }
set_xmpp_endpoint(const std::string & endpoint)71     void set_xmpp_endpoint(const std::string& endpoint) {
72       settings_->xmpp_endpoint = endpoint;
73     }
set_name(const std::string & name)74     void set_name(const std::string& name) { settings_->name = name; }
set_description(const std::string & description)75     void set_description(const std::string& description) {
76       settings_->description = description;
77     }
set_location(const std::string & location)78     void set_location(const std::string& location) {
79       settings_->location = location;
80     }
set_local_anonymous_access_role(AuthScope role)81     void set_local_anonymous_access_role(AuthScope role) {
82       settings_->local_anonymous_access_role = role;
83     }
set_local_discovery_enabled(bool enabled)84     void set_local_discovery_enabled(bool enabled) {
85       settings_->local_discovery_enabled = enabled;
86     }
set_local_pairing_enabled(bool enabled)87     void set_local_pairing_enabled(bool enabled) {
88       settings_->local_pairing_enabled = enabled;
89     }
set_cloud_id(const std::string & id)90     void set_cloud_id(const std::string& id) { settings_->cloud_id = id; }
set_refresh_token(const std::string & token)91     void set_refresh_token(const std::string& token) {
92       settings_->refresh_token = token;
93     }
set_robot_account(const std::string & account)94     void set_robot_account(const std::string& account) {
95       settings_->robot_account = account;
96     }
set_last_configured_ssid(const std::string & ssid)97     void set_last_configured_ssid(const std::string& ssid) {
98       settings_->last_configured_ssid = ssid;
99     }
set_secret(const std::vector<uint8_t> & secret)100     void set_secret(const std::vector<uint8_t>& secret) {
101       settings_->secret = secret;
102     }
set_root_client_token_owner(RootClientTokenOwner root_client_token_owner)103     void set_root_client_token_owner(
104         RootClientTokenOwner root_client_token_owner) {
105       settings_->root_client_token_owner = root_client_token_owner;
106     }
107 
108     void Commit();
109 
110    private:
111     FRIEND_TEST_ALL_PREFIXES(ConfigTest, Setters);
set_device_id(const std::string & id)112     void set_device_id(const std::string& id) {
113       config_->settings_.device_id = id;
114     }
115 
116     friend class Config;
117     void LoadState();
118     Config* config_;
119     Settings* settings_;
120     bool save_{true};
121   };
122 
123  private:
124   void Load();
125   void Save();
126 
127   Settings settings_;
128   provider::ConfigStore* config_store_{nullptr};
129   std::vector<OnChangedCallback> on_changed_;
130 
131   DISALLOW_COPY_AND_ASSIGN(Config);
132 };
133 
134 }  // namespace weave
135 
136 #endif  // LIBWEAVE_SRC_CONFIG_H_
137