blob: 213a4befd4cba31b6befa4b4b388e75d0e2e6ccc [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/native_file_system/origin_scoped_native_file_system_permission_context.h"
#include <memory>
#include <string>
#include "base/base_paths.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_path_override.h"
#include "build/build_config.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/native_file_system/native_file_system_permission_request_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/base/testing_profile.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_task_environment.h"
#include "content/public/test/test_renderer_host.h"
#include "content/public/test/web_contents_tester.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/webui/webui_allowlist.h"
#include "url/gurl.h"
#include "url/origin.h"
using content::BrowserContext;
using content::WebContents;
using content::WebContentsTester;
using permissions::PermissionAction;
using UserAction = ChromeNativeFileSystemPermissionContext::UserAction;
using PermissionStatus =
content::NativeFileSystemPermissionGrant::PermissionStatus;
using PermissionRequestOutcome =
content::NativeFileSystemPermissionGrant::PermissionRequestOutcome;
using SensitiveDirectoryResult =
ChromeNativeFileSystemPermissionContext::SensitiveDirectoryResult;
using HandleType = content::NativeFileSystemPermissionContext::HandleType;
using UserActivationState =
content::NativeFileSystemPermissionGrant::UserActivationState;
class OriginScopedNativeFileSystemPermissionContextTest : public testing::Test {
public:
void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
web_contents_ =
content::WebContentsTester::CreateTestWebContents(&profile_, nullptr);
NativeFileSystemPermissionRequestManager::CreateForWebContents(
web_contents_.get());
content::WebContentsTester::For(web_contents_.get())
->NavigateAndCommit(kTestOrigin.GetURL());
NativeFileSystemPermissionRequestManager::FromWebContents(
web_contents_.get())
->set_auto_response_for_test(PermissionAction::DISMISSED);
permission_context_ =
std::make_unique<OriginScopedNativeFileSystemPermissionContext>(
browser_context());
}
void TearDown() override {
ASSERT_TRUE(temp_dir_.Delete());
web_contents_.reset();
}
void SetDefaultContentSettingValue(ContentSettingsType type,
ContentSetting value) {
HostContentSettingsMap* content_settings =
HostContentSettingsMapFactory::GetForProfile(&profile_);
content_settings->SetDefaultContentSetting(type, value);
}
void SetContentSettingValueForOrigin(url::Origin origin,
ContentSettingsType type,
ContentSetting value) {
HostContentSettingsMap* content_settings =
HostContentSettingsMapFactory::GetForProfile(&profile_);
content_settings->SetContentSettingDefaultScope(
origin.GetURL(), origin.GetURL(), type,
/*resource_identifier=*/std::string(), value);
}
OriginScopedNativeFileSystemPermissionContext* permission_context() {
return permission_context_.get();
}
BrowserContext* browser_context() { return &profile_; }
WebContents* web_contents() { return web_contents_.get(); }
int process_id() {
return web_contents()->GetMainFrame()->GetProcess()->GetID();
}
content::GlobalFrameRoutingId frame_id() {
return content::GlobalFrameRoutingId(
process_id(), web_contents()->GetMainFrame()->GetRoutingID());
}
protected:
const url::Origin kTestOrigin =
url::Origin::Create(GURL("https://example.com"));
const url::Origin kTestOrigin2 =
url::Origin::Create(GURL("https://test.com"));
const base::FilePath kTestPath =
base::FilePath(FILE_PATH_LITERAL("/foo/bar"));
const url::Origin kChromeOrigin =
url::Origin::Create(GURL("chrome://test-origin"));
content::BrowserTaskEnvironment task_environment_;
base::ScopedTempDir temp_dir_;
std::unique_ptr<OriginScopedNativeFileSystemPermissionContext>
permission_context_;
content::RenderViewHostTestEnabler render_view_host_test_enabler_;
TestingProfile profile_;
std::unique_ptr<WebContents> web_contents_;
};
#if !defined(OS_ANDROID)
TEST_F(OriginScopedNativeFileSystemPermissionContextTest,
GetReadPermissionGrant_InitialState_LoadFromStorage) {
auto grant = permission_context()->GetReadPermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kLoadFromStorage);
EXPECT_EQ(PermissionStatus::ASK, grant->GetStatus());
}
TEST_F(OriginScopedNativeFileSystemPermissionContextTest,
GetReadPermissionGrant_InitialState_Open_File) {
auto grant = permission_context()->GetReadPermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kOpen);
EXPECT_EQ(PermissionStatus::GRANTED, grant->GetStatus());
}
TEST_F(OriginScopedNativeFileSystemPermissionContextTest,
GetReadPermissionGrant_InitialState_Open_Directory) {
auto grant = permission_context()->GetReadPermissionGrant(
kTestOrigin, kTestPath, HandleType::kDirectory, UserAction::kOpen);
EXPECT_EQ(PermissionStatus::ASK, grant->GetStatus());
}
TEST_F(OriginScopedNativeFileSystemPermissionContextTest,
GetWritePermissionGrant_InitialState_LoadFromStorage) {
auto grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kLoadFromStorage);
EXPECT_EQ(PermissionStatus::ASK, grant->GetStatus());
}
TEST_F(OriginScopedNativeFileSystemPermissionContextTest,
GetWritePermissionGrant_InitialState_Open_File) {
auto grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kOpen);
EXPECT_EQ(PermissionStatus::ASK, grant->GetStatus());
}
TEST_F(OriginScopedNativeFileSystemPermissionContextTest,
GetWritePermissionGrant_InitialState_Open_Directory) {
auto grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kDirectory, UserAction::kOpen);
EXPECT_EQ(PermissionStatus::ASK, grant->GetStatus());
}
TEST_F(OriginScopedNativeFileSystemPermissionContextTest,
GetWritePermissionGrant_InitialState_WritableImplicitState) {
auto grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kSave);
EXPECT_EQ(PermissionStatus::GRANTED, grant->GetStatus());
// The existing grant should not change if the permission is blocked globally.
SetDefaultContentSettingValue(ContentSettingsType::FILE_SYSTEM_WRITE_GUARD,
CONTENT_SETTING_BLOCK);
EXPECT_EQ(PermissionStatus::GRANTED, grant->GetStatus());
// Getting a grant for the same file again should also not change the grant,
// even now asking for more permissions is blocked globally.
grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kSave);
EXPECT_EQ(PermissionStatus::GRANTED, grant->GetStatus());
}
TEST_F(OriginScopedNativeFileSystemPermissionContextTest,
GetWritePermissionGrant_WriteGrantedChangesExistingGrant) {
auto grant1 = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kOpen);
auto grant2 = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kSave);
auto grant3 = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kOpen);
// All grants should be the same grant, and be granted.
EXPECT_EQ(grant1, grant2);
EXPECT_EQ(grant1, grant3);
EXPECT_EQ(PermissionStatus::GRANTED, grant1->GetStatus());
}
TEST_F(OriginScopedNativeFileSystemPermissionContextTest,
GetWritePermissionGrant_GrantIsRevokedWhenNoLongerUsed) {
auto grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kSave);
EXPECT_EQ(PermissionStatus::GRANTED, grant->GetStatus());
grant.reset();
// After reset grant should go away, so new grant request should be in ASK
// state.
grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kOpen);
EXPECT_EQ(PermissionStatus::ASK, grant->GetStatus());
}
TEST_F(OriginScopedNativeFileSystemPermissionContextTest,
GetWritePermissionGrant_InitialState_OpenAction_GlobalGuardBlocked) {
SetDefaultContentSettingValue(ContentSettingsType::FILE_SYSTEM_WRITE_GUARD,
CONTENT_SETTING_BLOCK);
auto grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kOpen);
EXPECT_EQ(PermissionStatus::DENIED, grant->GetStatus());
grant.reset();
SetContentSettingValueForOrigin(kTestOrigin,
ContentSettingsType::FILE_SYSTEM_WRITE_GUARD,
CONTENT_SETTING_ASK);
grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kOpen);
EXPECT_EQ(PermissionStatus::ASK, grant->GetStatus());
}
TEST_F(
OriginScopedNativeFileSystemPermissionContextTest,
GetWritePermissionGrant_InitialState_WritableImplicitState_GlobalGuardBlocked) {
SetDefaultContentSettingValue(ContentSettingsType::FILE_SYSTEM_WRITE_GUARD,
CONTENT_SETTING_BLOCK);
auto grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kSave);
EXPECT_EQ(PermissionStatus::DENIED, grant->GetStatus());
grant.reset();
SetContentSettingValueForOrigin(kTestOrigin,
ContentSettingsType::FILE_SYSTEM_WRITE_GUARD,
CONTENT_SETTING_ASK);
grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kSave);
EXPECT_EQ(PermissionStatus::GRANTED, grant->GetStatus());
}
TEST_F(
OriginScopedNativeFileSystemPermissionContextTest,
GetWritePermissionGrant_WriteGrantedChangesExistingGrant_GlobalGuardBlocked) {
SetContentSettingValueForOrigin(kTestOrigin,
ContentSettingsType::FILE_SYSTEM_WRITE_GUARD,
CONTENT_SETTING_BLOCK);
auto grant1 = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kOpen);
auto grant2 = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kSave);
auto grant3 = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kOpen);
// All grants should be the same grant, and be denied.
EXPECT_EQ(grant1, grant2);
EXPECT_EQ(grant1, grant3);
EXPECT_EQ(PermissionStatus::DENIED, grant1->GetStatus());
}
TEST_F(
OriginScopedNativeFileSystemPermissionContextTest,
GetWritePermissionGrant_GrantIsRevokedWhenNoLongerUsed_GlobalGuardBlockedBeforeNewGrant) {
SetDefaultContentSettingValue(ContentSettingsType::FILE_SYSTEM_WRITE_GUARD,
CONTENT_SETTING_BLOCK);
auto grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kSave);
EXPECT_EQ(PermissionStatus::DENIED, grant->GetStatus());
grant.reset();
// After reset grant should go away, but the new grant request should be in
// DENIED state.
grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kOpen);
EXPECT_EQ(PermissionStatus::DENIED, grant->GetStatus());
}
TEST_F(
OriginScopedNativeFileSystemPermissionContextTest,
GetWritePermissionGrant_GrantIsRevokedWhenNoLongerUsed_GlobalGuardBlockedAfterNewGrant) {
auto grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kSave);
EXPECT_EQ(PermissionStatus::GRANTED, grant->GetStatus());
grant.reset();
// After reset grant should go away, but the new grant request should be in
// ASK state.
grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kOpen);
EXPECT_EQ(PermissionStatus::ASK, grant->GetStatus());
SetDefaultContentSettingValue(ContentSettingsType::FILE_SYSTEM_WRITE_GUARD,
CONTENT_SETTING_BLOCK);
// After the guard is blocked, the permission status for |grant| should remain
// unchanged.
EXPECT_EQ(PermissionStatus::ASK, grant->GetStatus());
}
TEST_F(OriginScopedNativeFileSystemPermissionContextTest,
RequestPermission_Dismissed) {
NativeFileSystemPermissionRequestManager::FromWebContents(web_contents_.get())
->set_auto_response_for_test(PermissionAction::DISMISSED);
content::RenderFrameHostTester::For(web_contents_->GetMainFrame())
->SimulateUserActivation();
auto grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kOpen);
base::RunLoop loop;
grant->RequestPermission(
frame_id(), UserActivationState::kRequired,
base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) {
EXPECT_EQ(PermissionRequestOutcome::kUserDismissed, outcome);
loop.Quit();
}));
loop.Run();
// Dismissed, so status should not change.
EXPECT_EQ(PermissionStatus::ASK, grant->GetStatus());
}
TEST_F(OriginScopedNativeFileSystemPermissionContextTest,
RequestPermission_Granted) {
NativeFileSystemPermissionRequestManager::FromWebContents(web_contents_.get())
->set_auto_response_for_test(PermissionAction::GRANTED);
content::RenderFrameHostTester::For(web_contents_->GetMainFrame())
->SimulateUserActivation();
auto grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kOpen);
base::RunLoop loop;
grant->RequestPermission(
frame_id(), UserActivationState::kRequired,
base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) {
EXPECT_EQ(PermissionRequestOutcome::kUserGranted, outcome);
loop.Quit();
}));
loop.Run();
EXPECT_EQ(PermissionStatus::GRANTED, grant->GetStatus());
}
TEST_F(OriginScopedNativeFileSystemPermissionContextTest,
RequestPermission_Denied) {
NativeFileSystemPermissionRequestManager::FromWebContents(web_contents_.get())
->set_auto_response_for_test(PermissionAction::DENIED);
content::RenderFrameHostTester::For(web_contents_->GetMainFrame())
->SimulateUserActivation();
auto grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kOpen);
base::RunLoop loop;
grant->RequestPermission(
frame_id(), UserActivationState::kRequired,
base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) {
EXPECT_EQ(PermissionRequestOutcome::kUserDenied, outcome);
loop.Quit();
}));
loop.Run();
EXPECT_EQ(PermissionStatus::DENIED, grant->GetStatus());
}
TEST_F(OriginScopedNativeFileSystemPermissionContextTest,
RequestPermission_NoUserActivation) {
NativeFileSystemPermissionRequestManager::FromWebContents(web_contents_.get())
->set_auto_response_for_test(PermissionAction::GRANTED);
auto grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kOpen);
base::RunLoop loop;
grant->RequestPermission(
frame_id(), UserActivationState::kRequired,
base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) {
EXPECT_EQ(PermissionRequestOutcome::kNoUserActivation, outcome);
loop.Quit();
}));
loop.Run();
// No user activation, so status should not change.
EXPECT_EQ(PermissionStatus::ASK, grant->GetStatus());
}
TEST_F(OriginScopedNativeFileSystemPermissionContextTest,
RequestPermission_NoUserActivation_UserActivationNotRequired) {
NativeFileSystemPermissionRequestManager::FromWebContents(web_contents_.get())
->set_auto_response_for_test(PermissionAction::GRANTED);
auto grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kOpen);
base::RunLoop loop;
grant->RequestPermission(
frame_id(), UserActivationState::kNotRequired,
base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) {
EXPECT_EQ(PermissionRequestOutcome::kUserGranted, outcome);
loop.Quit();
}));
loop.Run();
// No user activation, so status should not change.
EXPECT_EQ(PermissionStatus::GRANTED, grant->GetStatus());
}
TEST_F(OriginScopedNativeFileSystemPermissionContextTest,
RequestPermission_AlreadyGranted) {
// If the permission has already been granted, a call to RequestPermission()
// should call the passed-in callback and return immediately without showing a
// prompt.
auto grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kSave);
base::RunLoop loop;
grant->RequestPermission(
frame_id(), UserActivationState::kRequired,
base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) {
EXPECT_EQ(PermissionRequestOutcome::kRequestAborted, outcome);
loop.Quit();
}));
loop.Run();
EXPECT_EQ(PermissionStatus::GRANTED, grant->GetStatus());
}
TEST_F(OriginScopedNativeFileSystemPermissionContextTest,
RequestPermission_GlobalGuardBlockedBeforeOpenGrant) {
// If the guard content setting is blocked, a call to RequestPermission()
// should update the PermissionStatus to DENIED, call the passed-in
// callback, and return immediately without showing a prompt.
SetDefaultContentSettingValue(ContentSettingsType::FILE_SYSTEM_WRITE_GUARD,
CONTENT_SETTING_BLOCK);
auto grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kOpen);
base::RunLoop loop;
grant->RequestPermission(
frame_id(), UserActivationState::kRequired,
base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) {
EXPECT_EQ(PermissionRequestOutcome::kRequestAborted, outcome);
loop.Quit();
}));
loop.Run();
EXPECT_EQ(PermissionStatus::DENIED, grant->GetStatus());
auto grant2 = permission_context()->GetWritePermissionGrant(
kTestOrigin2, kTestPath, HandleType::kFile, UserAction::kOpen);
base::RunLoop loop2;
grant2->RequestPermission(
frame_id(), UserActivationState::kRequired,
base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) {
EXPECT_EQ(PermissionRequestOutcome::kRequestAborted, outcome);
loop2.Quit();
}));
loop2.Run();
EXPECT_EQ(PermissionStatus::DENIED, grant2->GetStatus());
grant2.reset();
SetContentSettingValueForOrigin(kTestOrigin2,
ContentSettingsType::FILE_SYSTEM_WRITE_GUARD,
CONTENT_SETTING_ASK);
grant2 = permission_context()->GetWritePermissionGrant(
kTestOrigin2, kTestPath, HandleType::kFile, UserAction::kOpen);
base::RunLoop loop3;
grant2->RequestPermission(
frame_id(), UserActivationState::kRequired,
base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) {
EXPECT_EQ(PermissionRequestOutcome::kNoUserActivation, outcome);
loop3.Quit();
}));
loop3.Run();
EXPECT_EQ(PermissionStatus::ASK, grant2->GetStatus());
}
TEST_F(OriginScopedNativeFileSystemPermissionContextTest,
RequestPermission_GlobalGuardBlockedAfterOpenGrant) {
// If the guard content setting is blocked, a call to RequestPermission()
// should update the PermissionStatus to DENIED, call the passed-in
// callback, and return immediately without showing a prompt.
auto grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kOpen);
auto grant2 = permission_context()->GetWritePermissionGrant(
kTestOrigin2, kTestPath, HandleType::kFile, UserAction::kOpen);
SetDefaultContentSettingValue(ContentSettingsType::FILE_SYSTEM_WRITE_GUARD,
CONTENT_SETTING_BLOCK);
base::RunLoop loop;
grant->RequestPermission(
frame_id(), UserActivationState::kRequired,
base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) {
EXPECT_EQ(PermissionRequestOutcome::kBlockedByContentSetting, outcome);
loop.Quit();
}));
loop.Run();
EXPECT_EQ(PermissionStatus::DENIED, grant->GetStatus());
base::RunLoop loop2;
grant2->RequestPermission(
frame_id(), UserActivationState::kRequired,
base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) {
EXPECT_EQ(PermissionRequestOutcome::kBlockedByContentSetting, outcome);
loop2.Quit();
}));
loop2.Run();
EXPECT_EQ(PermissionStatus::DENIED, grant2->GetStatus());
grant.reset();
grant2.reset();
SetContentSettingValueForOrigin(kTestOrigin,
ContentSettingsType::FILE_SYSTEM_WRITE_GUARD,
CONTENT_SETTING_ASK);
grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kOpen);
grant2 = permission_context()->GetWritePermissionGrant(
kTestOrigin2, kTestPath, HandleType::kFile, UserAction::kOpen);
base::RunLoop loop3;
grant->RequestPermission(
frame_id(), UserActivationState::kRequired,
base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) {
EXPECT_EQ(PermissionRequestOutcome::kNoUserActivation, outcome);
loop3.Quit();
}));
loop3.Run();
EXPECT_EQ(PermissionStatus::ASK, grant->GetStatus());
base::RunLoop loop4;
grant2->RequestPermission(
frame_id(), UserActivationState::kRequired,
base::BindLambdaForTesting([&](PermissionRequestOutcome outcome) {
EXPECT_EQ(PermissionRequestOutcome::kRequestAborted, outcome);
loop4.Quit();
}));
loop4.Run();
EXPECT_EQ(PermissionStatus::DENIED, grant2->GetStatus());
}
TEST_F(OriginScopedNativeFileSystemPermissionContextTest,
GetWritePermissionGrant_AllowlistedOrigin_InitialState) {
SetDefaultContentSettingValue(ContentSettingsType::FILE_SYSTEM_WRITE_GUARD,
CONTENT_SETTING_BLOCK);
auto* allowlist = WebUIAllowlist::GetOrCreate(browser_context());
allowlist->RegisterAutoGrantedPermission(
kChromeOrigin, ContentSettingsType::FILE_SYSTEM_READ_GUARD);
allowlist->RegisterAutoGrantedPermission(
kChromeOrigin, ContentSettingsType::FILE_SYSTEM_WRITE_GUARD);
// Allowlisted origin automatically gets write permission.
auto grant1 = permission_context()->GetWritePermissionGrant(
kChromeOrigin, kTestPath, HandleType::kFile, UserAction::kOpen);
EXPECT_EQ(PermissionStatus::GRANTED, grant1->GetStatus());
auto grant2 = permission_context()->GetWritePermissionGrant(
kChromeOrigin, kTestPath, HandleType::kDirectory, UserAction::kOpen);
EXPECT_EQ(PermissionStatus::GRANTED, grant2->GetStatus());
// Other origin should gets blocked.
auto grant3 = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kOpen);
EXPECT_EQ(PermissionStatus::DENIED, grant3->GetStatus());
auto grant4 = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kDirectory, UserAction::kOpen);
EXPECT_EQ(PermissionStatus::DENIED, grant4->GetStatus());
}
TEST_F(OriginScopedNativeFileSystemPermissionContextTest,
GetWritePermissionGrant_AllowlistedOrigin_ExistingGrant) {
SetDefaultContentSettingValue(ContentSettingsType::FILE_SYSTEM_WRITE_GUARD,
CONTENT_SETTING_BLOCK);
auto* allowlist = WebUIAllowlist::GetOrCreate(browser_context());
allowlist->RegisterAutoGrantedPermission(
kChromeOrigin, ContentSettingsType::FILE_SYSTEM_READ_GUARD);
allowlist->RegisterAutoGrantedPermission(
kChromeOrigin, ContentSettingsType::FILE_SYSTEM_WRITE_GUARD);
// Initial grant (file).
auto grant1 = permission_context()->GetWritePermissionGrant(
kChromeOrigin, kTestPath, HandleType::kFile, UserAction::kOpen);
EXPECT_EQ(PermissionStatus::GRANTED, grant1->GetStatus());
// Existing grant (file).
auto grant2 = permission_context()->GetWritePermissionGrant(
kChromeOrigin, kTestPath, HandleType::kFile, UserAction::kOpen);
EXPECT_EQ(PermissionStatus::GRANTED, grant2->GetStatus());
// Initial grant (directory).
auto grant3 = permission_context()->GetWritePermissionGrant(
kChromeOrigin, kTestPath, HandleType::kDirectory, UserAction::kOpen);
EXPECT_EQ(PermissionStatus::GRANTED, grant3->GetStatus());
// Existing grant (directory).
auto grant4 = permission_context()->GetWritePermissionGrant(
kChromeOrigin, kTestPath, HandleType::kDirectory, UserAction::kOpen);
EXPECT_EQ(PermissionStatus::GRANTED, grant4->GetStatus());
}
TEST_F(OriginScopedNativeFileSystemPermissionContextTest,
GetReadPermissionGrant_FileBecomesDirectory) {
auto file_grant = permission_context()->GetReadPermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kOpen);
EXPECT_EQ(PermissionStatus::GRANTED, file_grant->GetStatus());
auto directory_grant = permission_context()->GetReadPermissionGrant(
kTestOrigin, kTestPath, HandleType::kDirectory, UserAction::kOpen);
EXPECT_EQ(PermissionStatus::ASK, directory_grant->GetStatus());
// Requesting a permission grant for a directory which was previously a file
// should have revoked the original file permission.
EXPECT_EQ(PermissionStatus::DENIED, file_grant->GetStatus());
}
TEST_F(OriginScopedNativeFileSystemPermissionContextTest,
GetWritePermissionGrant_FileBecomesDirectory) {
auto file_grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kFile, UserAction::kSave);
EXPECT_EQ(PermissionStatus::GRANTED, file_grant->GetStatus());
auto directory_grant = permission_context()->GetWritePermissionGrant(
kTestOrigin, kTestPath, HandleType::kDirectory, UserAction::kOpen);
EXPECT_EQ(PermissionStatus::ASK, directory_grant->GetStatus());
// Requesting a permission grant for a directory which was previously a file
// should have revoked the original file permission.
EXPECT_EQ(PermissionStatus::DENIED, file_grant->GetStatus());
}
#endif // !defined(OS_ANDROID)