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 16using testing::Return; 17 18namespace weave { 19namespace privet { 20 21class 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 52TEST_F(AuthManagerTest, RandomSecret) { 53 AuthManager auth{{}, {}, {}, &clock_}; 54 EXPECT_EQ(auth.GetAuthSecret().size(), 32u); 55 EXPECT_EQ(auth.GetAccessSecret().size(), 32u); 56} 57 58TEST_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 66TEST_F(AuthManagerTest, Constructor) { 67 EXPECT_EQ(kSecret1, auth_.GetAuthSecret()); 68 EXPECT_EQ(kSecret2, auth_.GetAccessSecret()); 69 EXPECT_EQ(kFingerprint, auth_.GetCertificateFingerprint()); 70} 71 72TEST_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 89TEST_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 96TEST_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 107TEST_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 118TEST_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 129TEST_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 136TEST_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 143TEST_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 152TEST_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 159TEST_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 192TEST_F(AuthManagerTest, GetRootClientAuthToken) { 193 EXPECT_EQ("WCCDQxkgAUYIGhudoQBCDEBQZgRhYq78I8GtFUZHNBbfGw==", 194 Base64Encode( 195 auth_.GetRootClientAuthToken(RootClientTokenOwner::kClient))); 196} 197 198TEST_F(AuthManagerTest, GetRootClientAuthTokenDifferentOwner) { 199 EXPECT_EQ( 200 "WCqDQxkgAUYIGhudoQBMDEpnb29nbGUuY29tUOoLAxSUAZAAv54drarqhag=", 201 Base64Encode(auth_.GetRootClientAuthToken(RootClientTokenOwner::kCloud))); 202} 203 204TEST_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 212TEST_F(AuthManagerTest, GetRootClientAuthTokenDifferentSecret) { 213 AuthManager auth{kSecret2, {}, kSecret1, &clock_}; 214 EXPECT_EQ( 215 "WCCDQxkgAUYIGhudoQBCDEBQ2MZF8YXv5pbtmMxwz9VtLA==", 216 Base64Encode(auth.GetRootClientAuthToken(RootClientTokenOwner::kClient))); 217} 218 219TEST_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 232TEST_F(AuthManagerTest, CreateSessionId) { 233 EXPECT_EQ("463315200:1", auth_.CreateSessionId()); 234} 235 236TEST_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 248TEST_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 270TEST_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 279TEST_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 292TEST_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 307TEST_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 322class 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 338TEST_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 360TEST_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 373TEST_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 380TEST_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 389TEST_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