Implement revocation list check when validating auth token

BUG: 26728665
Change-Id: Ib46df44357f1503ef3490566660288a5e09cd01e
Reviewed-on: https://weave-review.googlesource.com/2728
Reviewed-by: Alex Vakulenko <avakulenko@google.com>
diff --git a/src/privet/auth_manager.cc b/src/privet/auth_manager.cc
index 90cf62b..ddead46 100644
--- a/src/privet/auth_manager.cc
+++ b/src/privet/auth_manager.cc
@@ -513,6 +513,28 @@
                         "Invalid session id");
   }
 
+  if (black_list_) {
+    std::vector<uint8_t> user_id;
+    std::vector<uint8_t> app_id;
+    for (size_t i = 0; i < result.num_delegatees; ++i) {
+      if (result.delegatees[i].type == kUwMacaroonDelegateeTypeUser) {
+        user_id.assign(result.delegatees[i].id,
+                       result.delegatees[i].id + result.delegatees[i].id_len);
+      } else if (result.delegatees[i].type == kUwMacaroonDelegateeTypeApp) {
+        app_id.assign(result.delegatees[i].id,
+                      result.delegatees[i].id + result.delegatees[i].id_len);
+      } else {
+        // Do not block by other types of delegatees.
+        continue;
+      }
+      if (black_list_->IsBlocked(
+              user_id, app_id, FromJ2000Time(result.delegatees[i].timestamp))) {
+        return Error::AddTo(error, FROM_HERE, errors::kInvalidAuthCode,
+                            "Auth token is revoked");
+      }
+    }
+  }
+
   CHECK_GE(FromJ2000Time(result.expiration_time), now);
 
   if (!access_token)
diff --git a/src/privet/auth_manager_unittest.cc b/src/privet/auth_manager_unittest.cc
index 8a4938e..f2c8728 100644
--- a/src/privet/auth_manager_unittest.cc
+++ b/src/privet/auth_manager_unittest.cc
@@ -14,9 +14,10 @@
 #include "src/test/mock_black_list_manager.h"
 #include "src/test/mock_clock.h"
 
+using testing::_;
 using testing::Return;
 using testing::SaveArg;
-using testing::_;
+using testing::StrictMock;
 
 namespace weave {
 namespace privet {
@@ -26,6 +27,7 @@
   MockBlackListManager() {
     EXPECT_CALL(*this, AddEntryAddedCallback(_))
         .WillOnce(SaveArg<0>(&changed_callback_));
+    EXPECT_CALL(*this, IsBlocked(_, _, _)).WillRepeatedly(Return(false));
   }
 
   base::Closure changed_callback_;
@@ -59,7 +61,7 @@
       60, 62, 10, 18, 82, 35, 88, 100, 30, 45, 7, 46, 67, 84, 58, 85};
 
   test::MockClock clock_;
-  MockBlackListManager black_list_;
+  StrictMock<MockBlackListManager> black_list_;
   AuthManager auth_{kSecret1, kFingerprint, kSecret2, &clock_, &black_list_};
 };
 
@@ -350,6 +352,21 @@
   EXPECT_TRUE(error->HasError("invalidAuthCode"));
 }
 
+TEST_F(AuthManagerTest, CreateAccessTokenFromAuthRevoked) {
+  TestUserId user{"234"};
+  EXPECT_CALL(black_list_, IsBlocked(user.user, _, clock_.Now()))
+      .WillOnce(Return(true));
+  std::vector<uint8_t> access_token;
+  auto root = auth_.GetRootClientAuthToken(RootClientTokenOwner::kCloud);
+  auto extended = DelegateToUser(root, base::TimeDelta::FromSeconds(1000),
+                                 UserInfo{AuthScope::kUser, user});
+  ErrorPtr error;
+  EXPECT_FALSE(
+      auth_.CreateAccessTokenFromAuth(extended, base::TimeDelta::FromDays(1),
+                                      nullptr, nullptr, nullptr, &error));
+  EXPECT_TRUE(error->HasError("invalidAuthCode"));
+}
+
 class AuthManagerClaimTest : public testing::Test {
  public:
   void SetUp() override { EXPECT_EQ(auth_.GetAuthSecret().size(), 32u); }