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/files/file_path.h" | 5 #include "base/files/file_path.h" |
6 #include "base/path_service.h" | 6 #include "base/path_service.h" |
7 #include "base/strings/string_number_conversions.h" | 7 #include "base/strings/string_number_conversions.h" |
8 #include "base/strings/stringprintf.h" | 8 #include "base/strings/stringprintf.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 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 enum Result { | 135 enum Result { |
136 OK = 0, | 136 OK = 0, |
137 NAMESPACE_NOT_DEFINED = 1, | 137 NAMESPACE_NOT_DEFINED = 1, |
138 FUNCTION_NOT_DEFINED = 2, | 138 FUNCTION_NOT_DEFINED = 2, |
139 COULD_NOT_ESTABLISH_CONNECTION_ERROR = 3, | 139 COULD_NOT_ESTABLISH_CONNECTION_ERROR = 3, |
140 OTHER_ERROR = 4, | 140 OTHER_ERROR = 4, |
141 INCORRECT_RESPONSE_SENDER = 5, | 141 INCORRECT_RESPONSE_SENDER = 5, |
142 INCORRECT_RESPONSE_MESSAGE = 6, | 142 INCORRECT_RESPONSE_MESSAGE = 6, |
143 }; | 143 }; |
144 | 144 |
| 145 bool AppendIframe(const GURL& src) { |
| 146 bool result; |
| 147 CHECK(content::ExecuteScriptAndExtractBool( |
| 148 browser()->tab_strip_model()->GetActiveWebContents(), |
| 149 "actions.appendIframe('" + src.spec() + "');", &result)); |
| 150 return result; |
| 151 } |
| 152 |
145 Result CanConnectAndSendMessages(const std::string& extension_id) { | 153 Result CanConnectAndSendMessages(const std::string& extension_id) { |
146 return CanConnectAndSendMessages(browser(), extension_id); | 154 return CanConnectAndSendMessages(browser(), extension_id, ""); |
147 } | 155 } |
148 | 156 |
149 Result CanConnectAndSendMessages(Browser* browser, | 157 Result CanConnectAndSendMessages(Browser* browser, |
150 const std::string& extension_id) { | 158 const std::string& extension_id) { |
| 159 return CanConnectAndSendMessages(browser, extension_id, ""); |
| 160 } |
| 161 |
| 162 Result CanConnectAndSendMessages(const std::string& extension_id, |
| 163 const char* frame_xpath) { |
| 164 return CanConnectAndSendMessages(browser(), extension_id, frame_xpath); |
| 165 } |
| 166 |
| 167 Result CanConnectAndSendMessages(Browser* browser, |
| 168 const std::string& extension_id, |
| 169 const char* frame_xpath) { |
151 int result; | 170 int result; |
152 CHECK(content::ExecuteScriptAndExtractInt( | 171 CHECK(content::ExecuteScriptInFrameAndExtractInt( |
153 browser->tab_strip_model()->GetActiveWebContents(), | 172 browser->tab_strip_model()->GetActiveWebContents(), |
| 173 frame_xpath, |
154 "assertions.canConnectAndSendMessages('" + extension_id + "')", | 174 "assertions.canConnectAndSendMessages('" + extension_id + "')", |
155 &result)); | 175 &result)); |
156 return static_cast<Result>(result); | 176 return static_cast<Result>(result); |
157 } | 177 } |
158 | 178 |
159 testing::AssertionResult AreAnyNonWebApisDefined() { | 179 testing::AssertionResult AreAnyNonWebApisDefined() { |
| 180 return AreAnyNonWebApisDefined(""); |
| 181 } |
| 182 |
| 183 testing::AssertionResult AreAnyNonWebApisDefined(const char* frame_xpath) { |
160 // All runtime API methods are non-web except for sendRequest and connect. | 184 // All runtime API methods are non-web except for sendRequest and connect. |
161 const char* non_messaging_apis[] = { | 185 const char* non_messaging_apis[] = { |
162 "getBackgroundPage", | 186 "getBackgroundPage", |
163 "getManifest", | 187 "getManifest", |
164 "getURL", | 188 "getURL", |
165 "reload", | 189 "reload", |
166 "requestUpdateCheck", | 190 "requestUpdateCheck", |
167 "connectNative", | 191 "connectNative", |
168 "sendNativeMessage", | 192 "sendNativeMessage", |
169 "onStartup", | 193 "onStartup", |
(...skipping 12 matching lines...) Expand all Loading... |
182 | 206 |
183 // Turn the array into a JS array, which effectively gets eval()ed. | 207 // Turn the array into a JS array, which effectively gets eval()ed. |
184 std::string as_js_array; | 208 std::string as_js_array; |
185 for (size_t i = 0; i < arraysize(non_messaging_apis); ++i) { | 209 for (size_t i = 0; i < arraysize(non_messaging_apis); ++i) { |
186 as_js_array += as_js_array.empty() ? "[" : ","; | 210 as_js_array += as_js_array.empty() ? "[" : ","; |
187 as_js_array += base::StringPrintf("'%s'", non_messaging_apis[i]); | 211 as_js_array += base::StringPrintf("'%s'", non_messaging_apis[i]); |
188 } | 212 } |
189 as_js_array += "]"; | 213 as_js_array += "]"; |
190 | 214 |
191 bool any_defined; | 215 bool any_defined; |
192 CHECK(content::ExecuteScriptAndExtractBool( | 216 CHECK(content::ExecuteScriptInFrameAndExtractBool( |
193 browser()->tab_strip_model()->GetActiveWebContents(), | 217 browser()->tab_strip_model()->GetActiveWebContents(), |
| 218 frame_xpath, |
194 "assertions.areAnyRuntimePropertiesDefined(" + as_js_array + ")", | 219 "assertions.areAnyRuntimePropertiesDefined(" + as_js_array + ")", |
195 &any_defined)); | 220 &any_defined)); |
196 return any_defined ? | 221 return any_defined ? |
197 testing::AssertionSuccess() : testing::AssertionFailure(); | 222 testing::AssertionSuccess() : testing::AssertionFailure(); |
198 } | 223 } |
199 | 224 |
200 GURL GetURLForPath(const std::string& host, const std::string& path) { | 225 GURL GetURLForPath(const std::string& host, const std::string& path) { |
201 std::string port = base::IntToString(embedded_test_server()->port()); | 226 std::string port = base::IntToString(embedded_test_server()->port()); |
202 GURL::Replacements replacements; | 227 GURL::Replacements replacements; |
203 replacements.SetHostStr(host); | 228 replacements.SetHostStr(host); |
204 replacements.SetPortStr(port); | 229 replacements.SetPortStr(port); |
205 return embedded_test_server()->GetURL(path).ReplaceComponents(replacements); | 230 return embedded_test_server()->GetURL(path).ReplaceComponents(replacements); |
206 } | 231 } |
207 | 232 |
208 GURL chromium_org_url() { | 233 GURL chromium_org_url() { |
209 return GetURLForPath("www.chromium.org", "/chromium.org.html"); | 234 return GetURLForPath("www.chromium.org", "/chromium.org.html"); |
210 } | 235 } |
211 | 236 |
212 GURL google_com_url() { | 237 GURL google_com_url() { |
213 return GetURLForPath("www.google.com", "/google.com.html"); | 238 return GetURLForPath("www.google.com", "/google.com.html"); |
214 } | 239 } |
215 | 240 |
216 const Extension* LoadChromiumConnectableExtension() { | 241 const Extension* LoadChromiumConnectableExtension() { |
217 return LoadExtensionIntoDir(&web_connectable_dir_, base::StringPrintf( | 242 const Extension* extension = |
218 "{" | 243 LoadExtensionIntoDir(&web_connectable_dir_, base::StringPrintf( |
219 " \"name\": \"chromium_connectable\"," | 244 "{" |
220 " %s," | 245 " \"name\": \"chromium_connectable\"," |
221 " \"externally_connectable\": {" | 246 " %s," |
222 " \"matches\": [\"*://*.chromium.org:*/*\"]" | 247 " \"externally_connectable\": {" |
223 " }" | 248 " \"matches\": [\"*://*.chromium.org:*/*\"]" |
224 "}", | 249 " }" |
225 common_manifest())); | 250 "}", |
| 251 common_manifest())); |
| 252 CHECK(extension); |
| 253 return extension; |
226 } | 254 } |
227 | 255 |
228 scoped_refptr<const Extension> LoadNotConnectableExtension() { | 256 const Extension* LoadNotConnectableExtension() { |
229 return LoadExtensionIntoDir(¬_connectable_dir_, base::StringPrintf( | 257 const Extension* extension = |
230 "{" | 258 LoadExtensionIntoDir(¬_connectable_dir_, base::StringPrintf( |
231 " \"name\": \"not_connectable\"," | 259 "{" |
232 " %s" | 260 " \"name\": \"not_connectable\"," |
233 "}", | 261 " %s" |
234 common_manifest())); | 262 "}", |
| 263 common_manifest())); |
| 264 CHECK(extension); |
| 265 return extension; |
235 } | 266 } |
236 | 267 |
237 void InitializeTestServer() { | 268 void InitializeTestServer() { |
238 base::FilePath test_data; | 269 base::FilePath test_data; |
239 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data)); | 270 EXPECT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data)); |
240 embedded_test_server()->ServeFilesFromDirectory(test_data.AppendASCII( | 271 embedded_test_server()->ServeFilesFromDirectory(test_data.AppendASCII( |
241 "extensions/api_test/messaging/externally_connectable/sites")); | 272 "extensions/api_test/messaging/externally_connectable/sites")); |
242 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); | 273 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); |
243 host_resolver()->AddRule("*", embedded_test_server()->base_url().host()); | 274 host_resolver()->AddRule("*", embedded_test_server()->base_url().host()); |
244 } | 275 } |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 } | 319 } |
289 | 320 |
290 // Tests two extensions on the same sites: one web connectable, one not. | 321 // Tests two extensions on the same sites: one web connectable, one not. |
291 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, | 322 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, |
292 WebConnectableAndNotConnectable) { | 323 WebConnectableAndNotConnectable) { |
293 InitializeTestServer(); | 324 InitializeTestServer(); |
294 | 325 |
295 // Install the web connectable extension. chromium.org can connect to it, | 326 // Install the web connectable extension. chromium.org can connect to it, |
296 // google.com can't. | 327 // google.com can't. |
297 const Extension* chromium_connectable = LoadChromiumConnectableExtension(); | 328 const Extension* chromium_connectable = LoadChromiumConnectableExtension(); |
298 ASSERT_TRUE(chromium_connectable); | |
299 | 329 |
300 ui_test_utils::NavigateToURL(browser(), chromium_org_url()); | 330 ui_test_utils::NavigateToURL(browser(), chromium_org_url()); |
301 EXPECT_EQ(OK, CanConnectAndSendMessages(chromium_connectable->id())); | 331 EXPECT_EQ(OK, CanConnectAndSendMessages(chromium_connectable->id())); |
302 EXPECT_FALSE(AreAnyNonWebApisDefined()); | 332 EXPECT_FALSE(AreAnyNonWebApisDefined()); |
303 | 333 |
304 ui_test_utils::NavigateToURL(browser(), google_com_url()); | 334 ui_test_utils::NavigateToURL(browser(), google_com_url()); |
305 EXPECT_EQ(NAMESPACE_NOT_DEFINED, | 335 EXPECT_EQ(NAMESPACE_NOT_DEFINED, |
306 CanConnectAndSendMessages(chromium_connectable->id())); | 336 CanConnectAndSendMessages(chromium_connectable->id())); |
307 EXPECT_FALSE(AreAnyNonWebApisDefined()); | 337 EXPECT_FALSE(AreAnyNonWebApisDefined()); |
308 | 338 |
309 // Install the non-connectable extension. Nothing can connect to it. | 339 // Install the non-connectable extension. Nothing can connect to it. |
310 const Extension* not_connectable = LoadNotConnectableExtension(); | 340 const Extension* not_connectable = LoadNotConnectableExtension(); |
311 ASSERT_TRUE(not_connectable); | |
312 | 341 |
313 ui_test_utils::NavigateToURL(browser(), chromium_org_url()); | 342 ui_test_utils::NavigateToURL(browser(), chromium_org_url()); |
314 // Namespace will be defined here because |chromium_connectable| can connect | 343 // Namespace will be defined here because |chromium_connectable| can connect |
315 // to it - so this will be the "cannot establish connection" error. | 344 // to it - so this will be the "cannot establish connection" error. |
316 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR, | 345 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR, |
317 CanConnectAndSendMessages(not_connectable->id())); | 346 CanConnectAndSendMessages(not_connectable->id())); |
318 EXPECT_FALSE(AreAnyNonWebApisDefined()); | 347 EXPECT_FALSE(AreAnyNonWebApisDefined()); |
319 | 348 |
320 ui_test_utils::NavigateToURL(browser(), google_com_url()); | 349 ui_test_utils::NavigateToURL(browser(), google_com_url()); |
321 EXPECT_EQ(NAMESPACE_NOT_DEFINED, | 350 EXPECT_EQ(NAMESPACE_NOT_DEFINED, |
322 CanConnectAndSendMessages(not_connectable->id())); | 351 CanConnectAndSendMessages(not_connectable->id())); |
323 EXPECT_FALSE(AreAnyNonWebApisDefined()); | 352 EXPECT_FALSE(AreAnyNonWebApisDefined()); |
324 } | 353 } |
325 | 354 |
326 // Tests that enabling and disabling an extension makes the runtime bindings | 355 // Tests that enabling and disabling an extension makes the runtime bindings |
327 // appear and disappear. | 356 // appear and disappear. |
328 // | 357 // |
329 // TODO(kalman): Test with multiple extensions that can be accessed by the same | 358 // TODO(kalman): Test with multiple extensions that can be accessed by the same |
330 // host. | 359 // host. |
331 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, | 360 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, |
332 EnablingAndDisabling) { | 361 EnablingAndDisabling) { |
333 InitializeTestServer(); | 362 InitializeTestServer(); |
334 | 363 |
335 const Extension* chromium_connectable = LoadChromiumConnectableExtension(); | 364 const Extension* chromium_connectable = LoadChromiumConnectableExtension(); |
336 ASSERT_TRUE(chromium_connectable); | |
337 const Extension* not_connectable = LoadNotConnectableExtension(); | 365 const Extension* not_connectable = LoadNotConnectableExtension(); |
338 ASSERT_TRUE(not_connectable); | |
339 | 366 |
340 ui_test_utils::NavigateToURL(browser(), chromium_org_url()); | 367 ui_test_utils::NavigateToURL(browser(), chromium_org_url()); |
341 EXPECT_EQ(OK, CanConnectAndSendMessages(chromium_connectable->id())); | 368 EXPECT_EQ(OK, CanConnectAndSendMessages(chromium_connectable->id())); |
342 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR, | 369 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR, |
343 CanConnectAndSendMessages(not_connectable->id())); | 370 CanConnectAndSendMessages(not_connectable->id())); |
344 | 371 |
345 DisableExtension(chromium_connectable->id()); | 372 DisableExtension(chromium_connectable->id()); |
346 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR, | 373 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR, |
347 CanConnectAndSendMessages(chromium_connectable->id())); | 374 CanConnectAndSendMessages(chromium_connectable->id())); |
348 | 375 |
349 EnableExtension(chromium_connectable->id()); | 376 EnableExtension(chromium_connectable->id()); |
350 EXPECT_EQ(OK, CanConnectAndSendMessages(chromium_connectable->id())); | 377 EXPECT_EQ(OK, CanConnectAndSendMessages(chromium_connectable->id())); |
351 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR, | 378 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR, |
352 CanConnectAndSendMessages(not_connectable->id())); | 379 CanConnectAndSendMessages(not_connectable->id())); |
353 } | 380 } |
354 | 381 |
355 // Tests connection from incognito tabs. Spanning mode only. | 382 // Tests connection from incognito tabs. Spanning mode only. |
356 // | 383 // |
357 // TODO(kalman): ensure that we exercise split vs spanning incognito logic | 384 // TODO(kalman): ensure that we exercise split vs spanning incognito logic |
358 // somewhere. This is a test that should be shared with the content script logic | 385 // somewhere. This is a test that should be shared with the content script logic |
359 // so it's not really our specific concern for web connectable. | 386 // so it's not really our specific concern for web connectable. |
360 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, FromIncognito) { | 387 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, FromIncognito) { |
361 InitializeTestServer(); | 388 InitializeTestServer(); |
362 | 389 |
363 const Extension* chromium_connectable = LoadChromiumConnectableExtension(); | 390 const Extension* chromium_connectable = LoadChromiumConnectableExtension(); |
364 ASSERT_TRUE(chromium_connectable); | |
365 | 391 |
366 Browser* incognito_browser = ui_test_utils::OpenURLOffTheRecord( | 392 Browser* incognito_browser = ui_test_utils::OpenURLOffTheRecord( |
367 profile()->GetOffTheRecordProfile(), | 393 profile()->GetOffTheRecordProfile(), |
368 chromium_org_url()); | 394 chromium_org_url()); |
369 | 395 |
370 // No connection because incognito enabled hasn't been set. | 396 // No connection because incognito enabled hasn't been set. |
371 const std::string& id = chromium_connectable->id(); | 397 const std::string& id = chromium_connectable->id(); |
372 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR, | 398 EXPECT_EQ(COULD_NOT_ESTABLISH_CONNECTION_ERROR, |
373 CanConnectAndSendMessages(incognito_browser, id)); | 399 CanConnectAndSendMessages(incognito_browser, id)); |
374 | 400 |
375 // Then yes. | 401 // Then yes. |
376 ExtensionPrefs::Get(profile())->SetIsIncognitoEnabled(id, true); | 402 ExtensionPrefs::Get(profile())->SetIsIncognitoEnabled(id, true); |
377 EXPECT_EQ(OK, CanConnectAndSendMessages(incognito_browser, id)); | 403 EXPECT_EQ(OK, CanConnectAndSendMessages(incognito_browser, id)); |
378 } | 404 } |
379 | 405 |
| 406 // Tests a connection from an iframe within a tab which doesn't have |
| 407 // permission. Iframe should work. |
| 408 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, |
| 409 FromIframeWithPermission) { |
| 410 InitializeTestServer(); |
| 411 |
| 412 const Extension* extension = LoadChromiumConnectableExtension(); |
| 413 |
| 414 ui_test_utils::NavigateToURL(browser(), google_com_url()); |
| 415 EXPECT_EQ(NAMESPACE_NOT_DEFINED, CanConnectAndSendMessages(extension->id())); |
| 416 EXPECT_FALSE(AreAnyNonWebApisDefined()); |
| 417 |
| 418 ASSERT_TRUE(AppendIframe(chromium_org_url())); |
| 419 |
| 420 const char* frame_xpath = "//iframe[1]"; |
| 421 EXPECT_EQ(OK, CanConnectAndSendMessages(extension->id(), frame_xpath)); |
| 422 EXPECT_FALSE(AreAnyNonWebApisDefined(frame_xpath)); |
| 423 } |
| 424 |
| 425 // Tests connection from an iframe without permission within a tab that does. |
| 426 // Iframe shouldn't work. |
| 427 IN_PROC_BROWSER_TEST_F(ExternallyConnectableMessagingTest, |
| 428 FromIframeWithoutPermission) { |
| 429 InitializeTestServer(); |
| 430 |
| 431 const Extension* extension = LoadChromiumConnectableExtension(); |
| 432 |
| 433 ui_test_utils::NavigateToURL(browser(), chromium_org_url()); |
| 434 EXPECT_EQ(OK, CanConnectAndSendMessages(extension->id())); |
| 435 EXPECT_FALSE(AreAnyNonWebApisDefined()); |
| 436 |
| 437 ASSERT_TRUE(AppendIframe(google_com_url())); |
| 438 |
| 439 const char* frame_xpath = "//iframe[1]"; |
| 440 EXPECT_EQ(NAMESPACE_NOT_DEFINED, |
| 441 CanConnectAndSendMessages(extension->id(), frame_xpath)); |
| 442 EXPECT_FALSE(AreAnyNonWebApisDefined(frame_xpath)); |
| 443 } |
| 444 |
380 } // namespace | 445 } // namespace |
381 } // namespace extensions | 446 }; // namespace extensions |
OLD | NEW |