Home | History | Annotate | Download | only in privet
      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 #include "src/privet/auth_manager.h"
      6 
      7 #include <gmock/gmock.h>
      8 #include <gtest/gtest.h>
      9 #include <weave/settings.h>
     10 
     11 #include "src/config.h"
     12 #include "src/data_encoding.h"
     13 #include "src/privet/mock_delegates.h"
     14 #include "src/test/mock_clock.h"
     15 
     16 using testing::Return;
     17 
     18 namespace weave {
     19 namespace privet {
     20 
     21 class AuthManagerTest : public testing::Test {
     22  public:
     23   void SetUp() override {
     24     EXPECT_GE(auth_.GetAuthSecret().size(), 32u);
     25     EXPECT_GE(auth_.GetAccessSecret().size(), 32u);
     26     EXPECT_GE(auth_.GetCertificateFingerprint().size(), 32u);
     27 
     28     EXPECT_CALL(clock_, Now())
     29         .WillRepeatedly(Return(base::Time::FromTimeT(1410000000)));
     30   }
     31 
     32  protected:
     33   std::vector<uint8_t> DelegateToUser(const std::vector<uint8_t>& token,
     34                                       base::TimeDelta ttl,
     35                                       const UserInfo& user_info) const {
     36     return auth_.DelegateToUser(token, ttl, user_info);
     37   }
     38   const std::vector<uint8_t> kSecret1{
     39       78, 40, 39, 68, 29, 19, 70, 86, 38, 61, 13, 55, 33, 32, 51, 52,
     40       34, 43, 97, 48, 8,  56, 11, 99, 50, 59, 24, 26, 31, 71, 76, 28};
     41   const std::vector<uint8_t> kSecret2{
     42       69, 53, 17, 37, 80, 73, 2,  5, 79, 64, 41, 57, 12, 54, 65, 63,
     43       72, 74, 93, 81, 20, 95, 89, 3, 94, 92, 27, 21, 49, 90, 36, 6};
     44   const std::vector<uint8_t> kFingerprint{
     45       22, 47, 23, 77, 42, 98, 96, 25,  83, 16, 9, 14, 91, 44, 15, 75,
     46       60, 62, 10, 18, 82, 35, 88, 100, 30, 45, 7, 46, 67, 84, 58, 85};
     47 
     48   test::MockClock clock_;
     49   AuthManager auth_{kSecret1, kFingerprint, kSecret2, &clock_};
     50 };
     51 
     52 TEST_F(AuthManagerTest, RandomSecret) {
     53   AuthManager auth{{}, {}, {}, &clock_};
     54   EXPECT_EQ(auth.GetAuthSecret().size(), 32u);
     55   EXPECT_EQ(auth.GetAccessSecret().size(), 32u);
     56 }
     57 
     58 TEST_F(AuthManagerTest, DifferentSecret) {
     59   AuthManager auth{kSecret2, {}, kSecret1};
     60   EXPECT_EQ(auth.GetAuthSecret().size(), 32u);
     61   EXPECT_EQ(auth.GetAccessSecret().size(), 32u);
     62   EXPECT_NE(auth_.GetAccessSecret(), auth.GetAccessSecret());
     63   EXPECT_NE(auth_.GetAuthSecret(), auth.GetAuthSecret());
     64 }
     65 
     66 TEST_F(AuthManagerTest, Constructor) {
     67   EXPECT_EQ(kSecret1, auth_.GetAuthSecret());
     68   EXPECT_EQ(kSecret2, auth_.GetAccessSecret());
     69   EXPECT_EQ(kFingerprint, auth_.GetCertificateFingerprint());
     70 }
     71 
     72 TEST_F(AuthManagerTest, CreateAccessToken) {
     73   EXPECT_EQ("WC2FRggaG52hAEIBFEYJRDIzNABCCkBGBRobnaEAUFAF46oQlMmXgnLstt7wU2w=",
     74             Base64Encode(auth_.CreateAccessToken(
     75                 UserInfo{AuthScope::kViewer, TestUserId{"234"}}, {})));
     76   EXPECT_EQ("WC2FRggaG52hAEIBCEYJRDI1NwBCCkBGBRobnaEAUEdWRNHcu/0mA6c3e0tgDrk=",
     77             Base64Encode(auth_.CreateAccessToken(
     78                 UserInfo{AuthScope::kManager, TestUserId{"257"}}, {})));
     79   EXPECT_EQ("WC2FRggaG52hAEIBAkYJRDQ1NgBCCkBGBRobnaEAUH2ZLgUPdTtjNRa+PoDkMW4=",
     80             Base64Encode(auth_.CreateAccessToken(
     81                 UserInfo{AuthScope::kOwner, TestUserId{"456"}}, {})));
     82   auto new_time = clock_.Now() + base::TimeDelta::FromDays(11);
     83   EXPECT_CALL(clock_, Now()).WillRepeatedly(Return(new_time));
     84   EXPECT_EQ("WC2FRggaG6whgEIBDkYJRDM0NQBCCkBGBRobrCGAUDAFptj7bbYmbpaa6Wpb1Wo=",
     85             Base64Encode(auth_.CreateAccessToken(
     86                 UserInfo{AuthScope::kUser, TestUserId{"345"}}, {})));
     87 }
     88 
     89 TEST_F(AuthManagerTest, CreateSameToken) {
     90   EXPECT_EQ(auth_.CreateAccessToken(
     91                 UserInfo{AuthScope::kViewer, TestUserId{"555"}}, {}),
     92             auth_.CreateAccessToken(
     93                 UserInfo{AuthScope::kViewer, TestUserId{"555"}}, {}));
     94 }
     95 
     96 TEST_F(AuthManagerTest, CreateSameTokenWithApp) {
     97   EXPECT_EQ(auth_.CreateAccessToken(
     98                 UserInfo{AuthScope::kViewer,
     99                          {AuthType::kLocal, {1, 2, 3}, {4, 5, 6}}},
    100                 {}),
    101             auth_.CreateAccessToken(
    102                 UserInfo{AuthScope::kViewer,
    103                          {AuthType::kLocal, {1, 2, 3}, {4, 5, 6}}},
    104                 {}));
    105 }
    106 
    107 TEST_F(AuthManagerTest, CreateSameTokenWithDifferentType) {
    108   EXPECT_NE(auth_.CreateAccessToken(
    109                 UserInfo{AuthScope::kViewer,
    110                          {AuthType::kLocal, {1, 2, 3}, {4, 5, 6}}},
    111                 {}),
    112             auth_.CreateAccessToken(
    113                 UserInfo{AuthScope::kViewer,
    114                          {AuthType::kPairing, {1, 2, 3}, {4, 5, 6}}},
    115                 {}));
    116 }
    117 
    118 TEST_F(AuthManagerTest, CreateSameTokenWithDifferentApp) {
    119   EXPECT_NE(auth_.CreateAccessToken(
    120                 UserInfo{AuthScope::kViewer,
    121                          {AuthType::kLocal, {1, 2, 3}, {4, 5, 6}}},
    122                 {}),
    123             auth_.CreateAccessToken(
    124                 UserInfo{AuthScope::kViewer,
    125                          {AuthType::kLocal, {1, 2, 3}, {4, 5, 7}}},
    126                 {}));
    127 }
    128 
    129 TEST_F(AuthManagerTest, CreateTokenDifferentScope) {
    130   EXPECT_NE(auth_.CreateAccessToken(
    131                 UserInfo{AuthScope::kViewer, TestUserId{"456"}}, {}),
    132             auth_.CreateAccessToken(
    133                 UserInfo{AuthScope::kOwner, TestUserId{"456"}}, {}));
    134 }
    135 
    136 TEST_F(AuthManagerTest, CreateTokenDifferentUser) {
    137   EXPECT_NE(auth_.CreateAccessToken(
    138                 UserInfo{AuthScope::kOwner, TestUserId{"456"}}, {}),
    139             auth_.CreateAccessToken(
    140                 UserInfo{AuthScope::kOwner, TestUserId{"789"}}, {}));
    141 }
    142 
    143 TEST_F(AuthManagerTest, CreateTokenDifferentTime) {
    144   auto token = auth_.CreateAccessToken(
    145       UserInfo{AuthScope::kOwner, TestUserId{"567"}}, {});
    146   EXPECT_CALL(clock_, Now())
    147       .WillRepeatedly(Return(base::Time::FromTimeT(1400000000)));
    148   EXPECT_NE(token, auth_.CreateAccessToken(
    149                        UserInfo{AuthScope::kOwner, TestUserId{"567"}}, {}));
    150 }
    151 
    152 TEST_F(AuthManagerTest, CreateTokenDifferentInstance) {
    153   EXPECT_NE(auth_.CreateAccessToken(
    154                 UserInfo{AuthScope::kUser, TestUserId{"123"}}, {}),
    155             AuthManager({}, {}).CreateAccessToken(
    156                 UserInfo{AuthScope::kUser, TestUserId{"123"}}, {}));
    157 }
    158 
    159 TEST_F(AuthManagerTest, ParseAccessToken) {
    160   // Multiple attempts with random secrets.
    161   const auto kStartTime = base::Time::FromTimeT(1412121212);
    162   for (size_t i = 0; i < 1000; ++i) {
    163     EXPECT_CALL(clock_, Now()).WillRepeatedly(Return(kStartTime));
    164 
    165     AuthManager auth{{}, {}, {}, &clock_};
    166 
    167     auto token =
    168         auth.CreateAccessToken(UserInfo{AuthScope::kUser, TestUserId{"5"}},
    169                                base::TimeDelta::FromSeconds(i));
    170     UserInfo user_info;
    171     EXPECT_FALSE(auth_.ParseAccessToken(token, &user_info, nullptr));
    172     EXPECT_TRUE(auth.ParseAccessToken(token, &user_info, nullptr));
    173     EXPECT_EQ(AuthScope::kUser, user_info.scope());
    174     EXPECT_EQ(TestUserId{"5"}, user_info.id());
    175 
    176     EXPECT_CALL(clock_, Now())
    177         .WillRepeatedly(Return(kStartTime + base::TimeDelta::FromSeconds(i)));
    178     EXPECT_TRUE(auth.ParseAccessToken(token, &user_info, nullptr));
    179 
    180     auto extended =
    181         DelegateToUser(token, base::TimeDelta::FromSeconds(1000),
    182                        UserInfo{AuthScope::kUser, TestUserId{"234"}});
    183     EXPECT_FALSE(auth.ParseAccessToken(extended, &user_info, nullptr));
    184 
    185     EXPECT_CALL(clock_, Now())
    186         .WillRepeatedly(
    187             Return(kStartTime + base::TimeDelta::FromSeconds(i + 1)));
    188     EXPECT_FALSE(auth.ParseAccessToken(token, &user_info, nullptr));
    189   }
    190 }
    191 
    192 TEST_F(AuthManagerTest, GetRootClientAuthToken) {
    193   EXPECT_EQ("WCCDQxkgAUYIGhudoQBCDEBQZgRhYq78I8GtFUZHNBbfGw==",
    194             Base64Encode(
    195                 auth_.GetRootClientAuthToken(RootClientTokenOwner::kClient)));
    196 }
    197 
    198 TEST_F(AuthManagerTest, GetRootClientAuthTokenDifferentOwner) {
    199   EXPECT_EQ(
    200       "WCqDQxkgAUYIGhudoQBMDEpnb29nbGUuY29tUOoLAxSUAZAAv54drarqhag=",
    201       Base64Encode(auth_.GetRootClientAuthToken(RootClientTokenOwner::kCloud)));
    202 }
    203 
    204 TEST_F(AuthManagerTest, GetRootClientAuthTokenDifferentTime) {
    205   auto new_time = clock_.Now() + base::TimeDelta::FromDays(15);
    206   EXPECT_CALL(clock_, Now()).WillRepeatedly(Return(new_time));
    207   EXPECT_EQ("WCCDQxkgAUYIGhuxZ4BCDEBQjO+OTbjjTzZ/Dvk66nfQqg==",
    208             Base64Encode(
    209                 auth_.GetRootClientAuthToken(RootClientTokenOwner::kClient)));
    210 }
    211 
    212 TEST_F(AuthManagerTest, GetRootClientAuthTokenDifferentSecret) {
    213   AuthManager auth{kSecret2, {}, kSecret1, &clock_};
    214   EXPECT_EQ(
    215       "WCCDQxkgAUYIGhudoQBCDEBQ2MZF8YXv5pbtmMxwz9VtLA==",
    216       Base64Encode(auth.GetRootClientAuthToken(RootClientTokenOwner::kClient)));
    217 }
    218 
    219 TEST_F(AuthManagerTest, IsValidAuthToken) {
    220   EXPECT_TRUE(auth_.IsValidAuthToken(
    221       auth_.GetRootClientAuthToken(RootClientTokenOwner::kClient), nullptr));
    222   // Multiple attempts with random secrets.
    223   for (size_t i = 0; i < 1000; ++i) {
    224     AuthManager auth{{}, {}, {}, &clock_};
    225 
    226     auto token = auth.GetRootClientAuthToken(RootClientTokenOwner::kClient);
    227     EXPECT_FALSE(auth_.IsValidAuthToken(token, nullptr));
    228     EXPECT_TRUE(auth.IsValidAuthToken(token, nullptr));
    229   }
    230 }
    231 
    232 TEST_F(AuthManagerTest, CreateSessionId) {
    233   EXPECT_EQ("463315200:1", auth_.CreateSessionId());
    234 }
    235 
    236 TEST_F(AuthManagerTest, IsValidSessionId) {
    237   EXPECT_TRUE(auth_.IsValidSessionId("463315200:1"));
    238   EXPECT_TRUE(auth_.IsValidSessionId("463315200:2"));
    239   EXPECT_TRUE(auth_.IsValidSessionId("463315150"));
    240 
    241   // Future
    242   EXPECT_FALSE(auth_.IsValidSessionId("463315230:1"));
    243 
    244   // Expired
    245   EXPECT_FALSE(auth_.IsValidSessionId("463315100:1"));
    246 }
    247 
    248 TEST_F(AuthManagerTest, CreateAccessTokenFromAuth) {
    249   std::vector<uint8_t> access_token;
    250   AuthScope scope;
    251   base::TimeDelta ttl;
    252   auto root = auth_.GetRootClientAuthToken(RootClientTokenOwner::kCloud);
    253   auto extended = DelegateToUser(root, base::TimeDelta::FromSeconds(1000),
    254                                  UserInfo{AuthScope::kUser, TestUserId{"234"}});
    255   EXPECT_EQ(
    256       "WE+IQxkgAUYIGhudoQBMDEpnb29nbGUuY29tRggaG52hAEYFGhudpOhCAQ5FCUMyMzRNEUs0"
    257       "NjMzMTUyMDA6MVCRVKU+0SpOoBppnwqdKMwP",
    258       Base64Encode(extended));
    259   EXPECT_TRUE(
    260       auth_.CreateAccessTokenFromAuth(extended, base::TimeDelta::FromDays(1),
    261                                       &access_token, &scope, &ttl, nullptr));
    262   UserInfo user_info;
    263   EXPECT_TRUE(auth_.ParseAccessToken(access_token, &user_info, nullptr));
    264   EXPECT_EQ(scope, user_info.scope());
    265   EXPECT_EQ(AuthScope::kUser, user_info.scope());
    266 
    267   EXPECT_EQ(TestUserId{"234"}, user_info.id());
    268 }
    269 
    270 TEST_F(AuthManagerTest, CreateAccessTokenFromAuthNotMinted) {
    271   std::vector<uint8_t> access_token;
    272   auto root = auth_.GetRootClientAuthToken(RootClientTokenOwner::kClient);
    273   ErrorPtr error;
    274   EXPECT_FALSE(auth_.CreateAccessTokenFromAuth(
    275       root, base::TimeDelta::FromDays(1), nullptr, nullptr, nullptr, &error));
    276   EXPECT_TRUE(error->HasError("invalidAuthCode"));
    277 }
    278 
    279 TEST_F(AuthManagerTest, CreateAccessTokenFromAuthValidateAfterSomeTime) {
    280   auto root = auth_.GetRootClientAuthToken(RootClientTokenOwner::kClient);
    281   auto extended = DelegateToUser(root, base::TimeDelta::FromSeconds(1000),
    282                                  UserInfo{AuthScope::kUser, TestUserId{"234"}});
    283 
    284   // new_time < session_id_expiration < token_expiration.
    285   auto new_time = clock_.Now() + base::TimeDelta::FromSeconds(15);
    286   EXPECT_CALL(clock_, Now()).WillRepeatedly(Return(new_time));
    287   EXPECT_TRUE(
    288       auth_.CreateAccessTokenFromAuth(extended, base::TimeDelta::FromDays(1),
    289                                       nullptr, nullptr, nullptr, nullptr));
    290 }
    291 
    292 TEST_F(AuthManagerTest, CreateAccessTokenFromAuthExpired) {
    293   auto root = auth_.GetRootClientAuthToken(RootClientTokenOwner::kClient);
    294   auto extended = DelegateToUser(root, base::TimeDelta::FromSeconds(10),
    295                                  UserInfo{AuthScope::kUser, TestUserId{"234"}});
    296   ErrorPtr error;
    297 
    298   // token_expiration < new_time < session_id_expiration.
    299   auto new_time = clock_.Now() + base::TimeDelta::FromSeconds(15);
    300   EXPECT_CALL(clock_, Now()).WillRepeatedly(Return(new_time));
    301   EXPECT_FALSE(
    302       auth_.CreateAccessTokenFromAuth(extended, base::TimeDelta::FromDays(1),
    303                                       nullptr, nullptr, nullptr, &error));
    304   EXPECT_TRUE(error->HasError("invalidAuthCode"));
    305 }
    306 
    307 TEST_F(AuthManagerTest, CreateAccessTokenFromAuthExpiredSessionid) {
    308   auto root = auth_.GetRootClientAuthToken(RootClientTokenOwner::kClient);
    309   auto extended = DelegateToUser(root, base::TimeDelta::FromSeconds(1000),
    310                                  UserInfo{AuthScope::kUser, TestUserId{"234"}});
    311   ErrorPtr error;
    312 
    313   // session_id_expiration < new_time < token_expiration.
    314   auto new_time = clock_.Now() + base::TimeDelta::FromSeconds(200);
    315   EXPECT_CALL(clock_, Now()).WillRepeatedly(Return(new_time));
    316   EXPECT_FALSE(
    317       auth_.CreateAccessTokenFromAuth(extended, base::TimeDelta::FromDays(1),
    318                                       nullptr, nullptr, nullptr, &error));
    319   EXPECT_TRUE(error->HasError("invalidAuthCode"));
    320 }
    321 
    322 class AuthManagerClaimTest : public testing::Test {
    323  public:
    324   void SetUp() override { EXPECT_EQ(auth_.GetAuthSecret().size(), 32u); }
    325 
    326   bool TestClaim(RootClientTokenOwner owner, RootClientTokenOwner claimer) {
    327     Config::Transaction change{&config_};
    328     change.set_root_client_token_owner(owner);
    329     change.Commit();
    330     return !auth_.ClaimRootClientAuthToken(claimer, nullptr).empty();
    331   }
    332 
    333  protected:
    334   Config config_{nullptr};
    335   AuthManager auth_{&config_, {}};
    336 };
    337 
    338 TEST_F(AuthManagerClaimTest, WithPreviosOwner) {
    339   EXPECT_DEATH(
    340       TestClaim(RootClientTokenOwner::kNone, RootClientTokenOwner::kNone), "");
    341   EXPECT_DEATH(
    342       TestClaim(RootClientTokenOwner::kClient, RootClientTokenOwner::kNone),
    343       "");
    344   EXPECT_DEATH(
    345       TestClaim(RootClientTokenOwner::kCloud, RootClientTokenOwner::kNone), "");
    346   EXPECT_TRUE(
    347       TestClaim(RootClientTokenOwner::kNone, RootClientTokenOwner::kClient));
    348   EXPECT_FALSE(
    349       TestClaim(RootClientTokenOwner::kClient, RootClientTokenOwner::kClient));
    350   EXPECT_FALSE(
    351       TestClaim(RootClientTokenOwner::kCloud, RootClientTokenOwner::kClient));
    352   EXPECT_TRUE(
    353       TestClaim(RootClientTokenOwner::kNone, RootClientTokenOwner::kCloud));
    354   EXPECT_TRUE(
    355       TestClaim(RootClientTokenOwner::kClient, RootClientTokenOwner::kCloud));
    356   EXPECT_TRUE(
    357       TestClaim(RootClientTokenOwner::kCloud, RootClientTokenOwner::kCloud));
    358 }
    359 
    360 TEST_F(AuthManagerClaimTest, NormalClaim) {
    361   auto token =
    362       auth_.ClaimRootClientAuthToken(RootClientTokenOwner::kCloud, nullptr);
    363   EXPECT_FALSE(auth_.IsValidAuthToken(token, nullptr));
    364   EXPECT_EQ(RootClientTokenOwner::kNone,
    365             config_.GetSettings().root_client_token_owner);
    366 
    367   EXPECT_TRUE(auth_.ConfirmClientAuthToken(token, nullptr));
    368   EXPECT_TRUE(auth_.IsValidAuthToken(token, nullptr));
    369   EXPECT_EQ(RootClientTokenOwner::kCloud,
    370             config_.GetSettings().root_client_token_owner);
    371 }
    372 
    373 TEST_F(AuthManagerClaimTest, DoubleConfirm) {
    374   auto token =
    375       auth_.ClaimRootClientAuthToken(RootClientTokenOwner::kCloud, nullptr);
    376   EXPECT_TRUE(auth_.ConfirmClientAuthToken(token, nullptr));
    377   EXPECT_TRUE(auth_.ConfirmClientAuthToken(token, nullptr));
    378 }
    379 
    380 TEST_F(AuthManagerClaimTest, DoubleClaim) {
    381   auto token1 =
    382       auth_.ClaimRootClientAuthToken(RootClientTokenOwner::kCloud, nullptr);
    383   auto token2 =
    384       auth_.ClaimRootClientAuthToken(RootClientTokenOwner::kCloud, nullptr);
    385   EXPECT_TRUE(auth_.ConfirmClientAuthToken(token1, nullptr));
    386   EXPECT_FALSE(auth_.ConfirmClientAuthToken(token2, nullptr));
    387 }
    388 
    389 TEST_F(AuthManagerClaimTest, TokenOverflow) {
    390   auto token =
    391       auth_.ClaimRootClientAuthToken(RootClientTokenOwner::kCloud, nullptr);
    392   for (size_t i = 0; i < 100; ++i)
    393     auth_.ClaimRootClientAuthToken(RootClientTokenOwner::kCloud, nullptr);
    394   EXPECT_FALSE(auth_.ConfirmClientAuthToken(token, nullptr));
    395 }
    396 
    397 }  // namespace privet
    398 }  // namespace weave
    399