OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 #include <vector> | 6 #include <vector> |
7 | 7 |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
11 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
12 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" |
13 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
14 #include "chrome/browser/extensions/extension_apitest.h" | 14 #include "chrome/browser/extensions/extension_apitest.h" |
15 #include "chrome/browser/extensions/test_extension_dir.h" | 15 #include "chrome/browser/extensions/test_extension_dir.h" |
| 16 #include "chrome/browser/profiles/profile.h" |
16 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 17 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
17 #include "chrome/common/chrome_paths.h" | 18 #include "chrome/common/chrome_paths.h" |
18 #include "chrome/test/base/ui_test_utils.h" | 19 #include "chrome/test/base/ui_test_utils.h" |
19 #include "components/crx_file/id_util.h" | 20 #include "components/crx_file/id_util.h" |
20 #include "content/public/test/browser_test_utils.h" | 21 #include "content/public/test/browser_test_utils.h" |
21 #include "extensions/common/extension_builder.h" | 22 #include "extensions/common/extension_builder.h" |
22 #include "extensions/common/manifest_handlers/content_capabilities_handler.h" | 23 #include "extensions/common/manifest_handlers/content_capabilities_handler.h" |
23 #include "extensions/common/switches.h" | 24 #include "extensions/common/switches.h" |
24 #include "extensions/common/url_pattern.h" | 25 #include "extensions/common/url_pattern.h" |
25 #include "net/dns/mock_host_resolver.h" | 26 #include "net/dns/mock_host_resolver.h" |
26 #include "net/test/embedded_test_server/embedded_test_server.h" | 27 #include "net/test/embedded_test_server/embedded_test_server.h" |
| 28 #include "storage/browser/quota/special_storage_policy.h" |
27 | 29 |
28 using extensions::DictionaryBuilder; | 30 using extensions::DictionaryBuilder; |
29 using extensions::Extension; | 31 using extensions::Extension; |
30 using extensions::ExtensionBuilder; | 32 using extensions::ExtensionBuilder; |
31 using extensions::ListBuilder; | 33 using extensions::ListBuilder; |
32 | 34 |
33 class ContentCapabilitiesTest : public ExtensionApiTest { | 35 class ContentCapabilitiesTest : public ExtensionApiTest { |
34 protected: | 36 protected: |
35 void SetUpCommandLine(base::CommandLine* command_line) override { | 37 void SetUpCommandLine(base::CommandLine* command_line) override { |
36 ExtensionApiTest::SetUpCommandLine(command_line); | 38 ExtensionApiTest::SetUpCommandLine(command_line); |
37 command_line->AppendSwitchASCII( | 39 command_line->AppendSwitchASCII( |
38 extensions::switches::kWhitelistedExtensionID, | 40 extensions::switches::kWhitelistedExtensionID, |
39 crx_file::id_util::GenerateIdForPath( | 41 crx_file::id_util::GenerateIdForPath( |
40 base::MakeAbsoluteFilePath(test_extension_dir_.unpacked_path()))); | 42 base::MakeAbsoluteFilePath(test_extension_dir_.unpacked_path()))); |
41 } | 43 } |
42 | 44 |
43 // Builds an extension manifest with the given content_capabilities matches | 45 // Builds an extension manifest with the given content_capabilities matches |
44 // and permissions. The extension always has the same (whitelisted) ID. | 46 // and permissions. The extension always has the same (whitelisted) ID. |
45 scoped_refptr<const Extension> LoadExtensionWithCapabilities( | 47 scoped_refptr<const Extension> LoadExtensionWithCapabilities( |
46 const std::string& matches, | 48 const std::string& matches, |
47 const std::string& permissions) { | 49 const std::string& permissions, |
| 50 const std::string& extension_permissions = "[]") { |
48 std::string manifest = base::StringPrintf( | 51 std::string manifest = base::StringPrintf( |
49 "{\n" | 52 "{\n" |
50 " \"name\": \"content_capabilities test extensions\",\n" | 53 " \"name\": \"content_capabilities test extensions\",\n" |
51 " \"version\": \"1\",\n" | 54 " \"version\": \"1\",\n" |
52 " \"manifest_version\": 2,\n" | 55 " \"manifest_version\": 2,\n" |
53 " \"content_capabilities\": {\n" | 56 " \"content_capabilities\": {\n" |
54 " \"matches\": %s,\n" | 57 " \"matches\": %s,\n" |
55 " \"permissions\": %s\n" | 58 " \"permissions\": %s\n" |
56 " }\n" | 59 " },\n" |
| 60 " \"permissions\": %s\n" |
57 "}\n", | 61 "}\n", |
58 matches.c_str(), permissions.c_str()); | 62 matches.c_str(), permissions.c_str(), extension_permissions.c_str()); |
59 test_extension_dir_.WriteManifest(manifest); | 63 test_extension_dir_.WriteManifest(manifest); |
60 return LoadExtension(test_extension_dir_.unpacked_path()); | 64 return LoadExtension(test_extension_dir_.unpacked_path()); |
61 } | 65 } |
62 | 66 |
63 std::string MakeJSONList(const std::string& s0 = "", | 67 std::string MakeJSONList(const std::string& s0 = "", |
64 const std::string& s1 = "", | 68 const std::string& s1 = "", |
65 const std::string& s2 = "") { | 69 const std::string& s2 = "") { |
66 std::vector<std::string> v; | 70 std::vector<std::string> v; |
67 if (!s0.empty()) | 71 if (!s0.empty()) |
68 v.push_back(s0); | 72 v.push_back(s0); |
(...skipping 27 matching lines...) Expand all Loading... |
96 embedded_test_server()->ServeFilesFromDirectory( | 100 embedded_test_server()->ServeFilesFromDirectory( |
97 test_data.AppendASCII("extensions/content_capabilities")); | 101 test_data.AppendASCII("extensions/content_capabilities")); |
98 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); | 102 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); |
99 host_resolver()->AddRule("*", embedded_test_server()->base_url().host()); | 103 host_resolver()->AddRule("*", embedded_test_server()->base_url().host()); |
100 } | 104 } |
101 | 105 |
102 // Run some script in the context of the given origin and in the presence of | 106 // Run some script in the context of the given origin and in the presence of |
103 // the given extension. This is used to wrap calls into the JS test functions | 107 // the given extension. This is used to wrap calls into the JS test functions |
104 // defined by | 108 // defined by |
105 // $(DIR_TEST_DATA)/extensions/content_capabilities/capability_tests.js. | 109 // $(DIR_TEST_DATA)/extensions/content_capabilities/capability_tests.js. |
106 bool TestContentCapability(const Extension* extension, | 110 testing::AssertionResult TestScriptResult(const Extension* extension, |
107 const char* origin, | 111 const GURL& url, |
108 const char* code) { | 112 const char* code) { |
109 ui_test_utils::NavigateToURL(browser(), GetTestURLFor(origin)); | 113 ui_test_utils::NavigateToURL(browser(), url); |
110 bool result = false; | 114 bool result = false; |
111 CHECK(content::ExecuteScriptAndExtractBool(web_contents(), code, &result)); | 115 if (!content::ExecuteScriptAndExtractBool(web_contents(), code, &result)) |
112 return result; | 116 return testing::AssertionFailure() << "Could not execute test script."; |
| 117 if (!result) |
| 118 return testing::AssertionFailure(); |
| 119 return testing::AssertionSuccess(); |
113 } | 120 } |
114 | 121 |
115 bool CanReadClipboard(const Extension* extension, const char* origin) { | 122 testing::AssertionResult CanReadClipboard(const Extension* extension, |
116 return TestContentCapability(extension, origin, "tests.canReadClipboard()"); | 123 const GURL& url) { |
| 124 return TestScriptResult(extension, url, "tests.canReadClipboard()"); |
117 } | 125 } |
118 | 126 |
119 bool CanWriteClipboard(const Extension* extension, const char* origin) { | 127 testing::AssertionResult CanWriteClipboard(const Extension* extension, |
120 return TestContentCapability(extension, origin, | 128 const GURL& url) { |
121 "tests.canWriteClipboard()"); | 129 return TestScriptResult(extension, url, "tests.canWriteClipboard()"); |
| 130 } |
| 131 |
| 132 testing::AssertionResult HasUnlimitedStorage(const Extension* extension, |
| 133 const GURL& url) { |
| 134 if (profile()->GetSpecialStoragePolicy()->IsStorageUnlimited(url)) |
| 135 return testing::AssertionSuccess(); |
| 136 return testing::AssertionFailure(); |
122 } | 137 } |
123 | 138 |
124 private: | 139 private: |
125 extensions::TestExtensionDir test_extension_dir_; | 140 extensions::TestExtensionDir test_extension_dir_; |
126 }; | 141 }; |
127 | 142 |
128 IN_PROC_BROWSER_TEST_F(ContentCapabilitiesTest, NoCapabilities) { | 143 IN_PROC_BROWSER_TEST_F(ContentCapabilitiesTest, NoCapabilities) { |
129 InitializeTestServer(); | 144 InitializeTestServer(); |
130 scoped_refptr<const Extension> extension = LoadExtensionWithCapabilities( | 145 scoped_refptr<const Extension> extension = LoadExtensionWithCapabilities( |
131 MakeJSONList("http://foo.example.com/*"), MakeJSONList()); | 146 MakeJSONList("http://foo.example.com/*"), MakeJSONList()); |
132 EXPECT_FALSE(CanReadClipboard(extension.get(), "foo.example.com")); | 147 EXPECT_FALSE( |
133 EXPECT_FALSE(CanWriteClipboard(extension.get(), "foo.example.com")); | 148 CanReadClipboard(extension.get(), GetTestURLFor("foo.example.com"))); |
| 149 EXPECT_FALSE( |
| 150 CanWriteClipboard(extension.get(), GetTestURLFor("foo.example.com"))); |
| 151 EXPECT_FALSE( |
| 152 HasUnlimitedStorage(extension.get(), GetTestURLFor("foo.example.com"))); |
134 } | 153 } |
135 | 154 |
136 IN_PROC_BROWSER_TEST_F(ContentCapabilitiesTest, ClipboardRead) { | 155 IN_PROC_BROWSER_TEST_F(ContentCapabilitiesTest, ClipboardRead) { |
137 InitializeTestServer(); | 156 InitializeTestServer(); |
138 scoped_refptr<const Extension> extension = LoadExtensionWithCapabilities( | 157 scoped_refptr<const Extension> extension = LoadExtensionWithCapabilities( |
139 MakeJSONList("http://foo.example.com/*"), MakeJSONList("clipboardRead")); | 158 MakeJSONList("http://foo.example.com/*"), MakeJSONList("clipboardRead")); |
140 EXPECT_TRUE(CanReadClipboard(extension.get(), "foo.example.com")); | 159 EXPECT_TRUE( |
141 EXPECT_FALSE(CanReadClipboard(extension.get(), "bar.example.com")); | 160 CanReadClipboard(extension.get(), GetTestURLFor("foo.example.com"))); |
142 EXPECT_FALSE(CanWriteClipboard(extension.get(), "foo.example.com")); | 161 EXPECT_FALSE( |
| 162 CanReadClipboard(extension.get(), GetTestURLFor("bar.example.com"))); |
| 163 EXPECT_FALSE( |
| 164 CanWriteClipboard(extension.get(), GetTestURLFor("foo.example.com"))); |
143 } | 165 } |
144 | 166 |
145 IN_PROC_BROWSER_TEST_F(ContentCapabilitiesTest, ClipboardWrite) { | 167 IN_PROC_BROWSER_TEST_F(ContentCapabilitiesTest, ClipboardWrite) { |
146 InitializeTestServer(); | 168 InitializeTestServer(); |
147 scoped_refptr<const Extension> extension = LoadExtensionWithCapabilities( | 169 scoped_refptr<const Extension> extension = LoadExtensionWithCapabilities( |
148 MakeJSONList("http://foo.example.com/*"), MakeJSONList("clipboardWrite")); | 170 MakeJSONList("http://foo.example.com/*"), MakeJSONList("clipboardWrite")); |
149 EXPECT_TRUE(CanWriteClipboard(extension.get(), "foo.example.com")); | 171 EXPECT_TRUE( |
150 EXPECT_FALSE(CanWriteClipboard(extension.get(), "bar.example.com")); | 172 CanWriteClipboard(extension.get(), GetTestURLFor("foo.example.com"))); |
151 EXPECT_FALSE(CanReadClipboard(extension.get(), "foo.example.com")); | 173 EXPECT_FALSE( |
| 174 CanWriteClipboard(extension.get(), GetTestURLFor("bar.example.com"))); |
| 175 EXPECT_FALSE( |
| 176 CanReadClipboard(extension.get(), GetTestURLFor("foo.example.com"))); |
152 } | 177 } |
153 | 178 |
154 IN_PROC_BROWSER_TEST_F(ContentCapabilitiesTest, ClipboardReadWrite) { | 179 IN_PROC_BROWSER_TEST_F(ContentCapabilitiesTest, ClipboardReadWrite) { |
155 InitializeTestServer(); | 180 InitializeTestServer(); |
156 scoped_refptr<const Extension> extension = LoadExtensionWithCapabilities( | 181 scoped_refptr<const Extension> extension = LoadExtensionWithCapabilities( |
157 MakeJSONList("http://foo.example.com/*"), | 182 MakeJSONList("http://foo.example.com/*"), |
158 MakeJSONList("clipboardRead", "clipboardWrite")); | 183 MakeJSONList("clipboardRead", "clipboardWrite")); |
159 EXPECT_TRUE(CanReadClipboard(extension.get(), "foo.example.com")); | 184 EXPECT_TRUE( |
160 EXPECT_TRUE(CanWriteClipboard(extension.get(), "foo.example.com")); | 185 CanReadClipboard(extension.get(), GetTestURLFor("foo.example.com"))); |
161 EXPECT_FALSE(CanReadClipboard(extension.get(), "bar.example.com")); | 186 EXPECT_TRUE( |
162 EXPECT_FALSE(CanWriteClipboard(extension.get(), "bar.example.com")); | 187 CanWriteClipboard(extension.get(), GetTestURLFor("foo.example.com"))); |
| 188 EXPECT_FALSE( |
| 189 CanReadClipboard(extension.get(), GetTestURLFor("bar.example.com"))); |
| 190 EXPECT_FALSE( |
| 191 CanWriteClipboard(extension.get(), GetTestURLFor("bar.example.com"))); |
163 } | 192 } |
| 193 |
| 194 IN_PROC_BROWSER_TEST_F(ContentCapabilitiesTest, UnlimitedStorage) { |
| 195 InitializeTestServer(); |
| 196 scoped_refptr<const Extension> extension = |
| 197 LoadExtensionWithCapabilities(MakeJSONList("http://foo.example.com/*"), |
| 198 MakeJSONList("unlimitedStorage")); |
| 199 EXPECT_TRUE( |
| 200 HasUnlimitedStorage(extension.get(), GetTestURLFor("foo.example.com"))); |
| 201 EXPECT_FALSE( |
| 202 HasUnlimitedStorage(extension.get(), GetTestURLFor("bar.example.com"))); |
| 203 } |
| 204 |
| 205 IN_PROC_BROWSER_TEST_F(ContentCapabilitiesTest, WebUnlimitedStorageIsIsolated) { |
| 206 InitializeTestServer(); |
| 207 // This extension grants unlimited storage to bar.example.com but does not |
| 208 // have unlimitedStorage itself. |
| 209 scoped_refptr<const Extension> extension = LoadExtensionWithCapabilities( |
| 210 MakeJSONList("http://bar.example.com/*"), |
| 211 MakeJSONList("unlimitedStorage"), MakeJSONList("storage")); |
| 212 EXPECT_FALSE( |
| 213 HasUnlimitedStorage(extension.get(), extension->GetResourceURL(""))); |
| 214 EXPECT_TRUE( |
| 215 HasUnlimitedStorage(extension.get(), GetTestURLFor("bar.example.com"))); |
| 216 } |
| 217 |
| 218 IN_PROC_BROWSER_TEST_F(ContentCapabilitiesTest, |
| 219 ExtensionUnlimitedStorageIsIsolated) { |
| 220 InitializeTestServer(); |
| 221 // This extension has unlimitedStorage but doesn't grant it to foo.example.com |
| 222 scoped_refptr<const Extension> extension = LoadExtensionWithCapabilities( |
| 223 MakeJSONList("http://foo.example.com/*"), MakeJSONList("clipboardRead"), |
| 224 MakeJSONList("unlimitedStorage")); |
| 225 |
| 226 EXPECT_TRUE( |
| 227 HasUnlimitedStorage(extension.get(), extension->GetResourceURL(""))); |
| 228 EXPECT_FALSE( |
| 229 HasUnlimitedStorage(extension.get(), GetTestURLFor("foo.example.com"))); |
| 230 } |
OLD | NEW |