Add "manager" scope into privet API

BUG=25049439

Change-Id: Ide930d204ebf243c0aa9df3820959f5dfdb0e1d1
Reviewed-on: https://weave-review.googlesource.com/1966
Reviewed-by: Vitaly Buka <vitalybuka@google.com>
Reviewed-by: Alex Vakulenko <avakulenko@google.com>
diff --git a/include/weave/settings.h b/include/weave/settings.h
index 1c8b095..eeb3f93 100644
--- a/include/weave/settings.h
+++ b/include/weave/settings.h
@@ -17,6 +17,7 @@
   kNone,
   kViewer,
   kUser,
+  kManager,
   kOwner,
 };
 
diff --git a/src/privet/auth_manager_unittest.cc b/src/privet/auth_manager_unittest.cc
index 91b0d4e..66ed8da 100644
--- a/src/privet/auth_manager_unittest.cc
+++ b/src/privet/auth_manager_unittest.cc
@@ -64,8 +64,11 @@
   EXPECT_EQ(
       "iZx0qgEHFF5lq+Q503GtgU0d6gLQ9TlLsU+DcFbZb2QxOjIzNDoxNDEwMDAwMDAw",
       Base64Encode(auth_.CreateAccessToken(UserInfo{AuthScope::kViewer, 234})));
+  EXPECT_EQ("cWkAHxSBYtTFV3Va/9mcynR8iFZo2qr+8+WewmumF74zOjI1NzoxNDEwMDAwMDAw",
+            Base64Encode(
+                auth_.CreateAccessToken(UserInfo{AuthScope::kManager, 257})));
   EXPECT_EQ(
-      "fTjecsbwtYj6i8/qPJz900B8EMAjRqU8jLT9kfMoz0czOjQ1NjoxNDEwMDAwMDAw",
+      "s3GnCThkQXIzGQoPDlJoiehQiJ5yy4SYUVQzMN2kY0o0OjQ1NjoxNDEwMDAwMDAw",
       Base64Encode(auth_.CreateAccessToken(UserInfo{AuthScope::kOwner, 456})));
   EXPECT_CALL(clock_, Now())
       .WillRepeatedly(Return(clock_.Now() + base::TimeDelta::FromDays(11)));
diff --git a/src/privet/cloud_delegate.cc b/src/privet/cloud_delegate.cc
index fdd8500..ed22c15 100644
--- a/src/privet/cloud_delegate.cc
+++ b/src/privet/cloud_delegate.cc
@@ -295,7 +295,7 @@
   CommandInstance* GetCommandInternal(const std::string& command_id,
                                       const UserInfo& user_info,
                                       ErrorPtr* error) const {
-    if (user_info.scope() != AuthScope::kOwner) {
+    if (user_info.scope() < AuthScope::kManager) {
       auto it = command_owners_.find(command_id);
       if (it == command_owners_.end())
         return ReturnNotFound(command_id, error);
@@ -316,7 +316,7 @@
     CHECK(user_info.scope() != AuthScope::kNone);
     CHECK_NE(user_info.user_id(), 0u);
 
-    if (user_info.scope() == AuthScope::kOwner ||
+    if (user_info.scope() == AuthScope::kManager ||
         owner_id == user_info.user_id()) {
       return true;
     }
diff --git a/src/privet/privet_handler.cc b/src/privet/privet_handler.cc
index bfcc991..57c8633 100644
--- a/src/privet/privet_handler.cc
+++ b/src/privet/privet_handler.cc
@@ -421,9 +421,9 @@
                    &PrivetHandler::HandleAccessControlConfirm,
                    AuthScope::kOwner);
   AddSecureHandler("/privet/v3/setup/start", &PrivetHandler::HandleSetupStart,
-                   AuthScope::kOwner);
+                   AuthScope::kManager);
   AddSecureHandler("/privet/v3/setup/status", &PrivetHandler::HandleSetupStatus,
-                   AuthScope::kOwner);
+                   AuthScope::kManager);
   AddSecureHandler("/privet/v3/state", &PrivetHandler::HandleState,
                    AuthScope::kViewer);
   AddSecureHandler("/privet/v3/commandDefs", &PrivetHandler::HandleCommandDefs,
@@ -821,6 +821,13 @@
 
   const base::DictionaryValue* registration = nullptr;
   if (input.GetDictionary(kGcdKey, &registration)) {
+    if (user_info.scope() < AuthScope::kOwner) {
+      ErrorPtr error;
+      Error::AddTo(&error, FROM_HERE, errors::kDomain,
+                   errors::kInvalidAuthorizationScope,
+                   "Only owner can register device");
+      return ReturnError(*error, callback);
+    }
     registration->GetString(kSetupStartTicketIdKey, &ticket);
     if (ticket.empty()) {
       ErrorPtr error;
diff --git a/src/privet/privet_handler_unittest.cc b/src/privet/privet_handler_unittest.cc
index ab15493..fcbd0d0 100644
--- a/src/privet/privet_handler_unittest.cc
+++ b/src/privet/privet_handler_unittest.cc
@@ -594,6 +594,21 @@
   EXPECT_JSON_EQ(kExpected, HandleRequest("/privet/v3/setup/start", kInput));
 }
 
+TEST_F(PrivetHandlerSetupTest, GcdSetupAsMaster) {
+  EXPECT_CALL(security_, ParseAccessToken(_, _))
+      .WillRepeatedly(DoAll(SetArgPointee<1>(base::Time::Now()),
+                            Return(UserInfo{AuthScope::kManager, 1})));
+  const char kInput[] = R"({
+    'gcd': {
+      'ticketId': 'testTicket',
+      'user': 'testUser'
+    }
+  })";
+
+  EXPECT_PRED2(IsEqualError, CodeWithReason(403, "invalidAuthorizationScope"),
+               HandleRequest("/privet/v3/setup/start", kInput));
+}
+
 TEST_F(PrivetHandlerTestWithAuth, ClaimAccessControl) {
   EXPECT_JSON_EQ("{'clientToken': 'RootClientAuthToken'}",
                  HandleRequest("/privet/v3/accessControl/claim", "{}"));
diff --git a/src/privet/privet_types.cc b/src/privet/privet_types.cc
index ab026e1..7c85937 100644
--- a/src/privet/privet_types.cc
+++ b/src/privet/privet_types.cc
@@ -53,6 +53,7 @@
     {AuthScope::kNone, "none"},
     {AuthScope::kViewer, "viewer"},
     {AuthScope::kUser, "user"},
+    {AuthScope::kManager, "manager"},
     {AuthScope::kOwner, "owner"},
 };