Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(202)

Side by Side Diff: cloud_print/service/win/service_state.cc

Issue 10414020: Service state file processing (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "cloud_print/service/win/service_state.h"
6
7 #include "base/json/json_reader.h"
8 #include "base/json/json_writer.h"
9 #include "base/logging.h"
10 #include "base/message_loop.h"
11 #include "base/string_util.h"
12 #include "base/utf_string_conversions.h"
13 #include "net/base/escape.h"
14 #include "net/base/io_buffer.h"
15 #include "net/url_request/url_request.h"
16 #include "net/url_request/url_request_context.h"
17 #include "net/url_request/url_request_context_builder.h"
18
19 namespace {
20
21 const char kCloudPrintJsonName[] = "cloud_print";
22 const char kEnabledOptionName[] = "enabled";
23
24 const char kEmailOptionName[] = "email";
25 const char kPasswordOptionName[] = "password";
26 const char kProxyIdOptionName[] = "proxy_id";
27 const char kRobotEmailOptionName[] = "robot_email";
28 const char kRobotTokenOptionName[] = "robot_refresh_token";
29 const char kAuthTokenOptionName[] = "auth_token";
30 const char kXmppAuthTokenOptionName[] = "xmpp_auth_token";
31
32 class ServiceStateURLRequestDelegate : public net::URLRequest::Delegate {
33 public:
34 virtual void OnResponseStarted(net::URLRequest* request) {
35 if (request->GetResponseCode() == 200)
36 Read(request);
37 request->Cancel();
38 };
39
40 virtual void OnReadCompleted(net::URLRequest* request, int bytes_read) {
41 MessageLoop::current()->Quit();
42 };
43
44 const std::string& data() const {
45 return data_;
46 }
47
48 private:
49 void Read(net::URLRequest* request) {
50 // Read as many bytes as are available synchronously.
51 const int kBufSize = 100000;
52 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(kBufSize));
53 while (true) {
54 int num_bytes = 0;
55 if (!request->Read(buf, kBufSize, &num_bytes)) {
gene 2012/05/21 23:08:06 from url_request.h // Read() must be called at
Vitaly Buka (NO REVIEWS) 2012/05/22 05:47:20 Done.
56 return;
57 }
58 data_.append(buf->data(), buf->data() + num_bytes);
59 }
60 }
61 std::string data_;
62 };
63
64
65 void SetNotEmptyJsonString(base::DictionaryValue* dictionary,
66 const std::string& name,
67 const std::string& value) {
68 if (!value.empty())
69 dictionary->SetString(name, value);
70 }
71
72 } // namespace
73
74 ServiceState::OptionsDelegate::~OptionsDelegate() {
75 }
76
77 ServiceState::ServiceState() {
78 Reset();
79 }
80
81 ServiceState::~ServiceState() {
82 }
83
84 void ServiceState::Reset() {
85 email_.clear();
86 password_.clear();
87 proxy_id_.clear();
88 robot_email_.clear();
89 robot_token_.clear();
90 auth_token_.clear();
91 xmpp_auth_token_.clear();
92 }
93
94 bool ServiceState::FromString(const std::string& json) {
95 Reset();
96 scoped_ptr<base::Value> data(base::JSONReader::Read(json));
97 if (!data.get())
98 return false;
99
100 const base::DictionaryValue* services = NULL;
101 if (!data->GetAsDictionary(&services))
102 return false;
103
104 base::DictionaryValue* cloud_print = NULL;
105 if (!services->GetDictionary(kCloudPrintJsonName, &cloud_print))
106 return false;
107
108 bool valid_file = true;
109 // Don't exit on fail. Collect all data for re-use by user later.
110 if (!cloud_print->GetBoolean(kEnabledOptionName, &valid_file))
111 valid_file = false;
112
113 cloud_print->GetString(kEmailOptionName, &email_);
114 cloud_print->GetString(kProxyIdOptionName, &proxy_id_);
115 cloud_print->GetString(kRobotEmailOptionName, &robot_email_);
116 cloud_print->GetString(kRobotTokenOptionName, &robot_token_);
117 cloud_print->GetString(kAuthTokenOptionName, &auth_token_);
118 cloud_print->GetString(kXmppAuthTokenOptionName, &xmpp_auth_token_);
119
120 return valid_file && IsValid();
121 }
122
123 bool ServiceState::IsValid() const {
124 if (email_.empty() || proxy_id_.empty())
125 return false;
126 bool valid_robot = !robot_email_.empty() && !robot_token_.empty();
127 bool valid_auth = !auth_token_.empty() && !xmpp_auth_token_.empty();
128 return valid_robot || valid_auth;
129 }
130
131 std::string ServiceState::ToString() {
132 scoped_ptr<base::DictionaryValue> services(new DictionaryValue());
133
134 scoped_ptr<base::DictionaryValue> cloud_print(new DictionaryValue());
135 cloud_print->SetBoolean(kEnabledOptionName, true);
136
137 SetNotEmptyJsonString(cloud_print.get(), kEmailOptionName, email_);
138 SetNotEmptyJsonString(cloud_print.get(), kProxyIdOptionName, proxy_id_);
139 SetNotEmptyJsonString(cloud_print.get(), kRobotEmailOptionName, robot_email_);
140 SetNotEmptyJsonString(cloud_print.get(), kRobotTokenOptionName, robot_token_);
141 SetNotEmptyJsonString(cloud_print.get(), kAuthTokenOptionName, auth_token_);
142 SetNotEmptyJsonString(cloud_print.get(), kXmppAuthTokenOptionName,
143 xmpp_auth_token_);
144
145 services->Set(kCloudPrintJsonName, cloud_print.release());
146
147 std::string json;
148 base::JSONWriter::WriteWithOptions(services.get(),
149 base::JSONWriter::OPTIONS_PRETTY_PRINT,
150 &json);
151 return json;
152 }
153
154 std::string ServiceState::LoginToGoogle(const std::string& service,
155 const std::string& email,
156 const std::string& password) {
157 MessageLoop loop(MessageLoop::TYPE_IO);
158
159 net::URLRequestContextBuilder builder;
160 scoped_ptr<net::URLRequestContext> context(builder.Build());
161
162 ServiceStateURLRequestDelegate fetcher_delegate;
163 GURL url("https://www.google.com/accounts/ClientLogin");
gene 2012/05/21 23:18:37 Move this to consts in the begining of the file.
Vitaly Buka (NO REVIEWS) 2012/05/22 05:47:20 Done.
164
165 std::string post_body;
166 post_body += "accountType=GOOGLE";
167 post_body += "&Email=" + net::EscapeUrlEncodedData(email, true);
168 post_body += "&Passwd=" + net::EscapeUrlEncodedData(password, true);
169 post_body += "&source=" + net::EscapeUrlEncodedData("CP-Service", true);
170 post_body += "&service=" + net::EscapeUrlEncodedData(service, true);
171
172 net::URLRequest request(url, &fetcher_delegate);
173
174 request.AppendBytesToUpload(post_body.c_str(), post_body.size());
175 request.SetExtraRequestHeaderByName(
176 "Content-Type", "application/x-www-form-urlencoded", true);
177 request.set_context(context.get());
178 request.set_method("POST");
179 request.Start();
180
181 MessageLoop::current()->Run();
182
183 const char kAuthStart[] = "Auth=";
184 std::vector<std::string> lines;
185 Tokenize(fetcher_delegate.data(), "\r\n", &lines);
186 for (size_t i = 0; i < lines.size(); ++i) {
187 std::vector<std::string> tokens;
188 if (StartsWithASCII(lines[i], kAuthStart, false))
189 return lines[i].substr(arraysize(kAuthStart) - 1);
190 }
191
192 return std::string();
193 }
194
195 bool ServiceState::Configure(OptionsDelegate* delegate) {
196 if (!delegate) {
197 NOTREACHED();
198 return false;
199 }
200
201 robot_token_.clear();
202 robot_email_.clear();
203 email_ = delegate->GetOption(kEmailOptionName, email_, false);
204 password_ = delegate->GetOption(kPasswordOptionName, "", true);
205 proxy_id_ = delegate->GetOption(kProxyIdOptionName, proxy_id_, false);
206 auth_token_ = LoginToGoogle("cloudprint", email_, password_);
207 xmpp_auth_token_ = LoginToGoogle("chromiumsync", email_, password_);
gene 2012/05/21 23:18:37 You need to clear robot accounts here, otherwise i
Vitaly Buka (NO REVIEWS) 2012/05/22 05:47:20 Done.
208
209 return IsValid();
210 }
211
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698