| 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 "remoting/host/token_validator_base.h" | 5 #include "remoting/host/token_validator_base.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include "base/base64.h" | 9 #include "base/base64.h" |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 | 78 |
| 79 const GURL& TokenValidatorBase::token_url() const { | 79 const GURL& TokenValidatorBase::token_url() const { |
| 80 return third_party_auth_config_.token_url; | 80 return third_party_auth_config_.token_url; |
| 81 } | 81 } |
| 82 | 82 |
| 83 const std::string& TokenValidatorBase::token_scope() const { | 83 const std::string& TokenValidatorBase::token_scope() const { |
| 84 return token_scope_; | 84 return token_scope_; |
| 85 } | 85 } |
| 86 | 86 |
| 87 // URLFetcherDelegate interface. | 87 // URLFetcherDelegate interface. |
| 88 void TokenValidatorBase::OnResponseStarted(net::URLRequest* source) { | 88 void TokenValidatorBase::OnResponseStarted(net::URLRequest* source, |
| 89 int net_result) { |
| 90 DCHECK_NE(net_result, net::ERR_IO_PENDING); |
| 89 DCHECK_EQ(request_.get(), source); | 91 DCHECK_EQ(request_.get(), source); |
| 90 | 92 |
| 91 int bytes_read = 0; | 93 if (net_result != net::OK) |
| 92 request_->Read(buffer_.get(), kBufferSize, &bytes_read); | 94 return; |
| 93 OnReadCompleted(request_.get(), bytes_read); | 95 |
| 96 int bytes_read = request_->Read(buffer_.get(), kBufferSize); |
| 97 if (bytes_read > 0) |
| 98 OnReadCompleted(request_.get(), bytes_read); |
| 94 } | 99 } |
| 95 | 100 |
| 96 void TokenValidatorBase::OnReadCompleted(net::URLRequest* source, | 101 void TokenValidatorBase::OnReadCompleted(net::URLRequest* source, |
| 97 int bytes_read) { | 102 int net_result) { |
| 103 DCHECK_NE(net_result, net::ERR_IO_PENDING); |
| 98 DCHECK_EQ(request_.get(), source); | 104 DCHECK_EQ(request_.get(), source); |
| 99 | 105 |
| 100 do { | 106 while (net_result > 0) { |
| 101 if (!request_->status().is_success() || bytes_read <= 0) | 107 data_.append(buffer_->data(), net_result); |
| 102 break; | 108 net_result = request_->Read(buffer_.get(), kBufferSize); |
| 109 } |
| 103 | 110 |
| 104 data_.append(buffer_->data(), bytes_read); | 111 if (net_result == net::ERR_IO_PENDING) |
| 105 } while (request_->Read(buffer_.get(), kBufferSize, &bytes_read)); | 112 return; |
| 106 | 113 |
| 107 const net::URLRequestStatus status = request_->status(); | 114 retrying_request_ = false; |
| 108 | 115 std::string shared_token = ProcessResponse(net_result); |
| 109 if (!status.is_io_pending()) { | 116 request_.reset(); |
| 110 retrying_request_ = false; | 117 on_token_validated_.Run(shared_token); |
| 111 std::string shared_token = ProcessResponse(); | |
| 112 request_.reset(); | |
| 113 on_token_validated_.Run(shared_token); | |
| 114 } | |
| 115 } | 118 } |
| 116 | 119 |
| 117 void TokenValidatorBase::OnReceivedRedirect( | 120 void TokenValidatorBase::OnReceivedRedirect( |
| 118 net::URLRequest* request, | 121 net::URLRequest* request, |
| 119 const net::RedirectInfo& redirect_info, | 122 const net::RedirectInfo& redirect_info, |
| 120 bool* defer_redirect) { | 123 bool* defer_redirect) { |
| 121 if (!retrying_request_ && redirect_info.new_method == "GET" && | 124 if (!retrying_request_ && redirect_info.new_method == "GET" && |
| 122 redirect_info.new_url == third_party_auth_config_.token_validation_url) { | 125 redirect_info.new_url == third_party_auth_config_.token_validation_url) { |
| 123 // A sequence of redirects caused the original POST request to become a GET | 126 // A sequence of redirects caused the original POST request to become a GET |
| 124 // request for this URL. Cancel the request, and re-submit the POST request. | 127 // request for this URL. Cancel the request, and re-submit the POST request. |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 } | 186 } |
| 184 request_->ContinueWithCertificate(nullptr, nullptr); | 187 request_->ContinueWithCertificate(nullptr, nullptr); |
| 185 } | 188 } |
| 186 } | 189 } |
| 187 | 190 |
| 188 bool TokenValidatorBase::IsValidScope(const std::string& token_scope) { | 191 bool TokenValidatorBase::IsValidScope(const std::string& token_scope) { |
| 189 // TODO(rmsousa): Deal with reordering/subsets/supersets/aliases/etc. | 192 // TODO(rmsousa): Deal with reordering/subsets/supersets/aliases/etc. |
| 190 return token_scope == token_scope_; | 193 return token_scope == token_scope_; |
| 191 } | 194 } |
| 192 | 195 |
| 193 std::string TokenValidatorBase::ProcessResponse() { | 196 std::string TokenValidatorBase::ProcessResponse(int net_result) { |
| 194 // Verify that we got a successful response. | 197 // Verify that we got a successful response. |
| 195 net::URLRequestStatus status = request_->status(); | 198 if (net_result != net::OK) { |
| 196 if (!status.is_success()) { | 199 LOG(ERROR) << "Error validating token, err=" << net_result; |
| 197 LOG(ERROR) << "Error validating token, status=" << status.status() | |
| 198 << " err=" << status.error(); | |
| 199 return std::string(); | 200 return std::string(); |
| 200 } | 201 } |
| 201 | 202 |
| 202 int response = request_->GetResponseCode(); | 203 int response = request_->GetResponseCode(); |
| 203 if (response != 200) { | 204 if (response != 200) { |
| 204 LOG(ERROR) | 205 LOG(ERROR) << "Error " << response << " validating token: '" << data_ |
| 205 << "Error " << response << " validating token: '" << data_ << "'"; | 206 << "'"; |
| 206 return std::string(); | 207 return std::string(); |
| 207 } | 208 } |
| 208 | 209 |
| 209 // Decode the JSON data from the response. | 210 // Decode the JSON data from the response. |
| 210 std::unique_ptr<base::Value> value = base::JSONReader::Read(data_); | 211 std::unique_ptr<base::Value> value = base::JSONReader::Read(data_); |
| 211 base::DictionaryValue* dict; | 212 base::DictionaryValue* dict; |
| 212 if (!value || !value->GetAsDictionary(&dict)) { | 213 if (!value || !value->GetAsDictionary(&dict)) { |
| 213 LOG(ERROR) << "Invalid token validation response: '" << data_ << "'"; | 214 LOG(ERROR) << "Invalid token validation response: '" << data_ << "'"; |
| 214 return std::string(); | 215 return std::string(); |
| 215 } | 216 } |
| 216 | 217 |
| 217 std::string token_scope; | 218 std::string token_scope; |
| 218 dict->GetStringWithoutPathExpansion("scope", &token_scope); | 219 dict->GetStringWithoutPathExpansion("scope", &token_scope); |
| 219 if (!IsValidScope(token_scope)) { | 220 if (!IsValidScope(token_scope)) { |
| 220 LOG(ERROR) << "Invalid scope: '" << token_scope | 221 LOG(ERROR) << "Invalid scope: '" << token_scope << "', expected: '" |
| 221 << "', expected: '" << token_scope_ <<"'."; | 222 << token_scope_ << "'."; |
| 222 return std::string(); | 223 return std::string(); |
| 223 } | 224 } |
| 224 | 225 |
| 225 std::string shared_secret; | 226 std::string shared_secret; |
| 226 // Everything is valid, so return the shared secret to the caller. | 227 // Everything is valid, so return the shared secret to the caller. |
| 227 dict->GetStringWithoutPathExpansion("access_token", &shared_secret); | 228 dict->GetStringWithoutPathExpansion("access_token", &shared_secret); |
| 228 return shared_secret; | 229 return shared_secret; |
| 229 } | 230 } |
| 230 | 231 |
| 231 } // namespace remoting | 232 } // namespace remoting |
| OLD | NEW |