blob: 1fbb4b4f0af3f7f3590d51655cef79b9769da896 [file] [log] [blame]
[email protected]fc5e65d6b2012-06-13 00:22:571// 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
3// found in the LICENSE file.
4
5#include <string>
6
7#include "base/compiler_specific.h"
8#include "base/memory/scoped_ptr.h"
9#include "base/message_loop.h"
10#include "base/values.h"
11#include "chrome/browser/extensions/active_tab_permission_manager.h"
[email protected]a6394ae2012-07-16 20:58:4312#include "chrome/browser/extensions/tab_helper.h"
[email protected]1034cb42012-07-17 08:37:5413#include "chrome/browser/sessions/session_id.h"
[email protected]fc5e65d6b2012-06-13 00:22:5714#include "chrome/browser/ui/tab_contents/tab_contents.h"
15#include "chrome/browser/ui/tab_contents/test_tab_contents.h"
16#include "chrome/common/chrome_notification_types.h"
17#include "chrome/common/extensions/extension.h"
[email protected]6c4f0a992012-07-18 07:41:0618#include "chrome/common/extensions/extension_builder.h"
[email protected]5243df072012-07-11 21:41:0119#include "chrome/common/extensions/features/feature.h"
[email protected]6c4f0a992012-07-18 07:41:0620#include "chrome/common/extensions/value_builder.h"
[email protected]fc5e65d6b2012-06-13 00:22:5721#include "content/public/browser/browser_thread.h"
[email protected]6c4f0a992012-07-18 07:41:0622#include "content/public/browser/navigation_details.h"
23#include "content/public/browser/navigation_entry.h"
[email protected]fc5e65d6b2012-06-13 00:22:5724#include "content/public/browser/notification_service.h"
25#include "content/public/browser/notification_types.h"
26#include "content/public/browser/web_contents.h"
[email protected]6c4f0a992012-07-18 07:41:0627#include "content/public/common/frame_navigate_params.h"
[email protected]fc5e65d6b2012-06-13 00:22:5728#include "content/public/common/page_transition_types.h"
29#include "content/public/test/test_browser_thread.h"
30
31using base::DictionaryValue;
32using base::ListValue;
33using content::BrowserThread;
34using content::NavigationController;
35
36namespace extensions {
37namespace {
38
39scoped_refptr<const Extension> CreateTestExtension(
[email protected]6c4f0a992012-07-18 07:41:0640 const std::string& id,
[email protected]fc5e65d6b2012-06-13 00:22:5741 bool has_active_tab_permission) {
[email protected]6c4f0a992012-07-18 07:41:0642 ListBuilder permissions;
43 if (has_active_tab_permission)
44 permissions.Append("activeTab");
45 return ExtensionBuilder()
46 .SetManifest(DictionaryBuilder()
47 .Set("name", "Extension with ID " + id)
48 .Set("version", "1.0")
49 .Set("manifest_version", 2)
50 .Set("permissions", permissions))
51 .SetID(id)
52 .Build();
[email protected]fc5e65d6b2012-06-13 00:22:5753}
54
55class ActiveTabTest : public TabContentsTestHarness {
56 public:
57 ActiveTabTest()
[email protected]6c4f0a992012-07-18 07:41:0658 : extension(CreateTestExtension("deadbeef", true)),
59 another_extension(CreateTestExtension("feedbeef", true)),
60 extension_without_active_tab(CreateTestExtension("badbeef", false)),
[email protected]5243df072012-07-11 21:41:0161 ui_thread_(BrowserThread::UI, MessageLoop::current()) {
[email protected]2baf5a72012-07-12 03:09:5762 }
63
64 virtual void SetUp() {
65 TabContentsTestHarness::SetUp();
[email protected]5243df072012-07-11 21:41:0166 Feature::SetChannelForTesting(chrome::VersionInfo::CHANNEL_UNKNOWN);
67 }
[email protected]fc5e65d6b2012-06-13 00:22:5768
69 protected:
70 int tab_id() {
[email protected]1034cb42012-07-17 08:37:5471 return SessionID::IdForTab(tab_contents());
[email protected]fc5e65d6b2012-06-13 00:22:5772 }
73
74 ActiveTabPermissionManager* active_tab_permission_manager() {
75 return tab_contents()->extension_tab_helper()->
76 active_tab_permission_manager();
77 }
78
79 bool IsAllowed(const scoped_refptr<const Extension>& extension,
80 const GURL& url) {
81 return IsAllowed(extension, url, tab_id());
82 }
83
84 bool IsAllowed(const scoped_refptr<const Extension>& extension,
85 const GURL& url,
86 int tab_id) {
87 return (extension->CanExecuteScriptOnPage(url, tab_id, NULL, NULL) &&
88 extension->CanCaptureVisiblePage(url, tab_id, NULL));
89 }
90
91 bool IsBlocked(const scoped_refptr<const Extension>& extension,
92 const GURL& url) {
93 return IsBlocked(extension, url, tab_id());
94 }
95
96 bool IsBlocked(const scoped_refptr<const Extension>& extension,
97 const GURL& url,
98 int tab_id) {
99 return (!extension->CanExecuteScriptOnPage(url, tab_id, NULL, NULL) &&
100 !extension->CanCaptureVisiblePage(url, tab_id, NULL));
101 }
102
[email protected]fc5e65d6b2012-06-13 00:22:57103 // An extension with the activeTab permission.
104 scoped_refptr<const Extension> extension;
105
106 // Another extension with activeTab (for good measure).
107 scoped_refptr<const Extension> another_extension;
108
109 // An extension without the activeTab permission.
110 scoped_refptr<const Extension> extension_without_active_tab;
111
112 private:
113 content::TestBrowserThread ui_thread_;
114};
115
116TEST_F(ActiveTabTest, GrantToSinglePage) {
117 GURL google("http://www.google.com");
118 NavigateAndCommit(google);
119
120 // No access unless it's been granted.
121 EXPECT_TRUE(IsBlocked(extension, google));
122 EXPECT_TRUE(IsBlocked(another_extension, google));
123 EXPECT_TRUE(IsBlocked(extension_without_active_tab, google));
124
125 active_tab_permission_manager()->GrantIfRequested(extension);
126 active_tab_permission_manager()->GrantIfRequested(
127 extension_without_active_tab);
128
129 // Granted to extension and extension_without_active_tab, but the latter
130 // doesn't have the activeTab permission so not granted.
131 EXPECT_TRUE(IsAllowed(extension, google));
132 EXPECT_TRUE(IsBlocked(another_extension, google));
133 EXPECT_TRUE(IsBlocked(extension_without_active_tab, google));
134
135 // Other subdomains shouldn't be given access.
136 GURL mail_google("http://mail.google.com");
137 EXPECT_TRUE(IsBlocked(extension, mail_google));
138 EXPECT_TRUE(IsBlocked(another_extension, google));
139 EXPECT_TRUE(IsBlocked(extension_without_active_tab, google));
140
141 // Reloading the page should clear the active permissions.
142 Reload();
143
144 EXPECT_TRUE(IsBlocked(extension, google));
145 EXPECT_TRUE(IsBlocked(another_extension, google));
146 EXPECT_TRUE(IsBlocked(extension_without_active_tab, google));
147
148 // But they should still be able to be granted again.
149 active_tab_permission_manager()->GrantIfRequested(extension);
150
151 EXPECT_TRUE(IsAllowed(extension, google));
152 EXPECT_TRUE(IsBlocked(another_extension, google));
153 EXPECT_TRUE(IsBlocked(extension_without_active_tab, google));
154
155 // And grant a few more times redundantly for good measure.
156 active_tab_permission_manager()->GrantIfRequested(extension);
157 active_tab_permission_manager()->GrantIfRequested(extension);
158 active_tab_permission_manager()->GrantIfRequested(another_extension);
159 active_tab_permission_manager()->GrantIfRequested(another_extension);
160 active_tab_permission_manager()->GrantIfRequested(another_extension);
161 active_tab_permission_manager()->GrantIfRequested(extension);
162 active_tab_permission_manager()->GrantIfRequested(extension);
163 active_tab_permission_manager()->GrantIfRequested(another_extension);
164 active_tab_permission_manager()->GrantIfRequested(another_extension);
165
166 EXPECT_TRUE(IsAllowed(extension, google));
167 EXPECT_TRUE(IsAllowed(another_extension, google));
168 EXPECT_TRUE(IsBlocked(extension_without_active_tab, google));
169
170 // Navigating to a new URL should clear the active permissions.
171 GURL chromium("http://www.chromium.org");
172 NavigateAndCommit(chromium);
173
174 EXPECT_TRUE(IsBlocked(extension, google));
175 EXPECT_TRUE(IsBlocked(another_extension, google));
176 EXPECT_TRUE(IsBlocked(extension_without_active_tab, google));
177
178 EXPECT_TRUE(IsBlocked(extension, chromium));
179 EXPECT_TRUE(IsBlocked(another_extension, chromium));
180 EXPECT_TRUE(IsBlocked(extension_without_active_tab, chromium));
181
182 // Should be able to grant to multiple extensions at the same time (if they
183 // have the activeTab permission, of course).
184 active_tab_permission_manager()->GrantIfRequested(extension);
185 active_tab_permission_manager()->GrantIfRequested(another_extension);
186 active_tab_permission_manager()->GrantIfRequested(
187 extension_without_active_tab);
188
189 EXPECT_TRUE(IsBlocked(extension, google));
190 EXPECT_TRUE(IsBlocked(another_extension, google));
191 EXPECT_TRUE(IsBlocked(extension_without_active_tab, google));
192
193 EXPECT_TRUE(IsAllowed(extension, chromium));
194 EXPECT_TRUE(IsAllowed(another_extension, chromium));
195 EXPECT_TRUE(IsBlocked(extension_without_active_tab, chromium));
196
197 // Should be able to go back to URLs that were previously cleared.
198 NavigateAndCommit(google);
199
200 active_tab_permission_manager()->GrantIfRequested(extension);
201 active_tab_permission_manager()->GrantIfRequested(another_extension);
202 active_tab_permission_manager()->GrantIfRequested(
203 extension_without_active_tab);
204
205 EXPECT_TRUE(IsAllowed(extension, google));
206 EXPECT_TRUE(IsAllowed(another_extension, google));
207 EXPECT_TRUE(IsBlocked(extension_without_active_tab, google));
208
209 EXPECT_TRUE(IsBlocked(extension, chromium));
210 EXPECT_TRUE(IsBlocked(another_extension, chromium));
211 EXPECT_TRUE(IsBlocked(extension_without_active_tab, chromium));
212};
213
[email protected]fc5e65d6b2012-06-13 00:22:57214TEST_F(ActiveTabTest, Uninstalling) {
215 // Some semi-arbitrary setup.
216 GURL google("http://www.google.com");
217 NavigateAndCommit(google);
218
[email protected]fc5e65d6b2012-06-13 00:22:57219 active_tab_permission_manager()->GrantIfRequested(extension);
220
[email protected]6c4f0a992012-07-18 07:41:06221 EXPECT_TRUE(active_tab_permission_manager()->IsGranted(extension));
[email protected]fc5e65d6b2012-06-13 00:22:57222 EXPECT_TRUE(IsAllowed(extension, google));
[email protected]fc5e65d6b2012-06-13 00:22:57223
224 // Uninstalling the extension should clear its tab permissions.
225 UnloadedExtensionInfo details(
226 extension,
227 extension_misc::UNLOAD_REASON_DISABLE);
228 content::NotificationService::current()->Notify(
229 chrome::NOTIFICATION_EXTENSION_UNLOADED,
230 content::Source<Profile>(tab_contents()->profile()),
231 content::Details<UnloadedExtensionInfo>(&details));
232
[email protected]6c4f0a992012-07-18 07:41:06233 EXPECT_FALSE(active_tab_permission_manager()->IsGranted(extension));
234 // Note: can't EXPECT_FALSE(IsAllowed) here because uninstalled extensions
235 // are just that... considered to be uninstalled, and the manager might
236 // just ignore them from here on.
[email protected]fc5e65d6b2012-06-13 00:22:57237
238 // Granting the extension again should give them back.
239 active_tab_permission_manager()->GrantIfRequested(extension);
240
[email protected]6c4f0a992012-07-18 07:41:06241 EXPECT_TRUE(active_tab_permission_manager()->IsGranted(extension));
[email protected]fc5e65d6b2012-06-13 00:22:57242 EXPECT_TRUE(IsAllowed(extension, google));
[email protected]fc5e65d6b2012-06-13 00:22:57243}
244
245TEST_F(ActiveTabTest, OnlyActiveTab) {
246 GURL google("http://www.google.com");
247 NavigateAndCommit(google);
248
249 active_tab_permission_manager()->GrantIfRequested(extension);
250
251 EXPECT_TRUE(IsAllowed(extension, google, tab_id()));
252 EXPECT_TRUE(IsBlocked(extension, google, tab_id() + 1));
253}
254
[email protected]6c4f0a992012-07-18 07:41:06255TEST_F(ActiveTabTest, NavigateInPage) {
256 GURL google("http://www.google.com");
257 NavigateAndCommit(google);
258
259 active_tab_permission_manager()->GrantIfRequested(extension);
260
261 // Perform an in-page navigation. The extension should not lose the temporary
262 // permission.
263 GURL google_h1("http://www.google.com#h1");
264 NavigateAndCommit(google_h1);
265
266 EXPECT_TRUE(IsAllowed(extension, google, tab_id()));
267 EXPECT_TRUE(IsAllowed(extension, google_h1, tab_id()));
268
269 GURL chromium("http://www.chromium.org");
270 NavigateAndCommit(chromium);
271
272 EXPECT_FALSE(IsAllowed(extension, google, tab_id()));
273 EXPECT_FALSE(IsAllowed(extension, google_h1, tab_id()));
274 EXPECT_FALSE(IsAllowed(extension, chromium, tab_id()));
275
276 active_tab_permission_manager()->GrantIfRequested(extension);
277
278 EXPECT_FALSE(IsAllowed(extension, google, tab_id()));
279 EXPECT_FALSE(IsAllowed(extension, google_h1, tab_id()));
280 EXPECT_TRUE(IsAllowed(extension, chromium, tab_id()));
281
282 GURL chromium_h1("http://www.chromium.org#h1");
283 NavigateAndCommit(chromium_h1);
284
285 EXPECT_FALSE(IsAllowed(extension, google, tab_id()));
286 EXPECT_FALSE(IsAllowed(extension, google_h1, tab_id()));
287 EXPECT_TRUE(IsAllowed(extension, chromium, tab_id()));
288 EXPECT_TRUE(IsAllowed(extension, chromium_h1, tab_id()));
289
290 Reload();
291
292 EXPECT_FALSE(IsAllowed(extension, google, tab_id()));
293 EXPECT_FALSE(IsAllowed(extension, google_h1, tab_id()));
294 EXPECT_FALSE(IsAllowed(extension, chromium, tab_id()));
295 EXPECT_FALSE(IsAllowed(extension, chromium_h1, tab_id()));
296}
297
[email protected]fc5e65d6b2012-06-13 00:22:57298} // namespace
299} // namespace extensions