Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / extensions / common / permissions / media_galleries_permission.cc
blob1b3b9198f60c109724a829c72f67c80348f460e5
1 // Copyright 2014 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.
5 #include "extensions/common/permissions/media_galleries_permission.h"
7 #include <set>
8 #include <string>
10 #include "base/logging.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "extensions/common/permissions/permissions_info.h"
13 #include "grit/extensions_strings.h"
14 #include "ui/base/l10n/l10n_util.h"
16 namespace extensions {
18 namespace {
20 // copyTo permission requires delete permission as a prerequisite.
21 // delete permission requires read permission as a prerequisite.
22 bool IsValidPermissionSet(bool has_read, bool has_copy_to, bool has_delete,
23 std::string* error) {
24 if (has_copy_to) {
25 if (has_read && has_delete)
26 return true;
27 if (error)
28 *error = "copyTo permission requires read and delete permissions";
29 return false;
31 if (has_delete) {
32 if (has_read)
33 return true;
34 if (error)
35 *error = "delete permission requires read permission";
36 return false;
38 return true;
41 // Adds the permissions from the |data_set| to |ids|.
42 void AddPermissionsToLists(
43 const std::set<MediaGalleriesPermissionData>& data_set,
44 PermissionIDSet* ids) {
45 // TODO(sashab): Once GetMessages() is deprecated, move this logic back into
46 // GetPermissions().
47 bool has_all_auto_detected = false;
48 bool has_read = false;
49 bool has_copy_to = false;
50 bool has_delete = false;
52 for (std::set<MediaGalleriesPermissionData>::const_iterator it =
53 data_set.begin();
54 it != data_set.end(); ++it) {
55 if (it->permission() ==
56 MediaGalleriesPermission::kAllAutoDetectedPermission)
57 has_all_auto_detected = true;
58 else if (it->permission() == MediaGalleriesPermission::kReadPermission)
59 has_read = true;
60 else if (it->permission() == MediaGalleriesPermission::kCopyToPermission)
61 has_copy_to = true;
62 else if (it->permission() == MediaGalleriesPermission::kDeletePermission)
63 has_delete = true;
66 if (!IsValidPermissionSet(has_read, has_copy_to, has_delete, NULL)) {
67 NOTREACHED();
68 return;
71 // If |has_all_auto_detected| is false, then Chrome will prompt the user at
72 // runtime when the extension call the getMediaGalleries API.
73 if (!has_all_auto_detected)
74 return;
75 // No access permission case.
76 if (!has_read)
77 return;
79 // Separate PermissionMessage IDs for read, copyTo, and delete. Otherwise an
80 // extension can silently gain new access capabilities.
81 ids->insert(APIPermission::kMediaGalleriesAllGalleriesRead);
83 // For copyTo and delete, the proper combined permission message will be
84 // derived in ChromePermissionMessageProvider::GetWarningMessages(), such
85 // that the user get 1 entry for all media galleries access permissions,
86 // rather than several separate entries.
87 if (has_copy_to)
88 ids->insert(APIPermission::kMediaGalleriesAllGalleriesCopyTo);
89 if (has_delete)
90 ids->insert(APIPermission::kMediaGalleriesAllGalleriesDelete);
93 } // namespace
95 const char MediaGalleriesPermission::kAllAutoDetectedPermission[] =
96 "allAutoDetected";
97 const char MediaGalleriesPermission::kScanPermission[] = "scan";
98 const char MediaGalleriesPermission::kReadPermission[] = "read";
99 const char MediaGalleriesPermission::kCopyToPermission[] = "copyTo";
100 const char MediaGalleriesPermission::kDeletePermission[] = "delete";
102 MediaGalleriesPermission::MediaGalleriesPermission(
103 const APIPermissionInfo* info)
104 : SetDisjunctionPermission<MediaGalleriesPermissionData,
105 MediaGalleriesPermission>(info) {
108 MediaGalleriesPermission::~MediaGalleriesPermission() {
111 bool MediaGalleriesPermission::FromValue(
112 const base::Value* value,
113 std::string* error,
114 std::vector<std::string>* unhandled_permissions) {
115 size_t unhandled_permissions_count = 0;
116 if (unhandled_permissions)
117 unhandled_permissions_count = unhandled_permissions->size();
118 bool parsed_ok =
119 SetDisjunctionPermission<MediaGalleriesPermissionData,
120 MediaGalleriesPermission>::FromValue(
121 value, error, unhandled_permissions);
122 if (unhandled_permissions) {
123 for (size_t i = unhandled_permissions_count;
124 i < unhandled_permissions->size();
125 i++) {
126 (*unhandled_permissions)[i] =
127 "{\"mediaGalleries\": [" + (*unhandled_permissions)[i] + "]}";
130 if (!parsed_ok)
131 return false;
133 bool has_read = false;
134 bool has_copy_to = false;
135 bool has_delete = false;
136 for (std::set<MediaGalleriesPermissionData>::const_iterator it =
137 data_set_.begin(); it != data_set_.end(); ++it) {
138 if (it->permission() == kAllAutoDetectedPermission ||
139 it->permission() == kScanPermission) {
140 continue;
142 if (it->permission() == kReadPermission) {
143 has_read = true;
144 continue;
146 if (it->permission() == kCopyToPermission) {
147 has_copy_to = true;
148 continue;
150 if (it->permission() == kDeletePermission) {
151 has_delete = true;
152 continue;
155 // No other permissions, so reaching this means
156 // MediaGalleriesPermissionData is probably out of sync in some way.
157 // Fail so developers notice this.
158 NOTREACHED();
159 return false;
162 return IsValidPermissionSet(has_read, has_copy_to, has_delete, error);
165 PermissionIDSet MediaGalleriesPermission::GetPermissions() const {
166 PermissionIDSet result;
167 AddPermissionsToLists(data_set_, &result);
168 return result;
171 } // namespace extensions