summaryrefslogtreecommitdiffstats
path: root/cloud_print/service/service_state.cc
diff options
context:
space:
mode:
authorvitalybuka@chromium.org <vitalybuka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-06 02:42:07 +0000
committervitalybuka@chromium.org <vitalybuka@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-06 02:42:07 +0000
commite1a31ac75aa84f07134de78fc0cec6a49added50 (patch)
treee3a3289a65448e8b90244f299340b5b7721d019f /cloud_print/service/service_state.cc
parent2e2392b161702bd41f3a0058afd3786a912dfd3b (diff)
downloadchromium_src-e1a31ac75aa84f07134de78fc0cec6a49added50.zip
chromium_src-e1a31ac75aa84f07134de78fc0cec6a49added50.tar.gz
chromium_src-e1a31ac75aa84f07134de78fc0cec6a49added50.tar.bz2
Single binary for unittests.
Root solution for src/cloud_print. Build cloud_print_unittests on bots. Added virtual_driver_lib with shared files. Moved service_state out of win dir as platform independent. BUG=131058 TEST=unittests Review URL: https://chromiumcodereview.appspot.com/10505010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@140703 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cloud_print/service/service_state.cc')
-rw-r--r--cloud_print/service/service_state.cc211
1 files changed, 211 insertions, 0 deletions
diff --git a/cloud_print/service/service_state.cc b/cloud_print/service/service_state.cc
new file mode 100644
index 0000000..545210d
--- /dev/null
+++ b/cloud_print/service/service_state.cc
@@ -0,0 +1,211 @@
+// 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 "cloud_print/service/service_state.h"
+
+#include "base/json/json_reader.h"
+#include "base/json/json_writer.h"
+#include "base/logging.h"
+#include "base/message_loop.h"
+#include "base/string_util.h"
+#include "base/utf_string_conversions.h"
+#include "net/base/escape.h"
+#include "net/base/io_buffer.h"
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_builder.h"
+
+namespace {
+
+const char kCloudPrintJsonName[] = "cloud_print";
+const char kEnabledOptionName[] = "enabled";
+
+const char kEmailOptionName[] = "email";
+const char kPasswordOptionName[] = "password";
+const char kProxyIdOptionName[] = "proxy_id";
+const char kRobotEmailOptionName[] = "robot_email";
+const char kRobotTokenOptionName[] = "robot_refresh_token";
+const char kAuthTokenOptionName[] = "auth_token";
+const char kXmppAuthTokenOptionName[] = "xmpp_auth_token";
+
+const char kClientLoginUrl[] = "https://www.google.com/accounts/ClientLogin";
+
+const int64 kRequestTimeoutMs = 10 * 1000;
+
+class ServiceStateURLRequestDelegate : public net::URLRequest::Delegate {
+ public:
+ virtual void OnResponseStarted(net::URLRequest* request) {
+ if (request->GetResponseCode() == 200) {
+ Read(request);
+ if (request->status().is_io_pending())
+ return;
+ }
+ request->Cancel();
+ };
+
+ virtual void OnReadCompleted(net::URLRequest* request, int bytes_read) {
+ Read(request);
+ if (!request->status().is_io_pending())
+ MessageLoop::current()->Quit();
+ };
+
+ const std::string& data() const {
+ return data_;
+ }
+
+ private:
+ void Read(net::URLRequest* request) {
+ // Read as many bytes as are available synchronously.
+ const int kBufSize = 100000;
+ scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kBufSize));
+ int num_bytes = 0;
+ while (request->Read(buf, kBufSize, &num_bytes)) {
+ data_.append(buf->data(), buf->data() + num_bytes);
+ }
+ }
+ std::string data_;
+};
+
+
+void SetNotEmptyJsonString(base::DictionaryValue* dictionary,
+ const std::string& name,
+ const std::string& value) {
+ if (!value.empty())
+ dictionary->SetString(name, value);
+}
+
+} // namespace
+
+ServiceState::ServiceState() {
+ Reset();
+}
+
+ServiceState::~ServiceState() {
+}
+
+void ServiceState::Reset() {
+ email_.clear();
+ proxy_id_.clear();
+ robot_email_.clear();
+ robot_token_.clear();
+ auth_token_.clear();
+ xmpp_auth_token_.clear();
+}
+
+bool ServiceState::FromString(const std::string& json) {
+ Reset();
+ scoped_ptr<base::Value> data(base::JSONReader::Read(json));
+ if (!data.get())
+ return false;
+
+ const base::DictionaryValue* services = NULL;
+ if (!data->GetAsDictionary(&services))
+ return false;
+
+ base::DictionaryValue* cloud_print = NULL;
+ if (!services->GetDictionary(kCloudPrintJsonName, &cloud_print))
+ return false;
+
+ bool valid_file = true;
+ // Don't exit on fail. Collect all data for re-use by user later.
+ if (!cloud_print->GetBoolean(kEnabledOptionName, &valid_file))
+ valid_file = false;
+
+ cloud_print->GetString(kEmailOptionName, &email_);
+ cloud_print->GetString(kProxyIdOptionName, &proxy_id_);
+ cloud_print->GetString(kRobotEmailOptionName, &robot_email_);
+ cloud_print->GetString(kRobotTokenOptionName, &robot_token_);
+ cloud_print->GetString(kAuthTokenOptionName, &auth_token_);
+ cloud_print->GetString(kXmppAuthTokenOptionName, &xmpp_auth_token_);
+
+ return valid_file && IsValid();
+}
+
+bool ServiceState::IsValid() const {
+ if (email_.empty() || proxy_id_.empty())
+ return false;
+ bool valid_robot = !robot_email_.empty() && !robot_token_.empty();
+ bool valid_auth = !auth_token_.empty() && !xmpp_auth_token_.empty();
+ return valid_robot || valid_auth;
+}
+
+std::string ServiceState::ToString() {
+ scoped_ptr<base::DictionaryValue> services(new DictionaryValue());
+
+ scoped_ptr<base::DictionaryValue> cloud_print(new DictionaryValue());
+ cloud_print->SetBoolean(kEnabledOptionName, true);
+
+ SetNotEmptyJsonString(cloud_print.get(), kEmailOptionName, email_);
+ SetNotEmptyJsonString(cloud_print.get(), kProxyIdOptionName, proxy_id_);
+ SetNotEmptyJsonString(cloud_print.get(), kRobotEmailOptionName, robot_email_);
+ SetNotEmptyJsonString(cloud_print.get(), kRobotTokenOptionName, robot_token_);
+ SetNotEmptyJsonString(cloud_print.get(), kAuthTokenOptionName, auth_token_);
+ SetNotEmptyJsonString(cloud_print.get(), kXmppAuthTokenOptionName,
+ xmpp_auth_token_);
+
+ services->Set(kCloudPrintJsonName, cloud_print.release());
+
+ std::string json;
+ base::JSONWriter::WriteWithOptions(services.get(),
+ base::JSONWriter::OPTIONS_PRETTY_PRINT,
+ &json);
+ return json;
+}
+
+std::string ServiceState::LoginToGoogle(const std::string& service,
+ const std::string& email,
+ const std::string& password) {
+ MessageLoop loop(MessageLoop::TYPE_IO);
+
+ net::URLRequestContextBuilder builder;
+ scoped_ptr<net::URLRequestContext> context(builder.Build());
+
+ ServiceStateURLRequestDelegate fetcher_delegate;
+ GURL url(kClientLoginUrl);
+
+ std::string post_body;
+ post_body += "accountType=GOOGLE";
+ post_body += "&Email=" + net::EscapeUrlEncodedData(email, true);
+ post_body += "&Passwd=" + net::EscapeUrlEncodedData(password, true);
+ post_body += "&source=" + net::EscapeUrlEncodedData("CP-Service", true);
+ post_body += "&service=" + net::EscapeUrlEncodedData(service, true);
+
+ net::URLRequest request(url, &fetcher_delegate);
+
+ request.AppendBytesToUpload(post_body.c_str(), post_body.size());
+ request.SetExtraRequestHeaderByName(
+ "Content-Type", "application/x-www-form-urlencoded", true);
+ request.set_context(context.get());
+ request.set_method("POST");
+ request.Start();
+
+ MessageLoop::current()->PostDelayedTask(
+ FROM_HERE, MessageLoop::QuitClosure(), kRequestTimeoutMs);
+
+ MessageLoop::current()->Run();
+
+ const char kAuthStart[] = "Auth=";
+ std::vector<std::string> lines;
+ Tokenize(fetcher_delegate.data(), "\r\n", &lines);
+ for (size_t i = 0; i < lines.size(); ++i) {
+ std::vector<std::string> tokens;
+ if (StartsWithASCII(lines[i], kAuthStart, false))
+ return lines[i].substr(arraysize(kAuthStart) - 1);
+ }
+
+ return std::string();
+}
+
+bool ServiceState::Configure(const std::string& email,
+ const std::string& password,
+ const std::string& proxy_id) {
+ robot_token_.clear();
+ robot_email_.clear();
+ email_ = email;
+ proxy_id_ = proxy_id;
+ auth_token_ = LoginToGoogle("cloudprint", email_, password);
+ xmpp_auth_token_ = LoginToGoogle("chromiumsync", email_, password);
+ return IsValid();
+}
+