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 <string> | 5 #include <string> |
6 | 6 |
7 #include "base/compiler_specific.h" | 7 #include "base/compiler_specific.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
10 #include "base/values.h" | 10 #include "base/values.h" |
11 #include "chrome/browser/chrome_notification_types.h" | 11 #include "chrome/browser/chrome_notification_types.h" |
12 #include "chrome/browser/extensions/active_tab_permission_granter.h" | 12 #include "chrome/browser/extensions/active_tab_permission_granter.h" |
13 #include "chrome/browser/extensions/tab_helper.h" | 13 #include "chrome/browser/extensions/tab_helper.h" |
14 #include "chrome/browser/profiles/profile.h" | 14 #include "chrome/browser/profiles/profile.h" |
15 #include "chrome/browser/sessions/session_id.h" | 15 #include "chrome/browser/sessions/session_id.h" |
16 #include "chrome/common/extensions/extension.h" | 16 #include "chrome/common/extensions/extension.h" |
17 #include "chrome/common/extensions/extension_builder.h" | 17 #include "chrome/common/extensions/extension_builder.h" |
| 18 #include "chrome/common/extensions/features/feature_channel.h" |
18 #include "chrome/common/extensions/permissions/permissions_data.h" | 19 #include "chrome/common/extensions/permissions/permissions_data.h" |
19 #include "chrome/common/extensions/value_builder.h" | 20 #include "chrome/common/extensions/value_builder.h" |
20 #include "chrome/test/base/chrome_render_view_host_test_harness.h" | 21 #include "chrome/test/base/chrome_render_view_host_test_harness.h" |
21 #include "content/public/browser/browser_thread.h" | 22 #include "content/public/browser/browser_thread.h" |
22 #include "content/public/browser/navigation_details.h" | 23 #include "content/public/browser/navigation_details.h" |
23 #include "content/public/browser/navigation_entry.h" | 24 #include "content/public/browser/navigation_entry.h" |
24 #include "content/public/browser/notification_service.h" | 25 #include "content/public/browser/notification_service.h" |
25 #include "content/public/browser/notification_types.h" | 26 #include "content/public/browser/notification_types.h" |
26 #include "content/public/browser/web_contents.h" | 27 #include "content/public/browser/web_contents.h" |
27 #include "content/public/common/frame_navigate_params.h" | 28 #include "content/public/common/frame_navigate_params.h" |
28 #include "content/public/common/page_transition_types.h" | 29 #include "content/public/common/page_transition_types.h" |
29 #include "content/public/test/test_browser_thread.h" | 30 #include "content/public/test/test_browser_thread.h" |
30 #include "extensions/common/features/feature.h" | 31 #include "extensions/common/features/feature.h" |
31 | 32 |
32 using base::DictionaryValue; | 33 using base::DictionaryValue; |
33 using base::ListValue; | 34 using base::ListValue; |
34 using content::BrowserThread; | 35 using content::BrowserThread; |
35 using content::NavigationController; | 36 using content::NavigationController; |
36 | 37 |
37 namespace extensions { | 38 namespace extensions { |
38 namespace { | 39 namespace { |
39 | 40 |
40 scoped_refptr<const Extension> CreateTestExtension( | 41 scoped_refptr<const Extension> CreateTestExtension( |
41 const std::string& id, | 42 const std::string& id, |
42 bool has_active_tab_permission) { | 43 bool has_active_tab_permission, |
| 44 bool has_tab_capture_permission) { |
43 ListBuilder permissions; | 45 ListBuilder permissions; |
44 if (has_active_tab_permission) | 46 if (has_active_tab_permission) |
45 permissions.Append("activeTab"); | 47 permissions.Append("activeTab"); |
| 48 if (has_tab_capture_permission) |
| 49 permissions.Append("tabCapture"); |
46 return ExtensionBuilder() | 50 return ExtensionBuilder() |
47 .SetManifest(DictionaryBuilder() | 51 .SetManifest(DictionaryBuilder() |
48 .Set("name", "Extension with ID " + id) | 52 .Set("name", "Extension with ID " + id) |
49 .Set("version", "1.0") | 53 .Set("version", "1.0") |
50 .Set("manifest_version", 2) | 54 .Set("manifest_version", 2) |
51 .Set("permissions", permissions)) | 55 .Set("permissions", permissions)) |
52 .SetID(id) | 56 .SetID(id) |
53 .Build(); | 57 .Build(); |
54 } | 58 } |
55 | 59 |
56 class ActiveTabTest : public ChromeRenderViewHostTestHarness { | 60 class ActiveTabTest : public ChromeRenderViewHostTestHarness { |
57 protected: | 61 protected: |
58 ActiveTabTest() | 62 ActiveTabTest() |
59 : extension(CreateTestExtension("deadbeef", true)), | 63 : current_channel(chrome::VersionInfo::CHANNEL_DEV), |
60 another_extension(CreateTestExtension("feedbeef", true)), | 64 extension(CreateTestExtension("deadbeef", true, false)), |
61 extension_without_active_tab(CreateTestExtension("badbeef", false)) {} | 65 another_extension(CreateTestExtension("feedbeef", true, false)), |
| 66 extension_without_active_tab(CreateTestExtension("badbeef", |
| 67 false, |
| 68 false)), |
| 69 extension_with_tab_capture(CreateTestExtension("cafebeef", |
| 70 true, |
| 71 true)) {} |
62 | 72 |
63 virtual void SetUp() OVERRIDE { | 73 virtual void SetUp() OVERRIDE { |
64 ChromeRenderViewHostTestHarness::SetUp(); | 74 ChromeRenderViewHostTestHarness::SetUp(); |
65 TabHelper::CreateForWebContents(web_contents()); | 75 TabHelper::CreateForWebContents(web_contents()); |
66 } | 76 } |
67 | 77 |
68 int tab_id() { | 78 int tab_id() { |
69 return SessionID::IdForTab(web_contents()); | 79 return SessionID::IdForTab(web_contents()); |
70 } | 80 } |
71 | 81 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
107 bool HasTabsPermission(const scoped_refptr<const Extension>& extension) { | 117 bool HasTabsPermission(const scoped_refptr<const Extension>& extension) { |
108 return HasTabsPermission(extension, tab_id()); | 118 return HasTabsPermission(extension, tab_id()); |
109 } | 119 } |
110 | 120 |
111 bool HasTabsPermission(const scoped_refptr<const Extension>& extension, | 121 bool HasTabsPermission(const scoped_refptr<const Extension>& extension, |
112 int tab_id) { | 122 int tab_id) { |
113 return PermissionsData::HasAPIPermissionForTab( | 123 return PermissionsData::HasAPIPermissionForTab( |
114 extension.get(), tab_id, APIPermission::kTab); | 124 extension.get(), tab_id, APIPermission::kTab); |
115 } | 125 } |
116 | 126 |
| 127 bool IsGrantedForTab(const Extension* extension, |
| 128 const content::WebContents* web_contents) { |
| 129 return PermissionsData::HasAPIPermissionForTab( |
| 130 extension, |
| 131 SessionID::IdForTab(web_contents), |
| 132 APIPermission::kTab); |
| 133 } |
| 134 |
| 135 // TODO(justinlin): Remove when tabCapture is moved to stable. |
| 136 ScopedCurrentChannel current_channel; |
| 137 |
117 // An extension with the activeTab permission. | 138 // An extension with the activeTab permission. |
118 scoped_refptr<const Extension> extension; | 139 scoped_refptr<const Extension> extension; |
119 | 140 |
120 // Another extension with activeTab (for good measure). | 141 // Another extension with activeTab (for good measure). |
121 scoped_refptr<const Extension> another_extension; | 142 scoped_refptr<const Extension> another_extension; |
122 | 143 |
123 // An extension without the activeTab permission. | 144 // An extension without the activeTab permission. |
124 scoped_refptr<const Extension> extension_without_active_tab; | 145 scoped_refptr<const Extension> extension_without_active_tab; |
| 146 |
| 147 // An extension with both the activeTab and tabCapture permission. |
| 148 scoped_refptr<const Extension> extension_with_tab_capture; |
125 }; | 149 }; |
126 | 150 |
127 TEST_F(ActiveTabTest, GrantToSinglePage) { | 151 TEST_F(ActiveTabTest, GrantToSinglePage) { |
128 GURL google("http://www.google.com"); | 152 GURL google("http://www.google.com"); |
129 NavigateAndCommit(google); | 153 NavigateAndCommit(google); |
130 | 154 |
131 // No access unless it's been granted. | 155 // No access unless it's been granted. |
132 EXPECT_TRUE(IsBlocked(extension, google)); | 156 EXPECT_TRUE(IsBlocked(extension, google)); |
133 EXPECT_TRUE(IsBlocked(another_extension, google)); | 157 EXPECT_TRUE(IsBlocked(another_extension, google)); |
134 EXPECT_TRUE(IsBlocked(extension_without_active_tab, google)); | 158 EXPECT_TRUE(IsBlocked(extension_without_active_tab, google)); |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 EXPECT_TRUE(IsBlocked(extension_without_active_tab, chromium)); | 258 EXPECT_TRUE(IsBlocked(extension_without_active_tab, chromium)); |
235 }; | 259 }; |
236 | 260 |
237 TEST_F(ActiveTabTest, Uninstalling) { | 261 TEST_F(ActiveTabTest, Uninstalling) { |
238 // Some semi-arbitrary setup. | 262 // Some semi-arbitrary setup. |
239 GURL google("http://www.google.com"); | 263 GURL google("http://www.google.com"); |
240 NavigateAndCommit(google); | 264 NavigateAndCommit(google); |
241 | 265 |
242 active_tab_permission_granter()->GrantIfRequested(extension.get()); | 266 active_tab_permission_granter()->GrantIfRequested(extension.get()); |
243 | 267 |
244 EXPECT_TRUE(active_tab_permission_granter()->IsGranted(extension.get())); | 268 EXPECT_TRUE(IsGrantedForTab(extension.get(), web_contents())); |
245 EXPECT_TRUE(IsAllowed(extension, google)); | 269 EXPECT_TRUE(IsAllowed(extension, google)); |
246 | 270 |
247 // Uninstalling the extension should clear its tab permissions. | 271 // Uninstalling the extension should clear its tab permissions. |
248 UnloadedExtensionInfo details(extension.get(), | 272 UnloadedExtensionInfo details(extension.get(), |
249 extension_misc::UNLOAD_REASON_DISABLE); | 273 extension_misc::UNLOAD_REASON_DISABLE); |
250 content::NotificationService::current()->Notify( | 274 content::NotificationService::current()->Notify( |
251 chrome::NOTIFICATION_EXTENSION_UNLOADED, | 275 chrome::NOTIFICATION_EXTENSION_UNLOADED, |
252 content::Source<Profile>(Profile::FromBrowserContext( | 276 content::Source<Profile>(Profile::FromBrowserContext( |
253 web_contents()->GetBrowserContext())), | 277 web_contents()->GetBrowserContext())), |
254 content::Details<UnloadedExtensionInfo>(&details)); | 278 content::Details<UnloadedExtensionInfo>(&details)); |
255 | 279 |
256 EXPECT_FALSE(active_tab_permission_granter()->IsGranted(extension.get())); | |
257 // Note: can't EXPECT_FALSE(IsAllowed) here because uninstalled extensions | 280 // Note: can't EXPECT_FALSE(IsAllowed) here because uninstalled extensions |
258 // are just that... considered to be uninstalled, and the manager might | 281 // are just that... considered to be uninstalled, and the manager might |
259 // just ignore them from here on. | 282 // just ignore them from here on. |
260 | 283 |
261 // Granting the extension again should give them back. | 284 // Granting the extension again should give them back. |
262 active_tab_permission_granter()->GrantIfRequested(extension.get()); | 285 active_tab_permission_granter()->GrantIfRequested(extension.get()); |
263 | 286 |
264 EXPECT_TRUE(active_tab_permission_granter()->IsGranted(extension.get())); | 287 EXPECT_TRUE(IsGrantedForTab(extension.get(), web_contents())); |
265 EXPECT_TRUE(IsAllowed(extension, google)); | 288 EXPECT_TRUE(IsAllowed(extension, google)); |
266 } | 289 } |
267 | 290 |
268 TEST_F(ActiveTabTest, OnlyActiveTab) { | 291 TEST_F(ActiveTabTest, OnlyActiveTab) { |
269 GURL google("http://www.google.com"); | 292 GURL google("http://www.google.com"); |
270 NavigateAndCommit(google); | 293 NavigateAndCommit(google); |
271 | 294 |
272 active_tab_permission_granter()->GrantIfRequested(extension.get()); | 295 active_tab_permission_granter()->GrantIfRequested(extension.get()); |
273 | 296 |
274 EXPECT_TRUE(IsAllowed(extension, google, tab_id())); | 297 EXPECT_TRUE(IsAllowed(extension, google, tab_id())); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
312 EXPECT_TRUE(IsAllowed(extension, chromium_h1, tab_id())); | 335 EXPECT_TRUE(IsAllowed(extension, chromium_h1, tab_id())); |
313 | 336 |
314 Reload(); | 337 Reload(); |
315 | 338 |
316 EXPECT_FALSE(IsAllowed(extension, google, tab_id())); | 339 EXPECT_FALSE(IsAllowed(extension, google, tab_id())); |
317 EXPECT_FALSE(IsAllowed(extension, google_h1, tab_id())); | 340 EXPECT_FALSE(IsAllowed(extension, google_h1, tab_id())); |
318 EXPECT_FALSE(IsAllowed(extension, chromium, tab_id())); | 341 EXPECT_FALSE(IsAllowed(extension, chromium, tab_id())); |
319 EXPECT_FALSE(IsAllowed(extension, chromium_h1, tab_id())); | 342 EXPECT_FALSE(IsAllowed(extension, chromium_h1, tab_id())); |
320 } | 343 } |
321 | 344 |
| 345 TEST_F(ActiveTabTest, ChromeUrlGrants) { |
| 346 GURL internal("chrome://version"); |
| 347 NavigateAndCommit(internal); |
| 348 active_tab_permission_granter()->GrantIfRequested( |
| 349 extension_with_tab_capture.get()); |
| 350 // Do not grant tabs/hosts permissions for tab. |
| 351 EXPECT_TRUE(IsBlocked(extension_with_tab_capture, internal, tab_id())); |
| 352 EXPECT_TRUE(PermissionsData::HasAPIPermissionForTab( |
| 353 extension_with_tab_capture.get(), |
| 354 tab_id(), |
| 355 APIPermission::kTabCaptureForTab)); |
| 356 |
| 357 EXPECT_TRUE(IsBlocked(extension_with_tab_capture, internal, tab_id() + 1)); |
| 358 EXPECT_FALSE(PermissionsData::HasAPIPermissionForTab( |
| 359 extension_with_tab_capture.get(), |
| 360 tab_id() + 1, |
| 361 APIPermission::kTabCaptureForTab)); |
| 362 } |
| 363 |
322 } // namespace | 364 } // namespace |
323 } // namespace extensions | 365 } // namespace extensions |
OLD | NEW |