blob: 20d8bcf37010a2cabbf25196fbfbdc78cc2026b4 [file] [log] [blame]
Emilia Pazbf563df2021-12-01 13:54:571// Copyright 2021 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 "extensions/browser/permissions_manager.h"
Keishi Hattorie175ac52022-06-07 06:24:576#include "base/memory/raw_ptr.h"
Emilia Paz363fa0062022-01-15 05:12:037#include "extensions/browser/extension_prefs.h"
Emilia Paz41345b32022-03-21 18:45:398#include "extensions/browser/extension_registry.h"
Devlin Croninedd63182022-05-31 23:12:299#include "extensions/browser/extension_util.h"
Emilia Pazbf563df2021-12-01 13:54:5710#include "extensions/browser/extensions_test.h"
Emilia Paz363fa0062022-01-15 05:12:0311#include "extensions/browser/pref_types.h"
Emilia Paz41345b32022-03-21 18:45:3912#include "extensions/common/extension_builder.h"
13#include "extensions/common/extension_icon_set.h"
14#include "extensions/common/extensions_client.h"
Devlin Croninedd63182022-05-31 23:12:2915#include "extensions/common/permissions/permissions_data.h"
16#include "extensions/common/url_pattern_set.h"
Dmitrii Kuragin8045a832022-07-18 17:44:3217#include "testing/gmock/include/gmock/gmock.h"
Emilia Pazbf563df2021-12-01 13:54:5718#include "testing/gtest/include/gtest/gtest.h"
19#include "url/origin.h"
20
21namespace {
22
23std::unique_ptr<KeyedService> SetTestingPermissionsManager(
24 content::BrowserContext* browser_context) {
Emilia Paz363fa0062022-01-15 05:12:0325 return std::make_unique<extensions::PermissionsManager>(browser_context);
Emilia Pazbf563df2021-12-01 13:54:5726}
27
28} // namespace
29
30namespace extensions {
31
Emilia Paz4690682a2022-03-09 19:57:3032using UserSiteSetting = PermissionsManager::UserSiteSetting;
33
Emilia Pazbf563df2021-12-01 13:54:5734class PermissionsManagerUnittest : public ExtensionsTest {
35 public:
36 PermissionsManagerUnittest() = default;
37 ~PermissionsManagerUnittest() override = default;
38 PermissionsManagerUnittest(const PermissionsManagerUnittest&) = delete;
39 PermissionsManagerUnittest& operator=(const PermissionsManagerUnittest&) =
40 delete;
41
Emilia Paz41345b32022-03-21 18:45:3942 scoped_refptr<const Extension> AddExtensionWithHostPermission(
43 const std::string& name,
44 const std::string& host_permission);
45
Emilia Paz363fa0062022-01-15 05:12:0346 // Returns the restricted sites stored in `manager_`.
47 std::set<url::Origin> GetRestrictedSitesFromManager();
48 // Returns the permittes sites stored in `manager_`.
49 std::set<url::Origin> GetPermittedSitesFromManager();
50
51 // Returns the restricted sites stored in `extension_prefs_`.
52 const base::Value* GetRestrictedSitesFromPrefs();
53 // Returns the permitted sites stored in `extension_prefs_`.
54 const base::Value* GetPermittedSitesFromPrefs();
55
Devlin Croninedd63182022-05-31 23:12:2956 // Returns the restricted sites stored in `PermissionsData`.
57 std::set<std::string> GetRestrictedSitesFromPermissionsData();
58 // Returns the permitted sites stored in `PermissionsData`.
59 std::set<std::string> GetPermittedSitesFromPermissionsData();
60
Emilia Pazbf563df2021-12-01 13:54:5761 protected:
62 // ExtensionsTest:
63 void SetUp() override;
64
65 // PermissionsManager being tested.
Keishi Hattorie175ac52022-06-07 06:24:5766 raw_ptr<PermissionsManager> manager_;
Emilia Paz363fa0062022-01-15 05:12:0367
68 raw_ptr<ExtensionPrefs> extension_prefs_;
Emilia Pazbf563df2021-12-01 13:54:5769};
70
71void PermissionsManagerUnittest::SetUp() {
72 ExtensionsTest::SetUp();
73 manager_ = static_cast<PermissionsManager*>(
74 PermissionsManager::GetFactory()->SetTestingFactoryAndUse(
75 browser_context(),
76 base::BindRepeating(&SetTestingPermissionsManager)));
Emilia Paz363fa0062022-01-15 05:12:0377
78 extension_prefs_ = ExtensionPrefs::Get(browser_context());
Emilia Pazbf563df2021-12-01 13:54:5779}
80
Emilia Paz41345b32022-03-21 18:45:3981scoped_refptr<const Extension>
82PermissionsManagerUnittest::AddExtensionWithHostPermission(
83 const std::string& name,
84 const std::string& host_permission) {
85 scoped_refptr<const extensions::Extension> extension =
86 extensions::ExtensionBuilder(name)
87 .SetManifestVersion(3)
88 .SetManifestKey(
89 "host_permissions",
90 extensions::ListBuilder().Append(host_permission).Build())
91 .Build();
92
93 ExtensionRegistryFactory::GetForBrowserContext(browser_context())
94 ->AddEnabled(extension);
95
96 return extension;
97}
98
Emilia Paz363fa0062022-01-15 05:12:0399const base::Value* PermissionsManagerUnittest::GetRestrictedSitesFromPrefs() {
100 const base::DictionaryValue* permissions =
101 extension_prefs_->GetPrefAsDictionary(kUserPermissions);
102 return permissions->FindKey("restricted_sites");
103}
104
105const base::Value* PermissionsManagerUnittest::GetPermittedSitesFromPrefs() {
106 const base::DictionaryValue* permissions =
107 extension_prefs_->GetPrefAsDictionary(kUserPermissions);
108 return permissions->FindKey("permitted_sites");
109}
110
111std::set<url::Origin>
112PermissionsManagerUnittest::GetRestrictedSitesFromManager() {
113 const PermissionsManager::UserPermissionsSettings& permissions =
114 manager_->GetUserPermissionsSettings();
115 return permissions.restricted_sites;
116}
117
118std::set<url::Origin>
119PermissionsManagerUnittest::GetPermittedSitesFromManager() {
120 const PermissionsManager::UserPermissionsSettings& permissions =
121 manager_->GetUserPermissionsSettings();
122 return permissions.permitted_sites;
Emilia Pazbf563df2021-12-01 13:54:57123}
124
Devlin Croninedd63182022-05-31 23:12:29125std::set<std::string>
126PermissionsManagerUnittest::GetRestrictedSitesFromPermissionsData() {
127 std::set<std::string> string_patterns;
Devlin Croninc85468702022-06-08 00:49:18128 URLPatternSet patterns = PermissionsData::GetUserBlockedHosts(
Devlin Croninedd63182022-05-31 23:12:29129 util::GetBrowserContextId(browser_context()));
130 for (const auto& pattern : patterns)
131 string_patterns.insert(pattern.GetAsString());
132 return string_patterns;
133}
134
135std::set<std::string>
136PermissionsManagerUnittest::GetPermittedSitesFromPermissionsData() {
137 std::set<std::string> string_patterns;
Devlin Croninc85468702022-06-08 00:49:18138 URLPatternSet patterns = PermissionsData::GetUserAllowedHosts(
Devlin Croninedd63182022-05-31 23:12:29139 util::GetBrowserContextId(browser_context()));
140 for (const auto& pattern : patterns)
141 string_patterns.insert(pattern.GetAsString());
142 return string_patterns;
143}
144
Emilia Pazbf563df2021-12-01 13:54:57145TEST_F(PermissionsManagerUnittest, AddAndRemoveRestrictedSite) {
146 const url::Origin url = url::Origin::Create(GURL("http://a.example.com"));
Devlin Croninedd63182022-05-31 23:12:29147 const std::string expected_url_pattern = "http://a.example.com/*";
Emilia Paz363fa0062022-01-15 05:12:03148 std::set<url::Origin> set_with_url;
149 set_with_url.insert(url);
150 base::Value value_with_url(base::Value::Type::LIST);
151 value_with_url.Append(url.Serialize());
Emilia Pazbf563df2021-12-01 13:54:57152
Emilia Paz363fa0062022-01-15 05:12:03153 // Verify the restricted sites list is empty.
154 EXPECT_EQ(GetRestrictedSitesFromManager(), std::set<url::Origin>());
155 EXPECT_EQ(GetRestrictedSitesFromPrefs(), nullptr);
Devlin Croninedd63182022-05-31 23:12:29156 EXPECT_THAT(GetRestrictedSitesFromPermissionsData(), testing::IsEmpty());
Emilia Paz4690682a2022-03-09 19:57:30157 EXPECT_EQ(manager_->GetUserSiteSetting(url),
158 UserSiteSetting::kCustomizeByExtension);
Emilia Paz363fa0062022-01-15 05:12:03159
160 // Add `url` to restricted sites. Verify the site is stored both in manager
161 // and prefs restricted sites.
Emilia Pazbf563df2021-12-01 13:54:57162 manager_->AddUserRestrictedSite(url);
Emilia Paz363fa0062022-01-15 05:12:03163 EXPECT_EQ(GetRestrictedSitesFromManager(), set_with_url);
164 EXPECT_EQ(*GetRestrictedSitesFromPrefs(), value_with_url);
Devlin Croninedd63182022-05-31 23:12:29165 EXPECT_THAT(GetRestrictedSitesFromPermissionsData(),
166 testing::UnorderedElementsAre(expected_url_pattern));
Emilia Paz4690682a2022-03-09 19:57:30167 EXPECT_EQ(manager_->GetUserSiteSetting(url),
168 UserSiteSetting::kBlockAllExtensions);
Emilia Pazbf563df2021-12-01 13:54:57169
Emilia Paz363fa0062022-01-15 05:12:03170 // Adding an existent restricted site. Verify the entry is not duplicated.
Emilia Pazbf563df2021-12-01 13:54:57171 manager_->AddUserRestrictedSite(url);
Emilia Paz363fa0062022-01-15 05:12:03172 EXPECT_EQ(GetRestrictedSitesFromManager(), set_with_url);
173 EXPECT_EQ(*GetRestrictedSitesFromPrefs(), value_with_url);
Devlin Croninedd63182022-05-31 23:12:29174 EXPECT_THAT(GetRestrictedSitesFromPermissionsData(),
175 testing::UnorderedElementsAre(expected_url_pattern));
Emilia Pazbf563df2021-12-01 13:54:57176
Emilia Paz363fa0062022-01-15 05:12:03177 // Remove `url` from restricted sites. Verify the site is removed from both
178 // manager and prefs restricted sites.
Emilia Pazbf563df2021-12-01 13:54:57179 manager_->RemoveUserRestrictedSite(url);
Emilia Paz363fa0062022-01-15 05:12:03180 EXPECT_EQ(GetRestrictedSitesFromManager(), std::set<url::Origin>());
181 EXPECT_EQ(*GetRestrictedSitesFromPrefs(),
182 base::Value(base::Value::Type::LIST));
Devlin Croninedd63182022-05-31 23:12:29183 EXPECT_THAT(GetRestrictedSitesFromPermissionsData(), testing::IsEmpty());
Emilia Paz4690682a2022-03-09 19:57:30184 EXPECT_EQ(manager_->GetUserSiteSetting(url),
185 UserSiteSetting::kCustomizeByExtension);
Emilia Pazbf563df2021-12-01 13:54:57186}
187
188TEST_F(PermissionsManagerUnittest, AddAndRemovePermittedSite) {
189 const url::Origin url = url::Origin::Create(GURL("http://a.example.com"));
Devlin Croninedd63182022-05-31 23:12:29190 const std::string expected_url_pattern = "http://a.example.com/*";
Emilia Paz363fa0062022-01-15 05:12:03191 std::set<url::Origin> set_with_url;
192 set_with_url.insert(url);
193 base::Value value_with_url(base::Value::Type::LIST);
194 value_with_url.Append(url.Serialize());
Emilia Pazbf563df2021-12-01 13:54:57195
Emilia Paz363fa0062022-01-15 05:12:03196 // Verify the permitted sites list is empty.
197 EXPECT_EQ(GetPermittedSitesFromManager(), std::set<url::Origin>());
198 EXPECT_EQ(GetPermittedSitesFromPrefs(), nullptr);
Devlin Croninedd63182022-05-31 23:12:29199 EXPECT_THAT(GetPermittedSitesFromPermissionsData(), testing::IsEmpty());
Emilia Paz4690682a2022-03-09 19:57:30200 EXPECT_EQ(manager_->GetUserSiteSetting(url),
201 PermissionsManager::UserSiteSetting::kCustomizeByExtension);
Emilia Paz363fa0062022-01-15 05:12:03202
203 // Add `url` to permitted sites. Verify the site is stored both in manager
204 // and prefs permitted sites.
Emilia Pazbf563df2021-12-01 13:54:57205 manager_->AddUserPermittedSite(url);
Emilia Paz363fa0062022-01-15 05:12:03206 EXPECT_EQ(GetPermittedSitesFromManager(), set_with_url);
207 EXPECT_EQ(*GetPermittedSitesFromPrefs(), value_with_url);
Devlin Croninedd63182022-05-31 23:12:29208 EXPECT_THAT(GetPermittedSitesFromPermissionsData(),
209 testing::UnorderedElementsAre(expected_url_pattern));
Emilia Paz4690682a2022-03-09 19:57:30210 EXPECT_EQ(manager_->GetUserSiteSetting(url),
211 PermissionsManager::UserSiteSetting::kGrantAllExtensions);
Emilia Pazbf563df2021-12-01 13:54:57212
Emilia Paz363fa0062022-01-15 05:12:03213 // Adding an existent permitted site. Verify the entry is not duplicated.
Emilia Pazbf563df2021-12-01 13:54:57214 manager_->AddUserPermittedSite(url);
Emilia Paz363fa0062022-01-15 05:12:03215 EXPECT_EQ(GetPermittedSitesFromManager(), set_with_url);
216 EXPECT_EQ(*GetPermittedSitesFromPrefs(), value_with_url);
Devlin Croninedd63182022-05-31 23:12:29217 EXPECT_THAT(GetPermittedSitesFromPermissionsData(),
218 testing::UnorderedElementsAre(expected_url_pattern));
Emilia Pazbf563df2021-12-01 13:54:57219
Emilia Paz363fa0062022-01-15 05:12:03220 // Remove `url` from permitted sites. Verify the site is removed from both
221 // manager and prefs permitted sites.
Emilia Pazbf563df2021-12-01 13:54:57222 manager_->RemoveUserPermittedSite(url);
Emilia Paz363fa0062022-01-15 05:12:03223 EXPECT_EQ(GetPermittedSitesFromManager(), std::set<url::Origin>());
224 EXPECT_EQ(*GetPermittedSitesFromPrefs(),
225 base::Value(base::Value::Type::LIST));
Devlin Croninedd63182022-05-31 23:12:29226 EXPECT_THAT(GetPermittedSitesFromPermissionsData(), testing::IsEmpty());
Emilia Paz4690682a2022-03-09 19:57:30227 EXPECT_EQ(manager_->GetUserSiteSetting(url),
228 PermissionsManager::UserSiteSetting::kCustomizeByExtension);
Emilia Pazbf563df2021-12-01 13:54:57229}
230
231TEST_F(PermissionsManagerUnittest,
232 RestrictedAndPermittedSitesAreMutuallyExclusive) {
233 const url::Origin url = url::Origin::Create(GURL("http://a.example.com"));
Devlin Croninedd63182022-05-31 23:12:29234 const std::string expected_url_pattern = "http://a.example.com/*";
Emilia Pazbf563df2021-12-01 13:54:57235 std::set<url::Origin> empty_set;
236 std::set<url::Origin> set_with_url;
237 set_with_url.insert(url);
238
239 {
240 manager_->AddUserRestrictedSite(url);
241 const PermissionsManager::UserPermissionsSettings& actual_permissions =
242 manager_->GetUserPermissionsSettings();
243 EXPECT_EQ(actual_permissions.restricted_sites, set_with_url);
244 EXPECT_EQ(actual_permissions.permitted_sites, empty_set);
Emilia Paz4690682a2022-03-09 19:57:30245 EXPECT_EQ(manager_->GetUserSiteSetting(url),
246 PermissionsManager::UserSiteSetting::kBlockAllExtensions);
Emilia Pazbf563df2021-12-01 13:54:57247 }
248
249 {
250 // Adding an url to the permitted sites that is already in the restricted
251 // sites should remove it from restricted sites and add it to permitted
252 // sites.
253 manager_->AddUserPermittedSite(url);
254 const PermissionsManager::UserPermissionsSettings& actual_permissions =
255 manager_->GetUserPermissionsSettings();
256 EXPECT_EQ(actual_permissions.restricted_sites, empty_set);
257 EXPECT_EQ(actual_permissions.permitted_sites, set_with_url);
Emilia Paz4690682a2022-03-09 19:57:30258 EXPECT_EQ(manager_->GetUserSiteSetting(url),
259 PermissionsManager::UserSiteSetting::kGrantAllExtensions);
Emilia Pazbf563df2021-12-01 13:54:57260 }
261
262 {
263 // Adding an url to the restricted sites that is already in the permitted
264 // sites should remove it from permitted sites and add it to restricted
265 // sites.
266 manager_->AddUserRestrictedSite(url);
267 const PermissionsManager::UserPermissionsSettings& actual_permissions =
268 manager_->GetUserPermissionsSettings();
269 EXPECT_EQ(actual_permissions.restricted_sites, set_with_url);
270 EXPECT_EQ(actual_permissions.permitted_sites, empty_set);
Emilia Paz4690682a2022-03-09 19:57:30271 EXPECT_EQ(manager_->GetUserSiteSetting(url),
272 PermissionsManager::UserSiteSetting::kBlockAllExtensions);
Emilia Pazbf563df2021-12-01 13:54:57273 }
274}
275
Emilia Paz41345b32022-03-21 18:45:39276TEST_F(PermissionsManagerUnittest, GetSiteAccess_AllUrls) {
277 auto extension =
278 AddExtensionWithHostPermission("AllUrls Extension", "<all_urls>");
279
280 const GURL non_restricted_url("https://www.non-restricted.com");
281 {
282 const PermissionsManager::ExtensionSiteAccess site_access =
283 manager_->GetSiteAccess(*extension, non_restricted_url);
284 EXPECT_TRUE(site_access.has_site_access);
285 EXPECT_FALSE(site_access.withheld_site_access);
286 EXPECT_TRUE(site_access.has_all_sites_access);
287 EXPECT_FALSE(site_access.withheld_all_sites_access);
288 }
289
290 // Chrome pages should be restricted, and the extension shouldn't have grant
291 // or withheld site access.
292 const GURL restricted_url("chrome://extensions");
293 {
294 const PermissionsManager::ExtensionSiteAccess site_access =
295 manager_->GetSiteAccess(*extension, restricted_url);
296 EXPECT_FALSE(site_access.has_site_access);
297 EXPECT_FALSE(site_access.withheld_site_access);
298 EXPECT_TRUE(site_access.has_all_sites_access);
299 EXPECT_FALSE(site_access.withheld_all_sites_access);
300 }
301}
302
303TEST_F(PermissionsManagerUnittest, GetSiteAccess_RequestedUrl) {
304 auto extension = AddExtensionWithHostPermission("RequestedUrl Extension",
305 "*://*.requested.com/*");
306
307 const GURL requested_url("https://www.requested.com");
308 {
309 const PermissionsManager::ExtensionSiteAccess site_access =
310 manager_->GetSiteAccess(*extension, requested_url);
311 EXPECT_TRUE(site_access.has_site_access);
312 EXPECT_FALSE(site_access.withheld_site_access);
313 EXPECT_FALSE(site_access.has_all_sites_access);
314 EXPECT_FALSE(site_access.withheld_all_sites_access);
315 }
316
317 const GURL non_requested_url("https://non-requested.com");
318 {
319 const PermissionsManager::ExtensionSiteAccess site_access =
320 manager_->GetSiteAccess(*extension, non_requested_url);
321 EXPECT_FALSE(site_access.has_site_access);
322 EXPECT_FALSE(site_access.withheld_site_access);
323 EXPECT_FALSE(site_access.has_all_sites_access);
324 EXPECT_FALSE(site_access.withheld_all_sites_access);
325 }
326}
327
328// Tests that for the purposes of displaying an extension's site access to the
329// user (or granting/revoking permissions), we ignore paths in the URL. We
330// always strip the path from host permissions directly, but we don't strip the
331// path from content scripts.
332TEST_F(PermissionsManagerUnittest,
333 GetSiteAccess_ContentScript_RequestedUrlWithPath) {
334 scoped_refptr<const Extension> extension =
335 ExtensionBuilder("extension")
336 .AddContentScript("foo.js", {"https://www.example.com/foo"})
337 .SetLocation(mojom::ManifestLocation::kInternal)
338 .Build();
339 ExtensionRegistryFactory::GetForBrowserContext(browser_context())
340 ->AddEnabled(extension);
341
342 const GURL other_path_url("https://www.example.com/bar");
343 {
344 const PermissionsManager::ExtensionSiteAccess site_access =
345 manager_->GetSiteAccess(*extension, other_path_url);
346 // Even though the path doesn't match the one requested, the domain does
347 // match and thus we treat it as if the site was requested.
348 EXPECT_TRUE(site_access.has_site_access);
349 EXPECT_FALSE(site_access.withheld_site_access);
350 EXPECT_FALSE(site_access.has_all_sites_access);
351 EXPECT_FALSE(site_access.withheld_all_sites_access);
352 }
353}
354
355TEST_F(PermissionsManagerUnittest, GetSiteAccess_ActiveTab) {
356 auto extension =
357 AddExtensionWithHostPermission("ActiveTab Extension", "activeTab");
358
359 const GURL url("https://example.com");
360 {
361 const PermissionsManager::ExtensionSiteAccess site_access =
362 manager_->GetSiteAccess(*extension, url);
363 // The site access computation does not take into account active tab, and
364 // therefore it does not have or withheld any access.
365 EXPECT_FALSE(site_access.has_site_access);
366 EXPECT_FALSE(site_access.withheld_site_access);
367 EXPECT_FALSE(site_access.has_all_sites_access);
368 EXPECT_FALSE(site_access.withheld_all_sites_access);
369 }
370}
371
372TEST_F(PermissionsManagerUnittest, GetSiteAccess_NoHostPermissions) {
373 auto extension = AddExtensionWithHostPermission("", "Extension");
374
375 const GURL url("https://example.com");
376 {
377 const PermissionsManager::ExtensionSiteAccess site_access =
378 manager_->GetSiteAccess(*extension, url);
379 // The site access computation does not take into account active tab, and
380 // therefore it does not have or withheld any access.
381 EXPECT_FALSE(site_access.has_site_access);
382 EXPECT_FALSE(site_access.withheld_site_access);
383 EXPECT_FALSE(site_access.has_all_sites_access);
384 EXPECT_FALSE(site_access.withheld_all_sites_access);
385 }
386}
387
Emilia Pazbf563df2021-12-01 13:54:57388} // namespace extensions