Chromium Code Reviews| 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 |