1 // Copyright (c) 2013 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 "chrome/common/extensions/permissions/media_galleries_permission.h" 6 7 #include <set> 8 #include <string> 9 10 #include "base/logging.h" 11 #include "base/strings/utf_string_conversions.h" 12 #include "extensions/common/permissions/permissions_info.h" 13 #include "grit/generated_resources.h" 14 #include "ui/base/l10n/l10n_util.h" 15 16 namespace { 17 18 // copyTo permission requires delete permission as a prerequisite. 19 // delete permission requires read permission as a prerequisite. 20 bool IsValidPermissionSet(bool has_read, bool has_copy_to, bool has_delete) { 21 if (has_copy_to) 22 return has_read && has_delete; 23 if (has_delete) 24 return has_read; 25 return true; 26 } 27 28 } // namespace 29 30 namespace extensions { 31 32 const char MediaGalleriesPermission::kAllAutoDetectedPermission[] = 33 "allAutoDetected"; 34 const char MediaGalleriesPermission::kReadPermission[] = "read"; 35 const char MediaGalleriesPermission::kCopyToPermission[] = "copyTo"; 36 const char MediaGalleriesPermission::kDeletePermission[] = "delete"; 37 38 MediaGalleriesPermission::MediaGalleriesPermission( 39 const APIPermissionInfo* info) 40 : SetDisjunctionPermission<MediaGalleriesPermissionData, 41 MediaGalleriesPermission>(info) { 42 } 43 44 MediaGalleriesPermission::~MediaGalleriesPermission() { 45 } 46 47 bool MediaGalleriesPermission::FromValue(const base::Value* value) { 48 if (!SetDisjunctionPermission<MediaGalleriesPermissionData, 49 MediaGalleriesPermission>::FromValue(value)) { 50 return false; 51 } 52 53 bool has_read = false; 54 bool has_copy_to = false; 55 bool has_delete = false; 56 for (std::set<MediaGalleriesPermissionData>::const_iterator it = 57 data_set_.begin(); it != data_set_.end(); ++it) { 58 if (it->permission() == kAllAutoDetectedPermission) { 59 continue; 60 } 61 if (it->permission() == kReadPermission) { 62 has_read = true; 63 continue; 64 } 65 if (it->permission() == kCopyToPermission) { 66 has_copy_to = true; 67 continue; 68 } 69 if (it->permission() == kDeletePermission) { 70 has_delete = true; 71 continue; 72 } 73 74 // No other permissions, so reaching this means 75 // MediaGalleriesPermissionData is probably out of sync in some way. 76 // Fail so developers notice this. 77 NOTREACHED(); 78 return false; 79 } 80 81 return IsValidPermissionSet(has_read, has_copy_to, has_delete); 82 } 83 84 PermissionMessages MediaGalleriesPermission::GetMessages() const { 85 DCHECK(HasMessages()); 86 PermissionMessages result; 87 88 bool has_all_auto_detected = false; 89 bool has_read = false; 90 bool has_copy_to = false; 91 bool has_delete = false; 92 93 for (std::set<MediaGalleriesPermissionData>::const_iterator it = 94 data_set_.begin(); it != data_set_.end(); ++it) { 95 if (it->permission() == kAllAutoDetectedPermission) 96 has_all_auto_detected = true; 97 else if (it->permission() == kReadPermission) 98 has_read = true; 99 else if (it->permission() == kCopyToPermission) 100 has_copy_to = true; 101 else if (it->permission() == kDeletePermission) 102 has_delete = true; 103 } 104 105 if (!IsValidPermissionSet(has_read, has_copy_to, has_delete)) { 106 NOTREACHED(); 107 return result; 108 } 109 110 // If |has_all_auto_detected| is false, then Chrome will prompt the user at 111 // runtime when the extension call the getMediaGalleries API. 112 if (!has_all_auto_detected) 113 return result; 114 // No access permission case. 115 if (!has_read) 116 return result; 117 118 // Separate PermissionMessage IDs for read, copyTo, and delete. Otherwise an 119 // extension can silently gain new access capabilities. 120 result.push_back(PermissionMessage( 121 PermissionMessage::kMediaGalleriesAllGalleriesRead, 122 l10n_util::GetStringUTF16( 123 IDS_EXTENSION_PROMPT_WARNING_MEDIA_GALLERIES_READ))); 124 125 // For copyTo and delete, the proper combined permission message will be 126 // derived in ChromePermissionMessageProvider::GetWarningMessages(), such 127 // that the user get 1 entry for all media galleries access permissions, 128 // rather than several separate entries. 129 if (has_copy_to) { 130 result.push_back(PermissionMessage( 131 PermissionMessage::kMediaGalleriesAllGalleriesCopyTo, 132 base::string16())); 133 } 134 if (has_delete) { 135 result.push_back(PermissionMessage( 136 PermissionMessage::kMediaGalleriesAllGalleriesDelete, 137 base::string16())); 138 } 139 return result; 140 } 141 142 } // namespace extensions 143