| 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 |