| 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/permissions/chrome_permission_message_provide
r.h" | 5 #include "chrome/common/extensions/permissions/chrome_permission_message_provide
r.h" |
| 6 | 6 |
| 7 #include "base/memory/scoped_vector.h" | 7 #include "base/memory/scoped_vector.h" |
| 8 #include "base/metrics/field_trial.h" | 8 #include "base/metrics/field_trial.h" |
| 9 #include "base/stl_util.h" | 9 #include "base/stl_util.h" |
| 10 #include "base/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| 11 #include "base/strings/stringprintf.h" | 11 #include "base/strings/stringprintf.h" |
| 12 #include "chrome/common/extensions/permissions/chrome_permission_message_rules.h
" | 12 #include "chrome/common/extensions/permissions/chrome_permission_message_rules.h
" |
| 13 #include "chrome/grit/generated_resources.h" | 13 #include "chrome/grit/generated_resources.h" |
| 14 #include "extensions/common/extensions_client.h" | 14 #include "extensions/common/extensions_client.h" |
| 15 #include "extensions/common/permissions/permission_message.h" | 15 #include "extensions/common/permissions/permission_message.h" |
| 16 #include "extensions/common/permissions/permission_message_util.h" | 16 #include "extensions/common/permissions/permission_message_util.h" |
| 17 #include "extensions/common/permissions/permission_set.h" | 17 #include "extensions/common/permissions/permission_set.h" |
| 18 #include "extensions/common/url_pattern.h" | 18 #include "extensions/common/url_pattern.h" |
| 19 #include "extensions/common/url_pattern_set.h" | 19 #include "extensions/common/url_pattern_set.h" |
| 20 #include "grit/extensions_strings.h" | 20 #include "grit/extensions_strings.h" |
| 21 #include "ui/base/l10n/l10n_util.h" | 21 #include "ui/base/l10n/l10n_util.h" |
| 22 #include "url/gurl.h" | 22 #include "url/gurl.h" |
| 23 | 23 |
| 24 namespace extensions { | 24 namespace extensions { |
| 25 | 25 |
| 26 namespace { | 26 namespace { |
| 27 | 27 |
| 28 bool IsNewPermissionMessageSystemEnabled() { | |
| 29 const std::string group_name = | |
| 30 base::FieldTrialList::FindFullName("PermissionMessageSystem"); | |
| 31 return group_name == "NewSystem"; | |
| 32 } | |
| 33 | |
| 34 typedef std::set<PermissionMessage> PermissionMsgSet; | 28 typedef std::set<PermissionMessage> PermissionMsgSet; |
| 35 | 29 |
| 36 template<typename T> | 30 template<typename T> |
| 37 typename T::iterator FindMessageByID(T& messages, int id) { | 31 typename T::iterator FindMessageByID(T& messages, int id) { |
| 38 for (typename T::iterator it = messages.begin(); | 32 for (typename T::iterator it = messages.begin(); |
| 39 it != messages.end(); ++it) { | 33 it != messages.end(); ++it) { |
| 40 if (it->id() == id) | 34 if (it->id() == id) |
| 41 return it; | 35 return it; |
| 42 } | 36 } |
| 43 return messages.end(); | 37 return messages.end(); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 81 } | 75 } |
| 82 | 76 |
| 83 } // namespace | 77 } // namespace |
| 84 | 78 |
| 85 ChromePermissionMessageProvider::ChromePermissionMessageProvider() { | 79 ChromePermissionMessageProvider::ChromePermissionMessageProvider() { |
| 86 } | 80 } |
| 87 | 81 |
| 88 ChromePermissionMessageProvider::~ChromePermissionMessageProvider() { | 82 ChromePermissionMessageProvider::~ChromePermissionMessageProvider() { |
| 89 } | 83 } |
| 90 | 84 |
| 91 PermissionMessages ChromePermissionMessageProvider::GetPermissionMessages( | 85 PermissionMessages ChromePermissionMessageProvider::GetLegacyPermissionMessages( |
| 92 const PermissionSet* permissions, | 86 const PermissionSet* permissions, |
| 93 Manifest::Type extension_type) const { | 87 Manifest::Type extension_type) const { |
| 94 PermissionMessages messages; | 88 PermissionMessages messages; |
| 95 // TODO(sashab): Check if this the correct logic - if an app has effective | 89 // TODO(sashab): Check if this the correct logic - if an app has effective |
| 96 // full access (i.e. the plugin permission), do we not want to display *any* | 90 // full access (i.e. the plugin permission), do we not want to display *any* |
| 97 // other permission messages? | 91 // other permission messages? |
| 98 if (permissions->HasEffectiveFullAccess()) { | 92 if (permissions->HasEffectiveFullAccess()) { |
| 99 messages.push_back(PermissionMessage( | 93 messages.push_back(PermissionMessage( |
| 100 PermissionMessage::kFullAccess, | 94 PermissionMessage::kFullAccess, |
| 101 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_FULL_ACCESS))); | 95 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_FULL_ACCESS))); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 kSuppressList.insert( | 130 kSuppressList.insert( |
| 137 {PermissionMessage::kHostsAll, PermissionMessage::kTabs}); | 131 {PermissionMessage::kHostsAll, PermissionMessage::kTabs}); |
| 138 // Tabs already allows reading favicons. | 132 // Tabs already allows reading favicons. |
| 139 kSuppressList.insert({PermissionMessage::kTabs, PermissionMessage::kFavicon}); | 133 kSuppressList.insert({PermissionMessage::kTabs, PermissionMessage::kFavicon}); |
| 140 // Tabs already allows reading the list of most frequently visited sites. | 134 // Tabs already allows reading the list of most frequently visited sites. |
| 141 kSuppressList.insert( | 135 kSuppressList.insert( |
| 142 {PermissionMessage::kTabs, PermissionMessage::kTopSites}); | 136 {PermissionMessage::kTabs, PermissionMessage::kTopSites}); |
| 143 | 137 |
| 144 PermissionMsgSet host_msgs = | 138 PermissionMsgSet host_msgs = |
| 145 GetHostPermissionMessages(permissions, NULL, extension_type); | 139 GetHostPermissionMessages(permissions, NULL, extension_type); |
| 146 PermissionMsgSet api_msgs = GetAPIPermissionMessages(permissions, NULL); | 140 PermissionMsgSet api_msgs = |
| 141 GetAPIPermissionMessages(permissions, NULL, extension_type); |
| 147 PermissionMsgSet manifest_permission_msgs = | 142 PermissionMsgSet manifest_permission_msgs = |
| 148 GetManifestPermissionMessages(permissions, NULL); | 143 GetManifestPermissionMessages(permissions, NULL); |
| 149 messages.insert(messages.end(), host_msgs.begin(), host_msgs.end()); | 144 messages.insert(messages.end(), host_msgs.begin(), host_msgs.end()); |
| 150 messages.insert(messages.end(), api_msgs.begin(), api_msgs.end()); | 145 messages.insert(messages.end(), api_msgs.begin(), api_msgs.end()); |
| 151 messages.insert(messages.end(), manifest_permission_msgs.begin(), | 146 messages.insert(messages.end(), manifest_permission_msgs.begin(), |
| 152 manifest_permission_msgs.end()); | 147 manifest_permission_msgs.end()); |
| 153 | 148 |
| 154 for (std::multimap<PermissionMessage::ID, | 149 for (std::multimap<PermissionMessage::ID, |
| 155 PermissionMessage::ID>::const_iterator it = | 150 PermissionMessage::ID>::const_iterator it = |
| 156 kSuppressList.begin(); | 151 kSuppressList.begin(); |
| 157 it != kSuppressList.end(); | 152 it != kSuppressList.end(); |
| 158 ++it) { | 153 ++it) { |
| 159 SuppressMessage(messages, it->first, it->second); | 154 SuppressMessage(messages, it->first, it->second); |
| 160 } | 155 } |
| 161 | 156 |
| 162 return messages; | 157 return messages; |
| 163 } | 158 } |
| 164 | 159 |
| 165 PermissionMessageStrings | |
| 166 ChromePermissionMessageProvider::GetPermissionMessageStrings( | |
| 167 const PermissionSet* permissions, | |
| 168 Manifest::Type extension_type) const { | |
| 169 PermissionMessageStrings strings; | |
| 170 if (IsNewPermissionMessageSystemEnabled()) { | |
| 171 CoalescedPermissionMessages messages = GetCoalescedPermissionMessages( | |
| 172 GetAllPermissionIDs(permissions, extension_type)); | |
| 173 for (const CoalescedPermissionMessage& msg : messages) | |
| 174 strings.push_back(PermissionMessageString(msg)); | |
| 175 } else { | |
| 176 std::vector<base::string16> messages = | |
| 177 GetLegacyWarningMessages(permissions, extension_type); | |
| 178 std::vector<base::string16> details = | |
| 179 GetLegacyWarningMessagesDetails(permissions, extension_type); | |
| 180 DCHECK_EQ(messages.size(), details.size()); | |
| 181 for (size_t i = 0; i < messages.size(); i++) | |
| 182 strings.push_back(PermissionMessageString(messages[i], details[i])); | |
| 183 } | |
| 184 return strings; | |
| 185 } | |
| 186 | |
| 187 PermissionMessageIDs | 160 PermissionMessageIDs |
| 188 ChromePermissionMessageProvider::GetLegacyPermissionMessageIDs( | 161 ChromePermissionMessageProvider::GetLegacyPermissionMessageIDs( |
| 189 const PermissionSet* permissions, | 162 const PermissionSet* permissions, |
| 190 Manifest::Type extension_type) const { | 163 Manifest::Type extension_type) const { |
| 191 PermissionMessageIDs ids; | 164 PermissionMessageIDs ids; |
| 192 for (const PermissionMessage& msg : | 165 for (const PermissionMessage& msg : |
| 193 GetPermissionMessages(permissions, extension_type)) { | 166 GetLegacyPermissionMessages(permissions, extension_type)) { |
| 194 ids.push_back(msg.id()); | 167 ids.push_back(msg.id()); |
| 195 } | 168 } |
| 196 return ids; | 169 return ids; |
| 197 } | 170 } |
| 198 | 171 |
| 199 CoalescedPermissionMessages | 172 CoalescedPermissionMessages |
| 200 ChromePermissionMessageProvider::GetCoalescedPermissionMessages( | 173 ChromePermissionMessageProvider::GetCoalescedPermissionMessages( |
| 201 const PermissionIDSet& permissions) const { | 174 const PermissionIDSet& permissions) const { |
| 202 std::vector<ChromePermissionMessageRule> rules = | 175 std::vector<ChromePermissionMessageRule> rules = |
| 203 ChromePermissionMessageRule::GetAllRules(); | 176 ChromePermissionMessageRule::GetAllRules(); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 if (old_permissions->HasEffectiveFullAccess()) | 233 if (old_permissions->HasEffectiveFullAccess()) |
| 261 return false; | 234 return false; |
| 262 | 235 |
| 263 // Otherwise, it's a privilege increase if the new one has full access. | 236 // Otherwise, it's a privilege increase if the new one has full access. |
| 264 if (new_permissions->HasEffectiveFullAccess()) | 237 if (new_permissions->HasEffectiveFullAccess()) |
| 265 return true; | 238 return true; |
| 266 | 239 |
| 267 if (IsHostPrivilegeIncrease(old_permissions, new_permissions, extension_type)) | 240 if (IsHostPrivilegeIncrease(old_permissions, new_permissions, extension_type)) |
| 268 return true; | 241 return true; |
| 269 | 242 |
| 270 if (IsAPIPrivilegeIncrease(old_permissions, new_permissions)) | 243 if (IsAPIPrivilegeIncrease(old_permissions, new_permissions, extension_type)) |
| 271 return true; | 244 return true; |
| 272 | 245 |
| 273 if (IsManifestPermissionPrivilegeIncrease(old_permissions, new_permissions)) | 246 if (IsManifestPermissionPrivilegeIncrease(old_permissions, new_permissions)) |
| 274 return true; | 247 return true; |
| 275 | 248 |
| 276 return false; | 249 return false; |
| 277 } | 250 } |
| 278 | 251 |
| 279 PermissionIDSet ChromePermissionMessageProvider::GetAllPermissionIDs( | 252 PermissionIDSet ChromePermissionMessageProvider::GetAllPermissionIDs( |
| 280 const PermissionSet* permissions, | 253 const PermissionSet* permissions, |
| 281 Manifest::Type extension_type) const { | 254 Manifest::Type extension_type) const { |
| 282 PermissionIDSet permission_ids; | 255 PermissionIDSet permission_ids; |
| 283 GetAPIPermissionMessages(permissions, &permission_ids); | 256 GetAPIPermissionMessages(permissions, &permission_ids, extension_type); |
| 284 GetManifestPermissionMessages(permissions, &permission_ids); | 257 GetManifestPermissionMessages(permissions, &permission_ids); |
| 285 GetHostPermissionMessages(permissions, &permission_ids, extension_type); | 258 GetHostPermissionMessages(permissions, &permission_ids, extension_type); |
| 286 return permission_ids; | 259 return permission_ids; |
| 287 } | 260 } |
| 288 | 261 |
| 289 std::set<PermissionMessage> | 262 std::set<PermissionMessage> |
| 290 ChromePermissionMessageProvider::GetAPIPermissionMessages( | 263 ChromePermissionMessageProvider::GetAPIPermissionMessages( |
| 291 const PermissionSet* permissions, | 264 const PermissionSet* permissions, |
| 292 PermissionIDSet* permission_ids) const { | 265 PermissionIDSet* permission_ids, |
| 266 Manifest::Type extension_type) const { |
| 293 PermissionMsgSet messages; | 267 PermissionMsgSet messages; |
| 294 for (APIPermissionSet::const_iterator permission_it = | 268 for (APIPermissionSet::const_iterator permission_it = |
| 295 permissions->apis().begin(); | 269 permissions->apis().begin(); |
| 296 permission_it != permissions->apis().end(); ++permission_it) { | 270 permission_it != permissions->apis().end(); ++permission_it) { |
| 297 if (permission_ids != NULL) | 271 if (permission_ids != NULL) |
| 298 permission_ids->InsertAll(permission_it->GetPermissions()); | 272 permission_ids->InsertAll(permission_it->GetPermissions()); |
| 299 if (permission_it->HasMessages()) { | 273 if (permission_it->HasMessages()) { |
| 300 PermissionMessages new_messages = permission_it->GetMessages(); | 274 PermissionMessages new_messages = permission_it->GetMessages(); |
| 301 messages.insert(new_messages.begin(), new_messages.end()); | 275 messages.insert(new_messages.begin(), new_messages.end()); |
| 302 } | 276 } |
| 303 } | 277 } |
| 304 | 278 |
| 305 // A special hack: The warning message for declarativeWebRequest | 279 // A special hack: The warning message for declarativeWebRequest |
| 306 // permissions speaks about blocking parts of pages, which is a | 280 // permissions speaks about blocking parts of pages, which is a |
| 307 // subset of what the "<all_urls>" access allows. Therefore we | 281 // subset of what the "<all_urls>" access allows. Therefore we |
| 308 // display only the "<all_urls>" warning message if both permissions | 282 // display only the "<all_urls>" warning message if both permissions |
| 309 // are required. | 283 // are required. |
| 310 if (permissions->ShouldWarnAllHosts()) { | 284 if (permissions->ShouldWarnAllHosts()) { |
| 311 if (permission_ids != NULL) | 285 // Platform apps don't show hosts warnings. See crbug.com/255229. |
| 286 if (permission_ids != NULL && extension_type != Manifest::TYPE_PLATFORM_APP) |
| 312 permission_ids->insert(APIPermission::kHostsAll); | 287 permission_ids->insert(APIPermission::kHostsAll); |
| 313 messages.erase( | 288 messages.erase( |
| 314 PermissionMessage( | 289 PermissionMessage( |
| 315 PermissionMessage::kDeclarativeWebRequest, base::string16())); | 290 PermissionMessage::kDeclarativeWebRequest, base::string16())); |
| 316 } | 291 } |
| 317 return messages; | 292 return messages; |
| 318 } | 293 } |
| 319 | 294 |
| 320 std::set<PermissionMessage> | 295 std::set<PermissionMessage> |
| 321 ChromePermissionMessageProvider::GetManifestPermissionMessages( | 296 ChromePermissionMessageProvider::GetManifestPermissionMessages( |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 377 } | 352 } |
| 378 return messages; | 353 return messages; |
| 379 } | 354 } |
| 380 | 355 |
| 381 void ChromePermissionMessageProvider::CoalesceWarningMessages( | 356 void ChromePermissionMessageProvider::CoalesceWarningMessages( |
| 382 const PermissionSet* permissions, | 357 const PermissionSet* permissions, |
| 383 Manifest::Type extension_type, | 358 Manifest::Type extension_type, |
| 384 std::vector<base::string16>* message_strings, | 359 std::vector<base::string16>* message_strings, |
| 385 std::vector<base::string16>* message_details_strings) const { | 360 std::vector<base::string16>* message_details_strings) const { |
| 386 PermissionMessages messages = | 361 PermissionMessages messages = |
| 387 GetPermissionMessages(permissions, extension_type); | 362 GetLegacyPermissionMessages(permissions, extension_type); |
| 388 | 363 |
| 389 // WARNING: When modifying a coalescing rule in this list, be sure to also | 364 // WARNING: When modifying a coalescing rule in this list, be sure to also |
| 390 // modify the corresponding rule in | 365 // modify the corresponding rule in |
| 391 // ChromePermissionMessageProvider::GetCoalescedPermissionMessages(). | 366 // ChromePermissionMessageProvider::GetCoalescedPermissionMessages(). |
| 392 // TODO(sashab): Deprecate this function, and remove this list. | 367 // TODO(sashab): Deprecate this function, and remove this list. |
| 393 for (PermissionMessages::const_iterator i = messages.begin(); | 368 for (PermissionMessages::const_iterator i = messages.begin(); |
| 394 i != messages.end(); ++i) { | 369 i != messages.end(); ++i) { |
| 395 int id = i->id(); | 370 int id = i->id(); |
| 396 // Access to users' devices should provide a single warning message | 371 // Access to users' devices should provide a single warning message |
| 397 // specifying the transport method used; serial and/or Bluetooth. | 372 // specifying the transport method used; serial and/or Bluetooth. |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 487 continue; | 462 continue; |
| 488 } | 463 } |
| 489 | 464 |
| 490 message_strings->push_back(i->message()); | 465 message_strings->push_back(i->message()); |
| 491 message_details_strings->push_back(i->details()); | 466 message_details_strings->push_back(i->details()); |
| 492 } | 467 } |
| 493 } | 468 } |
| 494 | 469 |
| 495 bool ChromePermissionMessageProvider::IsAPIPrivilegeIncrease( | 470 bool ChromePermissionMessageProvider::IsAPIPrivilegeIncrease( |
| 496 const PermissionSet* old_permissions, | 471 const PermissionSet* old_permissions, |
| 497 const PermissionSet* new_permissions) const { | 472 const PermissionSet* new_permissions, |
| 473 Manifest::Type extension_type) const { |
| 498 if (new_permissions == NULL) | 474 if (new_permissions == NULL) |
| 499 return false; | 475 return false; |
| 500 | 476 |
| 501 PermissionMsgSet old_warnings = | 477 PermissionMsgSet old_warnings = |
| 502 GetAPIPermissionMessages(old_permissions, NULL); | 478 GetAPIPermissionMessages(old_permissions, NULL, extension_type); |
| 503 PermissionMsgSet new_warnings = | 479 PermissionMsgSet new_warnings = |
| 504 GetAPIPermissionMessages(new_permissions, NULL); | 480 GetAPIPermissionMessages(new_permissions, NULL, extension_type); |
| 505 PermissionMsgSet delta_warnings = | 481 PermissionMsgSet delta_warnings = |
| 506 base::STLSetDifference<PermissionMsgSet>(new_warnings, old_warnings); | 482 base::STLSetDifference<PermissionMsgSet>(new_warnings, old_warnings); |
| 507 | 483 |
| 508 // A special hack: kFileSystemWriteDirectory implies kFileSystemDirectory. | 484 // A special hack: kFileSystemWriteDirectory implies kFileSystemDirectory. |
| 509 // TODO(sammc): Remove this. See http://crbug.com/284849. | 485 // TODO(sammc): Remove this. See http://crbug.com/284849. |
| 510 if (old_warnings.find(PermissionMessage( | 486 if (old_warnings.find(PermissionMessage( |
| 511 PermissionMessage::kFileSystemWriteDirectory, base::string16())) != | 487 PermissionMessage::kFileSystemWriteDirectory, base::string16())) != |
| 512 old_warnings.end()) { | 488 old_warnings.end()) { |
| 513 delta_warnings.erase( | 489 delta_warnings.erase( |
| 514 PermissionMessage(PermissionMessage::kFileSystemDirectory, | 490 PermissionMessage(PermissionMessage::kFileSystemDirectory, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 565 std::set<std::string> old_hosts_set( | 541 std::set<std::string> old_hosts_set( |
| 566 permission_message_util::GetDistinctHosts(old_list, false, false)); | 542 permission_message_util::GetDistinctHosts(old_list, false, false)); |
| 567 std::set<std::string> new_hosts_only = | 543 std::set<std::string> new_hosts_only = |
| 568 base::STLSetDifference<std::set<std::string> >(new_hosts_set, | 544 base::STLSetDifference<std::set<std::string> >(new_hosts_set, |
| 569 old_hosts_set); | 545 old_hosts_set); |
| 570 | 546 |
| 571 return !new_hosts_only.empty(); | 547 return !new_hosts_only.empty(); |
| 572 } | 548 } |
| 573 | 549 |
| 574 } // namespace extensions | 550 } // namespace extensions |
| OLD | NEW |