Index: chrome/browser/permissions/permission_manager_unittest.cc |
diff --git a/chrome/browser/permissions/permission_manager_unittest.cc b/chrome/browser/permissions/permission_manager_unittest.cc |
index a24af584d21a71487e6aa58973239a2daf91ae5e..320dafd9edcf8dc33b272bd88d23bc16dc8c70b0 100644 |
--- a/chrome/browser/permissions/permission_manager_unittest.cc |
+++ b/chrome/browser/permissions/permission_manager_unittest.cc |
@@ -8,10 +8,14 @@ |
#include "build/build_config.h" |
#include "chrome/browser/content_settings/host_content_settings_map_factory.h" |
#include "chrome/browser/permissions/permission_manager_factory.h" |
+#include "chrome/browser/permissions/permission_request_manager.h" |
#include "chrome/browser/permissions/permission_result.h" |
#include "chrome/test/base/chrome_render_view_host_test_harness.h" |
#include "chrome/test/base/testing_profile.h" |
#include "components/content_settings/core/browser/host_content_settings_map.h" |
+#include "components/content_settings/core/common/pref_names.h" |
+#include "components/content_settings/core/test/content_settings_test_utils.h" |
+#include "components/sync_preferences/testing_pref_service_syncable.h" |
#include "content/public/browser/permission_type.h" |
#include "content/public/test/test_browser_thread_bundle.h" |
#include "device/vr/features/features.h" |
@@ -21,9 +25,16 @@ |
#include "chrome/browser/android/vr_shell/vr_tab_helper.h" |
#endif // BUILDFLAG(ENABLE_VR) && defined(OS_ANDROID) |
+#if !defined(OS_ANDROID) |
+#include "chrome/browser/extensions/api/content_settings/content_settings_custom_extension_provider.h" |
+#include "chrome/browser/extensions/api/content_settings/content_settings_store.h" |
+#endif // !defined(OS_ANDROID) |
+ |
using blink::mojom::PermissionStatus; |
using content::PermissionType; |
+namespace test { |
+ |
namespace { |
#if BUILDFLAG(ENABLE_VR) && defined(OS_ANDROID) |
@@ -42,7 +53,7 @@ class PermissionManagerTestingProfile final : public TestingProfile { |
DISALLOW_COPY_AND_ASSIGN(PermissionManagerTestingProfile); |
}; |
-} // anonymous namespace |
+} // namespace |
class PermissionManagerTest : public ChromeRenderViewHostTestHarness { |
public: |
@@ -155,7 +166,7 @@ TEST_F(PermissionManagerTest, GetPermissionStatusAfterSet) { |
#endif |
} |
-TEST_F(PermissionManagerTest, CheckPersmissionResultDefault) { |
+TEST_F(PermissionManagerTest, CheckPermissionResultDefault) { |
CheckPermissionResult(CONTENT_SETTINGS_TYPE_MIDI_SYSEX, CONTENT_SETTING_ASK, |
PermissionStatusSource::UNSPECIFIED); |
CheckPermissionResult(CONTENT_SETTINGS_TYPE_PUSH_MESSAGING, |
@@ -435,3 +446,285 @@ TEST_F(PermissionManagerTest, SuppressPermissionRequests) { |
EXPECT_EQ(PermissionStatus::GRANTED, callback_result()); |
} |
#endif // BUILDFLAG(ENABLE_VR) && defined(OS_ANDROID) |
+ |
+class PermissionManagerStatusSourceTest |
+ : public ChromeRenderViewHostTestHarness { |
+ public: |
+ PermissionManagerStatusSourceTest() : weak_factory_(this) {} |
+ |
+ void SetUp() override { |
+ ChromeRenderViewHostTestHarness::SetUp(); |
+ PermissionRequestManager::CreateForWebContents(web_contents()); |
+ } |
+ |
+ PermissionManager* GetPermissionManager() { |
+ return PermissionManagerFactory::GetForProfile(profile()); |
+ } |
+ |
+ base::WeakPtr<PermissionManagerStatusSourceTest> GetWeakPtr() { |
+ return weak_factory_.GetWeakPtr(); |
+ } |
+ |
+ void NavigateToAndLoadGurl(GURL& gurl) { |
+ NavigateAndCommit(gurl); |
+ PermissionRequestManager::FromWebContents(web_contents()) |
+ ->DocumentOnLoadCompletedInMainFrame(); |
+ } |
+ |
+ private: |
+ base::WeakPtrFactory<PermissionManagerStatusSourceTest> weak_factory_; |
+}; |
+ |
+// Helper class for setting ContentSettings via different sources. |
+class ContentSettingSourceSetter { |
+ public: |
+ ContentSettingSourceSetter(TestingProfile* profile, |
+ ContentSettingsType content_type) |
+ : prefs_(profile->GetTestingPrefService()), |
+ host_content_settings_map_( |
+ HostContentSettingsMapFactory::GetForProfile(profile)), |
+#if !defined(OS_ANDROID) |
+ store_(new extensions::ContentSettingsStore()), |
+#endif // !defined(OS_ANDROID) |
+ content_type_(content_type) { |
+#if !defined(OS_ANDROID) |
+ store_->RegisterExtension(extension_id_, base::Time::UnixEpoch(), true); |
+ content_settings::TestUtils::OverrideProvider( |
+ host_content_settings_map_, |
+ base::MakeUnique<content_settings::CustomExtensionProvider>(store_, |
+ true), |
+ HostContentSettingsMap::CUSTOM_EXTENSION_PROVIDER); |
+#endif // !defined(OS_ANDROID) |
+ } |
+ |
+ void SetPolicyDefault(ContentSetting setting) { |
+ prefs_->SetManagedPref(GetPrefNameForDefaultPermissionSetting(), |
+ base::MakeUnique<base::Value>(setting)); |
+ } |
+ |
+ void AddPolicyException(const std::string& pattern, ContentSetting setting) { |
+ auto pattern_list = base::MakeUnique<base::ListValue>(); |
+ pattern_list->Set(0, base::MakeUnique<base::Value>(pattern)); |
+ if (setting == CONTENT_SETTING_ALLOW) |
+ prefs_->SetManagedPref(GetPrefNameForAllowingSettingForPattern(), |
+ std::move(pattern_list)); |
+ } |
+ |
+#if !defined(OS_ANDROID) |
+ void AddExtensionException(std::string exception, |
+ ContentSetting content_settings) { |
+ ContentSettingsPattern pattern = |
+ ContentSettingsPattern::FromString(exception); |
+ store()->SetExtensionContentSetting( |
+ extension_id_, pattern, pattern, content_type_, std::string(), |
+ content_settings, extensions::kExtensionPrefsScopeRegular); |
+ } |
+#endif // !defined(OS_ANDROID) |
+ |
+ void AddUserException(std::string exception, |
+ ContentSetting content_settings) { |
+ ContentSettingsPattern pattern = |
+ ContentSettingsPattern::FromString(exception); |
+ host_content_settings_map_->SetContentSettingCustomScope( |
+ pattern, pattern, content_type_, std::string(), content_settings); |
+ } |
+ |
+ const char* GetPrefNameForDefaultPermissionSetting() { |
+ switch (content_type_) { |
+ case CONTENT_SETTINGS_TYPE_GEOLOCATION: |
+ return prefs::kManagedDefaultGeolocationSetting; |
+ case CONTENT_SETTINGS_TYPE_NOTIFICATIONS: |
+ return prefs::kManagedDefaultNotificationsSetting; |
+ default: |
+ // Add support as needed. |
+ NOTREACHED(); |
+ return ""; |
+ } |
+ } |
+ |
+ const char* GetPrefNameForAllowingSettingForPattern() { |
+ switch (content_type_) { |
+ case CONTENT_SETTINGS_TYPE_NOTIFICATIONS: |
+ return prefs::kManagedNotificationsAllowedForUrls; |
+ default: |
+ // Add support as needed. |
+ NOTREACHED(); |
+ return ""; |
+ } |
+ } |
+ |
+ const char* GetPrefNameForBlockingSettingForPattern() { |
+ switch (content_type_) { |
+ case CONTENT_SETTINGS_TYPE_NOTIFICATIONS: |
+ return prefs::kManagedNotificationsBlockedForUrls; |
+ default: |
+ // Add support as needed. |
+ NOTREACHED(); |
+ return ""; |
+ } |
+ } |
+ |
+#if !defined(OS_ANDROID) |
+ extensions::ContentSettingsStore* store() { return store_.get(); } |
+#endif // !defined(OS_ANDROID) |
+ |
+ private: |
+ sync_preferences::TestingPrefServiceSyncable* prefs_; |
+ HostContentSettingsMap* host_content_settings_map_; |
+#if !defined(OS_ANDROID) |
+ scoped_refptr<extensions::ContentSettingsStore> store_; |
+ std::string extension_id_ = "test-extension"; |
+#endif // !defined(OS_ANDROID) |
+ ContentSettingsType content_type_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(ContentSettingSourceSetter); |
+}; |
+ |
+// Check PermissionResult shows requests denied due to insecure origins. |
+TEST_F(PermissionManagerStatusSourceTest, InsecureOrigin) { |
+ GURL insecure_frame("http://www.example.com/geolocation"); |
+ NavigateToAndLoadGurl(insecure_frame); |
+ |
+ PermissionResult result = GetPermissionManager()->GetPermissionStatusForFrame( |
+ CONTENT_SETTINGS_TYPE_GEOLOCATION, web_contents()->GetMainFrame(), |
+ insecure_frame); |
+ |
+ EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting); |
+ EXPECT_EQ(PermissionStatusSource::INSECURE_ORIGIN, result.source); |
+ |
+ GURL secure_frame("https://www.example.com/geolocation"); |
+ NavigateToAndLoadGurl(secure_frame); |
+ |
+ result = GetPermissionManager()->GetPermissionStatusForFrame( |
+ CONTENT_SETTINGS_TYPE_GEOLOCATION, web_contents()->GetMainFrame(), |
+ secure_frame); |
+ |
+ EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting); |
+ EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source); |
+} |
+ |
+// Check PermissionResult shows permissions controlled by enterprise policy, |
+// including patterns set by the policy. |
+TEST_F(PermissionManagerStatusSourceTest, EnterprisePolicy) { |
+ GURL requesting_frame("https://www.example.com/path/to/page"); |
+ NavigateToAndLoadGurl(requesting_frame); |
+ ContentSettingSourceSetter pref_tester(profile(), |
+ CONTENT_SETTINGS_TYPE_NOTIFICATIONS); |
+ |
+ // Default setting should be 'ASK' and controlled by the user. |
+ PermissionResult result = GetPermissionManager()->GetPermissionStatusForFrame( |
+ CONTENT_SETTINGS_TYPE_NOTIFICATIONS, web_contents()->GetMainFrame(), |
+ requesting_frame); |
+ EXPECT_EQ(CONTENT_SETTING_ASK, result.content_setting); |
+ EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source); |
+ |
+ // Set the default via policy. |
+ pref_tester.SetPolicyDefault(CONTENT_SETTING_BLOCK); |
+ result = GetPermissionManager()->GetPermissionStatusForFrame( |
+ CONTENT_SETTINGS_TYPE_NOTIFICATIONS, web_contents()->GetMainFrame(), |
+ requesting_frame); |
+ EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting); |
+ EXPECT_EQ(PermissionStatusSource::ENTERPRISE_POLICY, result.source); |
+ |
+ pref_tester.AddPolicyException("https://*", CONTENT_SETTING_ALLOW); |
+ result = GetPermissionManager()->GetPermissionStatusForFrame( |
+ CONTENT_SETTINGS_TYPE_NOTIFICATIONS, web_contents()->GetMainFrame(), |
+ requesting_frame); |
+ |
+ EXPECT_EQ(CONTENT_SETTING_ALLOW, result.content_setting); |
+ EXPECT_EQ(PermissionStatusSource::ENTERPRISE_POLICY, result.source); |
+} |
+ |
+#if !defined(OS_ANDROID) |
+// Check PermissionResult shows permissions controlled by an extension, |
+// including patterns set by an extension. |
+TEST_F(PermissionManagerStatusSourceTest, Extension) { |
+ GURL requesting_frame("https://www.example.com/path/to/page"); |
+ NavigateToAndLoadGurl(requesting_frame); |
+ ContentSettingSourceSetter pref_tester(profile(), |
+ CONTENT_SETTINGS_TYPE_GEOLOCATION); |
+ |
+ // Add a universal setting for geolocation access. |
+ pref_tester.AddExtensionException("*", CONTENT_SETTING_BLOCK); |
+ PermissionResult result = GetPermissionManager()->GetPermissionStatusForFrame( |
+ CONTENT_SETTINGS_TYPE_GEOLOCATION, web_contents()->GetMainFrame(), |
+ requesting_frame); |
+ |
+ EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting); |
+ EXPECT_EQ(PermissionStatusSource::EXTENSION, result.source); |
+ |
+ // Override the above pattern. |
+ pref_tester.AddExtensionException("https://*", CONTENT_SETTING_ALLOW); |
+ result = GetPermissionManager()->GetPermissionStatusForFrame( |
+ CONTENT_SETTINGS_TYPE_GEOLOCATION, web_contents()->GetMainFrame(), |
+ requesting_frame); |
+ |
+ EXPECT_EQ(CONTENT_SETTING_ALLOW, result.content_setting); |
+ EXPECT_EQ(PermissionStatusSource::EXTENSION, result.source); |
+} |
+#endif // !defined(OS_ANDROID) |
+ |
+// Check PermissionResult shows permissions controlled by the user, including |
+// patterns set by the user. |
+TEST_F(PermissionManagerStatusSourceTest, User) { |
+ GURL requesting_frame("https://www.example.com/path/to/page"); |
+ NavigateToAndLoadGurl(requesting_frame); |
+ ContentSettingSourceSetter pref_tester(profile(), |
+ CONTENT_SETTINGS_TYPE_GEOLOCATION); |
+ |
+ pref_tester.AddUserException("*", CONTENT_SETTING_BLOCK); |
+ PermissionResult result = GetPermissionManager()->GetPermissionStatusForFrame( |
+ CONTENT_SETTINGS_TYPE_GEOLOCATION, web_contents()->GetMainFrame(), |
+ requesting_frame); |
+ |
+ EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting); |
+ EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source); |
+ |
+ // Override the above pattern. |
+ pref_tester.AddUserException("https://*", CONTENT_SETTING_ALLOW); |
+ result = GetPermissionManager()->GetPermissionStatusForFrame( |
+ CONTENT_SETTINGS_TYPE_GEOLOCATION, web_contents()->GetMainFrame(), |
+ requesting_frame); |
+ |
+ EXPECT_EQ(CONTENT_SETTING_ALLOW, result.content_setting); |
+ EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source); |
+} |
+ |
+#if !defined(OS_ANDROID) |
+// Check PermissionResult shows permissions controlled by a user, extensions, |
+// and policy, and verify the ContentSetting of the highest precedence source is |
+// surfaced by the PermissionManager. |
+TEST_F(PermissionManagerStatusSourceTest, SourceOverriddenByOtherSource) { |
+ GURL requesting_frame("https://www.example.com/path/to/page"); |
+ NavigateToAndLoadGurl(requesting_frame); |
+ ContentSettingSourceSetter pref_tester(profile(), |
+ CONTENT_SETTINGS_TYPE_NOTIFICATIONS); |
+ |
+ pref_tester.AddUserException("*", CONTENT_SETTING_ALLOW); |
+ PermissionResult result = GetPermissionManager()->GetPermissionStatusForFrame( |
+ CONTENT_SETTINGS_TYPE_NOTIFICATIONS, web_contents()->GetMainFrame(), |
+ requesting_frame); |
+ EXPECT_EQ(CONTENT_SETTING_ALLOW, result.content_setting); |
+ EXPECT_EQ(PermissionStatusSource::UNSPECIFIED, result.source); |
+ |
+ // Verify extension settings take precedence over the user's. |
+ pref_tester.AddExtensionException("https://*", CONTENT_SETTING_BLOCK); |
+ result = GetPermissionManager()->GetPermissionStatusForFrame( |
+ CONTENT_SETTINGS_TYPE_NOTIFICATIONS, web_contents()->GetMainFrame(), |
+ requesting_frame); |
+ EXPECT_EQ(CONTENT_SETTING_BLOCK, result.content_setting); |
+ EXPECT_EQ(PermissionStatusSource::EXTENSION, result.source); |
+ |
+ // Verify policy settings take precedence over extensions. |
+ pref_tester.AddPolicyException("https://*", CONTENT_SETTING_ALLOW); |
+ result = GetPermissionManager()->GetPermissionStatusForFrame( |
+ CONTENT_SETTINGS_TYPE_NOTIFICATIONS, web_contents()->GetMainFrame(), |
+ requesting_frame); |
+ EXPECT_EQ(CONTENT_SETTING_ALLOW, result.content_setting); |
+ EXPECT_EQ(PermissionStatusSource::ENTERPRISE_POLICY, result.source); |
+ EXPECT_NE(PermissionStatusSource::EXTENSION, result.source); |
+ EXPECT_NE(PermissionStatusSource::UNSPECIFIED, result.source); |
+} |
+#endif // !defined(OS_ANDROID) |
+ |
+} // namespace test |