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

Side by Side Diff: chrome/common/extensions/permissions/chrome_permission_message_provider.cc

Issue 27446002: Move permission warning message handling from PermissionSet to PermissionMessageProvider. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 2 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/common/extensions/permissions/chrome_permission_message_provide r.h"
6
7 #include "base/stl_util.h"
8 #include "chrome/common/extensions/permissions/permission_message_util.h"
9 #include "chrome/common/extensions/permissions/permission_set.h"
10 #include "extensions/common/extensions_client.h"
11 #include "extensions/common/permissions/permission_message.h"
12 #include "extensions/common/url_pattern_set.h"
13 #include "grit/generated_resources.h"
14 #include "ui/base/l10n/l10n_util.h"
15
16 namespace extensions {
17
18 ChromePermissionMessageProvider::ChromePermissionMessageProvider() {
19 }
20
21 ChromePermissionMessageProvider::~ChromePermissionMessageProvider() {
22 }
23
24 // static
25 PermissionMessages ChromePermissionMessageProvider::GetPermissionMessages(
26 const PermissionSet* permissions,
27 Manifest::Type extension_type) const {
28 PermissionMessages messages;
29
30 if (permissions->HasEffectiveFullAccess()) {
31 messages.push_back(PermissionMessage(
32 PermissionMessage::kFullAccess,
33 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_FULL_ACCESS)));
34 return messages;
35 }
36
37 std::set<PermissionMessage> host_msgs =
38 GetHostPermissionMessages(permissions, extension_type);
39 std::set<PermissionMessage> api_msgs = GetAPIPermissionMessages(permissions);
40 messages.insert(messages.end(), host_msgs.begin(), host_msgs.end());
41 messages.insert(messages.end(), api_msgs.begin(), api_msgs.end());
42
43 return messages;
44 }
45
46 // static
47 std::vector<string16> ChromePermissionMessageProvider::GetWarningMessages(
48 const PermissionSet* permissions,
49 Manifest::Type extension_type) const {
50 std::vector<string16> message_strings;
51 PermissionMessages messages =
52 GetPermissionMessages(permissions, extension_type);
53
54 bool audio_capture = false;
55 bool video_capture = false;
56 for (PermissionMessages::const_iterator i = messages.begin();
57 i != messages.end(); ++i) {
58 switch (i->id()) {
59 case PermissionMessage::kAudioCapture:
60 audio_capture = true;
61 break;
62 case PermissionMessage::kVideoCapture:
63 video_capture = true;
64 break;
65 default:
66 break;
67 }
68 }
69
70 for (PermissionMessages::const_iterator i = messages.begin();
71 i != messages.end(); ++i) {
72 int id = i->id();
73 if (audio_capture && video_capture) {
74 if (id == PermissionMessage::kAudioCapture) {
75 message_strings.push_back(l10n_util::GetStringUTF16(
76 IDS_EXTENSION_PROMPT_WARNING_AUDIO_AND_VIDEO_CAPTURE));
77 continue;
78 } else if (id == PermissionMessage::kVideoCapture) {
79 // The combined message will be pushed above.
80 continue;
81 }
82 }
83
84 message_strings.push_back(i->message());
85 }
86
87 return message_strings;
88 }
89
90 // static
91 std::vector<string16>
92 ChromePermissionMessageProvider::GetWarningMessagesDetails(
93 const PermissionSet* permissions,
94 Manifest::Type extension_type) const {
95 std::vector<string16> message_strings;
96 PermissionMessages messages =
97 GetPermissionMessages(permissions, extension_type);
98
99 for (PermissionMessages::const_iterator i = messages.begin();
100 i != messages.end(); ++i)
101 message_strings.push_back(i->details());
102
103 return message_strings;
104 }
105
106 // static
107 bool ChromePermissionMessageProvider::IsPrivilegeIncrease(
108 const PermissionSet* old_permissions,
109 const PermissionSet* new_permissions,
110 Manifest::Type extension_type) const {
111 // Things can't get worse than native code access.
112 if (old_permissions->HasEffectiveFullAccess())
113 return false;
114
115 // Otherwise, it's a privilege increase if the new one has full access.
116 if (new_permissions->HasEffectiveFullAccess())
117 return true;
118
119 if (IsHostPrivilegeIncrease(old_permissions, new_permissions, extension_type))
120 return true;
121
122 if (IsAPIPrivilegeIncrease(old_permissions, new_permissions))
123 return true;
124
125 return false;
126 }
127
128 std::set<PermissionMessage>
129 ChromePermissionMessageProvider::GetAPIPermissionMessages(
130 const PermissionSet* permissions) const {
131 std::set<PermissionMessage> messages;
132 for (APIPermissionSet::const_iterator permission_it =
133 permissions->apis().begin();
134 permission_it != permissions->apis().end(); ++permission_it) {
135 if (permission_it->HasMessages()) {
136 PermissionMessages new_messages = permission_it->GetMessages();
137 messages.insert(new_messages.begin(), new_messages.end());
138 }
139 }
140
141 // A special hack: If kFileSystemWriteDirectory would be displayed, hide
142 // kFileSystemDirectory and and kFileSystemWrite as the write directory
143 // message implies the other two.
144 // TODO(sammc): Remove this. See http://crbug.com/284849.
145 std::set<PermissionMessage>::iterator write_directory_message =
146 messages.find(PermissionMessage(
147 PermissionMessage::kFileSystemWriteDirectory, string16()));
148 if (write_directory_message != messages.end()) {
149 messages.erase(
150 PermissionMessage(PermissionMessage::kFileSystemWrite, string16()));
151 messages.erase(
152 PermissionMessage(PermissionMessage::kFileSystemDirectory, string16()));
153 }
154
155 // A special hack: The warning message for declarativeWebRequest
156 // permissions speaks about blocking parts of pages, which is a
157 // subset of what the "<all_urls>" access allows. Therefore we
158 // display only the "<all_urls>" warning message if both permissions
159 // are required.
160 if (permissions->HasEffectiveAccessToAllHosts()) {
161 messages.erase(
162 PermissionMessage(
163 PermissionMessage::kDeclarativeWebRequest, string16()));
164 }
165
166 return messages;
167 }
168
169 std::set<PermissionMessage>
170 ChromePermissionMessageProvider::GetHostPermissionMessages(
171 const PermissionSet* permissions,
172 Manifest::Type extension_type) const {
173 std::set<PermissionMessage> messages;
174 // Since platform apps always use isolated storage, they can't (silently)
175 // access user data on other domains, so there's no need to prompt.
176 // Note: this must remain consistent with IsHostPrivilegeIncrease.
177 // See crbug.com/255229.
178 if (extension_type == Manifest::TYPE_PLATFORM_APP)
179 return messages;
180
181 if (permissions->HasEffectiveAccessToAllHosts()) {
182 messages.insert(PermissionMessage(
183 PermissionMessage::kHostsAll,
184 l10n_util::GetStringUTF16(IDS_EXTENSION_PROMPT_WARNING_ALL_HOSTS)));
185 } else {
186 URLPatternSet regular_hosts;
187 ExtensionsClient::Get()->FilterHostPermissions(
188 permissions->effective_hosts(), &regular_hosts, &messages);
189
190 std::set<std::string> hosts =
191 permission_message_util::GetDistinctHosts(regular_hosts, true, true);
192 if (!hosts.empty())
193 messages.insert(permission_message_util::CreateFromHostList(hosts));
194 }
195 return messages;
196 }
197
198 bool ChromePermissionMessageProvider::IsAPIPrivilegeIncrease(
199 const PermissionSet* old_permissions,
200 const PermissionSet* new_permissions) const {
201 if (new_permissions == NULL)
202 return false;
203
204 typedef std::set<PermissionMessage> PermissionMsgSet;
205 PermissionMsgSet old_warnings = GetAPIPermissionMessages(old_permissions);
206 PermissionMsgSet new_warnings = GetAPIPermissionMessages(new_permissions);
207 PermissionMsgSet delta_warnings =
208 base::STLSetDifference<PermissionMsgSet>(new_warnings, old_warnings);
209
210 // A special hack: kFileSystemWriteDirectory implies kFileSystemDirectory and
211 // kFileSystemWrite.
212 // TODO(sammc): Remove this. See http://crbug.com/284849.
213 if (old_warnings.find(PermissionMessage(
214 PermissionMessage::kFileSystemWriteDirectory, string16())) !=
215 old_warnings.end()) {
216 delta_warnings.erase(
217 PermissionMessage(PermissionMessage::kFileSystemDirectory, string16()));
218 delta_warnings.erase(
219 PermissionMessage(PermissionMessage::kFileSystemWrite, string16()));
220 }
221
222 // We have less privileges if there are additional warnings present.
223 return !delta_warnings.empty();
224 }
225
226 bool ChromePermissionMessageProvider::IsHostPrivilegeIncrease(
227 const PermissionSet* old_permissions,
228 const PermissionSet* new_permissions,
229 Manifest::Type extension_type) const {
230 // Platform apps host permission changes do not count as privilege increases.
231 // Note: this must remain consistent with GetHostPermissionMessages.
232 if (extension_type == Manifest::TYPE_PLATFORM_APP)
233 return false;
234
235 // If the old permission set can access any host, then it can't be elevated.
236 if (old_permissions->HasEffectiveAccessToAllHosts())
237 return false;
238
239 // Likewise, if the new permission set has full host access, then it must be
240 // a privilege increase.
241 if (new_permissions->HasEffectiveAccessToAllHosts())
242 return true;
243
244 const URLPatternSet& old_list = old_permissions->effective_hosts();
245 const URLPatternSet& new_list = new_permissions->effective_hosts();
246
247 // TODO(jstritar): This is overly conservative with respect to subdomains.
248 // For example, going from *.google.com to www.google.com will be
249 // considered an elevation, even though it is not (http://crbug.com/65337).
250 std::set<std::string> new_hosts_set(
251 permission_message_util::GetDistinctHosts(new_list, false, false));
252 std::set<std::string> old_hosts_set(
253 permission_message_util::GetDistinctHosts(old_list, false, false));
254 std::set<std::string> new_hosts_only =
255 base::STLSetDifference<std::set<std::string> >(new_hosts_set,
256 old_hosts_set);
257
258 return !new_hosts_only.empty();
259 }
260
261 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698