Pass Config pointer into AuthManager

AuthManager needs to have logic for re-claming devices. This requires
persistent storage for secret and owner. It's going to be easier to
handle logic there than outside.

BUG=25766815

Change-Id: Icc417f23715b48461098503fd241cee534d2225c
Reviewed-on: https://weave-review.googlesource.com/1949
Reviewed-by: Vitaly Buka <vitalybuka@google.com>
diff --git a/src/device_manager.cc b/src/device_manager.cc
index cb575b8..88256da 100644
--- a/src/device_manager.cc
+++ b/src/device_manager.cc
@@ -33,15 +33,8 @@
   config_->Load();
 
   if (http_server) {
-    auth_manager_.reset(
-        new privet::AuthManager(config_->GetSettings().secret,
-                                http_server->GetHttpsCertificateFingerprint()));
-
-    if (auth_manager_->GetSecret() != config_->GetSettings().secret) {
-      // There is no Config::OnChangedCallback registered.
-      Config::Transaction transaction(config_.get());
-      transaction.set_secret(auth_manager_->GetSecret());
-    }
+    auth_manager_.reset(new privet::AuthManager(
+        config_.get(), http_server->GetHttpsCertificateFingerprint()));
   }
 
   device_info_.reset(new DeviceRegistrationInfo(
diff --git a/src/privet/auth_manager.cc b/src/privet/auth_manager.cc
index 92c33a7..3a2f5e0 100644
--- a/src/privet/auth_manager.cc
+++ b/src/privet/auth_manager.cc
@@ -7,6 +7,7 @@
 #include <base/rand_util.h>
 #include <base/strings/string_number_conversions.h>
 
+#include "src/config.h"
 #include "src/data_encoding.h"
 #include "src/privet/openssl_utils.h"
 #include "src/string_utils.h"
@@ -73,17 +74,36 @@
   DISALLOW_COPY_AND_ASSIGN(Caveat);
 };
 
+std::vector<uint8_t> CreateSecret() {
+  std::vector<uint8_t> secret(kSha256OutputSize);
+  base::RandBytes(secret.data(), secret.size());
+  return secret;
+}
+
 }  // namespace
 
+AuthManager::AuthManager(Config* config,
+                         const std::vector<uint8_t>& certificate_fingerprint)
+    : config_{config}, certificate_fingerprint_{certificate_fingerprint} {
+  SetSecret(config_ ? config_->GetSettings().secret : std::vector<uint8_t>{});
+}
+
 AuthManager::AuthManager(const std::vector<uint8_t>& secret,
                          const std::vector<uint8_t>& certificate_fingerprint,
                          base::Clock* clock)
-    : clock_{clock ? clock : &default_clock_},
-      secret_{secret},
-      certificate_fingerprint_{certificate_fingerprint} {
-  if (secret_.size() != kSha256OutputSize) {
-    secret_.resize(kSha256OutputSize);
-    base::RandBytes(secret_.data(), secret_.size());
+    : AuthManager(nullptr, certificate_fingerprint) {
+  SetSecret(secret);
+  if (clock)
+    clock_ = clock;
+}
+
+void AuthManager::SetSecret(const std::vector<uint8_t>& secret) {
+  secret_ = secret.size() == kSha256OutputSize ? secret : CreateSecret();
+  if (config_ && config_->GetSettings().secret != secret_) {
+    Config::Transaction change{config_};
+    change.set_secret(secret);
+    change.set_root_client_token_owner(RootClientTokenOwner::kNone);
+    change.Commit();
   }
 }
 
@@ -112,7 +132,7 @@
 
 std::vector<uint8_t> AuthManager::ClaimRootClientAuthToken() {
   pending_claims_.push_back(
-      std::unique_ptr<AuthManager>{new AuthManager{{}, {}, clock_}});
+      std::unique_ptr<AuthManager>{new AuthManager{nullptr, {}}});
   if (pending_claims_.size() > kMaxPendingClaims)
     pending_claims_.pop_front();
   return pending_claims_.back()->GetRootClientAuthToken();
@@ -144,6 +164,7 @@
       scope.GetCaveat(), issued.GetCaveat(),
   };
 
+  CHECK_EQ(kSha256OutputSize, secret_.size());
   UwMacaroon macaroon{};
   CHECK(uw_macaroon_new_from_root_key_(
       &macaroon, secret_.data(), secret_.size(), caveats, arraysize(caveats)));
@@ -167,6 +188,7 @@
     return false;
   }
 
+  CHECK_EQ(kSha256OutputSize, secret_.size());
   return uw_macaroon_verify_(&macaroon, secret_.data(), secret_.size());
 }
 
diff --git a/src/privet/auth_manager.h b/src/privet/auth_manager.h
index 8fcadfc..dd4ad3d 100644
--- a/src/privet/auth_manager.h
+++ b/src/privet/auth_manager.h
@@ -16,10 +16,17 @@
 #include "src/privet/privet_types.h"
 
 namespace weave {
+
+class Config;
+
 namespace privet {
 
 class AuthManager {
  public:
+  AuthManager(Config* config,
+              const std::vector<uint8_t>& certificate_fingerprint);
+
+  // Constructor for tests.
   AuthManager(const std::vector<uint8_t>& secret,
               const std::vector<uint8_t>& certificate_fingerprint,
               base::Clock* clock = nullptr);
@@ -43,8 +50,11 @@
   bool IsValidAuthToken(const std::vector<uint8_t>& token) const;
 
  private:
+  void SetSecret(const std::vector<uint8_t>& secret);
+
+  Config* config_{nullptr};
   base::DefaultClock default_clock_;
-  base::Clock* clock_{nullptr};
+  base::Clock* clock_{&default_clock_};
 
   std::vector<uint8_t> secret_;
   std::vector<uint8_t> certificate_fingerprint_;
diff --git a/src/privet/security_manager_unittest.cc b/src/privet/security_manager_unittest.cc
index d9f5c56..7c26026 100644
--- a/src/privet/security_manager_unittest.cc
+++ b/src/privet/security_manager_unittest.cc
@@ -104,11 +104,11 @@
   test::MockClock clock_;
   AuthManager auth_manager_{
       {},
-      {{
+      {
           59, 47, 77, 247, 129, 187, 188, 158, 172, 105, 246, 93, 102, 83, 8,
           138, 176, 141, 37, 63, 223, 40, 153, 121, 134, 23, 120, 106, 24, 205,
           7, 135,
-      }},
+      },
       &clock_};
   SecurityManager security_{&auth_manager_,
                             {PairingType::kEmbeddedCode},