blob: a93416b2e25bdb53dca4ee86e04b54d754518d16 [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"
Emilia Pazbf563df2021-12-01 13:54:5717#include "testing/gtest/include/gtest/gtest.h"
18#include "url/origin.h"
19
20namespace {
21
22std::unique_ptr<KeyedService> SetTestingPermissionsManager(
23 content::BrowserContext* browser_context) {
Emilia Paz363fa0062022-01-15 05:12:0324 return std::make_unique<extensions::PermissionsManager>(browser_context);
Emilia Pazbf563df2021-12-01 13:54:5725}
26
27} // namespace
28
29namespace extensions {
30
Emilia Paz4690682a2022-03-09 19:57:3031using UserSiteSetting = PermissionsManager::UserSiteSetting;
32
Emilia Pazbf563df2021-12-01 13:54:5733class PermissionsManagerUnittest : public ExtensionsTest {
34 public:
35 PermissionsManagerUnittest() = default;
36 ~PermissionsManagerUnittest() override = default;
37 PermissionsManagerUnittest(const PermissionsManagerUnittest&) = delete;
38 PermissionsManagerUnittest& operator=(const PermissionsManagerUnittest&) =
39 delete;
40
Emilia Paz41345b32022-03-21 18:45:3941 scoped_refptr<const Extension> AddExtensionWithHostPermission(
42 const std::string& name,
43 const std::string& host_permission);
44
Emilia Paz363fa0062022-01-15 05:12:0345 // Returns the restricted sites stored in `manager_`.
46 std::set<url::Origin> GetRestrictedSitesFromManager();
47 // Returns the permittes sites stored in `manager_`.
48 std::set<url::Origin> GetPermittedSitesFromManager();
49
50 // Returns the restricted sites stored in `extension_prefs_`.
51 const base::Value* GetRestrictedSitesFromPrefs();
52 // Returns the permitted sites stored in `extension_prefs_`.
53 const base::Value* GetPermittedSitesFromPrefs();
54
Devlin Croninedd63182022-05-31 23:12:2955 // Returns the restricted sites stored in `PermissionsData`.
56 std::set<std::string> GetRestrictedSitesFromPermissionsData();
57 // Returns the permitted sites stored in `PermissionsData`.
58 std::set<std::string> GetPermittedSitesFromPermissionsData();
59
Emilia Pazbf563df2021-12-01 13:54:5760 protected:
61 // ExtensionsTest:
62 void SetUp() override;
63
64 // PermissionsManager being tested.
Keishi Hattorie175ac52022-06-07 06:24:5765 raw_ptr<PermissionsManager> manager_;
Emilia Paz363fa0062022-01-15 05:12:0366
67 raw_ptr<ExtensionPrefs> extension_prefs_;
Emilia Pazbf563df2021-12-01 13:54:5768};
69
70void PermissionsManagerUnittest::SetUp() {
71 ExtensionsTest::SetUp();
72 manager_ = static_cast<PermissionsManager*>(
73 PermissionsManager::GetFactory()->SetTestingFactoryAndUse(
74 browser_context(),
75 base::BindRepeating(&SetTestingPermissionsManager)));
Emilia Paz363fa0062022-01-15 05:12:0376
77 extension_prefs_ = ExtensionPrefs::Get(browser_context());
Emilia Pazbf563df2021-12-01 13:54:5778}
79
Emilia Paz41345b32022-03-21 18:45:3980scoped_refptr<const Extension>
81PermissionsManagerUnittest::AddExtensionWithHostPermission(
82 const std::string& name,
83 const std::string& host_permission) {
84 scoped_refptr<const extensions::Extension> extension =
85 extensions::ExtensionBuilder(name)
86 .SetManifestVersion(3)
87 .SetManifestKey(
88 "host_permissions",
89 extensions::ListBuilder().Append(host_permission).Build())
90 .Build();
91
92 ExtensionRegistryFactory::GetForBrowserContext(browser_context())
93 ->AddEnabled(extension);
94
95 return extension;
96}
97
Emilia Paz363fa0062022-01-15 05:12:0398const base::Value* PermissionsManagerUnittest::GetRestrictedSitesFromPrefs() {
99 const base::DictionaryValue* permissions =
100 extension_prefs_->GetPrefAsDictionary(kUserPermissions);
101 return permissions->FindKey("restricted_sites");
102}
103
104const base::Value* PermissionsManagerUnittest::GetPermittedSitesFromPrefs() {
105 const base::DictionaryValue* permissions =
106 extension_prefs_->GetPrefAsDictionary(kUserPermissions);
107 return permissions->FindKey("permitted_sites");
108}
109
110std::set<url::Origin>
111PermissionsManagerUnittest::GetRestrictedSitesFromManager() {
112 const PermissionsManager::UserPermissionsSettings& permissions =
113 manager_->GetUserPermissionsSettings();
114 return permissions.restricted_sites;
115}
116
117std::set<url::Origin>
118PermissionsManagerUnittest::GetPermittedSitesFromManager() {
119 const PermissionsManager::UserPermissionsSettings& permissions =
120 manager_->GetUserPermissionsSettings();
121 return permissions.permitted_sites;
Emilia Pazbf563df2021-12-01 13:54:57122}
123
Devlin Croninedd63182022-05-31 23:12:29124std::set<std::string>
125PermissionsManagerUnittest::GetRestrictedSitesFromPermissionsData() {
126 std::set<std::string> string_patterns;
Devlin Croninc85468702022-06-08 00:49:18127 URLPatternSet patterns = PermissionsData::GetUserBlockedHosts(
Devlin Croninedd63182022-05-31 23:12:29128 util::GetBrowserContextId(browser_context()));
129 for (const auto& pattern : patterns)
130 string_patterns.insert(pattern.GetAsString());
131 return string_patterns;
132}
133
134std::set<std::string>
135PermissionsManagerUnittest::GetPermittedSitesFromPermissionsData() {
136 std::set<std::string> string_patterns;
Devlin Croninc85468702022-06-08 00:49:18137 URLPatternSet patterns = PermissionsData::GetUserAllowedHosts(
Devlin Croninedd63182022-05-31 23:12:29138 util::GetBrowserContextId(browser_context()));
139 for (const auto& pattern : patterns)
140 string_patterns.insert(pattern.GetAsString());
141 return string_patterns;
142}
143
Emilia Pazbf563df2021-12-01 13:54:57144TEST_F(PermissionsManagerUnittest, AddAndRemoveRestrictedSite) {
145 const url::Origin url = url::Origin::Create(GURL("http://a.example.com"));
Devlin Croninedd63182022-05-31 23:12:29146 const std::string expected_url_pattern = "http://a.example.com/*";
Emilia Paz363fa0062022-01-15 05:12:03147 std::set<url::Origin> set_with_url;
148 set_with_url.insert(url);
149 base::Value value_with_url(base::Value::Type::LIST);
150 value_with_url.Append(url.Serialize());
Emilia Pazbf563df2021-12-01 13:54:57151
Emilia Paz363fa0062022-01-15 05:12:03152 // Verify the restricted sites list is empty.
153 EXPECT_EQ(GetRestrictedSitesFromManager(), std::set<url::Origin>());
154 EXPECT_EQ(GetRestrictedSitesFromPrefs(), nullptr);
Devlin Croninedd63182022-05-31 23:12:29155 EXPECT_THAT(GetRestrictedSitesFromPermissionsData(), testing::IsEmpty());
Emilia Paz4690682a2022-03-09 19:57:30156 EXPECT_EQ(manager_->GetUserSiteSetting(url),
157 UserSiteSetting::kCustomizeByExtension);
Emilia Paz363fa0062022-01-15 05:12:03158
159 // Add `url` to restricted sites. Verify the site is stored both in manager
160 // and prefs restricted sites.
Emilia Pazbf563df2021-12-01 13:54:57161 manager_->AddUserRestrictedSite(url);
Emilia Paz363fa0062022-01-15 05:12:03162 EXPECT_EQ(GetRestrictedSitesFromManager(), set_with_url);
163 EXPECT_EQ(*GetRestrictedSitesFromPrefs(), value_with_url);
Devlin Croninedd63182022-05-31 23:12:29164 EXPECT_THAT(GetRestrictedSitesFromPermissionsData(),
165 testing::UnorderedElementsAre(expected_url_pattern));
Emilia Paz4690682a2022-03-09 19:57:30166 EXPECT_EQ(manager_->GetUserSiteSetting(url),
167 UserSiteSetting::kBlockAllExtensions);
Emilia Pazbf563df2021-12-01 13:54:57168
Emilia Paz363fa0062022-01-15 05:12:03169 // Adding an existent restricted site. Verify the entry is not duplicated.
Emilia Pazbf563df2021-12-01 13:54:57170 manager_->AddUserRestrictedSite(url);
Emilia Paz363fa0062022-01-15 05:12:03171 EXPECT_EQ(GetRestrictedSitesFromManager(), set_with_url);
172 EXPECT_EQ(*GetRestrictedSitesFromPrefs(), value_with_url);
Devlin Croninedd63182022-05-31 23:12:29173 EXPECT_THAT(GetRestrictedSitesFromPermissionsData(),
174 testing::UnorderedElementsAre(expected_url_pattern));
Emilia Pazbf563df2021-12-01 13:54:57175
Emilia Paz363fa0062022-01-15 05:12:03176 // Remove `url` from restricted sites. Verify the site is removed from both
177 // manager and prefs restricted sites.
Emilia Pazbf563df2021-12-01 13:54:57178 manager_->RemoveUserRestrictedSite(url);
Emilia Paz363fa0062022-01-15 05:12:03179 EXPECT_EQ(GetRestrictedSitesFromManager(), std::set<url::Origin>());
180 EXPECT_EQ(*GetRestrictedSitesFromPrefs(),
181 base::Value(base::Value::Type::LIST));
Devlin Croninedd63182022-05-31 23:12:29182 EXPECT_THAT(GetRestrictedSitesFromPermissionsData(), testing::IsEmpty());
Emilia Paz4690682a2022-03-09 19:57:30183 EXPECT_EQ(manager_->GetUserSiteSetting(url),
184 UserSiteSetting::kCustomizeByExtension);
Emilia Pazbf563df2021-12-01 13:54:57185}
186
187TEST_F(PermissionsManagerUnittest, AddAndRemovePermittedSite) {
188 const url::Origin url = url::Origin::Create(GURL("http://a.example.com"));
Devlin Croninedd63182022-05-31 23:12:29189 const std::string expected_url_pattern = "http://a.example.com/*";
Emilia Paz363fa0062022-01-15 05:12:03190 std::set<url::Origin> set_with_url;
191 set_with_url.insert(url);
192 base::Value value_with_url(base::Value::Type::LIST);
193 value_with_url.Append(url.Serialize());
Emilia Pazbf563df2021-12-01 13:54:57194
Emilia Paz363fa0062022-01-15 05:12:03195 // Verify the permitted sites list is empty.
196 EXPECT_EQ(GetPermittedSitesFromManager(), std::set<url::Origin>());
197 EXPECT_EQ(GetPermittedSitesFromPrefs(), nullptr);
Devlin Croninedd63182022-05-31 23:12:29198 EXPECT_THAT(GetPermittedSitesFromPermissionsData(), testing::IsEmpty());
Emilia Paz4690682a2022-03-09 19:57:30199 EXPECT_EQ(manager_->GetUserSiteSetting(url),
200 PermissionsManager::UserSiteSetting::kCustomizeByExtension);
Emilia Paz363fa0062022-01-15 05:12:03201
202 // Add `url` to permitted sites. Verify the site is stored both in manager
203 // and prefs permitted sites.
Emilia Pazbf563df2021-12-01 13:54:57204 manager_->AddUserPermittedSite(url);
Emilia Paz363fa0062022-01-15 05:12:03205 EXPECT_EQ(GetPermittedSitesFromManager(), set_with_url);
206 EXPECT_EQ(*GetPermittedSitesFromPrefs(), value_with_url);
Devlin Croninedd63182022-05-31 23:12:29207 EXPECT_THAT(GetPermittedSitesFromPermissionsData(),
208 testing::UnorderedElementsAre(expected_url_pattern));
Emilia Paz4690682a2022-03-09 19:57:30209 EXPECT_EQ(manager_->GetUserSiteSetting(url),
210 PermissionsManager::UserSiteSetting::kGrantAllExtensions);
Emilia Pazbf563df2021-12-01 13:54:57211
Emilia Paz363fa0062022-01-15 05:12:03212 // Adding an existent permitted site. Verify the entry is not duplicated.
Emilia Pazbf563df2021-12-01 13:54:57213 manager_->AddUserPermittedSite(url);
Emilia Paz363fa0062022-01-15 05:12:03214 EXPECT_EQ(GetPermittedSitesFromManager(), set_with_url);
215 EXPECT_EQ(*GetPermittedSitesFromPrefs(), value_with_url);
Devlin Croninedd63182022-05-31 23:12:29216 EXPECT_THAT(GetPermittedSitesFromPermissionsData(),
217 testing::UnorderedElementsAre(expected_url_pattern));
Emilia Pazbf563df2021-12-01 13:54:57218
Emilia Paz363fa0062022-01-15 05:12:03219 // Remove `url` from permitted sites. Verify the site is removed from both
220 // manager and prefs permitted sites.
Emilia Pazbf563df2021-12-01 13:54:57221 manager_->RemoveUserPermittedSite(url);
Emilia Paz363fa0062022-01-15 05:12:03222 EXPECT_EQ(GetPermittedSitesFromManager(), std::set<url::Origin>());
223 EXPECT_EQ(*GetPermittedSitesFromPrefs(),
224 base::Value(base::Value::Type::LIST));
Devlin Croninedd63182022-05-31 23:12:29225 EXPECT_THAT(GetPermittedSitesFromPermissionsData(), testing::IsEmpty());
Emilia Paz4690682a2022-03-09 19:57:30226 EXPECT_EQ(manager_->GetUserSiteSetting(url),
227 PermissionsManager::UserSiteSetting::kCustomizeByExtension);
Emilia Pazbf563df2021-12-01 13:54:57228}
229
230TEST_F(PermissionsManagerUnittest,
231 RestrictedAndPermittedSitesAreMutuallyExclusive) {
232 const url::Origin url = url::Origin::Create(GURL("http://a.example.com"));
Devlin Croninedd63182022-05-31 23:12:29233 const std::string expected_url_pattern = "http://a.example.com/*";
Emilia Pazbf563df2021-12-01 13:54:57234 std::set<url::Origin> empty_set;
235 std::set<url::Origin> set_with_url;
236 set_with_url.insert(url);
237
238 {
239 manager_->AddUserRestrictedSite(url);
240 const PermissionsManager::UserPermissionsSettings& actual_permissions =
241 manager_->GetUserPermissionsSettings();
242 EXPECT_EQ(actual_permissions.restricted_sites, set_with_url);
243 EXPECT_EQ(actual_permissions.permitted_sites, empty_set);
Emilia Paz4690682a2022-03-09 19:57:30244 EXPECT_EQ(manager_->GetUserSiteSetting(url),
245 PermissionsManager::UserSiteSetting::kBlockAllExtensions);
Emilia Pazbf563df2021-12-01 13:54:57246 }
247
248 {
249 // Adding an url to the permitted sites that is already in the restricted
250 // sites should remove it from restricted sites and add it to permitted
251 // sites.
252 manager_->AddUserPermittedSite(url);
253 const PermissionsManager::UserPermissionsSettings& actual_permissions =
254 manager_->GetUserPermissionsSettings();
255 EXPECT_EQ(actual_permissions.restricted_sites, empty_set);
256 EXPECT_EQ(actual_permissions.permitted_sites, set_with_url);
Emilia Paz4690682a2022-03-09 19:57:30257 EXPECT_EQ(manager_->GetUserSiteSetting(url),
258 PermissionsManager::UserSiteSetting::kGrantAllExtensions);
Emilia Pazbf563df2021-12-01 13:54:57259 }
260
261 {
262 // Adding an url to the restricted sites that is already in the permitted
263 // sites should remove it from permitted sites and add it to restricted
264 // sites.
265 manager_->AddUserRestrictedSite(url);
266 const PermissionsManager::UserPermissionsSettings& actual_permissions =
267 manager_->GetUserPermissionsSettings();
268 EXPECT_EQ(actual_permissions.restricted_sites, set_with_url);
269 EXPECT_EQ(actual_permissions.permitted_sites, empty_set);
Emilia Paz4690682a2022-03-09 19:57:30270 EXPECT_EQ(manager_->GetUserSiteSetting(url),
271 PermissionsManager::UserSiteSetting::kBlockAllExtensions);
Emilia Pazbf563df2021-12-01 13:54:57272 }
273}
274
Emilia Paz41345b32022-03-21 18:45:39275TEST_F(PermissionsManagerUnittest, GetSiteAccess_AllUrls) {
276 auto extension =
277 AddExtensionWithHostPermission("AllUrls Extension", "<all_urls>");
278
279 const GURL non_restricted_url("https://www.non-restricted.com");
280 {
281 const PermissionsManager::ExtensionSiteAccess site_access =
282 manager_->GetSiteAccess(*extension, non_restricted_url);
283 EXPECT_TRUE(site_access.has_site_access);
284 EXPECT_FALSE(site_access.withheld_site_access);
285 EXPECT_TRUE(site_access.has_all_sites_access);
286 EXPECT_FALSE(site_access.withheld_all_sites_access);
287 }
288
289 // Chrome pages should be restricted, and the extension shouldn't have grant
290 // or withheld site access.
291 const GURL restricted_url("chrome://extensions");
292 {
293 const PermissionsManager::ExtensionSiteAccess site_access =
294 manager_->GetSiteAccess(*extension, restricted_url);
295 EXPECT_FALSE(site_access.has_site_access);
296 EXPECT_FALSE(site_access.withheld_site_access);
297 EXPECT_TRUE(site_access.has_all_sites_access);
298 EXPECT_FALSE(site_access.withheld_all_sites_access);
299 }
300}
301
302TEST_F(PermissionsManagerUnittest, GetSiteAccess_RequestedUrl) {
303 auto extension = AddExtensionWithHostPermission("RequestedUrl Extension",
304 "*://*.requested.com/*");
305
306 const GURL requested_url("https://www.requested.com");
307 {
308 const PermissionsManager::ExtensionSiteAccess site_access =
309 manager_->GetSiteAccess(*extension, requested_url);
310 EXPECT_TRUE(site_access.has_site_access);
311 EXPECT_FALSE(site_access.withheld_site_access);
312 EXPECT_FALSE(site_access.has_all_sites_access);
313 EXPECT_FALSE(site_access.withheld_all_sites_access);
314 }
315
316 const GURL non_requested_url("https://non-requested.com");
317 {
318 const PermissionsManager::ExtensionSiteAccess site_access =
319 manager_->GetSiteAccess(*extension, non_requested_url);
320 EXPECT_FALSE(site_access.has_site_access);
321 EXPECT_FALSE(site_access.withheld_site_access);
322 EXPECT_FALSE(site_access.has_all_sites_access);
323 EXPECT_FALSE(site_access.withheld_all_sites_access);
324 }
325}
326
327// Tests that for the purposes of displaying an extension's site access to the
328// user (or granting/revoking permissions), we ignore paths in the URL. We
329// always strip the path from host permissions directly, but we don't strip the
330// path from content scripts.
331TEST_F(PermissionsManagerUnittest,
332 GetSiteAccess_ContentScript_RequestedUrlWithPath) {
333 scoped_refptr<const Extension> extension =
334 ExtensionBuilder("extension")
335 .AddContentScript("foo.js", {"https://www.example.com/foo"})
336 .SetLocation(mojom::ManifestLocation::kInternal)
337 .Build();
338 ExtensionRegistryFactory::GetForBrowserContext(browser_context())
339 ->AddEnabled(extension);
340
341 const GURL other_path_url("https://www.example.com/bar");
342 {
343 const PermissionsManager::ExtensionSiteAccess site_access =
344 manager_->GetSiteAccess(*extension, other_path_url);
345 // Even though the path doesn't match the one requested, the domain does
346 // match and thus we treat it as if the site was requested.
347 EXPECT_TRUE(site_access.has_site_access);
348 EXPECT_FALSE(site_access.withheld_site_access);
349 EXPECT_FALSE(site_access.has_all_sites_access);
350 EXPECT_FALSE(site_access.withheld_all_sites_access);
351 }
352}
353
354TEST_F(PermissionsManagerUnittest, GetSiteAccess_ActiveTab) {
355 auto extension =
356 AddExtensionWithHostPermission("ActiveTab Extension", "activeTab");
357
358 const GURL url("https://example.com");
359 {
360 const PermissionsManager::ExtensionSiteAccess site_access =
361 manager_->GetSiteAccess(*extension, url);
362 // The site access computation does not take into account active tab, and
363 // therefore it does not have or withheld any access.
364 EXPECT_FALSE(site_access.has_site_access);
365 EXPECT_FALSE(site_access.withheld_site_access);
366 EXPECT_FALSE(site_access.has_all_sites_access);
367 EXPECT_FALSE(site_access.withheld_all_sites_access);
368 }
369}
370
371TEST_F(PermissionsManagerUnittest, GetSiteAccess_NoHostPermissions) {
372 auto extension = AddExtensionWithHostPermission("", "Extension");
373
374 const GURL url("https://example.com");
375 {
376 const PermissionsManager::ExtensionSiteAccess site_access =
377 manager_->GetSiteAccess(*extension, url);
378 // The site access computation does not take into account active tab, and
379 // therefore it does not have or withheld any access.
380 EXPECT_FALSE(site_access.has_site_access);
381 EXPECT_FALSE(site_access.withheld_site_access);
382 EXPECT_FALSE(site_access.has_all_sites_access);
383 EXPECT_FALSE(site_access.withheld_all_sites_access);
384 }
385}
386
Emilia Pazbf563df2021-12-01 13:54:57387} // namespace extensions