OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/browser/extensions/permissions_updater.h" | 5 #include "chrome/browser/extensions/permissions_updater.h" |
6 | 6 |
7 #include "base/json/json_writer.h" | 7 #include "base/json/json_writer.h" |
8 #include "base/memory/ref_counted.h" | 8 #include "base/memory/ref_counted.h" |
9 #include "base/values.h" | 9 #include "base/values.h" |
10 #include "chrome/browser/chrome_notification_types.h" | 10 #include "chrome/browser/chrome_notification_types.h" |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 if (iter->MatchesSingleOrigin() && | 52 if (iter->MatchesSingleOrigin() && |
53 bounds.MatchesURL(GURL(iter->GetAsString()))) { | 53 bounds.MatchesURL(GURL(iter->GetAsString()))) { |
54 single_origin_permissions.AddPattern(*iter); | 54 single_origin_permissions.AddPattern(*iter); |
55 } | 55 } |
56 } | 56 } |
57 return single_origin_permissions; | 57 return single_origin_permissions; |
58 } | 58 } |
59 | 59 |
60 // Returns a PermissionSet that has the active permissions of the extension, | 60 // Returns a PermissionSet that has the active permissions of the extension, |
61 // bounded to its current manifest. | 61 // bounded to its current manifest. |
62 scoped_refptr<const PermissionSet> GetBoundedActivePermissions( | 62 scoped_ptr<const PermissionSet> GetBoundedActivePermissions( |
63 const Extension* extension, | 63 const Extension* extension, |
64 const scoped_refptr<const PermissionSet>& active_permissions) { | 64 const PermissionSet* active_permissions) { |
65 // If the extension has used the optional permissions API, it will have a | 65 // If the extension has used the optional permissions API, it will have a |
66 // custom set of active permissions defined in the extension prefs. Here, | 66 // custom set of active permissions defined in the extension prefs. Here, |
67 // we update the extension's active permissions based on the prefs. | 67 // we update the extension's active permissions based on the prefs. |
68 if (!active_permissions.get()) | 68 if (!active_permissions) |
69 return extension->permissions_data()->active_permissions(); | 69 return extension->permissions_data()->active_permissions()->Clone(); |
70 | 70 |
71 scoped_refptr<const PermissionSet> required_permissions = | 71 const PermissionSet* required_permissions = |
72 PermissionsParser::GetRequiredPermissions(extension); | 72 PermissionsParser::GetRequiredPermissions(extension); |
73 | 73 |
74 // We restrict the active permissions to be within the bounds defined in the | 74 // We restrict the active permissions to be within the bounds defined in the |
75 // extension's manifest. | 75 // extension's manifest. |
76 // a) active permissions must be a subset of optional + default permissions | 76 // a) active permissions must be a subset of optional + default permissions |
77 // b) active permissions must contains all default permissions | 77 // b) active permissions must contains all default permissions |
78 scoped_refptr<const PermissionSet> total_permissions = | 78 scoped_ptr<const PermissionSet> total_permissions = |
79 PermissionSet::CreateUnion( | 79 PermissionSet::CreateUnion( |
80 *required_permissions, | 80 *required_permissions, |
81 *PermissionsParser::GetOptionalPermissions(extension)); | 81 *PermissionsParser::GetOptionalPermissions(extension)); |
82 | 82 |
83 // Make sure the active permissions contain no more than optional + default. | 83 // Make sure the active permissions contain no more than optional + default. |
84 scoped_refptr<const PermissionSet> adjusted_active = | 84 scoped_ptr<const PermissionSet> adjusted_active = |
85 PermissionSet::CreateIntersection(*total_permissions, | 85 PermissionSet::CreateIntersection(*total_permissions, |
86 *active_permissions); | 86 *active_permissions); |
87 | 87 |
88 // Make sure the active permissions contain the default permissions. | 88 // Make sure the active permissions contain the default permissions. |
89 adjusted_active = | 89 adjusted_active = |
90 PermissionSet::CreateUnion(*required_permissions, *adjusted_active); | 90 PermissionSet::CreateUnion(*required_permissions, *adjusted_active); |
91 | 91 |
92 return adjusted_active; | 92 return adjusted_active; |
93 } | 93 } |
94 | 94 |
(...skipping 22 matching lines...) Expand all Loading... |
117 | 117 |
118 PermissionsUpdater::PermissionsUpdater(content::BrowserContext* browser_context, | 118 PermissionsUpdater::PermissionsUpdater(content::BrowserContext* browser_context, |
119 InitFlag init_flag) | 119 InitFlag init_flag) |
120 : browser_context_(browser_context), init_flag_(init_flag) { | 120 : browser_context_(browser_context), init_flag_(init_flag) { |
121 } | 121 } |
122 | 122 |
123 PermissionsUpdater::~PermissionsUpdater() {} | 123 PermissionsUpdater::~PermissionsUpdater() {} |
124 | 124 |
125 void PermissionsUpdater::AddPermissions( | 125 void PermissionsUpdater::AddPermissions( |
126 const Extension* extension, const PermissionSet* permissions) { | 126 const Extension* extension, const PermissionSet* permissions) { |
127 scoped_refptr<const PermissionSet> active( | 127 const PermissionSet* active( |
128 extension->permissions_data()->active_permissions()); | 128 extension->permissions_data()->active_permissions()); |
129 scoped_refptr<const PermissionSet> total( | 129 scoped_ptr<const PermissionSet> total = |
130 PermissionSet::CreateUnion(*active, *permissions)); | 130 PermissionSet::CreateUnion(*active, *permissions); |
131 scoped_refptr<const PermissionSet> added( | 131 scoped_ptr<const PermissionSet> added = |
132 PermissionSet::CreateDifference(*total, *active)); | 132 PermissionSet::CreateDifference(*total, *active); |
133 | 133 |
134 SetPermissions(extension, total, nullptr); | 134 SetPermissions(extension, total.Pass(), nullptr); |
135 | 135 |
136 // Update the granted permissions so we don't auto-disable the extension. | 136 // Update the granted permissions so we don't auto-disable the extension. |
137 GrantActivePermissions(extension); | 137 GrantActivePermissions(extension); |
138 | 138 |
139 NotifyPermissionsUpdated(ADDED, extension, added.get()); | 139 NotifyPermissionsUpdated(ADDED, extension, *added); |
140 } | 140 } |
141 | 141 |
142 void PermissionsUpdater::RemovePermissions(const Extension* extension, | 142 void PermissionsUpdater::RemovePermissions(const Extension* extension, |
143 const PermissionSet* to_remove, | 143 const PermissionSet* to_remove, |
144 RemoveType remove_type) { | 144 RemoveType remove_type) { |
145 // We should only be revoking revokable permissions. | 145 // We should only be revoking revokable permissions. |
146 CHECK(GetRevokablePermissions(extension)->Contains(*to_remove)); | 146 CHECK(GetRevokablePermissions(extension)->Contains(*to_remove)); |
147 | 147 |
148 scoped_refptr<const PermissionSet> active( | 148 const PermissionSet* active = |
149 extension->permissions_data()->active_permissions()); | 149 extension->permissions_data()->active_permissions(); |
150 scoped_refptr<const PermissionSet> remaining( | 150 scoped_ptr<const PermissionSet> remaining = |
151 PermissionSet::CreateDifference(*active, *to_remove)); | 151 PermissionSet::CreateDifference(*active, *to_remove); |
152 | 152 |
153 // Move any granted permissions that were in the withheld set back to the | 153 // Move any granted permissions that were in the withheld set back to the |
154 // withheld set so they can be added back later. | 154 // withheld set so they can be added back later. |
155 // Any revoked permission that isn't from the optional permissions can only | 155 // Any revoked permission that isn't from the optional permissions can only |
156 // be a withheld permission. | 156 // be a withheld permission. |
157 scoped_refptr<const PermissionSet> removed_withheld = | 157 scoped_ptr<const PermissionSet> removed_withheld = |
158 PermissionSet::CreateDifference( | 158 PermissionSet::CreateDifference( |
159 *to_remove, *PermissionsParser::GetOptionalPermissions(extension)); | 159 *to_remove, *PermissionsParser::GetOptionalPermissions(extension)); |
160 scoped_refptr<const PermissionSet> withheld = PermissionSet::CreateUnion( | 160 scoped_ptr<const PermissionSet> withheld = PermissionSet::CreateUnion( |
161 *removed_withheld, | 161 *removed_withheld, |
162 *extension->permissions_data()->withheld_permissions()); | 162 *extension->permissions_data()->withheld_permissions()); |
163 | 163 |
164 SetPermissions(extension, remaining, withheld); | 164 SetPermissions(extension, remaining.Pass(), withheld.Pass()); |
165 | 165 |
166 // We might not want to revoke the granted permissions because the extension, | 166 // We might not want to revoke the granted permissions because the extension, |
167 // not the user, removed the permissions. This allows the extension to add | 167 // not the user, removed the permissions. This allows the extension to add |
168 // them again without prompting the user. | 168 // them again without prompting the user. |
169 if (remove_type == REMOVE_HARD) { | 169 if (remove_type == REMOVE_HARD) { |
170 ExtensionPrefs::Get(browser_context_) | 170 ExtensionPrefs::Get(browser_context_) |
171 ->RemoveGrantedPermissions(extension->id(), to_remove); | 171 ->RemoveGrantedPermissions(extension->id(), to_remove); |
172 } | 172 } |
173 | 173 |
174 NotifyPermissionsUpdated(REMOVED, extension, to_remove); | 174 NotifyPermissionsUpdated(REMOVED, extension, *to_remove); |
175 } | 175 } |
176 | 176 |
177 void PermissionsUpdater::RemovePermissionsUnsafe( | 177 void PermissionsUpdater::RemovePermissionsUnsafe( |
178 const Extension* extension, | 178 const Extension* extension, |
179 const PermissionSet* to_remove) { | 179 const PermissionSet* to_remove) { |
180 scoped_refptr<const PermissionSet> active( | 180 const PermissionSet* active = |
181 extension->permissions_data()->active_permissions()); | 181 extension->permissions_data()->active_permissions(); |
182 scoped_refptr<const PermissionSet> total( | 182 scoped_ptr<const PermissionSet> total = |
183 PermissionSet::CreateDifference(*active, *to_remove)); | 183 PermissionSet::CreateDifference(*active, *to_remove); |
184 // |successfully_removed| might not equal |to_remove| if |to_remove| contains | 184 // |successfully_removed| might not equal |to_remove| if |to_remove| contains |
185 // permissions the extension didn't have. | 185 // permissions the extension didn't have. |
186 scoped_refptr<const PermissionSet> successfully_removed( | 186 scoped_ptr<const PermissionSet> successfully_removed = |
187 PermissionSet::CreateDifference(*active, *total)); | 187 PermissionSet::CreateDifference(*active, *total); |
188 | 188 |
189 SetPermissions(extension, total, nullptr); | 189 SetPermissions(extension, total.Pass(), nullptr); |
190 NotifyPermissionsUpdated(REMOVED, extension, successfully_removed.get()); | 190 NotifyPermissionsUpdated(REMOVED, extension, *successfully_removed); |
191 } | 191 } |
192 | 192 |
193 scoped_refptr<const PermissionSet> PermissionsUpdater::GetRevokablePermissions( | 193 scoped_ptr<const PermissionSet> PermissionsUpdater::GetRevokablePermissions( |
194 const Extension* extension) const { | 194 const Extension* extension) const { |
195 // Optional permissions are revokable. | 195 // Optional permissions are revokable. |
196 scoped_refptr<const PermissionSet> revokable_permissions = | 196 scoped_ptr<const PermissionSet> wrapper; |
| 197 const PermissionSet* revokable_permissions = |
197 PermissionsParser::GetOptionalPermissions(extension); | 198 PermissionsParser::GetOptionalPermissions(extension); |
198 scoped_refptr<const PermissionSet> active_permissions = | 199 const PermissionSet* active_permissions = |
199 extension->permissions_data()->active_permissions(); | 200 extension->permissions_data()->active_permissions(); |
200 // If click-to-script is enabled, then any hosts that are granted, but not | 201 // If click-to-script is enabled, then any hosts that are granted, but not |
201 // listed explicitly as a required permission, are also revokable. | 202 // listed explicitly as a required permission, are also revokable. |
202 if (FeatureSwitch::scripts_require_action()->IsEnabled()) { | 203 if (FeatureSwitch::scripts_require_action()->IsEnabled()) { |
203 scoped_refptr<const PermissionSet> required_permissions = | 204 const PermissionSet* required_permissions = |
204 PermissionsParser::GetRequiredPermissions(extension); | 205 PermissionsParser::GetRequiredPermissions(extension); |
205 auto find_revokable_hosts = [](const URLPatternSet& active_hosts, | 206 auto find_revokable_hosts = [](const URLPatternSet& active_hosts, |
206 const URLPatternSet& required_hosts) { | 207 const URLPatternSet& required_hosts) { |
207 URLPatternSet revokable_hosts; | 208 URLPatternSet revokable_hosts; |
208 for (const URLPattern& pattern : active_hosts) { | 209 for (const URLPattern& pattern : active_hosts) { |
209 if (std::find(required_hosts.begin(), required_hosts.end(), pattern) == | 210 if (std::find(required_hosts.begin(), required_hosts.end(), pattern) == |
210 required_hosts.end()) { | 211 required_hosts.end()) { |
211 revokable_hosts.AddPattern(pattern); | 212 revokable_hosts.AddPattern(pattern); |
212 } | 213 } |
213 } | 214 } |
214 return revokable_hosts; | 215 return revokable_hosts; |
215 }; | 216 }; |
216 URLPatternSet revokable_explicit_hosts = | 217 URLPatternSet revokable_explicit_hosts = |
217 find_revokable_hosts(active_permissions->explicit_hosts(), | 218 find_revokable_hosts(active_permissions->explicit_hosts(), |
218 required_permissions->explicit_hosts()); | 219 required_permissions->explicit_hosts()); |
219 URLPatternSet revokable_scriptable_hosts = | 220 URLPatternSet revokable_scriptable_hosts = |
220 find_revokable_hosts(active_permissions->scriptable_hosts(), | 221 find_revokable_hosts(active_permissions->scriptable_hosts(), |
221 required_permissions->scriptable_hosts()); | 222 required_permissions->scriptable_hosts()); |
222 scoped_refptr<const PermissionSet> revokable_host_permissions = | 223 scoped_ptr<const PermissionSet> revokable_host_permissions( |
223 new PermissionSet(APIPermissionSet(), ManifestPermissionSet(), | 224 new PermissionSet(APIPermissionSet(), ManifestPermissionSet(), |
224 revokable_explicit_hosts, revokable_scriptable_hosts); | 225 revokable_explicit_hosts, |
225 revokable_permissions = PermissionSet::CreateUnion( | 226 revokable_scriptable_hosts)); |
226 *revokable_permissions, *revokable_host_permissions); | 227 wrapper = PermissionSet::CreateUnion(*revokable_permissions, |
| 228 *revokable_host_permissions); |
| 229 revokable_permissions = wrapper.get(); |
227 } | 230 } |
228 return scoped_refptr<const PermissionSet>(PermissionSet::CreateIntersection( | 231 return PermissionSet::CreateIntersection(*active_permissions, |
229 *active_permissions, *revokable_permissions)); | 232 *revokable_permissions); |
230 } | 233 } |
231 | 234 |
232 void PermissionsUpdater::GrantActivePermissions(const Extension* extension) { | 235 void PermissionsUpdater::GrantActivePermissions(const Extension* extension) { |
233 CHECK(extension); | 236 CHECK(extension); |
234 | 237 |
235 ExtensionPrefs::Get(browser_context_)->AddGrantedPermissions( | 238 ExtensionPrefs::Get(browser_context_) |
236 extension->id(), | 239 ->AddGrantedPermissions( |
237 extension->permissions_data()->active_permissions().get()); | 240 extension->id(), extension->permissions_data()->active_permissions()); |
238 } | 241 } |
239 | 242 |
240 void PermissionsUpdater::InitializePermissions(const Extension* extension) { | 243 void PermissionsUpdater::InitializePermissions(const Extension* extension) { |
241 scoped_refptr<const PermissionSet> active_permissions(NULL); | 244 scoped_ptr<const PermissionSet> active_wrapper; |
242 scoped_refptr<const PermissionSet> bounded_active(NULL); | 245 scoped_ptr<const PermissionSet> bounded_wrapper; |
| 246 const PermissionSet* active_permissions = nullptr; |
| 247 const PermissionSet* bounded_active = nullptr; |
243 // If |extension| is a transient dummy extension, we do not want to look for | 248 // If |extension| is a transient dummy extension, we do not want to look for |
244 // it in preferences. | 249 // it in preferences. |
245 if (init_flag_ & INIT_FLAG_TRANSIENT) { | 250 if (init_flag_ & INIT_FLAG_TRANSIENT) { |
246 bounded_active = active_permissions = | 251 active_permissions = bounded_active = |
247 extension->permissions_data()->active_permissions(); | 252 extension->permissions_data()->active_permissions(); |
248 } else { | 253 } else { |
249 active_permissions = ExtensionPrefs::Get(browser_context_) | 254 // As part of initializing permissions, we restrict access to the main |
250 ->GetActivePermissions(extension->id()); | 255 // thread. |
251 bounded_active = GetBoundedActivePermissions(extension, active_permissions); | 256 active_wrapper = ExtensionPrefs::Get(browser_context_) |
| 257 ->GetActivePermissions(extension->id()); |
| 258 active_permissions = active_wrapper.get(); |
| 259 bounded_wrapper = |
| 260 GetBoundedActivePermissions(extension, active_permissions); |
| 261 bounded_active = bounded_wrapper.get(); |
252 } | 262 } |
253 | 263 |
254 // Determine whether or not to withhold host permissions. | 264 // Determine whether or not to withhold host permissions. |
255 bool should_withhold_permissions = false; | 265 bool should_withhold_permissions = false; |
256 if (PermissionsData::ScriptsMayRequireActionForExtension( | 266 if (PermissionsData::ScriptsMayRequireActionForExtension(extension, |
257 extension, bounded_active.get())) { | 267 bounded_active)) { |
258 should_withhold_permissions = | 268 should_withhold_permissions = |
259 init_flag_ & INIT_FLAG_TRANSIENT ? | 269 init_flag_ & INIT_FLAG_TRANSIENT ? |
260 !util::DefaultAllowedScriptingOnAllUrls() : | 270 !util::DefaultAllowedScriptingOnAllUrls() : |
261 !util::AllowedScriptingOnAllUrls(extension->id(), browser_context_); | 271 !util::AllowedScriptingOnAllUrls(extension->id(), browser_context_); |
262 } | 272 } |
263 | 273 |
264 URLPatternSet granted_explicit_hosts; | 274 URLPatternSet granted_explicit_hosts; |
265 URLPatternSet withheld_explicit_hosts; | 275 URLPatternSet withheld_explicit_hosts; |
266 SegregateUrlPermissions(bounded_active->explicit_hosts(), | 276 SegregateUrlPermissions(bounded_active->explicit_hosts(), |
267 should_withhold_permissions, | 277 should_withhold_permissions, |
268 &granted_explicit_hosts, | 278 &granted_explicit_hosts, |
269 &withheld_explicit_hosts); | 279 &withheld_explicit_hosts); |
270 | 280 |
271 URLPatternSet granted_scriptable_hosts; | 281 URLPatternSet granted_scriptable_hosts; |
272 URLPatternSet withheld_scriptable_hosts; | 282 URLPatternSet withheld_scriptable_hosts; |
273 SegregateUrlPermissions(bounded_active->scriptable_hosts(), | 283 SegregateUrlPermissions(bounded_active->scriptable_hosts(), |
274 should_withhold_permissions, | 284 should_withhold_permissions, |
275 &granted_scriptable_hosts, | 285 &granted_scriptable_hosts, |
276 &withheld_scriptable_hosts); | 286 &withheld_scriptable_hosts); |
277 | 287 |
278 // After withholding permissions, add back any origins to the active set that | 288 // After withholding permissions, add back any origins to the active set that |
279 // may have been lost during the set operations that would have dropped them. | 289 // may have been lost during the set operations that would have dropped them. |
280 // For example, the union of <all_urls> and "example.com" is <all_urls>, so | 290 // For example, the union of <all_urls> and "example.com" is <all_urls>, so |
281 // we may lose "example.com". However, "example.com" is important once | 291 // we may lose "example.com". However, "example.com" is important once |
282 // <all_urls> is stripped during withholding. | 292 // <all_urls> is stripped during withholding. |
283 if (active_permissions.get()) { | 293 if (active_permissions) { |
284 granted_explicit_hosts.AddPatterns( | 294 granted_explicit_hosts.AddPatterns( |
285 FilterSingleOriginPermissions(active_permissions->explicit_hosts(), | 295 FilterSingleOriginPermissions(active_permissions->explicit_hosts(), |
286 bounded_active->explicit_hosts())); | 296 bounded_active->explicit_hosts())); |
287 granted_scriptable_hosts.AddPatterns( | 297 granted_scriptable_hosts.AddPatterns( |
288 FilterSingleOriginPermissions(active_permissions->scriptable_hosts(), | 298 FilterSingleOriginPermissions(active_permissions->scriptable_hosts(), |
289 bounded_active->scriptable_hosts())); | 299 bounded_active->scriptable_hosts())); |
290 } | 300 } |
291 | 301 |
292 bounded_active = new PermissionSet(bounded_active->apis(), | 302 scoped_ptr<const PermissionSet> new_permissions(new PermissionSet( |
293 bounded_active->manifest_permissions(), | 303 bounded_active->apis(), bounded_active->manifest_permissions(), |
294 granted_explicit_hosts, | 304 granted_explicit_hosts, granted_scriptable_hosts)); |
295 granted_scriptable_hosts); | |
296 | 305 |
297 scoped_refptr<const PermissionSet> withheld = | 306 scoped_ptr<const PermissionSet> withheld( |
298 new PermissionSet(APIPermissionSet(), | 307 new PermissionSet(APIPermissionSet(), ManifestPermissionSet(), |
299 ManifestPermissionSet(), | 308 withheld_explicit_hosts, withheld_scriptable_hosts)); |
300 withheld_explicit_hosts, | 309 SetPermissions(extension, new_permissions.Pass(), withheld.Pass()); |
301 withheld_scriptable_hosts); | |
302 SetPermissions(extension, bounded_active, withheld); | |
303 } | 310 } |
304 | 311 |
305 void PermissionsUpdater::WithholdImpliedAllHosts(const Extension* extension) { | 312 void PermissionsUpdater::WithholdImpliedAllHosts(const Extension* extension) { |
306 scoped_refptr<const PermissionSet> active = | 313 const PermissionSet* active = |
307 extension->permissions_data()->active_permissions(); | 314 extension->permissions_data()->active_permissions(); |
308 scoped_refptr<const PermissionSet> withheld = | 315 const PermissionSet* withheld = |
309 extension->permissions_data()->withheld_permissions(); | 316 extension->permissions_data()->withheld_permissions(); |
310 | 317 |
311 URLPatternSet withheld_scriptable = withheld->scriptable_hosts(); | 318 URLPatternSet withheld_scriptable = withheld->scriptable_hosts(); |
312 URLPatternSet active_scriptable; | 319 URLPatternSet active_scriptable; |
313 SegregateUrlPermissions(active->scriptable_hosts(), | 320 SegregateUrlPermissions(active->scriptable_hosts(), |
314 true, // withhold permissions | 321 true, // withhold permissions |
315 &active_scriptable, | 322 &active_scriptable, |
316 &withheld_scriptable); | 323 &withheld_scriptable); |
317 | 324 |
318 URLPatternSet withheld_explicit = withheld->explicit_hosts(); | 325 URLPatternSet withheld_explicit = withheld->explicit_hosts(); |
319 URLPatternSet active_explicit; | 326 URLPatternSet active_explicit; |
320 SegregateUrlPermissions(active->explicit_hosts(), | 327 SegregateUrlPermissions(active->explicit_hosts(), |
321 true, // withhold permissions | 328 true, // withhold permissions |
322 &active_explicit, | 329 &active_explicit, |
323 &withheld_explicit); | 330 &withheld_explicit); |
324 | 331 |
325 URLPatternSet delta_explicit = URLPatternSet::CreateDifference( | 332 URLPatternSet delta_explicit = URLPatternSet::CreateDifference( |
326 active->explicit_hosts(), active_explicit); | 333 active->explicit_hosts(), active_explicit); |
327 URLPatternSet delta_scriptable = URLPatternSet::CreateDifference( | 334 URLPatternSet delta_scriptable = URLPatternSet::CreateDifference( |
328 active->scriptable_hosts(), active_scriptable); | 335 active->scriptable_hosts(), active_scriptable); |
329 | 336 |
330 SetPermissions(extension, | 337 SetPermissions(extension, make_scoped_ptr(new PermissionSet( |
331 new PermissionSet(active->apis(), | 338 active->apis(), active->manifest_permissions(), |
332 active->manifest_permissions(), | 339 active_explicit, active_scriptable)), |
333 active_explicit, | 340 make_scoped_ptr(new PermissionSet( |
334 active_scriptable), | 341 withheld->apis(), withheld->manifest_permissions(), |
335 new PermissionSet(withheld->apis(), | 342 withheld_explicit, withheld_scriptable))); |
336 withheld->manifest_permissions(), | |
337 withheld_explicit, | |
338 withheld_scriptable)); | |
339 | 343 |
340 scoped_refptr<const PermissionSet> delta(new PermissionSet( | 344 NotifyPermissionsUpdated( |
341 APIPermissionSet(), | 345 REMOVED, extension, |
342 ManifestPermissionSet(), | 346 PermissionSet(APIPermissionSet(), ManifestPermissionSet(), delta_explicit, |
343 delta_explicit, | 347 delta_scriptable)); |
344 delta_scriptable)); | |
345 NotifyPermissionsUpdated(REMOVED, extension, delta.get()); | |
346 } | 348 } |
347 | 349 |
348 void PermissionsUpdater::GrantWithheldImpliedAllHosts( | 350 void PermissionsUpdater::GrantWithheldImpliedAllHosts( |
349 const Extension* extension) { | 351 const Extension* extension) { |
350 scoped_refptr<const PermissionSet> active = | 352 const PermissionSet* active = |
351 extension->permissions_data()->active_permissions(); | 353 extension->permissions_data()->active_permissions(); |
352 scoped_refptr<const PermissionSet> withheld = | 354 const PermissionSet* withheld = |
353 extension->permissions_data()->withheld_permissions(); | 355 extension->permissions_data()->withheld_permissions(); |
354 | 356 |
355 // Move the all-hosts permission from withheld to active. | 357 // Move the all-hosts permission from withheld to active. |
356 // We can cheat a bit here since we know that the only host permission we | 358 // We can cheat a bit here since we know that the only host permission we |
357 // withhold is allhosts (or something similar enough to it), so we can just | 359 // withhold is allhosts (or something similar enough to it), so we can just |
358 // grant all withheld host permissions. | 360 // grant all withheld host permissions. |
359 URLPatternSet explicit_hosts = URLPatternSet::CreateUnion( | 361 URLPatternSet explicit_hosts = URLPatternSet::CreateUnion( |
360 active->explicit_hosts(), withheld->explicit_hosts()); | 362 active->explicit_hosts(), withheld->explicit_hosts()); |
361 URLPatternSet scriptable_hosts = URLPatternSet::CreateUnion( | 363 URLPatternSet scriptable_hosts = URLPatternSet::CreateUnion( |
362 active->scriptable_hosts(), withheld->scriptable_hosts()); | 364 active->scriptable_hosts(), withheld->scriptable_hosts()); |
363 | 365 |
364 URLPatternSet delta_explicit = | 366 URLPatternSet delta_explicit = |
365 URLPatternSet::CreateDifference(explicit_hosts, active->explicit_hosts()); | 367 URLPatternSet::CreateDifference(explicit_hosts, active->explicit_hosts()); |
366 URLPatternSet delta_scriptable = URLPatternSet::CreateDifference( | 368 URLPatternSet delta_scriptable = URLPatternSet::CreateDifference( |
367 scriptable_hosts, active->scriptable_hosts()); | 369 scriptable_hosts, active->scriptable_hosts()); |
368 | 370 |
369 // Since we only withhold host permissions (so far), we know that withheld | 371 // Since we only withhold host permissions (so far), we know that withheld |
370 // permissions will be empty. | 372 // permissions will be empty. |
371 SetPermissions(extension, | 373 SetPermissions(extension, make_scoped_ptr(new PermissionSet( |
372 new PermissionSet(active->apis(), | 374 active->apis(), active->manifest_permissions(), |
373 active->manifest_permissions(), | 375 explicit_hosts, scriptable_hosts)), |
374 explicit_hosts, | 376 make_scoped_ptr(new PermissionSet())); |
375 scriptable_hosts), | |
376 new PermissionSet()); | |
377 | 377 |
378 scoped_refptr<const PermissionSet> delta(new PermissionSet( | 378 NotifyPermissionsUpdated( |
379 APIPermissionSet(), | 379 ADDED, extension, |
380 ManifestPermissionSet(), | 380 PermissionSet(APIPermissionSet(), ManifestPermissionSet(), delta_explicit, |
381 delta_explicit, | 381 delta_scriptable)); |
382 delta_scriptable)); | |
383 NotifyPermissionsUpdated(ADDED, extension, delta.get()); | |
384 } | 382 } |
385 | 383 |
386 void PermissionsUpdater::SetPermissions( | 384 void PermissionsUpdater::SetPermissions( |
387 const Extension* extension, | 385 const Extension* extension, |
388 const scoped_refptr<const PermissionSet>& active, | 386 scoped_ptr<const PermissionSet> active, |
389 scoped_refptr<const PermissionSet> withheld) { | 387 scoped_ptr<const PermissionSet> withheld) { |
390 withheld = withheld.get() ? withheld | 388 DCHECK(active); |
391 : extension->permissions_data()->withheld_permissions(); | 389 const PermissionSet* active_weak = active.get(); |
392 extension->permissions_data()->SetPermissions(active, withheld); | 390 if (withheld) { |
| 391 extension->permissions_data()->SetPermissions(active.Pass(), |
| 392 withheld.Pass()); |
| 393 } else { |
| 394 extension->permissions_data()->SetActivePermissions(active.Pass()); |
| 395 } |
| 396 |
393 if ((init_flag_ & INIT_FLAG_TRANSIENT) == 0) { | 397 if ((init_flag_ & INIT_FLAG_TRANSIENT) == 0) { |
394 ExtensionPrefs::Get(browser_context_) | 398 ExtensionPrefs::Get(browser_context_) |
395 ->SetActivePermissions(extension->id(), active.get()); | 399 ->SetActivePermissions(extension->id(), active_weak); |
396 } | 400 } |
397 } | 401 } |
398 | 402 |
399 void PermissionsUpdater::DispatchEvent( | 403 void PermissionsUpdater::DispatchEvent( |
400 const std::string& extension_id, | 404 const std::string& extension_id, |
401 events::HistogramValue histogram_value, | 405 events::HistogramValue histogram_value, |
402 const char* event_name, | 406 const char* event_name, |
403 const PermissionSet* changed_permissions) { | 407 const PermissionSet& changed_permissions) { |
404 EventRouter* event_router = EventRouter::Get(browser_context_); | 408 EventRouter* event_router = EventRouter::Get(browser_context_); |
405 if (!event_router) | 409 if (!event_router) |
406 return; | 410 return; |
407 | 411 |
408 scoped_ptr<base::ListValue> value(new base::ListValue()); | 412 scoped_ptr<base::ListValue> value(new base::ListValue()); |
409 scoped_ptr<api::permissions::Permissions> permissions = | 413 scoped_ptr<api::permissions::Permissions> permissions = |
410 PackPermissionSet(changed_permissions); | 414 PackPermissionSet(&changed_permissions); |
411 value->Append(permissions->ToValue().release()); | 415 value->Append(permissions->ToValue().release()); |
412 scoped_ptr<Event> event(new Event(histogram_value, event_name, value.Pass())); | 416 scoped_ptr<Event> event(new Event(histogram_value, event_name, value.Pass())); |
413 event->restrict_to_browser_context = browser_context_; | 417 event->restrict_to_browser_context = browser_context_; |
414 event_router->DispatchEventToExtension(extension_id, event.Pass()); | 418 event_router->DispatchEventToExtension(extension_id, event.Pass()); |
415 } | 419 } |
416 | 420 |
417 void PermissionsUpdater::NotifyPermissionsUpdated( | 421 void PermissionsUpdater::NotifyPermissionsUpdated( |
418 EventType event_type, | 422 EventType event_type, |
419 const Extension* extension, | 423 const Extension* extension, |
420 const PermissionSet* changed) { | 424 const PermissionSet& changed) { |
421 DCHECK((init_flag_ & INIT_FLAG_TRANSIENT) == 0); | 425 DCHECK((init_flag_ & INIT_FLAG_TRANSIENT) == 0); |
422 if (!changed || changed->IsEmpty()) | 426 if (changed.IsEmpty()) |
423 return; | 427 return; |
424 | 428 |
425 UpdatedExtensionPermissionsInfo::Reason reason; | 429 UpdatedExtensionPermissionsInfo::Reason reason; |
426 events::HistogramValue histogram_value; | 430 events::HistogramValue histogram_value; |
427 const char* event_name = NULL; | 431 const char* event_name = NULL; |
428 | 432 |
429 if (event_type == REMOVED) { | 433 if (event_type == REMOVED) { |
430 reason = UpdatedExtensionPermissionsInfo::REMOVED; | 434 reason = UpdatedExtensionPermissionsInfo::REMOVED; |
431 histogram_value = events::PERMISSIONS_ON_REMOVED; | 435 histogram_value = events::PERMISSIONS_ON_REMOVED; |
432 event_name = permissions::OnRemoved::kEventName; | 436 event_name = permissions::OnRemoved::kEventName; |
(...skipping 28 matching lines...) Expand all Loading... |
461 Profile::FromBrowserContext(host->GetBrowserContext()))) { | 465 Profile::FromBrowserContext(host->GetBrowserContext()))) { |
462 host->Send(new ExtensionMsg_UpdatePermissions(params)); | 466 host->Send(new ExtensionMsg_UpdatePermissions(params)); |
463 } | 467 } |
464 } | 468 } |
465 | 469 |
466 // Trigger the onAdded and onRemoved events in the extension. | 470 // Trigger the onAdded and onRemoved events in the extension. |
467 DispatchEvent(extension->id(), histogram_value, event_name, changed); | 471 DispatchEvent(extension->id(), histogram_value, event_name, changed); |
468 } | 472 } |
469 | 473 |
470 } // namespace extensions | 474 } // namespace extensions |
OLD | NEW |