Index: remoting/host/host_token_validator_factory.cc |
diff --git a/remoting/host/host_token_validator_factory.cc b/remoting/host/host_token_validator_factory.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..277fdbde60b84cd78bed1e1ba654bfe25bee5aff |
--- /dev/null |
+++ b/remoting/host/host_token_validator_factory.cc |
@@ -0,0 +1,129 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "remoting/host/host_token_validator_factory.h" |
+ |
+#include <set> |
+ |
+#include "base/bind.h" |
+#include "base/callback.h" |
+#include "base/json/json_reader.h" |
+#include "base/location.h" |
+#include "base/logging.h" |
+#include "base/single_thread_task_runner.h" |
+#include "base/supports_user_data.h" |
Wez
2013/03/06 01:01:08
Is this include required?
rmsousa
2013/03/25 22:45:58
Done.
|
+#include "base/thread_task_runner_handle.h" |
Wez
2013/03/06 01:01:08
Is this include necessary?
rmsousa
2013/03/25 22:45:58
Done.
|
+#include "base/values.h" |
+#include "googleurl/src/gurl.h" |
+#include "net/base/escape.h" |
+#include "net/url_request/url_fetcher.h" |
+#include "net/url_request/url_fetcher_delegate.h" |
+#include "net/url_request/url_request_status.h" |
+ |
+namespace remoting { |
+ |
+class HostTokenValidator |
+ : public net::URLFetcherDelegate, |
+ public protocol::ThirdPartyAuthenticator::TokenValidator { |
+ public: |
+ HostTokenValidator( |
+ scoped_refptr<net::URLRequestContextGetter> request_context_getter) |
+ : request_context_getter_(request_context_getter) { |
+ } |
+ |
+ ~HostTokenValidator() { |
Wez
2013/03/06 01:01:08
nit: virtual
rmsousa
2013/03/25 22:45:58
Done.
|
+ } |
+ |
+ void ValidateThirdPartyToken( |
Wez
2013/03/06 01:01:08
nit: Add comment "TokenValidator interface."
Wez
2013/03/06 01:01:08
virtual + OVERRIDE
rmsousa
2013/03/25 22:45:58
Done.
rmsousa
2013/03/25 22:45:58
Done.
|
+ const std::string& token_validation_url, |
+ const std::string& token, |
+ const std::string& host_public_key, |
+ const std::string& token_signature, |
+ const std::string& scope, |
+ const base::Callback<void( |
+ const std::string& shared_secret)>& on_token_validated) { |
+ DCHECK(!request_); |
+ DCHECK(!scope.empty()); |
Wez
2013/03/06 01:01:08
nit: DCHECK e.g. that on_token_validated_ is non-n
rmsousa
2013/03/25 22:45:58
Done.
|
+ scope_ = scope; |
Wez
2013/03/06 01:01:08
nit: Space after DCHECKS, and after this parameter
rmsousa
2013/03/25 22:45:58
Done.
|
+ on_token_validated_ = on_token_validated; |
+ std::string post_body = |
+ "code=" + net::EscapeUrlEncodedData(token, true) + |
+ "&client_id=" + net::EscapeUrlEncodedData( |
+ host_public_key, true) + |
+ "&client_secret=" + net::EscapeUrlEncodedData( |
+ token_signature, true) + |
+ "&grant_type=authorization_code"; |
+ request_.reset(net::URLFetcher::Create( |
+ GURL(token_validation_url), net::URLFetcher::POST, this)); |
+ request_->SetUploadData("application/x-www-form-urlencoded", post_body); |
+ request_->SetRequestContext(request_context_getter_); |
+ request_->Start(); |
+ } |
+ |
+ void OnURLFetchComplete(const net::URLFetcher* source) { |
Wez
2013/03/06 01:01:08
nit: Add comment "URLFetcherDelegate interface."
Wez
2013/03/06 01:01:08
virtual + OVERRIDE
rmsousa
2013/03/25 22:45:58
Done.
rmsousa
2013/03/25 22:45:58
Done.
|
+ DCHECK_EQ(request_.get(), source); |
+ |
+ on_token_validated_.Run(GetSharedSecretFromResponse(source)); |
+ request_.reset(); |
Wez
2013/03/06 01:01:08
This will fail if the callback caused a new valida
rmsousa
2013/03/25 22:45:58
Good catch. Done.
|
+ } |
+ |
+ private: |
+ bool ValidateScope(const std::string& scope) { |
Wez
2013/03/06 01:01:08
nit: IsValidScope()
rmsousa
2013/03/25 22:45:58
Done.
|
+ // TODO(rmsousa): Deal with reordering/subsets/supersets/aliases/etc. |
+ return scope == scope_; |
+ } |
+ |
+ std::string GetSharedSecretFromResponse(const net::URLFetcher* source) { |
+ std::string shared_secret; |
Wez
2013/03/06 01:01:08
nit: Add a comment e.g. "Verify that we got a succ
rmsousa
2013/03/25 22:45:58
Done.
|
+ int response = source->GetResponseCode(); |
+ net::URLRequestStatus status = source->GetStatus(); |
+ std::string data; |
+ if (!status.is_success() || response != 200) { |
+ LOG(ERROR) << |
+ "Error " << response << " validating token: '" << data << "'"; |
+ return shared_secret; |
+ } |
+ |
+ source->GetResponseAsString(&data); |
Wez
2013/03/06 01:01:08
nit: Comment e.g. "Decode the JSON data from the r
rmsousa
2013/03/25 22:45:58
Done.
|
+ scoped_ptr<base::Value> value(base::JSONReader::Read(data)); |
+ if (!value.get() || value->GetType() != base::Value::TYPE_DICTIONARY) { |
+ LOG(ERROR) << "Invalid token validation response: '" << data << "'"; |
+ return shared_secret; |
+ } |
+ |
+ DictionaryValue* dict = static_cast<DictionaryValue*>(value.get()); |
Wez
2013/03/06 01:01:08
nit: Comment e.g. "Fetch the scope and check that
rmsousa
2013/03/25 22:45:58
Done.
|
+ std::string scope; |
+ dict->GetStringWithoutPathExpansion("scope", &scope); |
+ if (!ValidateScope(scope)) { |
+ LOG(ERROR) << |
+ "Invalid scope: '" << scope << "', expected: '" << scope_ <<"'."; |
+ return shared_secret; |
+ } |
+ |
+ dict->GetStringWithoutPathExpansion("access_token", &shared_secret); |
Wez
2013/03/06 01:01:08
nit: Comment e.g. "Scope was valid, so return the
rmsousa
2013/03/25 22:45:58
Done.
|
+ return shared_secret; |
+ } |
+ |
+ scoped_refptr<net::URLRequestContextGetter> request_context_getter_; |
+ scoped_ptr<net::URLFetcher> request_; |
+ std::string scope_; |
+ base::Callback<void(const std::string& shared_secret)> on_token_validated_; |
Wez
2013/03/06 01:01:08
nit: Blank line before DISALLOW...
rmsousa
2013/03/25 22:45:58
Done.
|
+ DISALLOW_COPY_AND_ASSIGN(HostTokenValidator); |
+}; |
+ |
+HostTokenValidatorFactory::HostTokenValidatorFactory( |
+ scoped_refptr<net::URLRequestContextGetter> request_context_getter) |
+ : request_context_getter_(request_context_getter) { |
+} |
+ |
+HostTokenValidatorFactory::~HostTokenValidatorFactory() { |
+} |
+ |
+scoped_ptr<protocol::ThirdPartyAuthenticator::TokenValidator> |
+ HostTokenValidatorFactory::CreateTokenValidator() { |
+ return scoped_ptr<protocol::ThirdPartyAuthenticator::TokenValidator>( |
+ new HostTokenValidator(request_context_getter_)); |
+} |
+ |
+} // namespace remoting |