| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/local_discovery/privetv3_session.h" | 5 #include "chrome/browser/local_discovery/privetv3_session.h" |
| 6 | 6 |
| 7 #include "base/base64.h" | 7 #include "base/base64.h" |
| 8 #include "base/strings/stringprintf.h" | 8 #include "base/strings/stringprintf.h" |
| 9 #include "base/thread_task_runner_handle.h" | 9 #include "base/thread_task_runner_handle.h" |
| 10 #include "chrome/browser/local_discovery/privet_http.h" | 10 #include "chrome/browser/local_discovery/privet_http.h" |
| 11 #include "content/public/test/test_utils.h" | 11 #include "content/public/test/test_utils.h" |
| 12 #include "crypto/hmac.h" | 12 #include "crypto/hmac.h" |
| 13 #include "crypto/p224_spake.h" | 13 #include "crypto/p224_spake.h" |
| 14 #include "net/url_request/test_url_fetcher_factory.h" | 14 #include "net/url_request/test_url_fetcher_factory.h" |
| 15 #include "net/url_request/url_request_test_util.h" | 15 #include "net/url_request/url_request_test_util.h" |
| 16 #include "testing/gmock/include/gmock/gmock.h" | 16 #include "testing/gmock/include/gmock/gmock.h" |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 17 #include "testing/gtest/include/gtest/gtest.h" |
| 18 | 18 |
| 19 namespace local_discovery { | 19 namespace local_discovery { |
| 20 | 20 |
| 21 namespace { | 21 namespace { |
| 22 | 22 |
| 23 using testing::_; |
| 24 using testing::ElementsAreArray; |
| 25 using testing::Field; |
| 23 using testing::InSequence; | 26 using testing::InSequence; |
| 24 using testing::Invoke; | 27 using testing::Invoke; |
| 28 using testing::InvokeWithoutArgs; |
| 29 using testing::Return; |
| 25 using testing::SaveArg; | 30 using testing::SaveArg; |
| 26 using testing::StrictMock; | 31 using testing::StrictMock; |
| 27 using testing::_; | |
| 28 | 32 |
| 29 using PairingType = PrivetV3Session::PairingType; | 33 using PairingType = PrivetV3Session::PairingType; |
| 30 using Result = PrivetV3Session::Result; | 34 using Result = PrivetV3Session::Result; |
| 31 | 35 |
| 32 const char kInfoResponse[] = | 36 const char kInfoResponse[] = |
| 33 "{\"version\":\"3.0\"," | 37 "{\"version\":\"3.0\"," |
| 34 "\"endpoints\":{\"httpsPort\": 443}," | 38 "\"endpoints\":{\"httpsPort\": 443}," |
| 35 "\"authentication\":{" | 39 "\"authentication\":{" |
| 36 " \"mode\":[\"anonymous\",\"pairing\",\"cloud\"]," | 40 " \"mode\":[\"anonymous\",\"pairing\",\"cloud\"]," |
| 37 " \"pairing\":[\"pinCode\",\"embeddedCode\"]," | 41 " \"pairing\":[\"pinCode\",\"embeddedCode\"]," |
| 38 " \"crypto\":[\"p224_spake2\"]" | 42 " \"crypto\":[\"p224_spake2\"]" |
| 39 "}}"; | 43 "}}"; |
| 40 | 44 |
| 41 class MockPrivetHTTPClient : public PrivetHTTPClient { | 45 class MockPrivetHTTPClient : public PrivetHTTPClient { |
| 42 public: | 46 public: |
| 43 MockPrivetHTTPClient() { | 47 MockPrivetHTTPClient() { |
| 44 request_context_ = new net::TestURLRequestContextGetter( | 48 request_context_ = new net::TestURLRequestContextGetter( |
| 45 base::ThreadTaskRunnerHandle::Get()); | 49 base::ThreadTaskRunnerHandle::Get()); |
| 46 } | 50 } |
| 47 | 51 |
| 48 MOCK_METHOD0(GetName, const std::string&()); | 52 MOCK_METHOD0(GetName, const std::string&()); |
| 49 MOCK_METHOD1( | 53 MOCK_METHOD1( |
| 50 CreateInfoOperationPtr, | 54 CreateInfoOperationPtr, |
| 51 PrivetJSONOperation*(const PrivetJSONOperation::ResultCallback&)); | 55 PrivetJSONOperation*(const PrivetJSONOperation::ResultCallback&)); |
| 56 MOCK_METHOD2(SwitchToHttps, void(uint16_t, const net::SHA256HashValue&)); |
| 57 MOCK_CONST_METHOD0(IsInHttpsMode, bool()); |
| 52 | 58 |
| 53 void RefreshPrivetToken( | 59 void RefreshPrivetToken( |
| 54 const PrivetURLFetcher::TokenCallback& callback) override { | 60 const PrivetURLFetcher::TokenCallback& callback) override { |
| 55 FAIL(); | 61 FAIL(); |
| 56 } | 62 } |
| 57 | 63 |
| 58 scoped_ptr<PrivetJSONOperation> CreateInfoOperation( | 64 scoped_ptr<PrivetJSONOperation> CreateInfoOperation( |
| 59 const PrivetJSONOperation::ResultCallback& callback) override { | 65 const PrivetJSONOperation::ResultCallback& callback) override { |
| 60 return make_scoped_ptr(CreateInfoOperationPtr(callback)); | 66 return make_scoped_ptr(CreateInfoOperationPtr(callback)); |
| 61 } | 67 } |
| 62 | 68 |
| 63 scoped_ptr<PrivetURLFetcher> CreateURLFetcher( | 69 scoped_ptr<PrivetURLFetcher> CreateURLFetcher( |
| 64 const GURL& url, | 70 const GURL& url, |
| 65 net::URLFetcher::RequestType request_type, | 71 net::URLFetcher::RequestType request_type, |
| 66 PrivetURLFetcher::Delegate* delegate) override { | 72 PrivetURLFetcher::Delegate* delegate) override { |
| 67 return make_scoped_ptr(new PrivetURLFetcher( | 73 return make_scoped_ptr(new PrivetURLFetcher( |
| 68 url, request_type, request_context_.get(), delegate)); | 74 url, request_type, request_context_.get(), delegate)); |
| 69 } | 75 } |
| 70 | 76 |
| 71 scoped_refptr<net::TestURLRequestContextGetter> request_context_; | 77 scoped_refptr<net::TestURLRequestContextGetter> request_context_; |
| 72 }; | 78 }; |
| 73 | 79 |
| 74 } // namespace | 80 } // namespace |
| 75 | 81 |
| 76 class PrivetV3SessionTest : public testing::Test { | 82 class PrivetV3SessionTest : public testing::Test { |
| 77 public: | 83 public: |
| 78 PrivetV3SessionTest() | 84 PrivetV3SessionTest() |
| 79 : fetcher_factory_(nullptr), | 85 : fetcher_factory_(nullptr), |
| 80 session_(make_scoped_ptr(new MockPrivetHTTPClient())) {} | 86 http_client_(new StrictMock<MockPrivetHTTPClient>()), |
| 81 | 87 session_(make_scoped_ptr(http_client_)) {} |
| 82 ~PrivetV3SessionTest() override {} | |
| 83 | 88 |
| 84 void OnInitialized(Result result, const base::DictionaryValue& info) { | 89 void OnInitialized(Result result, const base::DictionaryValue& info) { |
| 85 info_.MergeDictionary(&info); | 90 info_.MergeDictionary(&info); |
| 86 OnInitializedMock(result, info); | 91 OnInitializedMock(result, info); |
| 87 } | 92 } |
| 88 | 93 |
| 89 MOCK_METHOD2(OnInitializedMock, void(Result, const base::DictionaryValue&)); | 94 MOCK_METHOD2(OnInitializedMock, void(Result, const base::DictionaryValue&)); |
| 90 MOCK_METHOD1(OnPairingStarted, void(Result)); | 95 MOCK_METHOD1(OnPairingStarted, void(Result)); |
| 91 MOCK_METHOD1(OnCodeConfirmed, void(Result)); | 96 MOCK_METHOD1(OnCodeConfirmed, void(Result)); |
| 92 MOCK_METHOD2(OnMessageSend, void(Result, const base::DictionaryValue&)); | 97 MOCK_METHOD2(OnMessageSend, void(Result, const base::DictionaryValue&)); |
| 93 MOCK_METHOD1(OnPostData, void(const base::DictionaryValue&)); | 98 MOCK_METHOD1(OnPostData, void(const base::DictionaryValue&)); |
| 94 | 99 |
| 95 protected: | 100 protected: |
| 96 void SetUp() override { | 101 void SetUp() override { |
| 97 EXPECT_CALL(*this, OnInitializedMock(_, _)).Times(0); | |
| 98 EXPECT_CALL(*this, OnPairingStarted(_)).Times(0); | |
| 99 EXPECT_CALL(*this, OnCodeConfirmed(_)).Times(0); | |
| 100 EXPECT_CALL(*this, OnMessageSend(_, _)).Times(0); | |
| 101 EXPECT_CALL(*this, OnPostData(_)).Times(0); | |
| 102 session_.on_post_data_ = | 102 session_.on_post_data_ = |
| 103 base::Bind(&PrivetV3SessionTest::OnPostData, base::Unretained(this)); | 103 base::Bind(&PrivetV3SessionTest::OnPostData, base::Unretained(this)); |
| 104 |
| 105 EXPECT_CALL(*http_client_, IsInHttpsMode()).WillRepeatedly(Return(false)); |
| 104 } | 106 } |
| 105 | 107 |
| 108 base::MessageLoop loop_; |
| 109 net::FakeURLFetcherFactory fetcher_factory_; |
| 110 StrictMock<MockPrivetHTTPClient>* http_client_; |
| 106 base::DictionaryValue info_; | 111 base::DictionaryValue info_; |
| 107 base::MessageLoop loop_; | |
| 108 base::Closure quit_closure_; | 112 base::Closure quit_closure_; |
| 109 net::FakeURLFetcherFactory fetcher_factory_; | |
| 110 PrivetV3Session session_; | 113 PrivetV3Session session_; |
| 111 }; | 114 }; |
| 112 | 115 |
| 113 TEST_F(PrivetV3SessionTest, InitError) { | 116 TEST_F(PrivetV3SessionTest, InitError) { |
| 114 EXPECT_CALL(*this, OnInitializedMock(Result::STATUS_CONNECTIONERROR, _)) | 117 EXPECT_CALL(*this, OnInitializedMock(Result::STATUS_CONNECTIONERROR, _)) |
| 115 .Times(1); | 118 .Times(1); |
| 116 fetcher_factory_.SetFakeResponse(GURL("http://host/privet/info"), "", | 119 fetcher_factory_.SetFakeResponse(GURL("http://host/privet/info"), "", |
| 117 net::HTTP_OK, net::URLRequestStatus::FAILED); | 120 net::HTTP_OK, net::URLRequestStatus::FAILED); |
| 118 session_.Init( | 121 session_.Init( |
| 119 base::Bind(&PrivetV3SessionTest::OnInitialized, base::Unretained(this))); | 122 base::Bind(&PrivetV3SessionTest::OnInitialized, base::Unretained(this))); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 141 EXPECT_CALL(*this, OnInitializedMock(Result::STATUS_SESSIONERROR, _)) | 144 EXPECT_CALL(*this, OnInitializedMock(Result::STATUS_SESSIONERROR, _)) |
| 142 .Times(1); | 145 .Times(1); |
| 143 fetcher_factory_.SetFakeResponse(GURL("http://host/privet/info"), response, | 146 fetcher_factory_.SetFakeResponse(GURL("http://host/privet/info"), response, |
| 144 net::HTTP_OK, | 147 net::HTTP_OK, |
| 145 net::URLRequestStatus::SUCCESS); | 148 net::URLRequestStatus::SUCCESS); |
| 146 session_.Init( | 149 session_.Init( |
| 147 base::Bind(&PrivetV3SessionTest::OnInitialized, base::Unretained(this))); | 150 base::Bind(&PrivetV3SessionTest::OnInitialized, base::Unretained(this))); |
| 148 base::RunLoop().RunUntilIdle(); | 151 base::RunLoop().RunUntilIdle(); |
| 149 } | 152 } |
| 150 | 153 |
| 154 TEST_F(PrivetV3SessionTest, NoHttpsError) { |
| 155 EXPECT_CALL(*this, OnInitializedMock(Result::STATUS_SUCCESS, _)).Times(1); |
| 156 fetcher_factory_.SetFakeResponse(GURL("http://host/privet/info"), |
| 157 kInfoResponse, net::HTTP_OK, |
| 158 net::URLRequestStatus::SUCCESS); |
| 159 |
| 160 session_.Init( |
| 161 base::Bind(&PrivetV3SessionTest::OnInitialized, base::Unretained(this))); |
| 162 base::RunLoop().RunUntilIdle(); |
| 163 |
| 164 EXPECT_CALL(*this, OnMessageSend(Result::STATUS_SESSIONERROR, _)).Times(1); |
| 165 session_.SendMessage( |
| 166 "/privet/v3/state", base::DictionaryValue(), |
| 167 base::Bind(&PrivetV3SessionTest::OnMessageSend, base::Unretained(this))); |
| 168 base::RunLoop().RunUntilIdle(); |
| 169 } |
| 170 |
| 151 TEST_F(PrivetV3SessionTest, Pairing) { | 171 TEST_F(PrivetV3SessionTest, Pairing) { |
| 152 EXPECT_CALL(*this, OnInitializedMock(Result::STATUS_SUCCESS, _)) | 172 EXPECT_CALL(*this, OnInitializedMock(Result::STATUS_SUCCESS, _)) |
| 153 .Times(1); | 173 .Times(1); |
| 154 fetcher_factory_.SetFakeResponse(GURL("http://host/privet/info"), | 174 fetcher_factory_.SetFakeResponse(GURL("http://host/privet/info"), |
| 155 kInfoResponse, net::HTTP_OK, | 175 kInfoResponse, net::HTTP_OK, |
| 156 net::URLRequestStatus::SUCCESS); | 176 net::URLRequestStatus::SUCCESS); |
| 157 | 177 |
| 158 session_.Init( | 178 session_.Init( |
| 159 base::Bind(&PrivetV3SessionTest::OnInitialized, base::Unretained(this))); | 179 base::Bind(&PrivetV3SessionTest::OnInitialized, base::Unretained(this))); |
| 160 base::RunLoop().RunUntilIdle(); | 180 base::RunLoop().RunUntilIdle(); |
| 161 | 181 |
| 162 const base::ListValue* pairing = nullptr; | 182 const base::ListValue* pairing = nullptr; |
| 163 ASSERT_TRUE(info_.GetList("authentication.pairing", &pairing)); | 183 ASSERT_TRUE(info_.GetList("authentication.pairing", &pairing)); |
| 164 | 184 |
| 165 std::string pairing_string; | 185 std::string pairing_string; |
| 166 ASSERT_TRUE(pairing->GetString(0, &pairing_string)); | 186 ASSERT_TRUE(pairing->GetString(0, &pairing_string)); |
| 167 EXPECT_EQ("pinCode", pairing_string); | 187 EXPECT_EQ("pinCode", pairing_string); |
| 168 | 188 |
| 169 ASSERT_TRUE(pairing->GetString(1, &pairing_string)); | 189 ASSERT_TRUE(pairing->GetString(1, &pairing_string)); |
| 170 EXPECT_EQ("embeddedCode", pairing_string); | 190 EXPECT_EQ("embeddedCode", pairing_string); |
| 171 | 191 |
| 172 crypto::P224EncryptedKeyExchange spake( | 192 crypto::P224EncryptedKeyExchange spake( |
| 173 crypto::P224EncryptedKeyExchange::kPeerTypeServer, "testPin"); | 193 crypto::P224EncryptedKeyExchange::kPeerTypeServer, "testPin"); |
| 174 | 194 |
| 175 EXPECT_CALL(*this, OnPairingStarted(Result::STATUS_SUCCESS)).Times(1); | 195 EXPECT_CALL(*this, OnPairingStarted(Result::STATUS_SUCCESS)).Times(1); |
| 176 EXPECT_CALL(*this, OnPostData(_)) | 196 EXPECT_CALL(*this, OnPostData(_)) |
| 177 .WillOnce( | 197 .WillOnce( |
| 178 testing::Invoke([this, &spake](const base::DictionaryValue& data) { | 198 Invoke([this, &spake](const base::DictionaryValue& data) { |
| 179 std::string pairing_type; | 199 std::string pairing_type; |
| 180 EXPECT_TRUE(data.GetString("pairing", &pairing_type)); | 200 EXPECT_TRUE(data.GetString("pairing", &pairing_type)); |
| 181 EXPECT_EQ("embeddedCode", pairing_type); | 201 EXPECT_EQ("embeddedCode", pairing_type); |
| 182 | 202 |
| 183 std::string crypto_type; | 203 std::string crypto_type; |
| 184 EXPECT_TRUE(data.GetString("crypto", &crypto_type)); | 204 EXPECT_TRUE(data.GetString("crypto", &crypto_type)); |
| 185 EXPECT_EQ("p224_spake2", crypto_type); | 205 EXPECT_EQ("p224_spake2", crypto_type); |
| 186 | 206 |
| 187 std::string device_commitment; | 207 std::string device_commitment; |
| 188 base::Base64Encode(spake.GetNextMessage(), &device_commitment); | 208 base::Base64Encode(spake.GetNextMessage(), &device_commitment); |
| 189 fetcher_factory_.SetFakeResponse( | 209 fetcher_factory_.SetFakeResponse( |
| 190 GURL("http://host/privet/v3/pairing/start"), | 210 GURL("http://host/privet/v3/pairing/start"), |
| 191 base::StringPrintf( | 211 base::StringPrintf( |
| 192 "{\"deviceCommitment\":\"%s\",\"sessionId\":\"testId\"}", | 212 "{\"deviceCommitment\":\"%s\",\"sessionId\":\"testId\"}", |
| 193 device_commitment.c_str()), | 213 device_commitment.c_str()), |
| 194 net::HTTP_OK, net::URLRequestStatus::SUCCESS); | 214 net::HTTP_OK, net::URLRequestStatus::SUCCESS); |
| 195 })); | 215 })); |
| 196 session_.StartPairing(PairingType::PAIRING_TYPE_EMBEDDEDCODE, | 216 session_.StartPairing(PairingType::PAIRING_TYPE_EMBEDDEDCODE, |
| 197 base::Bind(&PrivetV3SessionTest::OnPairingStarted, | 217 base::Bind(&PrivetV3SessionTest::OnPairingStarted, |
| 198 base::Unretained(this))); | 218 base::Unretained(this))); |
| 199 base::RunLoop().RunUntilIdle(); | 219 base::RunLoop().RunUntilIdle(); |
| 200 | 220 |
| 201 EXPECT_TRUE(session_.fingerprint_.empty()); | |
| 202 EXPECT_EQ("Privet anonymous", session_.privet_auth_token_); | 221 EXPECT_EQ("Privet anonymous", session_.privet_auth_token_); |
| 203 | 222 |
| 223 std::string fingerprint("testFingerprint testFingerprint"); |
| 224 net::SHA256HashValue sha_fingerprint; |
| 225 ASSERT_EQ(sizeof(sha_fingerprint.data), fingerprint.size()); |
| 226 memcpy(sha_fingerprint.data, fingerprint.data(), fingerprint.size()); |
| 227 |
| 228 EXPECT_CALL(*http_client_, |
| 229 SwitchToHttps(443, Field(&net::SHA256HashValue::data, |
| 230 ElementsAreArray(sha_fingerprint.data)))) |
| 231 .WillOnce(InvokeWithoutArgs([this]() { |
| 232 EXPECT_CALL(*http_client_, IsInHttpsMode()) |
| 233 .WillRepeatedly(Return(true)); |
| 234 })); |
| 235 |
| 204 EXPECT_CALL(*this, OnCodeConfirmed(Result::STATUS_SUCCESS)).Times(1); | 236 EXPECT_CALL(*this, OnCodeConfirmed(Result::STATUS_SUCCESS)).Times(1); |
| 205 InSequence in_sequence; | |
| 206 EXPECT_CALL(*this, OnPostData(_)) | 237 EXPECT_CALL(*this, OnPostData(_)) |
| 207 .WillOnce( | 238 .WillOnce(Invoke( |
| 208 testing::Invoke([this, &spake](const base::DictionaryValue& data) { | 239 [this, &spake, fingerprint](const base::DictionaryValue& data) { |
| 209 std::string commitment_base64; | 240 std::string commitment_base64; |
| 210 EXPECT_TRUE(data.GetString("clientCommitment", &commitment_base64)); | 241 EXPECT_TRUE(data.GetString("clientCommitment", &commitment_base64)); |
| 211 std::string commitment; | 242 std::string commitment; |
| 212 EXPECT_TRUE(base::Base64Decode(commitment_base64, &commitment)); | 243 EXPECT_TRUE(base::Base64Decode(commitment_base64, &commitment)); |
| 213 | 244 |
| 214 std::string session_id; | 245 std::string session_id; |
| 215 EXPECT_TRUE(data.GetString("sessionId", &session_id)); | 246 EXPECT_TRUE(data.GetString("sessionId", &session_id)); |
| 216 EXPECT_EQ("testId", session_id); | 247 EXPECT_EQ("testId", session_id); |
| 217 | 248 |
| 218 EXPECT_EQ(spake.ProcessMessage(commitment), | 249 EXPECT_EQ(spake.ProcessMessage(commitment), |
| 219 crypto::P224EncryptedKeyExchange::kResultPending); | 250 crypto::P224EncryptedKeyExchange::kResultPending); |
| 220 | 251 |
| 221 std::string fingerprint("testFinterprint"); | |
| 222 std::string fingerprint_base64; | 252 std::string fingerprint_base64; |
| 223 base::Base64Encode(fingerprint, &fingerprint_base64); | 253 base::Base64Encode(fingerprint, &fingerprint_base64); |
| 224 | 254 |
| 225 crypto::HMAC hmac(crypto::HMAC::SHA256); | 255 crypto::HMAC hmac(crypto::HMAC::SHA256); |
| 226 const std::string& key = spake.GetUnverifiedKey(); | 256 const std::string& key = spake.GetUnverifiedKey(); |
| 227 EXPECT_TRUE(hmac.Init(key)); | 257 EXPECT_TRUE(hmac.Init(key)); |
| 228 std::string signature(hmac.DigestLength(), ' '); | 258 std::string signature(hmac.DigestLength(), ' '); |
| 229 EXPECT_TRUE(hmac.Sign(fingerprint, reinterpret_cast<unsigned char*>( | 259 EXPECT_TRUE(hmac.Sign(fingerprint, reinterpret_cast<unsigned char*>( |
| 230 string_as_array(&signature)), | 260 string_as_array(&signature)), |
| 231 signature.size())); | 261 signature.size())); |
| 232 | 262 |
| 233 std::string signature_base64; | 263 std::string signature_base64; |
| 234 base::Base64Encode(signature, &signature_base64); | 264 base::Base64Encode(signature, &signature_base64); |
| 235 | 265 |
| 236 fetcher_factory_.SetFakeResponse( | 266 fetcher_factory_.SetFakeResponse( |
| 237 GURL("http://host/privet/v3/pairing/confirm"), | 267 GURL("http://host/privet/v3/pairing/confirm"), |
| 238 base::StringPrintf( | 268 base::StringPrintf( |
| 239 "{\"certFingerprint\":\"%s\",\"certSignature\":\"%s\"}", | 269 "{\"certFingerprint\":\"%s\",\"certSignature\":\"%s\"}", |
| 240 fingerprint_base64.c_str(), signature_base64.c_str()), | 270 fingerprint_base64.c_str(), signature_base64.c_str()), |
| 241 net::HTTP_OK, net::URLRequestStatus::SUCCESS); | 271 net::HTTP_OK, net::URLRequestStatus::SUCCESS); |
| 242 })); | 272 })) |
| 243 EXPECT_CALL(*this, OnPostData(_)) | |
| 244 .WillOnce( | 273 .WillOnce( |
| 245 testing::Invoke([this, &spake](const base::DictionaryValue& data) { | 274 Invoke([this, &spake](const base::DictionaryValue& data) { |
| 246 std::string access_token_base64; | 275 std::string access_token_base64; |
| 247 EXPECT_TRUE(data.GetString("authCode", &access_token_base64)); | 276 EXPECT_TRUE(data.GetString("authCode", &access_token_base64)); |
| 248 std::string access_token; | 277 std::string access_token; |
| 249 EXPECT_TRUE(base::Base64Decode(access_token_base64, &access_token)); | 278 EXPECT_TRUE(base::Base64Decode(access_token_base64, &access_token)); |
| 250 | 279 |
| 251 crypto::HMAC hmac(crypto::HMAC::SHA256); | 280 crypto::HMAC hmac(crypto::HMAC::SHA256); |
| 252 const std::string& key = spake.GetUnverifiedKey(); | 281 const std::string& key = spake.GetUnverifiedKey(); |
| 253 EXPECT_TRUE(hmac.Init(key)); | 282 EXPECT_TRUE(hmac.Init(key)); |
| 254 EXPECT_TRUE(hmac.Verify("testId", access_token)); | 283 EXPECT_TRUE(hmac.Verify("testId", access_token)); |
| 255 | 284 |
| 256 fetcher_factory_.SetFakeResponse( | 285 fetcher_factory_.SetFakeResponse( |
| 257 GURL("http://host/privet/v3/auth"), | 286 GURL("http://host/privet/v3/auth"), |
| 258 "{\"accessToken\":\"567\",\"tokenType\":\"testType\"," | 287 "{\"accessToken\":\"567\",\"tokenType\":\"testType\"," |
| 259 "\"scope\":\"owner\"}", | 288 "\"scope\":\"owner\"}", |
| 260 net::HTTP_OK, net::URLRequestStatus::SUCCESS); | 289 net::HTTP_OK, net::URLRequestStatus::SUCCESS); |
| 261 })); | 290 })); |
| 262 session_.ConfirmCode("testPin", | 291 session_.ConfirmCode("testPin", |
| 263 base::Bind(&PrivetV3SessionTest::OnCodeConfirmed, | 292 base::Bind(&PrivetV3SessionTest::OnCodeConfirmed, |
| 264 base::Unretained(this))); | 293 base::Unretained(this))); |
| 265 base::RunLoop().RunUntilIdle(); | 294 base::RunLoop().RunUntilIdle(); |
| 266 | 295 |
| 267 EXPECT_FALSE(session_.fingerprint_.empty()); | 296 EXPECT_TRUE(session_.client_->IsInHttpsMode()); |
| 268 EXPECT_EQ("testType 567", session_.privet_auth_token_); | 297 EXPECT_EQ("testType 567", session_.privet_auth_token_); |
| 269 } | 298 } |
| 270 | 299 |
| 271 TEST_F(PrivetV3SessionTest, Cancel) { | 300 TEST_F(PrivetV3SessionTest, Cancel) { |
| 272 EXPECT_CALL(*this, OnInitializedMock(Result::STATUS_SUCCESS, _)).Times(1);; | 301 EXPECT_CALL(*this, OnInitializedMock(Result::STATUS_SUCCESS, _)).Times(1);; |
| 273 fetcher_factory_.SetFakeResponse(GURL("http://host/privet/info"), | 302 fetcher_factory_.SetFakeResponse(GURL("http://host/privet/info"), |
| 274 kInfoResponse, net::HTTP_OK, | 303 kInfoResponse, net::HTTP_OK, |
| 275 net::URLRequestStatus::SUCCESS); | 304 net::URLRequestStatus::SUCCESS); |
| 276 | 305 |
| 277 session_.Init( | 306 session_.Init( |
| 278 base::Bind(&PrivetV3SessionTest::OnInitialized, base::Unretained(this))); | 307 base::Bind(&PrivetV3SessionTest::OnInitialized, base::Unretained(this))); |
| 279 base::RunLoop().RunUntilIdle(); | 308 base::RunLoop().RunUntilIdle(); |
| 280 | 309 |
| 310 EXPECT_CALL(*http_client_, IsInHttpsMode()).WillRepeatedly(Return(false)); |
| 311 |
| 281 EXPECT_CALL(*this, OnPairingStarted(Result::STATUS_SUCCESS)).Times(1); | 312 EXPECT_CALL(*this, OnPairingStarted(Result::STATUS_SUCCESS)).Times(1); |
| 282 EXPECT_CALL(*this, OnPostData(_)) | 313 EXPECT_CALL(*this, OnPostData(_)) |
| 283 .WillOnce(testing::Invoke([this](const base::DictionaryValue& data) { | 314 .WillOnce(Invoke([this](const base::DictionaryValue& data) { |
| 284 std::string device_commitment; | 315 std::string device_commitment; |
| 285 base::Base64Encode("1234", &device_commitment); | 316 base::Base64Encode("1234", &device_commitment); |
| 286 fetcher_factory_.SetFakeResponse( | 317 fetcher_factory_.SetFakeResponse( |
| 287 GURL("http://host/privet/v3/pairing/start"), | 318 GURL("http://host/privet/v3/pairing/start"), |
| 288 base::StringPrintf( | 319 base::StringPrintf( |
| 289 "{\"deviceCommitment\":\"%s\",\"sessionId\":\"testId\"}", | 320 "{\"deviceCommitment\":\"%s\",\"sessionId\":\"testId\"}", |
| 290 device_commitment.c_str()), | 321 device_commitment.c_str()), |
| 291 net::HTTP_OK, net::URLRequestStatus::SUCCESS); | 322 net::HTTP_OK, net::URLRequestStatus::SUCCESS); |
| 292 })); | 323 })); |
| 293 session_.StartPairing(PairingType::PAIRING_TYPE_EMBEDDEDCODE, | 324 session_.StartPairing(PairingType::PAIRING_TYPE_EMBEDDEDCODE, |
| 294 base::Bind(&PrivetV3SessionTest::OnPairingStarted, | 325 base::Bind(&PrivetV3SessionTest::OnPairingStarted, |
| 295 base::Unretained(this))); | 326 base::Unretained(this))); |
| 296 base::RunLoop().RunUntilIdle(); | 327 base::RunLoop().RunUntilIdle(); |
| 297 | 328 |
| 298 fetcher_factory_.SetFakeResponse(GURL("http://host/privet/v3/pairing/cancel"), | 329 fetcher_factory_.SetFakeResponse(GURL("http://host/privet/v3/pairing/cancel"), |
| 299 kInfoResponse, net::HTTP_OK, | 330 kInfoResponse, net::HTTP_OK, |
| 300 net::URLRequestStatus::SUCCESS); | 331 net::URLRequestStatus::SUCCESS); |
| 301 EXPECT_CALL(*this, OnPostData(_)) | 332 EXPECT_CALL(*this, OnPostData(_)) |
| 302 .WillOnce(testing::Invoke([this](const base::DictionaryValue& data) { | 333 .WillOnce(Invoke([this](const base::DictionaryValue& data) { |
| 303 std::string session_id; | 334 std::string session_id; |
| 304 EXPECT_TRUE(data.GetString("sessionId", &session_id)); | 335 EXPECT_TRUE(data.GetString("sessionId", &session_id)); |
| 305 })); | 336 })); |
| 306 } | 337 } |
| 307 | 338 |
| 308 // TODO(vitalybuka): replace PrivetHTTPClient with regular URL fetcher and | 339 // TODO(vitalybuka): replace PrivetHTTPClient with regular URL fetcher and |
| 309 // implement SendMessage test. | 340 // implement SendMessage test. |
| 310 | 341 |
| 311 } // namespace local_discovery | 342 } // namespace local_discovery |
| OLD | NEW |