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

Side by Side Diff: remoting/protocol/pairing_registry.cc

Issue 21128006: Refactored PairingRegistry::Delegate such that it can retrieve/modify for a single client. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 4 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
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/protocol/pairing_registry.h" 5 #include "remoting/protocol/pairing_registry.h"
6 6
7 #include "base/base64.h" 7 #include "base/base64.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/guid.h" 9 #include "base/guid.h"
10 #include "base/json/json_string_value_serializer.h" 10 #include "base/json/json_string_value_serializer.h"
(...skipping 18 matching lines...) Expand all
29 PairingRegistry::Pairing::Pairing(const base::Time& created_time, 29 PairingRegistry::Pairing::Pairing(const base::Time& created_time,
30 const std::string& client_name, 30 const std::string& client_name,
31 const std::string& client_id, 31 const std::string& client_id,
32 const std::string& shared_secret) 32 const std::string& shared_secret)
33 : created_time_(created_time), 33 : created_time_(created_time),
34 client_name_(client_name), 34 client_name_(client_name),
35 client_id_(client_id), 35 client_id_(client_id),
36 shared_secret_(shared_secret) { 36 shared_secret_(shared_secret) {
37 } 37 }
38 38
39 PairingRegistry::Pairing::~Pairing() {
40 }
41
39 PairingRegistry::Pairing PairingRegistry::Pairing::Create( 42 PairingRegistry::Pairing PairingRegistry::Pairing::Create(
40 const std::string& client_name) { 43 const std::string& client_name) {
41 base::Time created_time = base::Time::Now(); 44 base::Time created_time = base::Time::Now();
42 std::string client_id = base::GenerateGUID(); 45 std::string client_id = base::GenerateGUID();
43 std::string shared_secret; 46 std::string shared_secret;
44 char buffer[kKeySize]; 47 char buffer[kKeySize];
45 crypto::RandBytes(buffer, arraysize(buffer)); 48 crypto::RandBytes(buffer, arraysize(buffer));
46 if (!base::Base64Encode(base::StringPiece(buffer, arraysize(buffer)), 49 if (!base::Base64Encode(base::StringPiece(buffer, arraysize(buffer)),
47 &shared_secret)) { 50 &shared_secret)) {
48 LOG(FATAL) << "Base64Encode failed."; 51 LOG(FATAL) << "Base64Encode failed.";
49 } 52 }
50 return Pairing(created_time, client_name, client_id, shared_secret); 53 return Pairing(created_time, client_name, client_id, shared_secret);
51 } 54 }
52 55
53 PairingRegistry::Pairing::~Pairing() { 56 PairingRegistry::Pairing PairingRegistry::Pairing::CreateFromJson(
57 const base::Value& pairing_json) {
58 const base::DictionaryValue* pairing = NULL;
59 if (!pairing_json.GetAsDictionary(&pairing)) {
60 LOG(ERROR) << "Failed to load pairing information: not a dictionary.";
61 return Pairing();
62 }
63
64 std::string client_name, client_id, shared_secret;
65 double created_time_value;
66 if (pairing->GetDouble(kCreatedTimeKey, &created_time_value) &&
67 pairing->GetString(kClientNameKey, &client_name) &&
68 pairing->GetString(kClientIdKey, &client_id) &&
69 pairing->GetString(kSharedSecretKey, &shared_secret)) {
70 base::Time created_time = base::Time::FromJsTime(created_time_value);
71 return Pairing(created_time, client_name, client_id, shared_secret);
72 }
73
74 LOG(ERROR) << "Failed to load pairing information: unexpected format.";
75 return Pairing();
76 }
77
78 scoped_ptr<base::Value> PairingRegistry::Pairing::EncodeJson() const {
79 scoped_ptr<base::DictionaryValue> pairing(new base::DictionaryValue());
80 pairing->SetDouble(kCreatedTimeKey, created_time().ToJsTime());
81 pairing->SetString(kClientNameKey, client_name());
82 pairing->SetString(kClientIdKey, client_id());
83 if (!shared_secret().empty())
84 pairing->SetString(kSharedSecretKey, shared_secret());
85 return pairing.PassAs<base::Value>();
54 } 86 }
55 87
56 bool PairingRegistry::Pairing::operator==(const Pairing& other) const { 88 bool PairingRegistry::Pairing::operator==(const Pairing& other) const {
57 return created_time_ == other.created_time_ && 89 return created_time_ == other.created_time_ &&
58 client_id_ == other.client_id_ && 90 client_id_ == other.client_id_ &&
59 client_name_ == other.client_name_ && 91 client_name_ == other.client_name_ &&
60 shared_secret_ == other.shared_secret_; 92 shared_secret_ == other.shared_secret_;
61 } 93 }
62 94
63 bool PairingRegistry::Pairing::is_valid() const { 95 bool PairingRegistry::Pairing::is_valid() const {
(...skipping 15 matching lines...) Expand all
79 AddPairing(result); 111 AddPairing(result);
80 return result; 112 return result;
81 } 113 }
82 114
83 void PairingRegistry::GetPairing(const std::string& client_id, 115 void PairingRegistry::GetPairing(const std::string& client_id,
84 const GetPairingCallback& callback) { 116 const GetPairingCallback& callback) {
85 DCHECK(CalledOnValidThread()); 117 DCHECK(CalledOnValidThread());
86 GetPairingCallback wrapped_callback = base::Bind( 118 GetPairingCallback wrapped_callback = base::Bind(
87 &PairingRegistry::InvokeGetPairingCallbackAndScheduleNext, 119 &PairingRegistry::InvokeGetPairingCallbackAndScheduleNext,
88 this, callback); 120 this, callback);
89 LoadCallback load_callback = base::Bind(
90 &PairingRegistry::DoGetPairing, this, client_id, wrapped_callback);
91 // |Unretained| and |get| are both safe here because the delegate is owned 121 // |Unretained| and |get| are both safe here because the delegate is owned
92 // by the pairing registry and so is guaranteed to exist when the request 122 // by the pairing registry and so is guaranteed to exist when the request
93 // is serviced. 123 // is serviced.
94 base::Closure request = base::Bind( 124 base::Closure request = base::Bind(
95 &PairingRegistry::Delegate::Load, 125 &PairingRegistry::Delegate::Load,
96 base::Unretained(delegate_.get()), load_callback); 126 base::Unretained(delegate_.get()), client_id, wrapped_callback);
97 ServiceOrQueueRequest(request); 127 ServiceOrQueueRequest(request);
98 } 128 }
99 129
100 void PairingRegistry::GetAllPairings( 130 void PairingRegistry::GetAllPairings(
101 const GetAllPairingsCallback& callback) { 131 const GetAllPairingsCallback& callback) {
102 DCHECK(CalledOnValidThread()); 132 DCHECK(CalledOnValidThread());
103 GetAllPairingsCallback wrapped_callback = base::Bind( 133 GetAllPairingsCallback wrapped_callback = base::Bind(
104 &PairingRegistry::InvokeGetAllPairingsCallbackAndScheduleNext, 134 &PairingRegistry::InvokeGetAllPairingsCallbackAndScheduleNext,
105 this, callback); 135 this, callback);
106 LoadCallback load_callback = base::Bind(
107 &PairingRegistry::SanitizePairings, this, wrapped_callback);
108 base::Closure request = base::Bind( 136 base::Closure request = base::Bind(
109 &PairingRegistry::Delegate::Load, 137 &PairingRegistry::Delegate::LoadAll,
110 base::Unretained(delegate_.get()), load_callback); 138 base::Unretained(delegate_.get()), wrapped_callback);
111 ServiceOrQueueRequest(request); 139 ServiceOrQueueRequest(request);
112 } 140 }
113 141
114 void PairingRegistry::DeletePairing( 142 void PairingRegistry::DeletePairing(
115 const std::string& client_id, const SaveCallback& callback) { 143 const std::string& client_id, const DoneCallback& callback) {
116 DCHECK(CalledOnValidThread()); 144 DCHECK(CalledOnValidThread());
117 SaveCallback wrapped_callback = base::Bind( 145 DoneCallback wrapped_callback = base::Bind(
118 &PairingRegistry::InvokeSaveCallbackAndScheduleNext, 146 &PairingRegistry::InvokeDoneCallbackAndScheduleNext,
119 this, callback); 147 this, callback);
120 LoadCallback load_callback = base::Bind(
121 &PairingRegistry::DoDeletePairing, this, client_id, wrapped_callback);
122 base::Closure request = base::Bind( 148 base::Closure request = base::Bind(
123 &PairingRegistry::Delegate::Load, 149 &PairingRegistry::Delegate::Delete,
124 base::Unretained(delegate_.get()), load_callback); 150 base::Unretained(delegate_.get()), client_id, wrapped_callback);
125 ServiceOrQueueRequest(request); 151 ServiceOrQueueRequest(request);
126 } 152 }
127 153
128 void PairingRegistry::ClearAllPairings( 154 void PairingRegistry::ClearAllPairings(
129 const SaveCallback& callback) { 155 const DoneCallback& callback) {
130 DCHECK(CalledOnValidThread()); 156 DCHECK(CalledOnValidThread());
131 SaveCallback wrapped_callback = base::Bind( 157 DoneCallback wrapped_callback = base::Bind(
132 &PairingRegistry::InvokeSaveCallbackAndScheduleNext, 158 &PairingRegistry::InvokeDoneCallbackAndScheduleNext,
133 this, callback); 159 this, callback);
134 base::Closure request = base::Bind( 160 base::Closure request = base::Bind(
135 &PairingRegistry::Delegate::Save, 161 &PairingRegistry::Delegate::DeleteAll,
136 base::Unretained(delegate_.get()), 162 base::Unretained(delegate_.get()), wrapped_callback);
137 EncodeJson(PairedClients()),
138 wrapped_callback);
139 ServiceOrQueueRequest(request); 163 ServiceOrQueueRequest(request);
140 } 164 }
141 165
142 void PairingRegistry::AddPairing(const Pairing& pairing) { 166 void PairingRegistry::AddPairing(const Pairing& pairing) {
143 SaveCallback callback = base::Bind( 167 DoneCallback wrapped_callback = base::Bind(
144 &PairingRegistry::InvokeSaveCallbackAndScheduleNext, 168 &PairingRegistry::InvokeDoneCallbackAndScheduleNext,
145 this, SaveCallback()); 169 this, DoneCallback());
146 LoadCallback load_callback = base::Bind(
147 &PairingRegistry::MergePairingAndSave, this, pairing, callback);
148 base::Closure request = base::Bind( 170 base::Closure request = base::Bind(
149 &PairingRegistry::Delegate::Load, 171 &PairingRegistry::Delegate::Save,
150 base::Unretained(delegate_.get()), load_callback); 172 base::Unretained(delegate_.get()), pairing, wrapped_callback);
151 ServiceOrQueueRequest(request); 173 ServiceOrQueueRequest(request);
152 } 174 }
153 175
154 void PairingRegistry::MergePairingAndSave(const Pairing& pairing, 176 void PairingRegistry::InvokeDoneCallbackAndScheduleNext(
155 const SaveCallback& callback, 177 const DoneCallback& callback, bool success) {
156 const std::string& pairings_json) { 178 // CreatePairing doesn't have a callback, so the callback can be null.
157 DCHECK(CalledOnValidThread()); 179 if (!callback.is_null())
158 PairedClients clients = DecodeJson(pairings_json); 180 callback.Run(success);
159 clients[pairing.client_id()] = pairing;
160 std::string new_pairings_json = EncodeJson(clients);
161 delegate_->Save(new_pairings_json, callback);
162 }
163 181
164 void PairingRegistry::DoGetPairing(const std::string& client_id,
165 const GetPairingCallback& callback,
166 const std::string& pairings_json) {
167 PairedClients clients = DecodeJson(pairings_json);
168 Pairing result = clients[client_id];
169 callback.Run(result);
170 }
171
172 void PairingRegistry::SanitizePairings(const GetAllPairingsCallback& callback,
173 const std::string& pairings_json) {
174 PairedClients clients = DecodeJson(pairings_json);
175 callback.Run(ConvertToListValue(clients, false));
176 }
177
178 void PairingRegistry::DoDeletePairing(const std::string& client_id,
179 const SaveCallback& callback,
180 const std::string& pairings_json) {
181 PairedClients clients = DecodeJson(pairings_json);
182 clients.erase(client_id);
183 std::string new_pairings_json = EncodeJson(clients);
184 delegate_->Save(new_pairings_json, callback);
185 }
186
187 void PairingRegistry::InvokeLoadCallbackAndScheduleNext(
188 const LoadCallback& callback, const std::string& pairings_json) {
189 callback.Run(pairings_json);
190 pending_requests_.pop(); 182 pending_requests_.pop();
191 ServiceNextRequest(); 183 ServiceNextRequest();
192 } 184 }
193
194 void PairingRegistry::InvokeSaveCallbackAndScheduleNext(
195 const SaveCallback& callback, bool success) {
196 // CreatePairing doesn't have a callback, so the callback can be null.
197 if (!callback.is_null()) {
198 callback.Run(success);
199 }
200 pending_requests_.pop();
201 ServiceNextRequest();
202 }
203 185
204 void PairingRegistry::InvokeGetPairingCallbackAndScheduleNext( 186 void PairingRegistry::InvokeGetPairingCallbackAndScheduleNext(
205 const GetPairingCallback& callback, Pairing pairing) { 187 const GetPairingCallback& callback, Pairing pairing) {
206 callback.Run(pairing); 188 callback.Run(pairing);
207 pending_requests_.pop(); 189 pending_requests_.pop();
208 ServiceNextRequest(); 190 ServiceNextRequest();
209 } 191 }
210 192
211 void PairingRegistry::InvokeGetAllPairingsCallbackAndScheduleNext( 193 void PairingRegistry::InvokeGetAllPairingsCallbackAndScheduleNext(
212 const GetAllPairingsCallback& callback, 194 const GetAllPairingsCallback& callback,
213 scoped_ptr<base::ListValue> pairings) { 195 scoped_ptr<base::ListValue> pairings) {
214 callback.Run(pairings.Pass()); 196 callback.Run(pairings.Pass());
215 pending_requests_.pop(); 197 pending_requests_.pop();
216 ServiceNextRequest(); 198 ServiceNextRequest();
217 } 199 }
218 200
219 // static
220 PairingRegistry::PairedClients PairingRegistry::DecodeJson(
221 const std::string& pairings_json) {
222 PairedClients result;
223
224 if (pairings_json.empty()) {
225 return result;
226 }
227
228 JSONStringValueSerializer registry(pairings_json);
229 int error_code;
230 std::string error_message;
231 scoped_ptr<base::Value> root(
232 registry.Deserialize(&error_code, &error_message));
233 if (!root) {
234 LOG(ERROR) << "Failed to load paired clients: " << error_message
235 << " (" << error_code << ").";
236 return result;
237 }
238
239 base::ListValue* root_list = NULL;
240 if (!root->GetAsList(&root_list)) {
241 LOG(ERROR) << "Failed to load paired clients: root node is not a list.";
242 return result;
243 }
244
245 for (size_t i = 0; i < root_list->GetSize(); ++i) {
246 base::DictionaryValue* pairing = NULL;
247 std::string client_name, client_id, shared_secret;
248 double created_time_value;
249 if (root_list->GetDictionary(i, &pairing) &&
250 pairing->GetDouble(kCreatedTimeKey, &created_time_value) &&
251 pairing->GetString(kClientNameKey, &client_name) &&
252 pairing->GetString(kClientIdKey, &client_id) &&
253 pairing->GetString(kSharedSecretKey, &shared_secret)) {
254 base::Time created_time = base::Time::FromJsTime(created_time_value);
255 result[client_id] = Pairing(
256 created_time, client_name, client_id, shared_secret);
257 } else {
258 LOG(ERROR) << "Paired client " << i << " has unexpected format.";
259 }
260 }
261
262 return result;
263 }
264
265 void PairingRegistry::ServiceOrQueueRequest(const base::Closure& request) { 201 void PairingRegistry::ServiceOrQueueRequest(const base::Closure& request) {
266 bool servicing_request = !pending_requests_.empty(); 202 bool servicing_request = !pending_requests_.empty();
267 pending_requests_.push(request); 203 pending_requests_.push(request);
268 if (!servicing_request) { 204 if (!servicing_request) {
269 ServiceNextRequest(); 205 ServiceNextRequest();
270 } 206 }
271 } 207 }
272 208
273 void PairingRegistry::ServiceNextRequest() { 209 void PairingRegistry::ServiceNextRequest() {
274 if (pending_requests_.empty()) { 210 if (pending_requests_.empty())
275 return; 211 return;
276 } 212
277 base::Closure request = pending_requests_.front(); 213 base::Closure request = pending_requests_.front();
278 request.Run(); 214 request.Run();
279 } 215 }
280 216
281 // static
282 std::string PairingRegistry::EncodeJson(const PairedClients& clients) {
283 scoped_ptr<base::ListValue> root = ConvertToListValue(clients, true);
284 std::string result;
285 JSONStringValueSerializer serializer(&result);
286 serializer.Serialize(*root);
287
288 return result;
289 }
290
291 // static
292 scoped_ptr<base::ListValue> PairingRegistry::ConvertToListValue(
293 const PairedClients& clients,
294 bool include_shared_secrets) {
295 scoped_ptr<base::ListValue> root(new base::ListValue());
296 for (PairedClients::const_iterator i = clients.begin();
297 i != clients.end(); ++i) {
298 base::DictionaryValue* pairing = new base::DictionaryValue();
299 pairing->SetDouble(kCreatedTimeKey, i->second.created_time().ToJsTime());
300 pairing->SetString(kClientNameKey, i->second.client_name());
301 pairing->SetString(kClientIdKey, i->second.client_id());
302 if (include_shared_secrets) {
303 pairing->SetString(kSharedSecretKey, i->second.shared_secret());
304 }
305 root->Append(pairing);
306 }
307 return root.Pass();
308 }
309
310 } // namespace protocol 217 } // namespace protocol
311 } // namespace remoting 218 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698