Generate Root Client Authorization Token

BUG=25934385

Change-Id: Ic7d421f2c0152c7580014229c28495520d8c9981
Reviewed-on: https://weave-review.googlesource.com/1868
Reviewed-by: Vitaly Buka <vitalybuka@google.com>
diff --git a/src/privet/auth_manager.cc b/src/privet/auth_manager.cc
index 0864242..be7e971 100644
--- a/src/privet/auth_manager.cc
+++ b/src/privet/auth_manager.cc
@@ -11,12 +11,18 @@
 #include "src/privet/openssl_utils.h"
 #include "src/string_utils.h"
 
+extern "C" {
+#include "third_party/libuweave/src/macaroon.h"
+}
+
 namespace weave {
 namespace privet {
 
 namespace {
 
 const char kTokenDelimeter[] = ":";
+const size_t kCaveatBuffetSize = 32;
+const size_t kMaxMacaroonSize = 1024;
 
 // Returns "scope:id:time".
 std::string CreateTokenData(const UserInfo& user_info, const base::Time& time) {
@@ -49,6 +55,22 @@
   return UserInfo{static_cast<AuthScope>(scope), id};
 }
 
+class Caveat {
+ public:
+  Caveat(UwMacaroonCaveatType type, uint32_t value) {
+    CHECK(uw_macaroon_caveat_create_with_uint_(type, value, buffer,
+                                               sizeof(buffer), &caveat));
+  }
+
+  const UwMacaroonCaveat& GetCaveat() const { return caveat; }
+
+ private:
+  UwMacaroonCaveat caveat;
+  uint8_t buffer[kCaveatBuffetSize];
+
+  DISALLOW_COPY_AND_ASSIGN(Caveat);
+};
+
 }  // namespace
 
 AuthManager::AuthManager(const std::vector<uint8_t>& secret,
@@ -84,5 +106,26 @@
   return SplitTokenData(std::string(data.begin(), data.end()), time);
 }
 
+std::vector<uint8_t> AuthManager::GetRootDeviceToken(
+    const base::Time& time) const {
+  Caveat scope{kUwMacaroonCaveatTypeScope, kUwMacaroonCaveatScopeTypeOwner};
+  Caveat issued{kUwMacaroonCaveatTypeIssued,
+                static_cast<uint32_t>(time.ToTimeT())};
+
+  UwMacaroonCaveat caveats[] = {
+      scope.GetCaveat(), issued.GetCaveat(),
+  };
+
+  UwMacaroon macaroon{};
+  CHECK(uw_macaroon_new_from_root_key_(
+      &macaroon, secret_.data(), secret_.size(), caveats, arraysize(caveats)));
+
+  std::vector<uint8_t> token(kMaxMacaroonSize);
+  size_t len = 0;
+  CHECK(uw_macaroon_dump_(&macaroon, token.data(), token.size(), &len));
+  token.resize(len);
+  return token;
+}
+
 }  // namespace privet
 }  // namespace weave