OLD | NEW |
---|---|
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 "chrome/common/extensions/api/sockets/sockets_handler.h" | 5 #include "chrome/common/extensions/api/sockets/sockets_handler.h" |
6 | 6 |
7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
9 #include "base/values.h" | 9 #include "base/values.h" |
10 #include "chrome/common/extensions/api/manifest_types.h" | 10 #include "chrome/common/extensions/api/manifest_types.h" |
11 #include "chrome/common/extensions/extension.h" | 11 #include "chrome/common/extensions/extension.h" |
12 #include "chrome/common/extensions/extension_messages.h" | |
12 #include "chrome/common/extensions/permissions/permissions_data.h" | 13 #include "chrome/common/extensions/permissions/permissions_data.h" |
13 #include "chrome/common/extensions/permissions/socket_permission_data.h" | 14 #include "chrome/common/extensions/permissions/socket_permission_data.h" |
14 #include "extensions/common/error_utils.h" | 15 #include "extensions/common/error_utils.h" |
15 #include "extensions/common/manifest_constants.h" | 16 #include "extensions/common/manifest_constants.h" |
16 #include "extensions/common/permissions/api_permission_set.h" | 17 #include "extensions/common/permissions/api_permission_set.h" |
18 #include "grit/generated_resources.h" | |
19 #include "ipc/ipc_message.h" | |
20 #include "ipc/ipc_message_utils.h" | |
21 #include "ui/base/l10n/l10n_util.h" | |
17 | 22 |
18 namespace extensions { | 23 namespace extensions { |
19 | 24 |
20 namespace sockets_errors { | 25 namespace sockets_errors { |
21 const char kErrorInvalidHostPattern[] = "Invalid host:port pattern '*'"; | 26 const char kErrorInvalidHostPattern[] = "Invalid host:port pattern '*'"; |
22 } | 27 } |
23 | 28 |
24 namespace keys = extensions::manifest_keys; | 29 namespace keys = extensions::manifest_keys; |
25 namespace errors = sockets_errors; | 30 namespace errors = sockets_errors; |
26 using api::manifest_types::Sockets; | 31 using api::manifest_types::Sockets; |
32 using content::SocketPermissionRequest; | |
33 | |
34 // TODO(rpaquay): Unit test for all this class (Diff, Union, etc). | |
35 class SocketsManifestPermission : public ManifestPermission { | |
Yoyo Zhou
2013/11/09 01:15:30
Do you anticipate something like SetDisjunctionPer
rpaquay
2013/11/11 18:37:35
I would say probably at some point. I don't know o
Yoyo Zhou
2013/11/12 02:39:29
Okay.
| |
36 public: | |
37 SocketsManifestPermission() { | |
38 } | |
39 | |
40 explicit SocketsManifestPermission(scoped_ptr<SocketsManifestData> data) | |
41 : data_(data.Pass()) { | |
42 } | |
43 | |
44 virtual std::string name() const OVERRIDE { | |
45 return keys::kSockets; | |
46 } | |
47 | |
48 virtual std::string id() const OVERRIDE { | |
49 return name(); | |
50 } | |
51 | |
52 // Returns true if this permission has any PermissionMessages. | |
53 virtual bool HasMessages() const OVERRIDE { | |
54 if (!data_) | |
55 return false; | |
56 | |
57 return data_->HasMessages(); | |
58 } | |
59 | |
60 // Returns the localized permission messages of this permission. | |
61 virtual PermissionMessages GetMessages() const OVERRIDE { | |
62 if (!data_) | |
63 return PermissionMessages(); | |
64 return data_->GetPermissionMessages(); | |
65 } | |
66 | |
67 // Parses the ManifestPermission from |value|. Returns false if error happens. | |
68 virtual bool FromValue(const base::Value* value) OVERRIDE { | |
69 // TODO(rpaquay): Null check? | |
70 if (!value) | |
71 return false; | |
72 | |
73 std::vector<InstallWarning> warnings; | |
74 string16 error; | |
75 scoped_ptr<SocketsManifestData> data( | |
76 SocketsManifestData::FromValue(*value, &warnings, &error)); | |
77 | |
78 if (!data) | |
79 return false; | |
80 | |
81 data_ = data.Pass(); | |
82 return true; | |
83 } | |
84 | |
85 // Stores this into a new created |value|. | |
86 virtual scoped_ptr<base::Value> ToValue() const OVERRIDE { | |
87 if (!data_) { | |
88 // TODO(rpaquay) : Is it ok to return NULL? | |
89 return scoped_ptr<base::Value>(base::Value::CreateNullValue()); | |
90 } | |
91 | |
92 Sockets sockets; | |
93 if (data_->is_udp()) { | |
94 sockets.udp.reset(new Sockets::Udp()); | |
95 sockets.udp->bind = AddEntry(SocketPermissionRequest::UDP_BIND).Pass(); | |
96 sockets.udp->send = AddEntry(SocketPermissionRequest::UDP_SEND_TO).Pass(); | |
97 sockets.udp->multicast_membership = | |
98 AddEntry(SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP).Pass(); | |
99 } | |
100 if (data_->is_tcp()) { | |
101 sockets.tcp.reset(new Sockets::Tcp()); | |
102 sockets.tcp->connect = AddEntry( | |
103 SocketPermissionRequest::TCP_CONNECT).Pass(); | |
104 } | |
105 if (data_->is_tcp_server()) { | |
106 sockets.tcp_server.reset(new Sockets::TcpServer()); | |
107 sockets.tcp_server->listen = AddEntry( | |
108 SocketPermissionRequest::TCP_LISTEN).Pass(); | |
109 } | |
110 | |
111 return sockets.ToValue().Pass(); | |
112 } | |
113 | |
114 // Clones this. | |
115 virtual ManifestPermission* Clone() const OVERRIDE { | |
116 if (!data_) | |
117 return new SocketsManifestPermission(); | |
118 | |
119 scoped_ptr<SocketsManifestData> clone_data(data_->Clone()); | |
120 return new SocketsManifestPermission(clone_data.Pass()); | |
121 } | |
122 | |
123 // Returns a new API permission which equals this - |rhs|. | |
124 virtual ManifestPermission* Diff(const ManifestPermission* rhs) | |
125 const OVERRIDE { | |
126 const SocketsManifestPermission* other = | |
127 static_cast<const SocketsManifestPermission*>(rhs); | |
128 | |
129 if (!data_) | |
130 return new SocketsManifestPermission(); | |
131 | |
132 if (!other->data_) | |
133 return Clone(); | |
134 | |
135 scoped_ptr<SocketsManifestData> data(data_->Diff(other->data_.get())); | |
136 return new SocketsManifestPermission(data.Pass()); | |
137 } | |
138 | |
139 // Returns a new API permission which equals the union of this and |rhs|. | |
140 virtual ManifestPermission* Union(const ManifestPermission* rhs) | |
141 const OVERRIDE { | |
142 const SocketsManifestPermission* other = | |
143 static_cast<const SocketsManifestPermission*>(rhs); | |
144 | |
145 if (!data_) | |
146 return other->Clone(); | |
147 | |
148 if (!other->data_) | |
149 return Clone(); | |
150 | |
151 scoped_ptr<SocketsManifestData> data(data_->Union(other->data_.get())); | |
152 return new SocketsManifestPermission(data.Pass()); | |
153 } | |
154 | |
155 // Returns a new API permission which equals the intersect of this and |rhs|. | |
156 virtual ManifestPermission* Intersect(const ManifestPermission* rhs) | |
157 const OVERRIDE { | |
158 const SocketsManifestPermission* other = | |
159 static_cast<const SocketsManifestPermission*>(rhs); | |
160 | |
161 if (!data_) | |
162 return new SocketsManifestPermission(); | |
163 | |
164 if (!other->data_) | |
165 return new SocketsManifestPermission(); | |
166 | |
167 scoped_ptr<SocketsManifestData> data(data_->Intersect(other->data_.get())); | |
168 return new SocketsManifestPermission(data.Pass()); | |
169 } | |
170 | |
171 // Returns true if |rhs| is a subset of this. | |
172 virtual bool Contains(const ManifestPermission* rhs) const OVERRIDE { | |
173 const SocketsManifestPermission* other = | |
174 static_cast<const SocketsManifestPermission*>(rhs); | |
175 | |
176 if (!data_) | |
177 return !other->data_; | |
178 | |
179 if (!other->data_) | |
180 return true; | |
181 | |
182 return data_->Contains(other->data_.get()); | |
183 } | |
184 | |
185 // Returns true if |rhs| is equal to this. | |
186 virtual bool Equal(const ManifestPermission* rhs) const OVERRIDE { | |
187 const SocketsManifestPermission* other = | |
188 static_cast<const SocketsManifestPermission*>(rhs); | |
189 | |
190 if (!data_) | |
191 return !other->data_; | |
192 | |
193 if (!other->data_) | |
194 return false; | |
195 | |
196 return data_->Equal(other->data_.get()); | |
197 } | |
198 | |
199 // IPC functions | |
200 // Writes this into the given IPC message |m|. | |
201 virtual void Write(IPC::Message* m) const OVERRIDE { | |
202 bool has_data = !!data_; | |
203 IPC::WriteParam(m, has_data); | |
204 if (has_data) { | |
205 data_->Write(m); | |
206 } | |
207 } | |
208 | |
209 // Reads from the given IPC message |m|. | |
210 virtual bool Read(const IPC::Message* m, PickleIterator* iter) OVERRIDE { | |
211 data_.reset(); | |
212 | |
213 bool has_data; | |
214 bool result = IPC::ReadParam(m, iter, &has_data); | |
215 if (!result) | |
216 return result; | |
217 | |
218 if (!has_data) | |
219 return true; | |
220 | |
221 data_.reset(new SocketsManifestData()); | |
222 return data_->Read(m, iter); | |
223 } | |
224 | |
225 // Logs this permission. | |
226 virtual void Log(std::string* log) const OVERRIDE { | |
227 if (data_) | |
228 data_->Log(log); | |
229 } | |
230 | |
231 private: | |
232 scoped_ptr<std::string> AddEntry( | |
233 content::SocketPermissionRequest::OperationType operation_type) const { | |
234 scoped_ptr<std::string> result; | |
235 for (SocketsManifestData::SocketPermissionEntrySet::const_iterator it = | |
236 data_->entries().begin(); it != data_->entries().end() ; ++it) { | |
237 if (it->pattern().type == operation_type) { | |
238 result.reset(new std::string(it->GetHostPatternAsString())); | |
239 break; | |
240 } | |
241 } | |
242 return result.Pass(); | |
243 } | |
244 | |
245 scoped_ptr<SocketsManifestData> data_; | |
Yoyo Zhou
2013/11/09 01:15:30
This looks like unusual ownership. ManifestDatas a
rpaquay
2013/11/11 18:37:35
The "initial" value is a clone of the extension ma
Yoyo Zhou
2013/11/13 02:57:07
(SocketPermissionData already exists, but it seems
rpaquay
2013/11/13 21:28:55
This makes sense. Patchset #6 swaps ownership betw
| |
246 }; | |
27 | 247 |
28 SocketsHandler::SocketsHandler() {} | 248 SocketsHandler::SocketsHandler() {} |
29 | 249 |
30 SocketsHandler::~SocketsHandler() {} | 250 SocketsHandler::~SocketsHandler() {} |
31 | 251 |
32 bool SocketsHandler::Parse(Extension* extension, string16* error) { | 252 bool SocketsHandler::Parse(Extension* extension, string16* error) { |
33 const base::Value* sockets = NULL; | 253 const base::Value* sockets = NULL; |
34 CHECK(extension->manifest()->Get(keys::kSockets, &sockets)); | 254 CHECK(extension->manifest()->Get(keys::kSockets, &sockets)); |
35 std::vector<InstallWarning> install_warnings; | 255 std::vector<InstallWarning> install_warnings; |
36 scoped_ptr<SocketsManifestData> data = | 256 scoped_ptr<SocketsManifestData> data = |
37 SocketsManifestData::FromValue(*sockets, | 257 SocketsManifestData::FromValue(*sockets, |
38 &install_warnings, | 258 &install_warnings, |
39 error); | 259 error); |
40 if (!data) | 260 if (!data) |
41 return false; | 261 return false; |
42 | 262 |
43 extension->AddInstallWarnings(install_warnings); | 263 extension->AddInstallWarnings(install_warnings); |
44 extension->SetManifestData(keys::kSockets, data.release()); | 264 extension->SetManifestData(keys::kSockets, data.release()); |
45 return true; | 265 return true; |
46 } | 266 } |
47 | 267 |
268 ManifestPermission* SocketsHandler::CreatePermission() { | |
269 return new SocketsManifestPermission(); | |
270 } | |
271 | |
272 ManifestPermission* SocketsHandler::CreateInitialRequiredPermission( | |
273 const Extension* extension) { | |
274 SocketsManifestData* data = SocketsManifestData::Get(extension); | |
275 if (data) { | |
276 return new SocketsManifestPermission( | |
277 scoped_ptr<SocketsManifestData>(data->Clone()).Pass()); | |
278 } | |
279 return new SocketsManifestPermission(); | |
280 } | |
281 | |
48 const std::vector<std::string> SocketsHandler::Keys() const { | 282 const std::vector<std::string> SocketsHandler::Keys() const { |
49 return SingleKey(manifest_keys::kSockets); | 283 return SingleKey(manifest_keys::kSockets); |
50 } | 284 } |
51 | 285 |
52 SocketsManifestData::SocketsManifestData() {} | 286 SocketsManifestData::SocketsManifestData() : kinds_(kNone) {} |
53 SocketsManifestData::~SocketsManifestData() {} | 287 SocketsManifestData::~SocketsManifestData() {} |
54 | 288 |
55 // static | 289 // static |
56 SocketsManifestData* SocketsManifestData::Get(const Extension* extension) { | 290 SocketsManifestData* SocketsManifestData::Get(const Extension* extension) { |
57 return static_cast<SocketsManifestData*>( | 291 return static_cast<SocketsManifestData*>( |
58 extension->GetManifestData(keys::kSockets)); | 292 extension->GetManifestData(keys::kSockets)); |
59 } | 293 } |
60 | 294 |
61 // static | 295 // static |
62 bool SocketsManifestData::CheckRequest( | 296 bool SocketsManifestData::CheckRequest( |
63 const Extension* extension, | 297 const Extension* extension, |
64 const content::SocketPermissionRequest& request) { | 298 const content::SocketPermissionRequest& request) { |
65 SocketsManifestData* data = SocketsManifestData::Get(extension); | 299 SocketsManifestData* data = SocketsManifestData::Get(extension); |
66 if (data == NULL) | 300 if (!data) |
67 return false; | 301 return false; |
68 | 302 |
69 return data->CheckRequestImpl(extension, request); | 303 return data->CheckRequestImpl(extension, request); |
70 } | 304 } |
71 | 305 |
72 // static | 306 // static |
73 scoped_ptr<SocketsManifestData> SocketsManifestData::FromValue( | 307 scoped_ptr<SocketsManifestData> SocketsManifestData::FromValue( |
74 const base::Value& value, | 308 const base::Value& value, |
75 std::vector<InstallWarning>* install_warnings, | 309 std::vector<InstallWarning>* install_warnings, |
76 string16* error) { | 310 string16* error) { |
77 scoped_ptr<Sockets> sockets = Sockets::FromValue(value, error); | 311 scoped_ptr<Sockets> sockets = Sockets::FromValue(value, error); |
78 if (!sockets) | 312 if (!sockets) |
79 return scoped_ptr<SocketsManifestData>(); | 313 return scoped_ptr<SocketsManifestData>(); |
80 | 314 |
81 scoped_ptr<SocketsManifestData> result(new SocketsManifestData()); | 315 scoped_ptr<SocketsManifestData> result(new SocketsManifestData()); |
82 if (sockets->udp) { | 316 if (sockets->udp) { |
317 result->kinds_ |= kUdpPermission; | |
83 if (!ParseHostPattern(result.get(), | 318 if (!ParseHostPattern(result.get(), |
84 content::SocketPermissionRequest::UDP_BIND, | 319 content::SocketPermissionRequest::UDP_BIND, |
85 sockets->udp->bind, | 320 sockets->udp->bind, |
86 error)) { | 321 error)) { |
87 return scoped_ptr<SocketsManifestData>(); | 322 return scoped_ptr<SocketsManifestData>(); |
88 } | 323 } |
89 if (!ParseHostPattern(result.get(), | 324 if (!ParseHostPattern(result.get(), |
90 content::SocketPermissionRequest::UDP_SEND_TO, | 325 content::SocketPermissionRequest::UDP_SEND_TO, |
91 sockets->udp->send, | 326 sockets->udp->send, |
92 error)) { | 327 error)) { |
93 return scoped_ptr<SocketsManifestData>(); | 328 return scoped_ptr<SocketsManifestData>(); |
94 } | 329 } |
95 if (!ParseHostPattern(result.get(), | 330 if (!ParseHostPattern(result.get(), |
96 content::SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP, | 331 content::SocketPermissionRequest::UDP_MULTICAST_MEMBERSHIP, |
97 sockets->udp->multicast_membership, | 332 sockets->udp->multicast_membership, |
98 error)) { | 333 error)) { |
99 return scoped_ptr<SocketsManifestData>(); | 334 return scoped_ptr<SocketsManifestData>(); |
100 } | 335 } |
101 } | 336 } |
102 if (sockets->tcp) { | 337 if (sockets->tcp) { |
338 result->kinds_ |= kTcpPermission; | |
103 if (!ParseHostPattern(result.get(), | 339 if (!ParseHostPattern(result.get(), |
104 content::SocketPermissionRequest::TCP_CONNECT, | 340 content::SocketPermissionRequest::TCP_CONNECT, |
105 sockets->tcp->connect, | 341 sockets->tcp->connect, |
106 error)) { | 342 error)) { |
107 return scoped_ptr<SocketsManifestData>(); | 343 return scoped_ptr<SocketsManifestData>(); |
108 } | 344 } |
109 } | 345 } |
110 if (sockets->tcp_server) { | 346 if (sockets->tcp_server) { |
347 result->kinds_ |= kTcpServerPermission; | |
111 if (!ParseHostPattern(result.get(), | 348 if (!ParseHostPattern(result.get(), |
112 content::SocketPermissionRequest::TCP_LISTEN, | 349 content::SocketPermissionRequest::TCP_LISTEN, |
113 sockets->tcp_server->listen, | 350 sockets->tcp_server->listen, |
114 error)) { | 351 error)) { |
115 return scoped_ptr<SocketsManifestData>(); | 352 return scoped_ptr<SocketsManifestData>(); |
116 } | 353 } |
117 } | 354 } |
118 return result.Pass(); | 355 return result.Pass(); |
119 } | 356 } |
120 | 357 |
(...skipping 16 matching lines...) Expand all Loading... | |
137 return true; | 374 return true; |
138 } | 375 } |
139 | 376 |
140 void SocketsManifestData::AddPermission(const SocketPermissionEntry& entry) { | 377 void SocketsManifestData::AddPermission(const SocketPermissionEntry& entry) { |
141 permissions_.insert(entry); | 378 permissions_.insert(entry); |
142 } | 379 } |
143 | 380 |
144 bool SocketsManifestData::CheckRequestImpl( | 381 bool SocketsManifestData::CheckRequestImpl( |
145 const Extension* extension, | 382 const Extension* extension, |
146 const content::SocketPermissionRequest& request) { | 383 const content::SocketPermissionRequest& request) { |
147 for (PermissionSet::const_iterator it = permissions_.begin(); | 384 for (SocketPermissionEntrySet::const_iterator it = permissions_.begin(); |
148 it != permissions_.end(); ++it) { | 385 it != permissions_.end(); ++it) { |
149 if (it->Check(request)) | 386 if (it->Check(request)) |
150 return true; | 387 return true; |
151 } | 388 } |
152 return false; | 389 return false; |
153 } | 390 } |
154 | 391 |
392 bool SocketsManifestData::HasMessages() const { | |
393 bool is_empty = permissions_.empty() && (kinds_ == kNone); | |
394 return !is_empty; | |
395 } | |
396 | |
397 PermissionMessages SocketsManifestData::GetPermissionMessages() const { | |
398 // TODO(rpaquay): This function and callees is (almost) a copy/paste | |
399 // from |extensions::SocketPermission|. | |
400 PermissionMessages result; | |
401 if (!AddAnyHostMessage(result)) { | |
402 AddSpecificHostMessage(result); | |
403 AddSubdomainHostMessage(result); | |
404 } | |
405 AddNetworkListMessage(result); | |
406 return result; | |
407 } | |
408 | |
409 SocketsManifestData* SocketsManifestData::Diff(const SocketsManifestData* rhs) | |
410 const { | |
411 scoped_ptr<SocketsManifestData> data(new SocketsManifestData()); | |
412 std::set_difference( | |
413 permissions_.begin(), permissions_.end(), | |
414 rhs->permissions_.begin(), rhs->permissions_.end(), | |
415 std::inserter<SocketPermissionEntrySet>( | |
416 data->permissions_, data->permissions_.begin())); | |
417 | |
418 data->kinds_ = (kinds_ & (~rhs->kinds_)); | |
419 return data.release(); | |
420 } | |
421 | |
422 SocketsManifestData* SocketsManifestData::Union(const SocketsManifestData* rhs) | |
423 const { | |
424 scoped_ptr<SocketsManifestData> data(new SocketsManifestData()); | |
425 std::set_union( | |
426 permissions_.begin(), permissions_.end(), | |
427 rhs->permissions_.begin(), rhs->permissions_.end(), | |
428 std::inserter<SocketPermissionEntrySet>( | |
429 data->permissions_, data->permissions_.begin())); | |
430 | |
431 data->kinds_ = (kinds_ | rhs->kinds_); | |
432 return data.release(); | |
433 } | |
434 | |
435 SocketsManifestData* SocketsManifestData::Intersect( | |
436 const SocketsManifestData* rhs) const { | |
437 scoped_ptr<SocketsManifestData> data(new SocketsManifestData()); | |
438 std::set_intersection( | |
439 permissions_.begin(), permissions_.end(), | |
440 rhs->permissions_.begin(), rhs->permissions_.end(), | |
441 std::inserter<SocketPermissionEntrySet>( | |
442 data->permissions_, data->permissions_.begin())); | |
443 | |
444 data->kinds_ = (kinds_ & rhs->kinds_); | |
445 return data.release(); | |
446 } | |
447 | |
448 bool SocketsManifestData::Contains(const SocketsManifestData* rhs) const { | |
449 return std::includes( | |
450 entries().begin(), entries().end(), | |
451 rhs->entries().begin(), rhs->entries().end()) && | |
452 ((kinds_ | rhs->kinds_) == kinds_); | |
453 } | |
454 | |
455 bool SocketsManifestData::Equal(const SocketsManifestData* rhs) const { | |
456 return (permissions_ == rhs->permissions_) && | |
457 (kinds_ == rhs->kinds_); | |
458 } | |
459 | |
460 SocketsManifestData* SocketsManifestData::Clone() const { | |
461 scoped_ptr<SocketsManifestData> result(new SocketsManifestData()); | |
462 result->permissions_ = permissions_; | |
463 result->kinds_ = kinds_; | |
464 return result.release(); | |
465 } | |
466 | |
467 void SocketsManifestData::Write(IPC::Message* m) const { | |
468 IPC::WriteParam(m, permissions_); | |
469 IPC::WriteParam(m, kinds_); | |
470 } | |
471 | |
472 bool SocketsManifestData::Read(const IPC::Message* m, PickleIterator* iter) { | |
473 return IPC::ReadParam(m, iter, &permissions_) && | |
474 IPC::ReadParam(m, iter, &kinds_); | |
475 } | |
476 | |
477 void SocketsManifestData::Log(std::string* log) const { | |
478 IPC::LogParam(permissions_, log); | |
479 IPC::LogParam(kinds_, log); | |
480 } | |
481 | |
482 bool SocketsManifestData::AddAnyHostMessage( | |
483 PermissionMessages& messages) const { | |
484 for (SocketPermissionEntrySet::const_iterator it = permissions_.begin(); | |
485 it != permissions_.end(); ++it) { | |
486 if (it->IsAddressBoundType() && | |
487 it->GetHostType() == SocketPermissionEntry::ANY_HOST) { | |
488 messages.push_back(PermissionMessage( | |
489 PermissionMessage::kSocketAnyHost, | |
490 l10n_util::GetStringUTF16( | |
491 IDS_EXTENSION_PROMPT_WARNING_SOCKET_ANY_HOST))); | |
492 return true; | |
493 } | |
494 } | |
495 return false; | |
496 } | |
497 | |
498 void SocketsManifestData::AddSubdomainHostMessage( | |
499 PermissionMessages& messages) const { | |
500 std::set<string16> domains; | |
501 for (SocketPermissionEntrySet::const_iterator it = permissions_.begin(); | |
502 it != permissions_.end(); ++it) { | |
503 if (it->GetHostType() == SocketPermissionEntry::HOSTS_IN_DOMAINS) | |
504 domains.insert(UTF8ToUTF16(it->pattern().host)); | |
505 } | |
506 if (!domains.empty()) { | |
507 int id = (domains.size() == 1) ? | |
508 IDS_EXTENSION_PROMPT_WARNING_SOCKET_HOSTS_IN_DOMAIN : | |
509 IDS_EXTENSION_PROMPT_WARNING_SOCKET_HOSTS_IN_DOMAINS; | |
510 messages.push_back(PermissionMessage( | |
511 PermissionMessage::kSocketDomainHosts, | |
512 l10n_util::GetStringFUTF16( | |
513 id, | |
514 JoinString( | |
515 std::vector<string16>( | |
516 domains.begin(), domains.end()), ' ')))); | |
517 } | |
518 } | |
519 | |
520 void SocketsManifestData::AddSpecificHostMessage( | |
521 PermissionMessages& messages) const { | |
522 std::set<string16> hostnames; | |
523 for (SocketPermissionEntrySet::const_iterator it = permissions_.begin(); | |
524 it != permissions_.end(); ++it) { | |
525 if (it->GetHostType() == SocketPermissionEntry::SPECIFIC_HOSTS) | |
526 hostnames.insert(UTF8ToUTF16(it->pattern().host)); | |
527 } | |
528 if (!hostnames.empty()) { | |
529 int id = (hostnames.size() == 1) ? | |
530 IDS_EXTENSION_PROMPT_WARNING_SOCKET_SPECIFIC_HOST : | |
531 IDS_EXTENSION_PROMPT_WARNING_SOCKET_SPECIFIC_HOSTS; | |
532 messages.push_back(PermissionMessage( | |
533 PermissionMessage::kSocketSpecificHosts, | |
534 l10n_util::GetStringFUTF16( | |
535 id, | |
536 JoinString( | |
537 std::vector<string16>( | |
538 hostnames.begin(), hostnames.end()), ' ')))); | |
539 } | |
540 } | |
541 | |
542 void SocketsManifestData::AddNetworkListMessage( | |
543 PermissionMessages& messages) const { | |
544 for (SocketPermissionEntrySet::const_iterator it = permissions_.begin(); | |
545 it != permissions_.end(); ++it) { | |
546 if (it->pattern().type == content::SocketPermissionRequest::NETWORK_STATE) { | |
547 messages.push_back(PermissionMessage( | |
548 PermissionMessage::kNetworkState, | |
549 l10n_util::GetStringUTF16( | |
550 IDS_EXTENSION_PROMPT_WARNING_NETWORK_STATE))); | |
551 } | |
552 } | |
553 } | |
554 | |
155 } // namespace extensions | 555 } // namespace extensions |
OLD | NEW |