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 "base/utf_string_conversions.h" | 5 #include "base/utf_string_conversions.h" |
6 #include "chrome/browser/automation/automation_util.h" | 6 #include "chrome/browser/automation/automation_util.h" |
7 #include "chrome/browser/extensions/extension_apitest.h" | 7 #include "chrome/browser/extensions/extension_apitest.h" |
8 #include "chrome/browser/extensions/extension_host.h" | 8 #include "chrome/browser/extensions/extension_host.h" |
9 #include "chrome/browser/extensions/extension_service.h" | 9 #include "chrome/browser/extensions/extension_service.h" |
10 #include "chrome/browser/profiles/profile.h" | 10 #include "chrome/browser/profiles/profile.h" |
11 #include "chrome/browser/ui/browser.h" | 11 #include "chrome/browser/ui/browser.h" |
12 #include "chrome/browser/ui/browser_commands.h" | 12 #include "chrome/browser/ui/browser_commands.h" |
13 #include "chrome/browser/ui/browser_tabstrip.h" | 13 #include "chrome/browser/ui/browser_tabstrip.h" |
14 #include "chrome/browser/ui/tab_contents/tab_contents.h" | 14 #include "chrome/browser/ui/tab_contents/tab_contents.h" |
15 #include "chrome/common/chrome_switches.h" | 15 #include "chrome/common/chrome_switches.h" |
16 #include "chrome/common/url_constants.h" | 16 #include "chrome/common/url_constants.h" |
17 #include "chrome/test/base/ui_test_utils.h" | 17 #include "chrome/test/base/ui_test_utils.h" |
18 #include "content/public/browser/render_process_host.h" | 18 #include "content/public/browser/render_process_host.h" |
19 #include "content/public/browser/render_view_host.h" | 19 #include "content/public/browser/render_view_host.h" |
20 #include "content/public/browser/site_instance.h" | 20 #include "content/public/browser/site_instance.h" |
21 #include "content/public/browser/web_contents.h" | 21 #include "content/public/browser/web_contents.h" |
22 #include "net/base/mock_host_resolver.h" | 22 #include "net/base/mock_host_resolver.h" |
23 | 23 |
24 using content::NavigationController; | 24 using content::NavigationController; |
25 using content::WebContents; | 25 using content::WebContents; |
26 using content::RenderViewHost; | |
27 using ui_test_utils::ExecuteJavaScript; | |
28 using ui_test_utils::ExecuteJavaScriptAndExtractString; | |
26 | 29 |
27 namespace { | 30 namespace { |
28 | 31 |
32 std::wstring WrapForJavascriptAndExtract( | |
33 const wchar_t* javascript_expression) { | |
34 return std::wstring(L"window.domAutomationController.send(") + | |
35 javascript_expression + L")"; | |
36 } | |
37 | |
29 class IsolatedAppTest : public ExtensionBrowserTest { | 38 class IsolatedAppTest : public ExtensionBrowserTest { |
30 public: | 39 public: |
31 // Returns whether the given tab's current URL has the given cookie. | 40 // Returns whether the given tab's current URL has the given cookie. |
32 bool WARN_UNUSED_RESULT HasCookie(WebContents* contents, std::string cookie) { | 41 bool WARN_UNUSED_RESULT HasCookie(WebContents* contents, std::string cookie) { |
33 int value_size; | 42 int value_size; |
34 std::string actual_cookie; | 43 std::string actual_cookie; |
35 automation_util::GetCookies(contents->GetURL(), contents, &value_size, | 44 automation_util::GetCookies(contents->GetURL(), contents, &value_size, |
36 &actual_cookie); | 45 &actual_cookie); |
37 return actual_cookie.find(cookie) != std::string::npos; | 46 return actual_cookie.find(cookie) != std::string::npos; |
38 } | 47 } |
(...skipping 14 matching lines...) Expand all Loading... | |
53 virtual void SetUpCommandLine(CommandLine* command_line) { | 62 virtual void SetUpCommandLine(CommandLine* command_line) { |
54 ExtensionBrowserTest::SetUpCommandLine(command_line); | 63 ExtensionBrowserTest::SetUpCommandLine(command_line); |
55 command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis); | 64 command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis); |
56 } | 65 } |
57 }; | 66 }; |
58 | 67 |
59 } // namespace | 68 } // namespace |
60 | 69 |
61 // Tests that cookies set within an isolated app are not visible to normal | 70 // Tests that cookies set within an isolated app are not visible to normal |
62 // pages or other apps. | 71 // pages or other apps. |
72 // | |
73 // TODO(ajwong): Also test what happens if an app spans multiple sites in its | |
74 // extent. These origins should also be isolated, but still have origin-based | |
75 // separation as you would expect. | |
76 // | |
77 // TODO(ajwong): Add test for session storage. In one tab, navigate to a | |
78 // normal page and set X=ss_normal. Then navigate to an isolated URL in the | |
79 // same origin and verify X does not exist. Set X=ss_isolated. Navigate back to | |
80 // a normal webpage, and verify X is still ss_normal. Navigate to the isolate | |
81 // URL and verify that X is ss_isolated. | |
63 IN_PROC_BROWSER_TEST_F(IsolatedAppTest, CookieIsolation) { | 82 IN_PROC_BROWSER_TEST_F(IsolatedAppTest, CookieIsolation) { |
64 host_resolver()->AddRule("*", "127.0.0.1"); | 83 host_resolver()->AddRule("*", "127.0.0.1"); |
65 ASSERT_TRUE(test_server()->Start()); | 84 ASSERT_TRUE(test_server()->Start()); |
66 | 85 |
67 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("isolated_apps/app1"))); | 86 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("isolated_apps/app1"))); |
68 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("isolated_apps/app2"))); | 87 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("isolated_apps/app2"))); |
69 | 88 |
70 // The app under test acts on URLs whose host is "localhost", | 89 // The app under test acts on URLs whose host is "localhost", |
71 // so the URLs we navigate to must have host "localhost". | 90 // so the URLs we navigate to must have host "localhost". |
72 GURL base_url = test_server()->GetURL( | 91 GURL base_url = test_server()->GetURL( |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
113 EXPECT_FALSE(HasCookie(tab3, "app1")); | 132 EXPECT_FALSE(HasCookie(tab3, "app1")); |
114 EXPECT_FALSE(HasCookie(tab3, "app2")); | 133 EXPECT_FALSE(HasCookie(tab3, "app2")); |
115 | 134 |
116 // Check that the non_app iframe cookie is associated with app1 and not the | 135 // Check that the non_app iframe cookie is associated with app1 and not the |
117 // normal tab. (For now, iframes are always rendered in their parent | 136 // normal tab. (For now, iframes are always rendered in their parent |
118 // process, even if they aren't in the app manifest.) | 137 // process, even if they aren't in the app manifest.) |
119 EXPECT_TRUE(HasCookie(tab1, "nonAppFrame=6")); | 138 EXPECT_TRUE(HasCookie(tab1, "nonAppFrame=6")); |
120 EXPECT_FALSE(HasCookie(tab3, "nonAppFrame")); | 139 EXPECT_FALSE(HasCookie(tab3, "nonAppFrame")); |
121 | 140 |
122 // Check that isolation persists even if the tab crashes and is reloaded. | 141 // Check that isolation persists even if the tab crashes and is reloaded. |
123 chrome::SelectNumberedTab(browser(), 1); | 142 chrome::SelectNumberedTab(browser(), 0); |
Charlie Reis
2012/07/10 21:37:48
Oh, good catch. Unfortunate naming (tab at index
| |
124 ui_test_utils::CrashTab(tab1); | 143 ui_test_utils::CrashTab(tab1); |
125 ui_test_utils::WindowedNotificationObserver observer( | 144 ui_test_utils::WindowedNotificationObserver observer( |
126 content::NOTIFICATION_LOAD_STOP, | 145 content::NOTIFICATION_LOAD_STOP, |
127 content::Source<NavigationController>( | 146 content::Source<NavigationController>( |
128 &chrome::GetActiveWebContents(browser())->GetController())); | 147 &chrome::GetActiveWebContents(browser())->GetController())); |
129 chrome::Reload(browser(), CURRENT_TAB); | 148 chrome::Reload(browser(), CURRENT_TAB); |
130 observer.Wait(); | 149 observer.Wait(); |
131 EXPECT_TRUE(HasCookie(tab1, "app1=3")); | 150 EXPECT_TRUE(HasCookie(tab1, "app1=3")); |
132 EXPECT_FALSE(HasCookie(tab1, "app2")); | 151 EXPECT_FALSE(HasCookie(tab1, "app2")); |
133 EXPECT_FALSE(HasCookie(tab1, "normalPage")); | 152 EXPECT_FALSE(HasCookie(tab1, "normalPage")); |
153 | |
154 // Check that tabs see cannot each other's localStorage even though they are | |
155 // in the same origin. | |
156 RenderViewHost* app1_rvh = tab1->GetRenderViewHost(); | |
157 RenderViewHost* app2_rvh = tab2->GetRenderViewHost(); | |
158 RenderViewHost* non_app_rvh = tab3->GetRenderViewHost(); | |
159 ASSERT_TRUE(ui_test_utils::ExecuteJavaScript( | |
160 app1_rvh, L"", L"window.localStorage.setItem('testdata', 'ls_app1');")); | |
161 ASSERT_TRUE(ui_test_utils::ExecuteJavaScript( | |
162 app2_rvh, L"", L"window.localStorage.setItem('testdata', 'ls_app2');")); | |
163 ASSERT_TRUE(ui_test_utils::ExecuteJavaScript( | |
164 non_app_rvh, L"", | |
165 L"window.localStorage.setItem('testdata', 'ls_normal');")); | |
166 | |
167 ASSERT_TRUE(ExecuteJavaScript( | |
168 app1_rvh, L"", L"window.localStorage.getItem('testdata');")); | |
169 | |
170 const std::wstring& kRetrieveLocalStorage = | |
171 WrapForJavascriptAndExtract(L"window.localStorage.getItem('testdata')"); | |
172 std::string result; | |
173 ASSERT_TRUE(ExecuteJavaScriptAndExtractString( | |
174 app1_rvh, L"", kRetrieveLocalStorage.c_str(), &result)); | |
175 EXPECT_EQ("ls_app1", result); | |
176 ASSERT_TRUE(ExecuteJavaScriptAndExtractString( | |
177 app2_rvh, L"", kRetrieveLocalStorage.c_str(), &result)); | |
178 EXPECT_EQ("ls_app2", result); | |
179 ASSERT_TRUE(ExecuteJavaScriptAndExtractString( | |
180 non_app_rvh, L"", kRetrieveLocalStorage.c_str(), &result)); | |
181 EXPECT_EQ("ls_normal", result); | |
134 } | 182 } |
135 | 183 |
136 // Ensure that cookies are not isolated if the isolated apps are not installed. | 184 // Ensure that cookies are not isolated if the isolated apps are not installed. |
137 IN_PROC_BROWSER_TEST_F(IsolatedAppTest, NoCookieIsolationWithoutApp) { | 185 IN_PROC_BROWSER_TEST_F(IsolatedAppTest, NoCookieIsolationWithoutApp) { |
138 host_resolver()->AddRule("*", "127.0.0.1"); | 186 host_resolver()->AddRule("*", "127.0.0.1"); |
139 ASSERT_TRUE(test_server()->Start()); | 187 ASSERT_TRUE(test_server()->Start()); |
140 | 188 |
141 // The app under test acts on URLs whose host is "localhost", | 189 // The app under test acts on URLs whose host is "localhost", |
142 // so the URLs we navigate to must have host "localhost". | 190 // so the URLs we navigate to must have host "localhost". |
143 GURL base_url = test_server()->GetURL( | 191 GURL base_url = test_server()->GetURL( |
144 "files/extensions/isolated_apps/"); | 192 "files/extensions/isolated_apps/"); |
145 GURL::Replacements replace_host; | 193 GURL::Replacements replace_host; |
146 std::string host_str("localhost"); // Must stay in scope with replace_host. | 194 std::string host_str("localhost"); // Must stay in scope with replace_host. |
147 replace_host.SetHostStr(host_str); | 195 replace_host.SetHostStr(host_str); |
148 base_url = base_url.ReplaceComponents(replace_host); | 196 base_url = base_url.ReplaceComponents(replace_host); |
149 | 197 |
150 ui_test_utils::NavigateToURLWithDisposition( | 198 ui_test_utils::NavigateToURLWithDisposition( |
151 browser(), base_url.Resolve("app1/main.html"), | 199 browser(), base_url.Resolve("app1/main.html"), |
152 CURRENT_TAB, ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | 200 CURRENT_TAB, ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); |
153 ui_test_utils::NavigateToURLWithDisposition( | 201 ui_test_utils::NavigateToURLWithDisposition( |
154 browser(), base_url.Resolve("app2/main.html"), | 202 browser(), base_url.Resolve("app2/main.html"), |
155 NEW_FOREGROUND_TAB, ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | 203 NEW_FOREGROUND_TAB, ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); |
156 ui_test_utils::NavigateToURLWithDisposition( | 204 ui_test_utils::NavigateToURLWithDisposition( |
157 browser(), base_url.Resolve("non_app/main.html"), | 205 browser(), base_url.Resolve("non_app/main.html"), |
158 NEW_FOREGROUND_TAB, ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | 206 NEW_FOREGROUND_TAB, ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); |
159 | 207 |
160 ASSERT_EQ(3, browser()->tab_count()); | 208 ASSERT_EQ(3, browser()->tab_count()); |
161 | 209 |
162 // Check that tabs see each others' cookies. | 210 // Check that tabs see each other's cookies. |
163 EXPECT_TRUE(HasCookie(chrome::GetWebContentsAt(browser(), 0), "app2=4")); | 211 EXPECT_TRUE(HasCookie(chrome::GetWebContentsAt(browser(), 0), "app2=4")); |
164 EXPECT_TRUE(HasCookie(chrome::GetWebContentsAt(browser(), 0), "normalPage=5")) ; | 212 EXPECT_TRUE(HasCookie(chrome::GetWebContentsAt(browser(), 0), "normalPage=5")) ; |
165 EXPECT_TRUE(HasCookie(chrome::GetWebContentsAt(browser(), 0), "nonAppFrame=6") ); | 213 EXPECT_TRUE(HasCookie(chrome::GetWebContentsAt(browser(), 0), "nonAppFrame=6") ); |
166 EXPECT_TRUE(HasCookie(chrome::GetWebContentsAt(browser(), 1), "app1=3")); | 214 EXPECT_TRUE(HasCookie(chrome::GetWebContentsAt(browser(), 1), "app1=3")); |
167 EXPECT_TRUE(HasCookie(chrome::GetWebContentsAt(browser(), 1), "normalPage=5")) ; | 215 EXPECT_TRUE(HasCookie(chrome::GetWebContentsAt(browser(), 1), "normalPage=5")) ; |
168 EXPECT_TRUE(HasCookie(chrome::GetWebContentsAt(browser(), 1), "nonAppFrame=6") ); | 216 EXPECT_TRUE(HasCookie(chrome::GetWebContentsAt(browser(), 1), "nonAppFrame=6") ); |
169 EXPECT_TRUE(HasCookie(chrome::GetWebContentsAt(browser(), 2), "app1=3")); | 217 EXPECT_TRUE(HasCookie(chrome::GetWebContentsAt(browser(), 2), "app1=3")); |
170 EXPECT_TRUE(HasCookie(chrome::GetWebContentsAt(browser(), 2), "app2=4")); | 218 EXPECT_TRUE(HasCookie(chrome::GetWebContentsAt(browser(), 2), "app2=4")); |
171 EXPECT_TRUE(HasCookie(chrome::GetWebContentsAt(browser(), 2), "nonAppFrame=6") ); | 219 EXPECT_TRUE(HasCookie(chrome::GetWebContentsAt(browser(), 2), "nonAppFrame=6") ); |
220 | |
221 // Check that all tabs share the same localStorage if they have the same | |
222 // origin. | |
223 RenderViewHost* app1_rvh = | |
224 chrome::GetWebContentsAt(browser(), 0)->GetRenderViewHost(); | |
225 RenderViewHost* app2_rvh = | |
226 chrome::GetWebContentsAt(browser(), 1)->GetRenderViewHost(); | |
227 RenderViewHost* non_app_rvh = | |
228 chrome::GetWebContentsAt(browser(), 2)->GetRenderViewHost(); | |
229 ASSERT_TRUE(ui_test_utils::ExecuteJavaScript( | |
230 app1_rvh, L"", L"window.localStorage.setItem('testdata', 'ls_app1');")); | |
231 ASSERT_TRUE(ui_test_utils::ExecuteJavaScript( | |
232 app2_rvh, L"", L"window.localStorage.setItem('testdata', 'ls_app2');")); | |
233 ASSERT_TRUE(ui_test_utils::ExecuteJavaScript( | |
234 non_app_rvh, L"", | |
235 L"window.localStorage.setItem('testdata', 'ls_normal');")); | |
236 | |
237 const std::wstring& kRetrieveLocalStorage = | |
238 WrapForJavascriptAndExtract(L"window.localStorage.getItem('testdata')"); | |
239 std::string result; | |
240 ASSERT_TRUE(ExecuteJavaScriptAndExtractString( | |
241 app1_rvh, L"", kRetrieveLocalStorage.c_str(), &result)); | |
242 EXPECT_EQ("ls_normal", result); | |
243 ASSERT_TRUE(ExecuteJavaScriptAndExtractString( | |
244 app2_rvh, L"", kRetrieveLocalStorage.c_str(), &result)); | |
245 EXPECT_EQ("ls_normal", result); | |
246 ASSERT_TRUE(ExecuteJavaScriptAndExtractString( | |
247 non_app_rvh, L"", kRetrieveLocalStorage.c_str(), &result)); | |
248 EXPECT_EQ("ls_normal", result); | |
172 } | 249 } |
173 | 250 |
174 // Tests that isolated apps processes do not render top-level non-app pages. | 251 // Tests that isolated apps processes do not render top-level non-app pages. |
175 // This is true even in the case of the OAuth workaround for hosted apps, | 252 // This is true even in the case of the OAuth workaround for hosted apps, |
176 // where non-app popups may be kept in the hosted app process. | 253 // where non-app popups may be kept in the hosted app process. |
177 IN_PROC_BROWSER_TEST_F(IsolatedAppTest, IsolatedAppProcessModel) { | 254 IN_PROC_BROWSER_TEST_F(IsolatedAppTest, IsolatedAppProcessModel) { |
178 host_resolver()->AddRule("*", "127.0.0.1"); | 255 host_resolver()->AddRule("*", "127.0.0.1"); |
179 ASSERT_TRUE(test_server()->Start()); | 256 ASSERT_TRUE(test_server()->Start()); |
180 | 257 |
181 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("isolated_apps/app1"))); | 258 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("isolated_apps/app1"))); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
218 chrome::GetWebContentsAt(browser(), 2)->GetRenderProcessHost()->GetI D()); | 295 chrome::GetWebContentsAt(browser(), 2)->GetRenderProcessHost()->GetI D()); |
219 EXPECT_NE(process_id_0, | 296 EXPECT_NE(process_id_0, |
220 chrome::GetWebContentsAt(browser(), 3)->GetRenderProcessHost()->GetI D()); | 297 chrome::GetWebContentsAt(browser(), 3)->GetRenderProcessHost()->GetI D()); |
221 | 298 |
222 // Navigating the second tab out of the app should cause a process swap. | 299 // Navigating the second tab out of the app should cause a process swap. |
223 const GURL& non_app_url(base_url.Resolve("non_app/main.html")); | 300 const GURL& non_app_url(base_url.Resolve("non_app/main.html")); |
224 NavigateInRenderer(chrome::GetWebContentsAt(browser(), 1), non_app_url); | 301 NavigateInRenderer(chrome::GetWebContentsAt(browser(), 1), non_app_url); |
225 EXPECT_NE(process_id_1, | 302 EXPECT_NE(process_id_1, |
226 chrome::GetWebContentsAt(browser(), 1)->GetRenderProcessHost()->GetI D()); | 303 chrome::GetWebContentsAt(browser(), 1)->GetRenderProcessHost()->GetI D()); |
227 } | 304 } |
OLD | NEW |