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 <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/memory/ref_counted.h" | 9 #include "base/memory/ref_counted.h" |
10 #include "base/values.h" | 10 #include "base/values.h" |
(...skipping 18 matching lines...) Expand all Loading... |
29 using extensions::permissions_api_helpers::PackPermissionSet; | 29 using extensions::permissions_api_helpers::PackPermissionSet; |
30 | 30 |
31 namespace extensions { | 31 namespace extensions { |
32 | 32 |
33 namespace permissions = api::permissions; | 33 namespace permissions = api::permissions; |
34 | 34 |
35 namespace { | 35 namespace { |
36 | 36 |
37 // Returns a PermissionSet that has the active permissions of the extension, | 37 // Returns a PermissionSet that has the active permissions of the extension, |
38 // bounded to its current manifest. | 38 // bounded to its current manifest. |
39 scoped_ptr<const PermissionSet> GetBoundedActivePermissions( | 39 std::unique_ptr<const PermissionSet> GetBoundedActivePermissions( |
40 const Extension* extension, | 40 const Extension* extension, |
41 const PermissionSet* active_permissions) { | 41 const PermissionSet* active_permissions) { |
42 // If the extension has used the optional permissions API, it will have a | 42 // If the extension has used the optional permissions API, it will have a |
43 // custom set of active permissions defined in the extension prefs. Here, | 43 // custom set of active permissions defined in the extension prefs. Here, |
44 // we update the extension's active permissions based on the prefs. | 44 // we update the extension's active permissions based on the prefs. |
45 if (!active_permissions) | 45 if (!active_permissions) |
46 return extension->permissions_data()->active_permissions().Clone(); | 46 return extension->permissions_data()->active_permissions().Clone(); |
47 | 47 |
48 const PermissionSet& required_permissions = | 48 const PermissionSet& required_permissions = |
49 PermissionsParser::GetRequiredPermissions(extension); | 49 PermissionsParser::GetRequiredPermissions(extension); |
50 | 50 |
51 // We restrict the active permissions to be within the bounds defined in the | 51 // We restrict the active permissions to be within the bounds defined in the |
52 // extension's manifest. | 52 // extension's manifest. |
53 // a) active permissions must be a subset of optional + default permissions | 53 // a) active permissions must be a subset of optional + default permissions |
54 // b) active permissions must contains all default permissions | 54 // b) active permissions must contains all default permissions |
55 scoped_ptr<const PermissionSet> total_permissions = | 55 std::unique_ptr<const PermissionSet> total_permissions = |
56 PermissionSet::CreateUnion( | 56 PermissionSet::CreateUnion( |
57 required_permissions, | 57 required_permissions, |
58 PermissionsParser::GetOptionalPermissions(extension)); | 58 PermissionsParser::GetOptionalPermissions(extension)); |
59 | 59 |
60 // Make sure the active permissions contain no more than optional + default. | 60 // Make sure the active permissions contain no more than optional + default. |
61 scoped_ptr<const PermissionSet> adjusted_active = | 61 std::unique_ptr<const PermissionSet> adjusted_active = |
62 PermissionSet::CreateIntersection(*total_permissions, | 62 PermissionSet::CreateIntersection(*total_permissions, |
63 *active_permissions); | 63 *active_permissions); |
64 | 64 |
65 // Make sure the active permissions contain the default permissions. | 65 // Make sure the active permissions contain the default permissions. |
66 adjusted_active = | 66 adjusted_active = |
67 PermissionSet::CreateUnion(required_permissions, *adjusted_active); | 67 PermissionSet::CreateUnion(required_permissions, *adjusted_active); |
68 | 68 |
69 return adjusted_active; | 69 return adjusted_active; |
70 } | 70 } |
71 | 71 |
72 } // namespace | 72 } // namespace |
73 | 73 |
74 PermissionsUpdater::PermissionsUpdater(content::BrowserContext* browser_context) | 74 PermissionsUpdater::PermissionsUpdater(content::BrowserContext* browser_context) |
75 : browser_context_(browser_context), init_flag_(INIT_FLAG_NONE) { | 75 : browser_context_(browser_context), init_flag_(INIT_FLAG_NONE) { |
76 } | 76 } |
77 | 77 |
78 PermissionsUpdater::PermissionsUpdater(content::BrowserContext* browser_context, | 78 PermissionsUpdater::PermissionsUpdater(content::BrowserContext* browser_context, |
79 InitFlag init_flag) | 79 InitFlag init_flag) |
80 : browser_context_(browser_context), init_flag_(init_flag) { | 80 : browser_context_(browser_context), init_flag_(init_flag) { |
81 } | 81 } |
82 | 82 |
83 PermissionsUpdater::~PermissionsUpdater() {} | 83 PermissionsUpdater::~PermissionsUpdater() {} |
84 | 84 |
85 void PermissionsUpdater::AddPermissions(const Extension* extension, | 85 void PermissionsUpdater::AddPermissions(const Extension* extension, |
86 const PermissionSet& permissions) { | 86 const PermissionSet& permissions) { |
87 const PermissionSet& active = | 87 const PermissionSet& active = |
88 extension->permissions_data()->active_permissions(); | 88 extension->permissions_data()->active_permissions(); |
89 scoped_ptr<const PermissionSet> total = | 89 std::unique_ptr<const PermissionSet> total = |
90 PermissionSet::CreateUnion(active, permissions); | 90 PermissionSet::CreateUnion(active, permissions); |
91 scoped_ptr<const PermissionSet> added = | 91 std::unique_ptr<const PermissionSet> added = |
92 PermissionSet::CreateDifference(*total, active); | 92 PermissionSet::CreateDifference(*total, active); |
93 | 93 |
94 scoped_ptr<const PermissionSet> new_withheld = | 94 std::unique_ptr<const PermissionSet> new_withheld = |
95 PermissionSet::CreateDifference( | 95 PermissionSet::CreateDifference( |
96 extension->permissions_data()->withheld_permissions(), permissions); | 96 extension->permissions_data()->withheld_permissions(), permissions); |
97 SetPermissions(extension, std::move(total), std::move(new_withheld)); | 97 SetPermissions(extension, std::move(total), std::move(new_withheld)); |
98 | 98 |
99 // Update the granted permissions so we don't auto-disable the extension. | 99 // Update the granted permissions so we don't auto-disable the extension. |
100 GrantActivePermissions(extension); | 100 GrantActivePermissions(extension); |
101 | 101 |
102 NotifyPermissionsUpdated(ADDED, extension, *added); | 102 NotifyPermissionsUpdated(ADDED, extension, *added); |
103 } | 103 } |
104 | 104 |
105 void PermissionsUpdater::RemovePermissions(const Extension* extension, | 105 void PermissionsUpdater::RemovePermissions(const Extension* extension, |
106 const PermissionSet& to_remove, | 106 const PermissionSet& to_remove, |
107 RemoveType remove_type) { | 107 RemoveType remove_type) { |
108 // We should only be revoking revokable permissions. | 108 // We should only be revoking revokable permissions. |
109 CHECK(GetRevokablePermissions(extension)->Contains(to_remove)); | 109 CHECK(GetRevokablePermissions(extension)->Contains(to_remove)); |
110 | 110 |
111 const PermissionSet& active = | 111 const PermissionSet& active = |
112 extension->permissions_data()->active_permissions(); | 112 extension->permissions_data()->active_permissions(); |
113 scoped_ptr<const PermissionSet> remaining = | 113 std::unique_ptr<const PermissionSet> remaining = |
114 PermissionSet::CreateDifference(active, to_remove); | 114 PermissionSet::CreateDifference(active, to_remove); |
115 | 115 |
116 // Move any granted permissions that were in the withheld set back to the | 116 // Move any granted permissions that were in the withheld set back to the |
117 // withheld set so they can be added back later. | 117 // withheld set so they can be added back later. |
118 // Any revoked permission that isn't from the optional permissions can only | 118 // Any revoked permission that isn't from the optional permissions can only |
119 // be a withheld permission. | 119 // be a withheld permission. |
120 scoped_ptr<const PermissionSet> removed_withheld = | 120 std::unique_ptr<const PermissionSet> removed_withheld = |
121 PermissionSet::CreateDifference( | 121 PermissionSet::CreateDifference( |
122 to_remove, PermissionsParser::GetOptionalPermissions(extension)); | 122 to_remove, PermissionsParser::GetOptionalPermissions(extension)); |
123 scoped_ptr<const PermissionSet> withheld = PermissionSet::CreateUnion( | 123 std::unique_ptr<const PermissionSet> withheld = PermissionSet::CreateUnion( |
124 *removed_withheld, extension->permissions_data()->withheld_permissions()); | 124 *removed_withheld, extension->permissions_data()->withheld_permissions()); |
125 | 125 |
126 SetPermissions(extension, std::move(remaining), std::move(withheld)); | 126 SetPermissions(extension, std::move(remaining), std::move(withheld)); |
127 | 127 |
128 // We might not want to revoke the granted permissions because the extension, | 128 // We might not want to revoke the granted permissions because the extension, |
129 // not the user, removed the permissions. This allows the extension to add | 129 // not the user, removed the permissions. This allows the extension to add |
130 // them again without prompting the user. | 130 // them again without prompting the user. |
131 if (remove_type == REMOVE_HARD) { | 131 if (remove_type == REMOVE_HARD) { |
132 ExtensionPrefs::Get(browser_context_) | 132 ExtensionPrefs::Get(browser_context_) |
133 ->RemoveGrantedPermissions(extension->id(), to_remove); | 133 ->RemoveGrantedPermissions(extension->id(), to_remove); |
134 } | 134 } |
135 | 135 |
136 NotifyPermissionsUpdated(REMOVED, extension, to_remove); | 136 NotifyPermissionsUpdated(REMOVED, extension, to_remove); |
137 } | 137 } |
138 | 138 |
139 void PermissionsUpdater::RemovePermissionsUnsafe( | 139 void PermissionsUpdater::RemovePermissionsUnsafe( |
140 const Extension* extension, | 140 const Extension* extension, |
141 const PermissionSet& to_remove) { | 141 const PermissionSet& to_remove) { |
142 const PermissionSet& active = | 142 const PermissionSet& active = |
143 extension->permissions_data()->active_permissions(); | 143 extension->permissions_data()->active_permissions(); |
144 scoped_ptr<const PermissionSet> total = | 144 std::unique_ptr<const PermissionSet> total = |
145 PermissionSet::CreateDifference(active, to_remove); | 145 PermissionSet::CreateDifference(active, to_remove); |
146 // |successfully_removed| might not equal |to_remove| if |to_remove| contains | 146 // |successfully_removed| might not equal |to_remove| if |to_remove| contains |
147 // permissions the extension didn't have. | 147 // permissions the extension didn't have. |
148 scoped_ptr<const PermissionSet> successfully_removed = | 148 std::unique_ptr<const PermissionSet> successfully_removed = |
149 PermissionSet::CreateDifference(active, *total); | 149 PermissionSet::CreateDifference(active, *total); |
150 | 150 |
151 SetPermissions(extension, std::move(total), nullptr); | 151 SetPermissions(extension, std::move(total), nullptr); |
152 NotifyPermissionsUpdated(REMOVED, extension, *successfully_removed); | 152 NotifyPermissionsUpdated(REMOVED, extension, *successfully_removed); |
153 } | 153 } |
154 | 154 |
155 scoped_ptr<const PermissionSet> PermissionsUpdater::GetRevokablePermissions( | 155 std::unique_ptr<const PermissionSet> |
156 const Extension* extension) const { | 156 PermissionsUpdater::GetRevokablePermissions(const Extension* extension) const { |
157 // The user can revoke any permissions they granted. In other words, any | 157 // The user can revoke any permissions they granted. In other words, any |
158 // permissions the extension didn't start with can be revoked. | 158 // permissions the extension didn't start with can be revoked. |
159 const PermissionSet& required = | 159 const PermissionSet& required = |
160 PermissionsParser::GetRequiredPermissions(extension); | 160 PermissionsParser::GetRequiredPermissions(extension); |
161 scoped_ptr<const PermissionSet> granted; | 161 std::unique_ptr<const PermissionSet> granted; |
162 scoped_ptr<const PermissionSet> withheld; | 162 std::unique_ptr<const PermissionSet> withheld; |
163 ScriptingPermissionsModifier(browser_context_, make_scoped_refptr(extension)) | 163 ScriptingPermissionsModifier(browser_context_, make_scoped_refptr(extension)) |
164 .WithholdPermissions(required, &granted, &withheld, true); | 164 .WithholdPermissions(required, &granted, &withheld, true); |
165 return PermissionSet::CreateDifference( | 165 return PermissionSet::CreateDifference( |
166 extension->permissions_data()->active_permissions(), *granted); | 166 extension->permissions_data()->active_permissions(), *granted); |
167 } | 167 } |
168 | 168 |
169 void PermissionsUpdater::GrantActivePermissions(const Extension* extension) { | 169 void PermissionsUpdater::GrantActivePermissions(const Extension* extension) { |
170 CHECK(extension); | 170 CHECK(extension); |
171 | 171 |
172 ExtensionPrefs::Get(browser_context_) | 172 ExtensionPrefs::Get(browser_context_) |
173 ->AddGrantedPermissions( | 173 ->AddGrantedPermissions( |
174 extension->id(), extension->permissions_data()->active_permissions()); | 174 extension->id(), extension->permissions_data()->active_permissions()); |
175 } | 175 } |
176 | 176 |
177 void PermissionsUpdater::InitializePermissions(const Extension* extension) { | 177 void PermissionsUpdater::InitializePermissions(const Extension* extension) { |
178 scoped_ptr<const PermissionSet> bounded_wrapper; | 178 std::unique_ptr<const PermissionSet> bounded_wrapper; |
179 const PermissionSet* bounded_active = nullptr; | 179 const PermissionSet* bounded_active = nullptr; |
180 // If |extension| is a transient dummy extension, we do not want to look for | 180 // If |extension| is a transient dummy extension, we do not want to look for |
181 // it in preferences. | 181 // it in preferences. |
182 if (init_flag_ & INIT_FLAG_TRANSIENT) { | 182 if (init_flag_ & INIT_FLAG_TRANSIENT) { |
183 bounded_active = &extension->permissions_data()->active_permissions(); | 183 bounded_active = &extension->permissions_data()->active_permissions(); |
184 } else { | 184 } else { |
185 scoped_ptr<const PermissionSet> active_permissions = | 185 std::unique_ptr<const PermissionSet> active_permissions = |
186 ExtensionPrefs::Get(browser_context_) | 186 ExtensionPrefs::Get(browser_context_) |
187 ->GetActivePermissions(extension->id()); | 187 ->GetActivePermissions(extension->id()); |
188 bounded_wrapper = | 188 bounded_wrapper = |
189 GetBoundedActivePermissions(extension, active_permissions.get()); | 189 GetBoundedActivePermissions(extension, active_permissions.get()); |
190 bounded_active = bounded_wrapper.get(); | 190 bounded_active = bounded_wrapper.get(); |
191 } | 191 } |
192 | 192 |
193 scoped_ptr<const PermissionSet> granted_permissions; | 193 std::unique_ptr<const PermissionSet> granted_permissions; |
194 scoped_ptr<const PermissionSet> withheld_permissions; | 194 std::unique_ptr<const PermissionSet> withheld_permissions; |
195 ScriptingPermissionsModifier(browser_context_, make_scoped_refptr(extension)) | 195 ScriptingPermissionsModifier(browser_context_, make_scoped_refptr(extension)) |
196 .WithholdPermissions(*bounded_active, &granted_permissions, | 196 .WithholdPermissions(*bounded_active, &granted_permissions, |
197 &withheld_permissions, | 197 &withheld_permissions, |
198 (init_flag_ & INIT_FLAG_TRANSIENT) != 0); | 198 (init_flag_ & INIT_FLAG_TRANSIENT) != 0); |
199 | 199 |
200 SetPermissions(extension, std::move(granted_permissions), | 200 SetPermissions(extension, std::move(granted_permissions), |
201 std::move(withheld_permissions)); | 201 std::move(withheld_permissions)); |
202 } | 202 } |
203 | 203 |
204 void PermissionsUpdater::SetPermissions( | 204 void PermissionsUpdater::SetPermissions( |
205 const Extension* extension, | 205 const Extension* extension, |
206 scoped_ptr<const PermissionSet> active, | 206 std::unique_ptr<const PermissionSet> active, |
207 scoped_ptr<const PermissionSet> withheld) { | 207 std::unique_ptr<const PermissionSet> withheld) { |
208 DCHECK(active); | 208 DCHECK(active); |
209 const PermissionSet& active_weak = *active; | 209 const PermissionSet& active_weak = *active; |
210 if (withheld) { | 210 if (withheld) { |
211 extension->permissions_data()->SetPermissions(std::move(active), | 211 extension->permissions_data()->SetPermissions(std::move(active), |
212 std::move(withheld)); | 212 std::move(withheld)); |
213 } else { | 213 } else { |
214 extension->permissions_data()->SetActivePermissions(std::move(active)); | 214 extension->permissions_data()->SetActivePermissions(std::move(active)); |
215 } | 215 } |
216 | 216 |
217 if ((init_flag_ & INIT_FLAG_TRANSIENT) == 0) { | 217 if ((init_flag_ & INIT_FLAG_TRANSIENT) == 0) { |
218 ExtensionPrefs::Get(browser_context_) | 218 ExtensionPrefs::Get(browser_context_) |
219 ->SetActivePermissions(extension->id(), active_weak); | 219 ->SetActivePermissions(extension->id(), active_weak); |
220 } | 220 } |
221 } | 221 } |
222 | 222 |
223 void PermissionsUpdater::DispatchEvent( | 223 void PermissionsUpdater::DispatchEvent( |
224 const std::string& extension_id, | 224 const std::string& extension_id, |
225 events::HistogramValue histogram_value, | 225 events::HistogramValue histogram_value, |
226 const char* event_name, | 226 const char* event_name, |
227 const PermissionSet& changed_permissions) { | 227 const PermissionSet& changed_permissions) { |
228 EventRouter* event_router = EventRouter::Get(browser_context_); | 228 EventRouter* event_router = EventRouter::Get(browser_context_); |
229 if (!event_router) | 229 if (!event_router) |
230 return; | 230 return; |
231 | 231 |
232 scoped_ptr<base::ListValue> value(new base::ListValue()); | 232 std::unique_ptr<base::ListValue> value(new base::ListValue()); |
233 scoped_ptr<api::permissions::Permissions> permissions = | 233 std::unique_ptr<api::permissions::Permissions> permissions = |
234 PackPermissionSet(changed_permissions); | 234 PackPermissionSet(changed_permissions); |
235 value->Append(permissions->ToValue().release()); | 235 value->Append(permissions->ToValue().release()); |
236 scoped_ptr<Event> event( | 236 std::unique_ptr<Event> event( |
237 new Event(histogram_value, event_name, std::move(value))); | 237 new Event(histogram_value, event_name, std::move(value))); |
238 event->restrict_to_browser_context = browser_context_; | 238 event->restrict_to_browser_context = browser_context_; |
239 event_router->DispatchEventToExtension(extension_id, std::move(event)); | 239 event_router->DispatchEventToExtension(extension_id, std::move(event)); |
240 } | 240 } |
241 | 241 |
242 void PermissionsUpdater::NotifyPermissionsUpdated( | 242 void PermissionsUpdater::NotifyPermissionsUpdated( |
243 EventType event_type, | 243 EventType event_type, |
244 const Extension* extension, | 244 const Extension* extension, |
245 const PermissionSet& changed) { | 245 const PermissionSet& changed) { |
246 DCHECK((init_flag_ & INIT_FLAG_TRANSIENT) == 0); | 246 DCHECK((init_flag_ & INIT_FLAG_TRANSIENT) == 0); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
286 Profile::FromBrowserContext(host->GetBrowserContext()))) { | 286 Profile::FromBrowserContext(host->GetBrowserContext()))) { |
287 host->Send(new ExtensionMsg_UpdatePermissions(params)); | 287 host->Send(new ExtensionMsg_UpdatePermissions(params)); |
288 } | 288 } |
289 } | 289 } |
290 | 290 |
291 // Trigger the onAdded and onRemoved events in the extension. | 291 // Trigger the onAdded and onRemoved events in the extension. |
292 DispatchEvent(extension->id(), histogram_value, event_name, changed); | 292 DispatchEvent(extension->id(), histogram_value, event_name, changed); |
293 } | 293 } |
294 | 294 |
295 } // namespace extensions | 295 } // namespace extensions |
OLD | NEW |