dlp: Pass file access callback to file stream reader
The callback is passed through the calls from the mojo interface to the file stream reader. Where it is used to gain a ScopedFileAccess token to read files. The callback is not yet created for the calls depending on the destination URL. That will happen with a CL for b/262203074. There are different cases for default behavior, where we do not need to query the daemon with a specific URL. Only files explicitly known/downloaded to the user can be protected. That excludes e.g. caches. The daemon would not deny those accesses, so we do not have to ask for permission. The other default are cases, where we want to allow access regardless of the rules. Here we have to query the daemon with a request for the system component (e.g. by the callback returned by ScopedFileAccessDelegate::GetCallbackForSystemIO). Design doc: go/access-to-dlp-restricted-files-upload BUG=b:262199707 Change-Id: Id71ac3463aae4c0d0b02bb3a264c2a8d05798f22 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4197601 Reviewed-by: Sergey Poromov <poromov@chromium.org> Reviewed-by: Austin Sullivan <asully@chromium.org> Commit-Queue: Daniel Brinkers <brinky@google.com> Reviewed-by: Marcello Salomao <msalomao@google.com> Reviewed-by: Marijn Kruisselbrink <mek@chromium.org> Cr-Commit-Position: refs/heads/main@{#1114995}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
9df0c47961
commit
9dacf9e173
chrome/browser
ash
chromeos
policy
media_galleries
sync_file_system
components/file_access
scoped_file_access_delegate.ccscoped_file_access_delegate.hscoped_file_access_delegate_unittest.cc
test
content/browser/blob_storage
storage
BUILD.gn
browser
BUILD.gn
blob
blob_data_builder.ccblob_data_builder.hblob_data_item.ccblob_data_item.hblob_reader.ccblob_reader.hblob_registry_impl.ccblob_registry_impl.hblob_storage_context.cc
file_system
file_stream_reader.hfile_system_backend.hfile_system_context.ccfile_system_context.hisolated_file_system_backend.ccisolated_file_system_backend.hlocal_file_stream_reader.cclocal_file_stream_reader.hlocal_file_stream_reader_unittest.ccsandbox_file_system_backend.ccsandbox_file_system_backend.h
test
@ -12,6 +12,7 @@
|
|||||||
#include "ash/webui/file_manager/url_constants.h"
|
#include "ash/webui/file_manager/url_constants.h"
|
||||||
#include "base/check_op.h"
|
#include "base/check_op.h"
|
||||||
#include "base/command_line.h"
|
#include "base/command_line.h"
|
||||||
|
#include "base/functional/callback_helpers.h"
|
||||||
#include "base/notreached.h"
|
#include "base/notreached.h"
|
||||||
#include "base/strings/escape.h"
|
#include "base/strings/escape.h"
|
||||||
#include "base/task/task_traits.h"
|
#include "base/task/task_traits.h"
|
||||||
@ -24,6 +25,7 @@
|
|||||||
#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
|
#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
|
||||||
#include "chrome/common/url_constants.h"
|
#include "chrome/common/url_constants.h"
|
||||||
#include "chromeos/ash/components/dbus/cros_disks/cros_disks_client.h"
|
#include "chromeos/ash/components/dbus/cros_disks/cros_disks_client.h"
|
||||||
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "components/user_manager/user.h"
|
#include "components/user_manager/user.h"
|
||||||
#include "storage/browser/file_system/async_file_util.h"
|
#include "storage/browser/file_system/async_file_util.h"
|
||||||
#include "storage/browser/file_system/external_mount_points.h"
|
#include "storage/browser/file_system/external_mount_points.h"
|
||||||
@ -421,7 +423,9 @@ FileSystemBackend::CreateFileStreamReader(
|
|||||||
int64_t offset,
|
int64_t offset,
|
||||||
int64_t max_bytes_to_read,
|
int64_t max_bytes_to_read,
|
||||||
const base::Time& expected_modification_time,
|
const base::Time& expected_modification_time,
|
||||||
storage::FileSystemContext* context) const {
|
storage::FileSystemContext* context,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access) const {
|
||||||
DCHECK(url.is_valid());
|
DCHECK(url.is_valid());
|
||||||
|
|
||||||
if (!IsAccessAllowed(url))
|
if (!IsAccessAllowed(url))
|
||||||
@ -431,8 +435,15 @@ FileSystemBackend::CreateFileStreamReader(
|
|||||||
case storage::kFileSystemTypeProvided:
|
case storage::kFileSystemTypeProvided:
|
||||||
return file_system_provider_delegate_->CreateFileStreamReader(
|
return file_system_provider_delegate_->CreateFileStreamReader(
|
||||||
url, offset, max_bytes_to_read, expected_modification_time, context);
|
url, offset, max_bytes_to_read, expected_modification_time, context);
|
||||||
|
// The dlp file_access callback is needed for the local filesystem only.
|
||||||
case storage::kFileSystemTypeLocal:
|
case storage::kFileSystemTypeLocal:
|
||||||
case storage::kFileSystemTypeRestrictedLocal:
|
case storage::kFileSystemTypeRestrictedLocal:
|
||||||
|
return storage::FileStreamReader::CreateForLocalFile(
|
||||||
|
base::ThreadPool::CreateTaskRunner(
|
||||||
|
{base::MayBlock(), base::TaskPriority::USER_VISIBLE})
|
||||||
|
.get(),
|
||||||
|
url.path(), offset, expected_modification_time,
|
||||||
|
std::move(file_access));
|
||||||
case storage::kFileSystemTypeDriveFs:
|
case storage::kFileSystemTypeDriveFs:
|
||||||
case storage::kFileSystemTypeSmbFs:
|
case storage::kFileSystemTypeSmbFs:
|
||||||
case storage::kFileSystemTypeFuseBox:
|
case storage::kFileSystemTypeFuseBox:
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
#include "base/memory/ref_counted.h"
|
#include "base/memory/ref_counted.h"
|
||||||
#include "components/account_id/account_id.h"
|
#include "components/account_id/account_id.h"
|
||||||
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "storage/browser/file_system/file_system_backend.h"
|
#include "storage/browser/file_system/file_system_backend.h"
|
||||||
#include "storage/browser/file_system/task_runner_bound_observer_list.h"
|
#include "storage/browser/file_system/task_runner_bound_observer_list.h"
|
||||||
#include "storage/common/file_system/file_system_types.h"
|
#include "storage/common/file_system/file_system_types.h"
|
||||||
@ -125,7 +126,9 @@ class FileSystemBackend : public storage::ExternalFileSystemBackend {
|
|||||||
int64_t offset,
|
int64_t offset,
|
||||||
int64_t max_bytes_to_read,
|
int64_t max_bytes_to_read,
|
||||||
const base::Time& expected_modification_time,
|
const base::Time& expected_modification_time,
|
||||||
storage::FileSystemContext* context) const override;
|
storage::FileSystemContext* context,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access) const override;
|
||||||
std::unique_ptr<storage::FileStreamWriter> CreateFileStreamWriter(
|
std::unique_ptr<storage::FileStreamWriter> CreateFileStreamWriter(
|
||||||
const storage::FileSystemURL& url,
|
const storage::FileSystemURL& url,
|
||||||
int64_t offset,
|
int64_t offset,
|
||||||
|
@ -4,12 +4,16 @@
|
|||||||
|
|
||||||
#include "chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate.h"
|
#include "chrome/browser/chromeos/policy/dlp/dlp_scoped_file_access_delegate.h"
|
||||||
|
|
||||||
|
#include "base/files/file_path.h"
|
||||||
#include "base/functional/bind.h"
|
#include "base/functional/bind.h"
|
||||||
#include "base/functional/callback_forward.h"
|
#include "base/functional/callback_forward.h"
|
||||||
#include "base/process/process_handle.h"
|
#include "base/process/process_handle.h"
|
||||||
#include "base/task/bind_post_task.h"
|
#include "base/task/bind_post_task.h"
|
||||||
#include "chrome/browser/chromeos/policy/dlp/dlp_file_access_copy_or_move_delegate_factory.h"
|
#include "chrome/browser/chromeos/policy/dlp/dlp_file_access_copy_or_move_delegate_factory.h"
|
||||||
#include "chromeos/dbus/dlp/dlp_client.h"
|
#include "chromeos/dbus/dlp/dlp_client.h"
|
||||||
|
#include "components/file_access/scoped_file_access.h"
|
||||||
|
#include "components/file_access/scoped_file_access_copy.h"
|
||||||
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "content/public/browser/browser_task_traits.h"
|
#include "content/public/browser/browser_task_traits.h"
|
||||||
#include "content/public/browser/browser_thread.h"
|
#include "content/public/browser/browser_thread.h"
|
||||||
|
|
||||||
@ -56,7 +60,7 @@ void DlpScopedFileAccessDelegate::Initialize(chromeos::DlpClient* client) {
|
|||||||
if (!request_files_access_for_system_io_callback_) {
|
if (!request_files_access_for_system_io_callback_) {
|
||||||
request_files_access_for_system_io_callback_ =
|
request_files_access_for_system_io_callback_ =
|
||||||
new file_access::ScopedFileAccessDelegate::
|
new file_access::ScopedFileAccessDelegate::
|
||||||
RequestFilesAccessForSystemIOCallback(base::BindPostTask(
|
RequestFilesAccessIOCallback(base::BindPostTask(
|
||||||
content::GetUIThreadTaskRunner({}),
|
content::GetUIThreadTaskRunner({}),
|
||||||
base::BindRepeating(&RequestFileAccessForSystem)));
|
base::BindRepeating(&RequestFileAccessForSystem)));
|
||||||
}
|
}
|
||||||
@ -115,6 +119,29 @@ void DlpScopedFileAccessDelegate::RequestFilesAccessForSystem(
|
|||||||
PostRequestFileAccessToDaemon(request, std::move(callback));
|
PostRequestFileAccessToDaemon(request, std::move(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DlpScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
DlpScopedFileAccessDelegate::CreateFileAccessCallback(
|
||||||
|
const GURL& destination) const {
|
||||||
|
return base::BindPostTask(
|
||||||
|
content::GetUIThreadTaskRunner({}),
|
||||||
|
base::BindRepeating(
|
||||||
|
[](const GURL& destination, const std::vector<base::FilePath>& files,
|
||||||
|
base::OnceCallback<void(file_access::ScopedFileAccess)> callback) {
|
||||||
|
if (file_access::ScopedFileAccessDelegate::HasInstance()) {
|
||||||
|
file_access::ScopedFileAccessDelegate::Get()->RequestFilesAccess(
|
||||||
|
files, destination,
|
||||||
|
base::BindPostTask(content::GetIOThreadTaskRunner({}),
|
||||||
|
std::move(callback)));
|
||||||
|
} else {
|
||||||
|
content::GetIOThreadTaskRunner({})->PostTask(
|
||||||
|
FROM_HERE,
|
||||||
|
base::BindOnce(std::move(callback),
|
||||||
|
file_access::ScopedFileAccess::Allowed()));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
destination));
|
||||||
|
}
|
||||||
|
|
||||||
void DlpScopedFileAccessDelegate::PostRequestFileAccessToDaemon(
|
void DlpScopedFileAccessDelegate::PostRequestFileAccessToDaemon(
|
||||||
const ::dlp::RequestFileAccessRequest request,
|
const ::dlp::RequestFileAccessRequest request,
|
||||||
base::OnceCallback<void(file_access::ScopedFileAccess)> callback) {
|
base::OnceCallback<void(file_access::ScopedFileAccess)> callback) {
|
||||||
|
@ -44,6 +44,8 @@ class DlpScopedFileAccessDelegate
|
|||||||
const std::vector<base::FilePath>& files,
|
const std::vector<base::FilePath>& files,
|
||||||
base::OnceCallback<void(file_access::ScopedFileAccess)> callback)
|
base::OnceCallback<void(file_access::ScopedFileAccess)> callback)
|
||||||
override;
|
override;
|
||||||
|
RequestFilesAccessIOCallback CreateFileAccessCallback(
|
||||||
|
const GURL& destination) const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit DlpScopedFileAccessDelegate(chromeos::DlpClient* client);
|
explicit DlpScopedFileAccessDelegate(chromeos::DlpClient* client);
|
||||||
|
@ -36,7 +36,8 @@ class DlpScopedFileAccessDelegateTest : public testing::Test {
|
|||||||
protected:
|
protected:
|
||||||
content::BrowserTaskEnvironment task_environment_;
|
content::BrowserTaskEnvironment task_environment_;
|
||||||
chromeos::FakeDlpClient fake_dlp_client_;
|
chromeos::FakeDlpClient fake_dlp_client_;
|
||||||
DlpScopedFileAccessDelegate delegate_{&fake_dlp_client_};
|
std::unique_ptr<DlpScopedFileAccessDelegate> delegate_{
|
||||||
|
new DlpScopedFileAccessDelegate(&fake_dlp_client_)};
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_F(DlpScopedFileAccessDelegateTest, TestNoSingleton) {
|
TEST_F(DlpScopedFileAccessDelegateTest, TestNoSingleton) {
|
||||||
@ -44,14 +45,14 @@ TEST_F(DlpScopedFileAccessDelegateTest, TestNoSingleton) {
|
|||||||
base::CreateTemporaryFile(&file_path);
|
base::CreateTemporaryFile(&file_path);
|
||||||
|
|
||||||
base::test::TestFuture<file_access::ScopedFileAccess> future1;
|
base::test::TestFuture<file_access::ScopedFileAccess> future1;
|
||||||
delegate_.RequestFilesAccess({file_path}, GURL("example.com"),
|
delegate_->RequestFilesAccess({file_path}, GURL("example.com"),
|
||||||
future1.GetCallback());
|
future1.GetCallback());
|
||||||
EXPECT_TRUE(future1.Get<0>().is_allowed());
|
EXPECT_TRUE(future1.Get<0>().is_allowed());
|
||||||
|
|
||||||
fake_dlp_client_.SetFileAccessAllowed(false);
|
fake_dlp_client_.SetFileAccessAllowed(false);
|
||||||
base::test::TestFuture<file_access::ScopedFileAccess> future2;
|
base::test::TestFuture<file_access::ScopedFileAccess> future2;
|
||||||
delegate_.RequestFilesAccess({file_path}, GURL("example.com"),
|
delegate_->RequestFilesAccess({file_path}, GURL("example.com"),
|
||||||
future2.GetCallback());
|
future2.GetCallback());
|
||||||
EXPECT_FALSE(future2.Get<0>().is_allowed());
|
EXPECT_FALSE(future2.Get<0>().is_allowed());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,6 +88,84 @@ TEST_F(DlpScopedFileAccessDelegateTest,
|
|||||||
EXPECT_TRUE(future1.Get<0>().is_allowed());
|
EXPECT_TRUE(future1.Get<0>().is_allowed());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(DlpScopedFileAccessDelegateTest, CreateFileAccessCallbackAllowTest) {
|
||||||
|
base::FilePath file_path;
|
||||||
|
base::CreateTemporaryFile(&file_path);
|
||||||
|
|
||||||
|
DlpScopedFileAccessDelegate::Initialize(&fake_dlp_client_);
|
||||||
|
fake_dlp_client_.SetFileAccessAllowed(true);
|
||||||
|
|
||||||
|
base::test::TestFuture<file_access::ScopedFileAccess> future;
|
||||||
|
auto* delegate = file_access::ScopedFileAccessDelegate::Get();
|
||||||
|
auto cb = delegate->CreateFileAccessCallback(GURL("https://google.com"));
|
||||||
|
cb.Run({file_path}, future.GetCallback());
|
||||||
|
EXPECT_TRUE(future.Get<0>().is_allowed());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DlpScopedFileAccessDelegateTest, CreateFileAccessCallbackDenyTest) {
|
||||||
|
base::FilePath file_path;
|
||||||
|
base::CreateTemporaryFile(&file_path);
|
||||||
|
|
||||||
|
DlpScopedFileAccessDelegate::Initialize(&fake_dlp_client_);
|
||||||
|
fake_dlp_client_.SetFileAccessAllowed(false);
|
||||||
|
|
||||||
|
base::test::TestFuture<file_access::ScopedFileAccess> future;
|
||||||
|
auto* delegate = file_access::ScopedFileAccessDelegate::Get();
|
||||||
|
auto cb = delegate->CreateFileAccessCallback(GURL("https://google.com"));
|
||||||
|
cb.Run({file_path}, future.GetCallback());
|
||||||
|
EXPECT_FALSE(future.Get<0>().is_allowed());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DlpScopedFileAccessDelegateTest,
|
||||||
|
CreateFileAccessCallbackLostInstanceTest) {
|
||||||
|
base::FilePath file_path;
|
||||||
|
base::CreateTemporaryFile(&file_path);
|
||||||
|
|
||||||
|
DlpScopedFileAccessDelegate::Initialize(&fake_dlp_client_);
|
||||||
|
fake_dlp_client_.SetFileAccessAllowed(false);
|
||||||
|
|
||||||
|
base::test::TestFuture<file_access::ScopedFileAccess> future;
|
||||||
|
auto* delegate = file_access::ScopedFileAccessDelegate::Get();
|
||||||
|
auto cb = delegate->CreateFileAccessCallback(GURL("https://google.com"));
|
||||||
|
delegate_.reset();
|
||||||
|
cb.Run({file_path}, future.GetCallback());
|
||||||
|
EXPECT_TRUE(future.Get<0>().is_allowed());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DlpScopedFileAccessDelegateTest, GetCallbackSystemTest) {
|
||||||
|
base::FilePath file_path;
|
||||||
|
base::CreateTemporaryFile(&file_path);
|
||||||
|
|
||||||
|
DlpScopedFileAccessDelegate::Initialize(&fake_dlp_client_);
|
||||||
|
|
||||||
|
// Post a task on IO thread to sync with to be sure the IO task setting
|
||||||
|
// `request_files_access_for_system_io_callback_` has run.
|
||||||
|
base::RunLoop init;
|
||||||
|
auto io_thread = content::GetIOThreadTaskRunner({});
|
||||||
|
io_thread->PostTask(
|
||||||
|
FROM_HERE, base::BindOnce(&base::RunLoop::Quit, base::Unretained(&init)));
|
||||||
|
init.Run();
|
||||||
|
|
||||||
|
base::test::TestFuture<file_access::ScopedFileAccess> future;
|
||||||
|
auto* delegate = file_access::ScopedFileAccessDelegate::Get();
|
||||||
|
auto cb = delegate->GetCallbackForSystem();
|
||||||
|
EXPECT_TRUE(cb);
|
||||||
|
cb.Run({file_path}, future.GetCallback());
|
||||||
|
EXPECT_TRUE(future.Get<0>().is_allowed());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(DlpScopedFileAccessDelegateTest, GetCallbackSystemNoSingeltonTest) {
|
||||||
|
base::FilePath file_path;
|
||||||
|
base::CreateTemporaryFile(&file_path);
|
||||||
|
|
||||||
|
base::test::TestFuture<file_access::ScopedFileAccess> future;
|
||||||
|
auto* delegate = file_access::ScopedFileAccessDelegate::Get();
|
||||||
|
auto cb = delegate->GetCallbackForSystem();
|
||||||
|
EXPECT_TRUE(cb);
|
||||||
|
cb.Run({file_path}, future.GetCallback());
|
||||||
|
EXPECT_TRUE(future.Get<0>().is_allowed());
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(DlpScopedFileAccessDelegateTest, TestMultipleInstances) {
|
TEST_F(DlpScopedFileAccessDelegateTest, TestMultipleInstances) {
|
||||||
DlpScopedFileAccessDelegate::Initialize(nullptr);
|
DlpScopedFileAccessDelegate::Initialize(nullptr);
|
||||||
EXPECT_NO_FATAL_FAILURE(DlpScopedFileAccessDelegate::Initialize(nullptr));
|
EXPECT_NO_FATAL_FAILURE(DlpScopedFileAccessDelegate::Initialize(nullptr));
|
||||||
@ -209,7 +288,6 @@ TEST_F(DlpScopedFileAccessDelegateTaskTest,
|
|||||||
std::move(callback));
|
std::move(callback));
|
||||||
}),
|
}),
|
||||||
false /* = restore_original_callback*/);
|
false /* = restore_original_callback*/);
|
||||||
|
|
||||||
// The request for file access should be granted as that is the default
|
// The request for file access should be granted as that is the default
|
||||||
// behaviour for no running dlp (no rules).
|
// behaviour for no running dlp (no rules).
|
||||||
io_thread_->PostTask(
|
io_thread_->PostTask(
|
||||||
|
@ -316,7 +316,9 @@ MediaFileSystemBackend::CreateFileStreamReader(
|
|||||||
int64_t offset,
|
int64_t offset,
|
||||||
int64_t max_bytes_to_read,
|
int64_t max_bytes_to_read,
|
||||||
const base::Time& expected_modification_time,
|
const base::Time& expected_modification_time,
|
||||||
FileSystemContext* context) const {
|
FileSystemContext* context,
|
||||||
|
file_access::ScopedFileAccessDelegate::
|
||||||
|
RequestFilesAccessIOCallback /*file_access*/) const {
|
||||||
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
|
#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
|
||||||
if (url.type() == storage::kFileSystemTypeDeviceMedia) {
|
if (url.type() == storage::kFileSystemTypeDeviceMedia) {
|
||||||
std::unique_ptr<storage::FileStreamReader> reader =
|
std::unique_ptr<storage::FileStreamReader> reader =
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "build/chromeos_buildflags.h"
|
#include "build/chromeos_buildflags.h"
|
||||||
#include "chrome/browser/media_galleries/media_galleries_preferences.h"
|
#include "chrome/browser/media_galleries/media_galleries_preferences.h"
|
||||||
#include "components/download/public/common/quarantine_connection.h"
|
#include "components/download/public/common/quarantine_connection.h"
|
||||||
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "storage/browser/file_system/file_system_backend.h"
|
#include "storage/browser/file_system/file_system_backend.h"
|
||||||
#include "storage/browser/file_system/file_system_request_info.h"
|
#include "storage/browser/file_system/file_system_request_info.h"
|
||||||
#include "storage/browser/file_system/task_runner_bound_observer_list.h"
|
#include "storage/browser/file_system/task_runner_bound_observer_list.h"
|
||||||
@ -85,7 +86,9 @@ class MediaFileSystemBackend : public storage::FileSystemBackend {
|
|||||||
int64_t offset,
|
int64_t offset,
|
||||||
int64_t max_bytes_to_read,
|
int64_t max_bytes_to_read,
|
||||||
const base::Time& expected_modification_time,
|
const base::Time& expected_modification_time,
|
||||||
storage::FileSystemContext* context) const override;
|
storage::FileSystemContext* context,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access) const override;
|
||||||
std::unique_ptr<storage::FileStreamWriter> CreateFileStreamWriter(
|
std::unique_ptr<storage::FileStreamWriter> CreateFileStreamWriter(
|
||||||
const storage::FileSystemURL& url,
|
const storage::FileSystemURL& url,
|
||||||
int64_t offset,
|
int64_t offset,
|
||||||
|
@ -163,7 +163,9 @@ SyncFileSystemBackend::CreateFileStreamReader(
|
|||||||
int64_t offset,
|
int64_t offset,
|
||||||
int64_t max_bytes_to_read,
|
int64_t max_bytes_to_read,
|
||||||
const base::Time& expected_modification_time,
|
const base::Time& expected_modification_time,
|
||||||
storage::FileSystemContext* context) const {
|
storage::FileSystemContext* context,
|
||||||
|
file_access::ScopedFileAccessDelegate::
|
||||||
|
RequestFilesAccessIOCallback /*file_access*/) const {
|
||||||
DCHECK(CanHandleType(url.type()));
|
DCHECK(CanHandleType(url.type()));
|
||||||
return GetDelegate()->CreateFileStreamReader(
|
return GetDelegate()->CreateFileStreamReader(
|
||||||
url, offset, expected_modification_time, context);
|
url, offset, expected_modification_time, context);
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "base/memory/raw_ptr.h"
|
#include "base/memory/raw_ptr.h"
|
||||||
#include "chrome/browser/sync_file_system/sync_callbacks.h"
|
#include "chrome/browser/sync_file_system/sync_callbacks.h"
|
||||||
#include "chrome/browser/sync_file_system/sync_status_code.h"
|
#include "chrome/browser/sync_file_system/sync_status_code.h"
|
||||||
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "storage/browser/file_system/file_system_backend.h"
|
#include "storage/browser/file_system/file_system_backend.h"
|
||||||
#include "storage/browser/file_system/file_system_quota_util.h"
|
#include "storage/browser/file_system/file_system_quota_util.h"
|
||||||
#include "storage/browser/file_system/sandbox_file_system_backend_delegate.h"
|
#include "storage/browser/file_system/sandbox_file_system_backend_delegate.h"
|
||||||
@ -60,7 +61,9 @@ class SyncFileSystemBackend : public storage::FileSystemBackend {
|
|||||||
int64_t offset,
|
int64_t offset,
|
||||||
int64_t max_bytes_to_read,
|
int64_t max_bytes_to_read,
|
||||||
const base::Time& expected_modification_time,
|
const base::Time& expected_modification_time,
|
||||||
storage::FileSystemContext* context) const override;
|
storage::FileSystemContext* context,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access) const override;
|
||||||
std::unique_ptr<storage::FileStreamWriter> CreateFileStreamWriter(
|
std::unique_ptr<storage::FileStreamWriter> CreateFileStreamWriter(
|
||||||
const storage::FileSystemURL& url,
|
const storage::FileSystemURL& url,
|
||||||
int64_t offset,
|
int64_t offset,
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
#include "components/file_access/scoped_file_access_delegate.h"
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
|
#include "base/files/file_path.h"
|
||||||
|
#include "base/functional/bind.h"
|
||||||
|
#include "components/file_access/scoped_file_access.h"
|
||||||
|
|
||||||
namespace file_access {
|
namespace file_access {
|
||||||
// static
|
// static
|
||||||
@ -35,6 +38,21 @@ void ScopedFileAccessDelegate::RequestFilesAccessForSystemIO(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
ScopedFileAccessDelegate::GetCallbackForSystem() {
|
||||||
|
return base::BindRepeating(
|
||||||
|
[](const std::vector<base::FilePath>& file_paths,
|
||||||
|
base::OnceCallback<void(ScopedFileAccess)> callback) {
|
||||||
|
if (request_files_access_for_system_io_callback_) {
|
||||||
|
request_files_access_for_system_io_callback_->Run(
|
||||||
|
file_paths, std::move(callback));
|
||||||
|
} else {
|
||||||
|
std::move(callback).Run(ScopedFileAccess::Allowed());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
ScopedFileAccessDelegate::ScopedFileAccessDelegate() {
|
ScopedFileAccessDelegate::ScopedFileAccessDelegate() {
|
||||||
if (scoped_file_access_delegate_) {
|
if (scoped_file_access_delegate_) {
|
||||||
delete scoped_file_access_delegate_;
|
delete scoped_file_access_delegate_;
|
||||||
@ -53,18 +71,18 @@ ScopedFileAccessDelegate*
|
|||||||
ScopedFileAccessDelegate::scoped_file_access_delegate_ = nullptr;
|
ScopedFileAccessDelegate::scoped_file_access_delegate_ = nullptr;
|
||||||
|
|
||||||
// static
|
// static
|
||||||
ScopedFileAccessDelegate::RequestFilesAccessForSystemIOCallback*
|
ScopedFileAccessDelegate::RequestFilesAccessIOCallback*
|
||||||
ScopedFileAccessDelegate::request_files_access_for_system_io_callback_ =
|
ScopedFileAccessDelegate::request_files_access_for_system_io_callback_ =
|
||||||
nullptr;
|
nullptr;
|
||||||
|
|
||||||
ScopedFileAccessDelegate::ScopedRequestFilesAccessCallbackForTesting::
|
ScopedFileAccessDelegate::ScopedRequestFilesAccessCallbackForTesting::
|
||||||
ScopedRequestFilesAccessCallbackForTesting(
|
ScopedRequestFilesAccessCallbackForTesting(
|
||||||
RequestFilesAccessForSystemIOCallback callback,
|
RequestFilesAccessIOCallback callback,
|
||||||
bool restore_original_callback)
|
bool restore_original_callback)
|
||||||
: restore_original_callback_(restore_original_callback) {
|
: restore_original_callback_(restore_original_callback) {
|
||||||
original_callback_ = request_files_access_for_system_io_callback_;
|
original_callback_ = request_files_access_for_system_io_callback_;
|
||||||
request_files_access_for_system_io_callback_ =
|
request_files_access_for_system_io_callback_ =
|
||||||
new RequestFilesAccessForSystemIOCallback(std::move(callback));
|
new RequestFilesAccessIOCallback(std::move(callback));
|
||||||
}
|
}
|
||||||
|
|
||||||
ScopedFileAccessDelegate::ScopedRequestFilesAccessCallbackForTesting::
|
ScopedFileAccessDelegate::ScopedRequestFilesAccessCallbackForTesting::
|
||||||
|
@ -29,7 +29,7 @@ namespace file_access {
|
|||||||
// to packages without direct access to the UI thread.
|
// to packages without direct access to the UI thread.
|
||||||
class COMPONENT_EXPORT(FILE_ACCESS) ScopedFileAccessDelegate {
|
class COMPONENT_EXPORT(FILE_ACCESS) ScopedFileAccessDelegate {
|
||||||
public:
|
public:
|
||||||
using RequestFilesAccessForSystemIOCallback =
|
using RequestFilesAccessIOCallback =
|
||||||
base::RepeatingCallback<void(const std::vector<base::FilePath>&,
|
base::RepeatingCallback<void(const std::vector<base::FilePath>&,
|
||||||
base::OnceCallback<void(ScopedFileAccess)>)>;
|
base::OnceCallback<void(ScopedFileAccess)>)>;
|
||||||
|
|
||||||
@ -62,6 +62,12 @@ class COMPONENT_EXPORT(FILE_ACCESS) ScopedFileAccessDelegate {
|
|||||||
const std::vector<base::FilePath>& files,
|
const std::vector<base::FilePath>& files,
|
||||||
base::OnceCallback<void(file_access::ScopedFileAccess)> callback) = 0;
|
base::OnceCallback<void(file_access::ScopedFileAccess)> callback) = 0;
|
||||||
|
|
||||||
|
// Creates a callback to gain file access for the given `destination`. The
|
||||||
|
// callback should be called on the IO thread. The method itself from the UI
|
||||||
|
// thread.
|
||||||
|
virtual RequestFilesAccessIOCallback CreateFileAccessCallback(
|
||||||
|
const GURL& destination) const = 0;
|
||||||
|
|
||||||
// Called from the IO thread. Switches to the UI thread and calls
|
// Called from the IO thread. Switches to the UI thread and calls
|
||||||
// RequestFilesAccessForSystem there. The `callback` is run on the IO thread
|
// RequestFilesAccessForSystem there. The `callback` is run on the IO thread
|
||||||
// again.
|
// again.
|
||||||
@ -105,7 +111,7 @@ class COMPONENT_EXPORT(FILE_ACCESS) ScopedFileAccessDelegate {
|
|||||||
// Otherwise, it destroys the original callback when this class is
|
// Otherwise, it destroys the original callback when this class is
|
||||||
// destroyed.
|
// destroyed.
|
||||||
explicit ScopedRequestFilesAccessCallbackForTesting(
|
explicit ScopedRequestFilesAccessCallbackForTesting(
|
||||||
RequestFilesAccessForSystemIOCallback callback,
|
RequestFilesAccessIOCallback callback,
|
||||||
bool restore_original_callback = true);
|
bool restore_original_callback = true);
|
||||||
|
|
||||||
virtual ~ScopedRequestFilesAccessCallbackForTesting();
|
virtual ~ScopedRequestFilesAccessCallbackForTesting();
|
||||||
@ -121,8 +127,12 @@ class COMPONENT_EXPORT(FILE_ACCESS) ScopedFileAccessDelegate {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
bool restore_original_callback_;
|
bool restore_original_callback_;
|
||||||
RequestFilesAccessForSystemIOCallback* original_callback_ = nullptr;
|
RequestFilesAccessIOCallback* original_callback_ = nullptr;
|
||||||
};
|
};
|
||||||
|
// Get a callback to get file access to files for system component
|
||||||
|
// destination. Can be called from IO or UI thread. The callback should be
|
||||||
|
// called on IO thread only.
|
||||||
|
static RequestFilesAccessIOCallback GetCallbackForSystem();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ScopedFileAccessDelegate();
|
ScopedFileAccessDelegate();
|
||||||
@ -136,7 +146,7 @@ class COMPONENT_EXPORT(FILE_ACCESS) ScopedFileAccessDelegate {
|
|||||||
// A single instance for a callback living on the IO thread which switches to
|
// A single instance for a callback living on the IO thread which switches to
|
||||||
// the UI thread to call RequestFilesAccessForSystem from there and switch
|
// the UI thread to call RequestFilesAccessForSystem from there and switch
|
||||||
// back to IO thread handing the ScopedFileAccess to another (given) callback.
|
// back to IO thread handing the ScopedFileAccess to another (given) callback.
|
||||||
static RequestFilesAccessForSystemIOCallback*
|
static RequestFilesAccessIOCallback*
|
||||||
request_files_access_for_system_io_callback_;
|
request_files_access_for_system_io_callback_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
#include "base/functional/bind.h"
|
#include "base/functional/bind.h"
|
||||||
#include "base/functional/callback_forward.h"
|
#include "base/functional/callback_forward.h"
|
||||||
|
#include "base/functional/callback_helpers.h"
|
||||||
#include "base/location.h"
|
#include "base/location.h"
|
||||||
#include "base/test/mock_callback.h"
|
#include "base/test/mock_callback.h"
|
||||||
#include "base/test/task_environment.h"
|
#include "base/test/task_environment.h"
|
||||||
@ -30,6 +31,10 @@ class ScopedFileAccessDelegateTestInstance : public ScopedFileAccessDelegate {
|
|||||||
void RequestFilesAccessForSystem(
|
void RequestFilesAccessForSystem(
|
||||||
const std::vector<base::FilePath>& files,
|
const std::vector<base::FilePath>& files,
|
||||||
base::OnceCallback<void(ScopedFileAccess)> callback) override {}
|
base::OnceCallback<void(ScopedFileAccess)> callback) override {}
|
||||||
|
RequestFilesAccessIOCallback CreateFileAccessCallback(
|
||||||
|
const GURL& destination) const override {
|
||||||
|
return base::DoNothing();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
int ScopedFileAccessDelegateTestInstance::instance_counter = 0;
|
int ScopedFileAccessDelegateTestInstance::instance_counter = 0;
|
||||||
|
|
||||||
|
@ -25,6 +25,10 @@ class MockScopedFileAccessDelegate : public ScopedFileAccessDelegate {
|
|||||||
(const std::vector<base::FilePath>&,
|
(const std::vector<base::FilePath>&,
|
||||||
base::OnceCallback<void(ScopedFileAccess)>),
|
base::OnceCallback<void(ScopedFileAccess)>),
|
||||||
(override));
|
(override));
|
||||||
|
MOCK_METHOD((RequestFilesAccessIOCallback),
|
||||||
|
CreateFileAccessCallback,
|
||||||
|
(const GURL& destination),
|
||||||
|
(const override));
|
||||||
};
|
};
|
||||||
} // namespace file_access
|
} // namespace file_access
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include "base/feature_list.h"
|
#include "base/feature_list.h"
|
||||||
#include "base/functional/bind.h"
|
#include "base/functional/bind.h"
|
||||||
|
#include "base/functional/callback_helpers.h"
|
||||||
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
|
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
|
||||||
#include "content/browser/child_process_security_policy_impl.h"
|
#include "content/browser/child_process_security_policy_impl.h"
|
||||||
#include "content/public/browser/browser_task_traits.h"
|
#include "content/public/browser/browser_task_traits.h"
|
||||||
@ -31,6 +32,11 @@ class BindingDelegate : public storage::BlobRegistryImpl::Delegate {
|
|||||||
bool CanAccessDataForOrigin(const url::Origin& origin) override {
|
bool CanAccessDataForOrigin(const url::Origin& origin) override {
|
||||||
return security_policy_handle_.CanAccessDataForOrigin(origin);
|
return security_policy_handle_.CanAccessDataForOrigin(origin);
|
||||||
}
|
}
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
GetAccessCallback() override {
|
||||||
|
// TODO (b/262203074) create actual callback
|
||||||
|
return base::NullCallback();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ChildProcessSecurityPolicyImpl::Handle security_policy_handle_;
|
ChildProcessSecurityPolicyImpl::Handle security_policy_handle_;
|
||||||
|
@ -12,11 +12,13 @@
|
|||||||
#include "base/files/file_enumerator.h"
|
#include "base/files/file_enumerator.h"
|
||||||
#include "base/files/file_util.h"
|
#include "base/files/file_util.h"
|
||||||
#include "base/functional/bind.h"
|
#include "base/functional/bind.h"
|
||||||
|
#include "base/functional/callback_helpers.h"
|
||||||
#include "base/guid.h"
|
#include "base/guid.h"
|
||||||
#include "base/supports_user_data.h"
|
#include "base/supports_user_data.h"
|
||||||
#include "base/task/single_thread_task_runner.h"
|
#include "base/task/single_thread_task_runner.h"
|
||||||
#include "base/task/task_runner.h"
|
#include "base/task/task_runner.h"
|
||||||
#include "base/task/thread_pool.h"
|
#include "base/task/thread_pool.h"
|
||||||
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "content/browser/storage_partition_impl.h"
|
#include "content/browser/storage_partition_impl.h"
|
||||||
#include "content/public/browser/blob_handle.h"
|
#include "content/public/browser/blob_handle.h"
|
||||||
#include "content/public/browser/browser_context.h"
|
#include "content/public/browser/browser_context.h"
|
||||||
@ -214,14 +216,16 @@ std::unique_ptr<BlobHandle> ChromeBlobStorageContext::CreateMemoryBackedBlob(
|
|||||||
return blob_handle;
|
return blob_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChromeBlobStorageContext::CreateFileSystemBlob(
|
void ChromeBlobStorageContext::CreateFileSystemBlobWithFileAccess(
|
||||||
scoped_refptr<storage::FileSystemContext> file_system_context,
|
scoped_refptr<storage::FileSystemContext> file_system_context,
|
||||||
mojo::PendingReceiver<blink::mojom::Blob> blob_receiver,
|
mojo::PendingReceiver<blink::mojom::Blob> blob_receiver,
|
||||||
const storage::FileSystemURL& url,
|
const storage::FileSystemURL& url,
|
||||||
const std::string& blob_uuid,
|
const std::string& blob_uuid,
|
||||||
const std::string& content_type,
|
const std::string& content_type,
|
||||||
const uint64_t file_size,
|
const uint64_t file_size,
|
||||||
const base::Time& file_modification_time) {
|
const base::Time& file_modification_time,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access) {
|
||||||
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
||||||
|
|
||||||
auto blob_builder = std::make_unique<storage::BlobDataBuilder>(blob_uuid);
|
auto blob_builder = std::make_unique<storage::BlobDataBuilder>(blob_uuid);
|
||||||
@ -229,9 +233,9 @@ void ChromeBlobStorageContext::CreateFileSystemBlob(
|
|||||||
// Use AppendFileSystemFile here, since we're streaming the file directly
|
// Use AppendFileSystemFile here, since we're streaming the file directly
|
||||||
// from the file system backend, and the file thus might not actually be
|
// from the file system backend, and the file thus might not actually be
|
||||||
// backed by a file on disk.
|
// backed by a file on disk.
|
||||||
blob_builder->AppendFileSystemFile(url, 0, file_size,
|
blob_builder->AppendFileSystemFile(
|
||||||
file_modification_time,
|
url, 0, file_size, file_modification_time,
|
||||||
std::move(file_system_context));
|
std::move(file_system_context), std::move(file_access));
|
||||||
}
|
}
|
||||||
blob_builder->set_content_type(content_type);
|
blob_builder->set_content_type(content_type);
|
||||||
|
|
||||||
@ -245,6 +249,19 @@ void ChromeBlobStorageContext::CreateFileSystemBlob(
|
|||||||
storage::BlobImpl::Create(std::move(blob_handle), std::move(blob_receiver));
|
storage::BlobImpl::Create(std::move(blob_handle), std::move(blob_receiver));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChromeBlobStorageContext::CreateFileSystemBlob(
|
||||||
|
scoped_refptr<storage::FileSystemContext> file_system_context,
|
||||||
|
mojo::PendingReceiver<blink::mojom::Blob> blob_receiver,
|
||||||
|
const storage::FileSystemURL& url,
|
||||||
|
const std::string& blob_uuid,
|
||||||
|
const std::string& content_type,
|
||||||
|
const uint64_t file_size,
|
||||||
|
const base::Time& file_modification_time) {
|
||||||
|
CreateFileSystemBlobWithFileAccess(
|
||||||
|
file_system_context, std::move(blob_receiver), url, blob_uuid,
|
||||||
|
content_type, file_size, file_modification_time, base::NullCallback());
|
||||||
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
scoped_refptr<network::SharedURLLoaderFactory>
|
scoped_refptr<network::SharedURLLoaderFactory>
|
||||||
ChromeBlobStorageContext::URLLoaderFactoryForToken(
|
ChromeBlobStorageContext::URLLoaderFactoryForToken(
|
||||||
|
@ -12,10 +12,12 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
|
#include "base/functional/callback_helpers.h"
|
||||||
#include "base/memory/ref_counted.h"
|
#include "base/memory/ref_counted.h"
|
||||||
#include "base/memory/scoped_refptr.h"
|
#include "base/memory/scoped_refptr.h"
|
||||||
#include "base/task/sequenced_task_runner_helpers.h"
|
#include "base/task/sequenced_task_runner_helpers.h"
|
||||||
#include "base/time/time.h"
|
#include "base/time/time.h"
|
||||||
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "content/common/content_export.h"
|
#include "content/common/content_export.h"
|
||||||
#include "content/public/browser/browser_thread.h"
|
#include "content/public/browser/browser_thread.h"
|
||||||
#include "mojo/public/cpp/bindings/pending_remote.h"
|
#include "mojo/public/cpp/bindings/pending_remote.h"
|
||||||
@ -78,6 +80,23 @@ class CONTENT_EXPORT ChromeBlobStorageContext
|
|||||||
base::span<const uint8_t> data,
|
base::span<const uint8_t> data,
|
||||||
const std::string& content_type);
|
const std::string& content_type);
|
||||||
|
|
||||||
|
// Creates a FileSystem File blob accessible by the renderer via the blob
|
||||||
|
// remote corresponding to `blob_receiver`. The callback can grant or deny the
|
||||||
|
// read access to the file. The callback `file_access` is used to grant or
|
||||||
|
// deny access to files under dlp restrictions. Leaving it at NullCallback
|
||||||
|
// will lead to default behaviour, which currently is granting it (until
|
||||||
|
// b/265908846 is done).
|
||||||
|
void CreateFileSystemBlobWithFileAccess(
|
||||||
|
scoped_refptr<storage::FileSystemContext> file_system_context,
|
||||||
|
mojo::PendingReceiver<blink::mojom::Blob> blob_receiver,
|
||||||
|
const storage::FileSystemURL& url,
|
||||||
|
const std::string& blob_uuid,
|
||||||
|
const std::string& content_type,
|
||||||
|
const uint64_t file_size,
|
||||||
|
const base::Time& file_modification_time,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access);
|
||||||
|
|
||||||
// Creates a FileSystem File blob accessible by the renderer via the blob
|
// Creates a FileSystem File blob accessible by the renderer via the blob
|
||||||
// remote corresponding to `blob_receiver`.
|
// remote corresponding to `blob_receiver`.
|
||||||
void CreateFileSystemBlob(
|
void CreateFileSystemBlob(
|
||||||
|
@ -5,6 +5,7 @@ import("//testing/test.gni")
|
|||||||
|
|
||||||
test("storage_unittests") {
|
test("storage_unittests") {
|
||||||
deps = [
|
deps = [
|
||||||
|
"//components/file_access:test_support",
|
||||||
"//storage/browser:unittests",
|
"//storage/browser:unittests",
|
||||||
"//storage/common:unittests",
|
"//storage/common:unittests",
|
||||||
]
|
]
|
||||||
|
@ -351,6 +351,7 @@ source_set("unittests") {
|
|||||||
"//base/test:test_support",
|
"//base/test:test_support",
|
||||||
"//build:chromeos_buildflags",
|
"//build:chromeos_buildflags",
|
||||||
"//components/file_access:file_access",
|
"//components/file_access:file_access",
|
||||||
|
"//components/file_access:test_support",
|
||||||
"//components/services/filesystem/public/mojom",
|
"//components/services/filesystem/public/mojom",
|
||||||
"//components/services/storage/public/cpp",
|
"//components/services/storage/public/cpp",
|
||||||
"//mojo/public/cpp/system",
|
"//mojo/public/cpp/system",
|
||||||
@ -420,6 +421,7 @@ static_library("test_support") {
|
|||||||
":browser",
|
":browser",
|
||||||
"//base/test:test_support",
|
"//base/test:test_support",
|
||||||
"//build:chromeos_buildflags",
|
"//build:chromeos_buildflags",
|
||||||
|
"//components/file_access:file_access",
|
||||||
"//components/services/storage/public/cpp",
|
"//components/services/storage/public/cpp",
|
||||||
"//components/services/storage/public/mojom",
|
"//components/services/storage/public/mojom",
|
||||||
"//net:test_support",
|
"//net:test_support",
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "base/strings/string_number_conversions.h"
|
#include "base/strings/string_number_conversions.h"
|
||||||
#include "base/strings/string_util.h"
|
#include "base/strings/string_util.h"
|
||||||
#include "base/time/time.h"
|
#include "base/time/time.h"
|
||||||
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "storage/browser/blob/blob_entry.h"
|
#include "storage/browser/blob/blob_entry.h"
|
||||||
#include "storage/browser/blob/blob_storage_registry.h"
|
#include "storage/browser/blob/blob_storage_registry.h"
|
||||||
#include "storage/browser/blob/shareable_blob_data_item.h"
|
#include "storage/browser/blob/shareable_blob_data_item.h"
|
||||||
@ -146,13 +147,16 @@ BlobDataBuilder::FutureFile BlobDataBuilder::AppendFutureFile(
|
|||||||
return FutureFile(std::move(item));
|
return FutureFile(std::move(item));
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlobDataBuilder::AppendFile(const FilePath& file_path,
|
void BlobDataBuilder::AppendFile(
|
||||||
uint64_t offset,
|
const FilePath& file_path,
|
||||||
uint64_t length,
|
uint64_t offset,
|
||||||
const base::Time& expected_modification_time) {
|
uint64_t length,
|
||||||
auto item = BlobDataItem::CreateFile(file_path, offset, length,
|
const base::Time& expected_modification_time,
|
||||||
expected_modification_time,
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
ShareableFileReference::Get(file_path));
|
file_access) {
|
||||||
|
auto item = BlobDataItem::CreateFile(
|
||||||
|
file_path, offset, length, expected_modification_time,
|
||||||
|
ShareableFileReference::Get(file_path), std::move(file_access));
|
||||||
DCHECK(!item->IsFutureFileItem()) << file_path.value();
|
DCHECK(!item->IsFutureFileItem()) << file_path.value();
|
||||||
|
|
||||||
auto shareable_item = base::MakeRefCounted<ShareableBlobDataItem>(
|
auto shareable_item = base::MakeRefCounted<ShareableBlobDataItem>(
|
||||||
@ -277,7 +281,8 @@ void BlobDataBuilder::SliceBlob(const BlobEntry* source,
|
|||||||
case BlobDataItem::Type::kFile: {
|
case BlobDataItem::Type::kFile: {
|
||||||
data_item = BlobDataItem::CreateFile(
|
data_item = BlobDataItem::CreateFile(
|
||||||
source_item->path(), source_item->offset() + item_offset, read_size,
|
source_item->path(), source_item->offset() + item_offset, read_size,
|
||||||
source_item->expected_modification_time(), source_item->file_ref_);
|
source_item->expected_modification_time(), source_item->file_ref_,
|
||||||
|
source_item->file_access_);
|
||||||
|
|
||||||
if (source_item->IsFutureFileItem()) {
|
if (source_item->IsFutureFileItem()) {
|
||||||
// The source file isn't a real file yet (path is fake), so store the
|
// The source file isn't a real file yet (path is fake), so store the
|
||||||
@ -290,7 +295,7 @@ void BlobDataBuilder::SliceBlob(const BlobEntry* source,
|
|||||||
data_item = BlobDataItem::CreateFileFilesystem(
|
data_item = BlobDataItem::CreateFileFilesystem(
|
||||||
source_item->filesystem_url(), source_item->offset() + item_offset,
|
source_item->filesystem_url(), source_item->offset() + item_offset,
|
||||||
read_size, source_item->expected_modification_time(),
|
read_size, source_item->expected_modification_time(),
|
||||||
source_item->file_system_context());
|
source_item->file_system_context(), source_item->file_access_);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BlobDataItem::Type::kReadableDataHandle: {
|
case BlobDataItem::Type::kReadableDataHandle: {
|
||||||
@ -320,11 +325,13 @@ void BlobDataBuilder::AppendFileSystemFile(
|
|||||||
uint64_t offset,
|
uint64_t offset,
|
||||||
uint64_t length,
|
uint64_t length,
|
||||||
const base::Time& expected_modification_time,
|
const base::Time& expected_modification_time,
|
||||||
scoped_refptr<FileSystemContext> file_system_context) {
|
scoped_refptr<FileSystemContext> file_system_context,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access) {
|
||||||
DCHECK_GT(length, 0ul);
|
DCHECK_GT(length, 0ul);
|
||||||
auto item = BlobDataItem::CreateFileFilesystem(
|
auto item = BlobDataItem::CreateFileFilesystem(
|
||||||
url, offset, length, expected_modification_time,
|
url, offset, length, expected_modification_time,
|
||||||
std::move(file_system_context));
|
std::move(file_system_context), std::move(file_access));
|
||||||
|
|
||||||
auto shareable_item = base::MakeRefCounted<ShareableBlobDataItem>(
|
auto shareable_item = base::MakeRefCounted<ShareableBlobDataItem>(
|
||||||
std::move(item), ShareableBlobDataItem::POPULATED_WITHOUT_QUOTA);
|
std::move(item), ShareableBlobDataItem::POPULATED_WITHOUT_QUOTA);
|
||||||
|
@ -13,8 +13,10 @@
|
|||||||
|
|
||||||
#include "base/component_export.h"
|
#include "base/component_export.h"
|
||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
|
#include "base/functional/callback_helpers.h"
|
||||||
#include "base/memory/scoped_refptr.h"
|
#include "base/memory/scoped_refptr.h"
|
||||||
#include "base/numerics/checked_math.h"
|
#include "base/numerics/checked_math.h"
|
||||||
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "components/services/storage/public/mojom/blob_storage_context.mojom.h"
|
#include "components/services/storage/public/mojom/blob_storage_context.mojom.h"
|
||||||
#include "storage/browser/blob/blob_data_item.h"
|
#include "storage/browser/blob/blob_data_item.h"
|
||||||
#include "storage/browser/blob/blob_data_snapshot.h"
|
#include "storage/browser/blob/blob_data_snapshot.h"
|
||||||
@ -132,11 +134,17 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobDataBuilder {
|
|||||||
|
|
||||||
// You must know the length of the file, you cannot use kuint64max to specify
|
// You must know the length of the file, you cannot use kuint64max to specify
|
||||||
// the whole file. This method creates a ShareableFileReference to the given
|
// the whole file. This method creates a ShareableFileReference to the given
|
||||||
// file, which is stored in this builder.
|
// file, which is stored in this builder. The callback `file_access` is used
|
||||||
void AppendFile(const base::FilePath& file_path,
|
// to grant or deny access to files under dlp restrictions. Leaving it at
|
||||||
uint64_t offset,
|
// NullCallback will lead to default behaviour, which currently is granting it
|
||||||
uint64_t length,
|
// (until b/265908846 is done).
|
||||||
const base::Time& expected_modification_time);
|
void AppendFile(
|
||||||
|
const base::FilePath& file_path,
|
||||||
|
uint64_t offset,
|
||||||
|
uint64_t length,
|
||||||
|
const base::Time& expected_modification_time,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access = base::NullCallback());
|
||||||
|
|
||||||
void AppendBlob(const std::string& uuid,
|
void AppendBlob(const std::string& uuid,
|
||||||
uint64_t offset,
|
uint64_t offset,
|
||||||
@ -150,7 +158,9 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobDataBuilder {
|
|||||||
uint64_t offset,
|
uint64_t offset,
|
||||||
uint64_t length,
|
uint64_t length,
|
||||||
const base::Time& expected_modification_time,
|
const base::Time& expected_modification_time,
|
||||||
scoped_refptr<FileSystemContext> file_system_context);
|
scoped_refptr<FileSystemContext> file_system_context,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access = base::NullCallback());
|
||||||
|
|
||||||
void AppendReadableDataHandle(scoped_refptr<DataHandle> data_handle) {
|
void AppendReadableDataHandle(scoped_refptr<DataHandle> data_handle) {
|
||||||
auto length = data_handle->GetSize();
|
auto length = data_handle->GetSize();
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
#include "base/ranges/algorithm.h"
|
#include "base/ranges/algorithm.h"
|
||||||
#include "base/strings/string_number_conversions.h"
|
#include "base/strings/string_number_conversions.h"
|
||||||
|
#include "base/time/time.h"
|
||||||
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "mojo/public/cpp/bindings/remote.h"
|
#include "mojo/public/cpp/bindings/remote.h"
|
||||||
#include "net/base/net_errors.h"
|
#include "net/base/net_errors.h"
|
||||||
#include "services/network/public/cpp/data_pipe_to_source_stream.h"
|
#include "services/network/public/cpp/data_pipe_to_source_stream.h"
|
||||||
@ -80,8 +82,12 @@ scoped_refptr<BlobDataItem> BlobDataItem::CreateBytesDescription(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
scoped_refptr<BlobDataItem> BlobDataItem::CreateFile(base::FilePath path) {
|
scoped_refptr<BlobDataItem> BlobDataItem::CreateFile(
|
||||||
return CreateFile(path, 0, blink::BlobUtils::kUnknownSize);
|
base::FilePath path,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access) {
|
||||||
|
return CreateFile(path, 0, blink::BlobUtils::kUnknownSize, base::Time(),
|
||||||
|
nullptr, std::move(file_access));
|
||||||
}
|
}
|
||||||
|
|
||||||
// static
|
// static
|
||||||
@ -90,12 +96,15 @@ scoped_refptr<BlobDataItem> BlobDataItem::CreateFile(
|
|||||||
uint64_t offset,
|
uint64_t offset,
|
||||||
uint64_t length,
|
uint64_t length,
|
||||||
base::Time expected_modification_time,
|
base::Time expected_modification_time,
|
||||||
scoped_refptr<ShareableFileReference> file_ref) {
|
scoped_refptr<ShareableFileReference> file_ref,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access) {
|
||||||
auto item =
|
auto item =
|
||||||
base::WrapRefCounted(new BlobDataItem(Type::kFile, offset, length));
|
base::WrapRefCounted(new BlobDataItem(Type::kFile, offset, length));
|
||||||
item->path_ = std::move(path);
|
item->path_ = std::move(path);
|
||||||
item->expected_modification_time_ = std::move(expected_modification_time);
|
item->expected_modification_time_ = std::move(expected_modification_time);
|
||||||
item->file_ref_ = std::move(file_ref);
|
item->file_ref_ = std::move(file_ref);
|
||||||
|
item->file_access_ = std::move(file_access);
|
||||||
// TODO(mek): DCHECK(!item->IsFutureFileItem()) when BlobDataBuilder has some
|
// TODO(mek): DCHECK(!item->IsFutureFileItem()) when BlobDataBuilder has some
|
||||||
// other way of slicing a future file.
|
// other way of slicing a future file.
|
||||||
return item;
|
return item;
|
||||||
@ -120,12 +129,15 @@ scoped_refptr<BlobDataItem> BlobDataItem::CreateFileFilesystem(
|
|||||||
uint64_t offset,
|
uint64_t offset,
|
||||||
uint64_t length,
|
uint64_t length,
|
||||||
base::Time expected_modification_time,
|
base::Time expected_modification_time,
|
||||||
scoped_refptr<FileSystemContext> file_system_context) {
|
scoped_refptr<FileSystemContext> file_system_context,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access) {
|
||||||
auto item = base::WrapRefCounted(
|
auto item = base::WrapRefCounted(
|
||||||
new BlobDataItem(Type::kFileFilesystem, offset, length));
|
new BlobDataItem(Type::kFileFilesystem, offset, length));
|
||||||
item->filesystem_url_ = url;
|
item->filesystem_url_ = url;
|
||||||
item->expected_modification_time_ = std::move(expected_modification_time);
|
item->expected_modification_time_ = std::move(expected_modification_time);
|
||||||
item->file_system_context_ = std::move(file_system_context);
|
item->file_system_context_ = std::move(file_system_context);
|
||||||
|
item->file_access_ = std::move(file_access);
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,8 +14,11 @@
|
|||||||
#include "base/component_export.h"
|
#include "base/component_export.h"
|
||||||
#include "base/containers/span.h"
|
#include "base/containers/span.h"
|
||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
|
#include "base/functional/callback_helpers.h"
|
||||||
#include "base/memory/ref_counted.h"
|
#include "base/memory/ref_counted.h"
|
||||||
#include "base/time/time.h"
|
#include "base/time/time.h"
|
||||||
|
#include "components/file_access/scoped_file_access.h"
|
||||||
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "components/services/storage/public/mojom/blob_storage_context.mojom.h"
|
#include "components/services/storage/public/mojom/blob_storage_context.mojom.h"
|
||||||
#include "net/base/io_buffer.h"
|
#include "net/base/io_buffer.h"
|
||||||
#include "storage/browser/blob/shareable_file_reference.h"
|
#include "storage/browser/blob/shareable_file_reference.h"
|
||||||
@ -83,13 +86,18 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobDataItem
|
|||||||
static scoped_refptr<BlobDataItem> CreateBytes(
|
static scoped_refptr<BlobDataItem> CreateBytes(
|
||||||
base::span<const uint8_t> bytes);
|
base::span<const uint8_t> bytes);
|
||||||
static scoped_refptr<BlobDataItem> CreateBytesDescription(size_t length);
|
static scoped_refptr<BlobDataItem> CreateBytesDescription(size_t length);
|
||||||
static scoped_refptr<BlobDataItem> CreateFile(base::FilePath path);
|
static scoped_refptr<BlobDataItem> CreateFile(
|
||||||
|
base::FilePath path,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access = base::NullCallback());
|
||||||
static scoped_refptr<BlobDataItem> CreateFile(
|
static scoped_refptr<BlobDataItem> CreateFile(
|
||||||
base::FilePath path,
|
base::FilePath path,
|
||||||
uint64_t offset,
|
uint64_t offset,
|
||||||
uint64_t length,
|
uint64_t length,
|
||||||
base::Time expected_modification_time = base::Time(),
|
base::Time expected_modification_time = base::Time(),
|
||||||
scoped_refptr<ShareableFileReference> file_ref = nullptr);
|
scoped_refptr<ShareableFileReference> file_ref = nullptr,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access = base::NullCallback());
|
||||||
static scoped_refptr<BlobDataItem> CreateFutureFile(uint64_t offset,
|
static scoped_refptr<BlobDataItem> CreateFutureFile(uint64_t offset,
|
||||||
uint64_t length,
|
uint64_t length,
|
||||||
uint64_t file_id);
|
uint64_t file_id);
|
||||||
@ -98,7 +106,9 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobDataItem
|
|||||||
uint64_t offset,
|
uint64_t offset,
|
||||||
uint64_t length,
|
uint64_t length,
|
||||||
base::Time expected_modification_time,
|
base::Time expected_modification_time,
|
||||||
scoped_refptr<FileSystemContext> file_system_context);
|
scoped_refptr<FileSystemContext> file_system_context,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access = base::NullCallback());
|
||||||
static scoped_refptr<BlobDataItem> CreateReadableDataHandle(
|
static scoped_refptr<BlobDataItem> CreateReadableDataHandle(
|
||||||
scoped_refptr<DataHandle> data_handle,
|
scoped_refptr<DataHandle> data_handle,
|
||||||
uint64_t offset,
|
uint64_t offset,
|
||||||
@ -146,6 +156,12 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobDataItem
|
|||||||
// Returns |file_id| given to CreateFutureFile.
|
// Returns |file_id| given to CreateFutureFile.
|
||||||
uint64_t GetFutureFileID() const;
|
uint64_t GetFutureFileID() const;
|
||||||
|
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access() const {
|
||||||
|
DCHECK(type_ == Type::kFile || type_ == Type::kFileFilesystem);
|
||||||
|
return file_access_;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class BlobBuilderFromStream;
|
friend class BlobBuilderFromStream;
|
||||||
friend class BlobDataBuilder;
|
friend class BlobDataBuilder;
|
||||||
@ -195,6 +211,9 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobDataItem
|
|||||||
|
|
||||||
scoped_refptr<FileSystemContext>
|
scoped_refptr<FileSystemContext>
|
||||||
file_system_context_; // For Type::kFileFilesystem.
|
file_system_context_; // For Type::kFileFilesystem.
|
||||||
|
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access_; // For Type::kFile and kFileFilesystem.
|
||||||
};
|
};
|
||||||
|
|
||||||
COMPONENT_EXPORT(STORAGE_BROWSER)
|
COMPONENT_EXPORT(STORAGE_BROWSER)
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "base/memory/ptr_util.h"
|
#include "base/memory/ptr_util.h"
|
||||||
#include "base/task/thread_pool.h"
|
#include "base/task/thread_pool.h"
|
||||||
#include "base/trace_event/trace_event.h"
|
#include "base/trace_event/trace_event.h"
|
||||||
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "net/base/io_buffer.h"
|
#include "net/base/io_buffer.h"
|
||||||
#include "net/base/net_errors.h"
|
#include "net/base/net_errors.h"
|
||||||
#include "storage/browser/blob/blob_data_handle.h"
|
#include "storage/browser/blob/blob_data_handle.h"
|
||||||
@ -515,8 +516,7 @@ BlobReader::Status BlobReader::ReadItem() {
|
|||||||
GetOrCreateFileReaderAtIndex(current_item_index_);
|
GetOrCreateFileReaderAtIndex(current_item_index_);
|
||||||
if (!reader)
|
if (!reader)
|
||||||
return ReportError(net::ERR_FILE_NOT_FOUND);
|
return ReportError(net::ERR_FILE_NOT_FOUND);
|
||||||
|
return ReadFileItem(reader, bytes_to_read, item.file_access());
|
||||||
return ReadFileItem(reader, bytes_to_read);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlobReader::AdvanceItem() {
|
void BlobReader::AdvanceItem() {
|
||||||
@ -560,8 +560,11 @@ void BlobReader::ReadBytesItem(const BlobDataItem& item, int bytes_to_read) {
|
|||||||
AdvanceBytesRead(bytes_to_read);
|
AdvanceBytesRead(bytes_to_read);
|
||||||
}
|
}
|
||||||
|
|
||||||
BlobReader::Status BlobReader::ReadFileItem(FileStreamReader* reader,
|
BlobReader::Status BlobReader::ReadFileItem(
|
||||||
int bytes_to_read) {
|
FileStreamReader* reader,
|
||||||
|
int bytes_to_read,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access) {
|
||||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||||
DCHECK(!io_pending_)
|
DCHECK(!io_pending_)
|
||||||
<< "Can't begin IO while another IO operation is pending.";
|
<< "Can't begin IO while another IO operation is pending.";
|
||||||
@ -725,7 +728,8 @@ std::unique_ptr<FileStreamReader> BlobReader::CreateFileStreamReader(
|
|||||||
}
|
}
|
||||||
return FileStreamReader::CreateForLocalFile(
|
return FileStreamReader::CreateForLocalFile(
|
||||||
file_task_runner_.get(), item.path(),
|
file_task_runner_.get(), item.path(),
|
||||||
item.offset() + additional_offset, item.expected_modification_time());
|
item.offset() + additional_offset, item.expected_modification_time(),
|
||||||
|
item.file_access());
|
||||||
case BlobDataItem::Type::kFileFilesystem: {
|
case BlobDataItem::Type::kFileFilesystem: {
|
||||||
int64_t max_bytes_to_read =
|
int64_t max_bytes_to_read =
|
||||||
item.length() == std::numeric_limits<uint64_t>::max()
|
item.length() == std::numeric_limits<uint64_t>::max()
|
||||||
@ -738,7 +742,8 @@ std::unique_ptr<FileStreamReader> BlobReader::CreateFileStreamReader(
|
|||||||
}
|
}
|
||||||
return item.file_system_context()->CreateFileStreamReader(
|
return item.file_system_context()->CreateFileStreamReader(
|
||||||
item.filesystem_url(), item.offset() + additional_offset,
|
item.filesystem_url(), item.offset() + additional_offset,
|
||||||
max_bytes_to_read, item.expected_modification_time());
|
max_bytes_to_read, item.expected_modification_time(),
|
||||||
|
item.file_access());
|
||||||
}
|
}
|
||||||
case BlobDataItem::Type::kBytes:
|
case BlobDataItem::Type::kBytes:
|
||||||
case BlobDataItem::Type::kBytesDescription:
|
case BlobDataItem::Type::kBytesDescription:
|
||||||
|
@ -13,9 +13,13 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "base/component_export.h"
|
#include "base/component_export.h"
|
||||||
|
#include "base/functional/callback_forward.h"
|
||||||
|
#include "base/functional/callback_helpers.h"
|
||||||
#include "base/gtest_prod_util.h"
|
#include "base/gtest_prod_util.h"
|
||||||
#include "base/memory/weak_ptr.h"
|
#include "base/memory/weak_ptr.h"
|
||||||
#include "base/sequence_checker.h"
|
#include "base/sequence_checker.h"
|
||||||
|
#include "components/file_access/scoped_file_access.h"
|
||||||
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "mojo/public/cpp/base/big_buffer.h"
|
#include "mojo/public/cpp/base/big_buffer.h"
|
||||||
#include "mojo/public/cpp/system/data_pipe.h"
|
#include "mojo/public/cpp/system/data_pipe.h"
|
||||||
#include "net/base/completion_once_callback.h"
|
#include "net/base/completion_once_callback.h"
|
||||||
@ -168,7 +172,7 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobReader {
|
|||||||
FRIEND_TEST_ALL_PREFIXES(BlobReaderTest, HandleBeforeAsyncCancel);
|
FRIEND_TEST_ALL_PREFIXES(BlobReaderTest, HandleBeforeAsyncCancel);
|
||||||
FRIEND_TEST_ALL_PREFIXES(BlobReaderTest, ReadFromIncompleteBlob);
|
FRIEND_TEST_ALL_PREFIXES(BlobReaderTest, ReadFromIncompleteBlob);
|
||||||
|
|
||||||
BlobReader(const BlobDataHandle* blob_handle);
|
explicit BlobReader(const BlobDataHandle* blob_handle);
|
||||||
|
|
||||||
bool total_size_calculated() const {
|
bool total_size_calculated() const {
|
||||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||||
@ -208,7 +212,11 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobReader {
|
|||||||
void AdvanceItem();
|
void AdvanceItem();
|
||||||
void AdvanceBytesRead(int result);
|
void AdvanceBytesRead(int result);
|
||||||
void ReadBytesItem(const BlobDataItem& item, int bytes_to_read);
|
void ReadBytesItem(const BlobDataItem& item, int bytes_to_read);
|
||||||
BlobReader::Status ReadFileItem(FileStreamReader* reader, int bytes_to_read);
|
BlobReader::Status ReadFileItem(
|
||||||
|
FileStreamReader* reader,
|
||||||
|
int bytes_to_read,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access);
|
||||||
void DidReadFile(int result);
|
void DidReadFile(int result);
|
||||||
void DeleteItemReaders();
|
void DeleteItemReaders();
|
||||||
Status ReadReadableDataHandle(const BlobDataItem& item, int bytes_to_read);
|
Status ReadReadableDataHandle(const BlobDataItem& item, int bytes_to_read);
|
||||||
|
@ -8,9 +8,12 @@
|
|||||||
|
|
||||||
#include "base/barrier_closure.h"
|
#include "base/barrier_closure.h"
|
||||||
#include "base/functional/bind.h"
|
#include "base/functional/bind.h"
|
||||||
|
#include "base/functional/callback.h"
|
||||||
#include "base/functional/callback_helpers.h"
|
#include "base/functional/callback_helpers.h"
|
||||||
#include "base/memory/raw_ptr.h"
|
#include "base/memory/raw_ptr.h"
|
||||||
#include "base/task/sequenced_task_runner.h"
|
#include "base/task/sequenced_task_runner.h"
|
||||||
|
#include "components/file_access/scoped_file_access.h"
|
||||||
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "net/base/features.h"
|
#include "net/base/features.h"
|
||||||
#include "storage/browser/blob/blob_builder_from_stream.h"
|
#include "storage/browser/blob/blob_builder_from_stream.h"
|
||||||
#include "storage/browser/blob/blob_data_builder.h"
|
#include "storage/browser/blob/blob_data_builder.h"
|
||||||
@ -57,17 +60,21 @@ class BlobRegistryImpl::BlobUnderConstruction {
|
|||||||
mojo::Remote<blink::mojom::Blob> blob;
|
mojo::Remote<blink::mojom::Blob> blob;
|
||||||
};
|
};
|
||||||
|
|
||||||
BlobUnderConstruction(BlobRegistryImpl* blob_registry,
|
BlobUnderConstruction(
|
||||||
const std::string& uuid,
|
BlobRegistryImpl* blob_registry,
|
||||||
const std::string& content_type,
|
const std::string& uuid,
|
||||||
const std::string& content_disposition,
|
const std::string& content_type,
|
||||||
std::vector<ElementEntry> elements,
|
const std::string& content_disposition,
|
||||||
mojo::ReportBadMessageCallback bad_message_callback)
|
std::vector<ElementEntry> elements,
|
||||||
|
mojo::ReportBadMessageCallback bad_message_callback,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access)
|
||||||
: blob_registry_(blob_registry),
|
: blob_registry_(blob_registry),
|
||||||
uuid_(uuid),
|
uuid_(uuid),
|
||||||
builder_(std::make_unique<BlobDataBuilder>(uuid)),
|
builder_(std::make_unique<BlobDataBuilder>(uuid)),
|
||||||
elements_(std::move(elements)),
|
elements_(std::move(elements)),
|
||||||
bad_message_callback_(std::move(bad_message_callback)) {
|
bad_message_callback_(std::move(bad_message_callback)),
|
||||||
|
file_access_(std::move(file_access)) {
|
||||||
builder_->set_content_type(content_type);
|
builder_->set_content_type(content_type);
|
||||||
builder_->set_content_disposition(content_disposition);
|
builder_->set_content_disposition(content_disposition);
|
||||||
}
|
}
|
||||||
@ -213,6 +220,10 @@ class BlobRegistryImpl::BlobUnderConstruction {
|
|||||||
// Number of dependent blobs that have started constructing.
|
// Number of dependent blobs that have started constructing.
|
||||||
size_t ready_dependent_blob_count_ = 0;
|
size_t ready_dependent_blob_count_ = 0;
|
||||||
|
|
||||||
|
// Callback to gain dlp file access.
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access_;
|
||||||
|
|
||||||
base::WeakPtrFactory<BlobUnderConstruction> weak_ptr_factory_{this};
|
base::WeakPtrFactory<BlobUnderConstruction> weak_ptr_factory_{this};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -383,9 +394,9 @@ void BlobRegistryImpl::BlobUnderConstruction::ResolvedAllBlobDependencies() {
|
|||||||
}
|
}
|
||||||
} else if (element->is_file()) {
|
} else if (element->is_file()) {
|
||||||
const auto& f = element->get_file();
|
const auto& f = element->get_file();
|
||||||
builder_->AppendFile(
|
builder_->AppendFile(f->path, f->offset, f->length,
|
||||||
f->path, f->offset, f->length,
|
f->expected_modification_time.value_or(base::Time()),
|
||||||
f->expected_modification_time.value_or(base::Time()));
|
file_access_);
|
||||||
} else if (element->is_blob()) {
|
} else if (element->is_blob()) {
|
||||||
DCHECK(blob_uuid_it != referenced_blob_uuids_.end());
|
DCHECK(blob_uuid_it != referenced_blob_uuids_.end());
|
||||||
const std::string& blob_uuid = *blob_uuid_it++;
|
const std::string& blob_uuid = *blob_uuid_it++;
|
||||||
@ -565,7 +576,7 @@ void BlobRegistryImpl::Register(
|
|||||||
|
|
||||||
blobs_under_construction_[uuid] = std::make_unique<BlobUnderConstruction>(
|
blobs_under_construction_[uuid] = std::make_unique<BlobUnderConstruction>(
|
||||||
this, uuid, content_type, content_disposition, std::move(element_entries),
|
this, uuid, content_type, content_disposition, std::move(element_entries),
|
||||||
receivers_.GetBadMessageCallback());
|
receivers_.GetBadMessageCallback(), delegate->GetAccessCallback());
|
||||||
|
|
||||||
std::unique_ptr<BlobDataHandle> handle = context_->AddFutureBlob(
|
std::unique_ptr<BlobDataHandle> handle = context_->AddFutureBlob(
|
||||||
uuid, content_type, content_disposition,
|
uuid, content_type, content_disposition,
|
||||||
|
@ -9,6 +9,9 @@
|
|||||||
#include "base/component_export.h"
|
#include "base/component_export.h"
|
||||||
#include "base/containers/flat_set.h"
|
#include "base/containers/flat_set.h"
|
||||||
#include "base/containers/unique_ptr_adapters.h"
|
#include "base/containers/unique_ptr_adapters.h"
|
||||||
|
#include "base/functional/callback_forward.h"
|
||||||
|
#include "components/file_access/scoped_file_access.h"
|
||||||
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "mojo/public/cpp/bindings/receiver_set.h"
|
#include "mojo/public/cpp/bindings/receiver_set.h"
|
||||||
#include "mojo/public/cpp/bindings/self_owned_associated_receiver.h"
|
#include "mojo/public/cpp/bindings/self_owned_associated_receiver.h"
|
||||||
#include "storage/browser/blob/blob_url_registry.h"
|
#include "storage/browser/blob/blob_url_registry.h"
|
||||||
@ -35,6 +38,8 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) BlobRegistryImpl
|
|||||||
virtual ~Delegate() {}
|
virtual ~Delegate() {}
|
||||||
virtual bool CanReadFile(const base::FilePath& file) = 0;
|
virtual bool CanReadFile(const base::FilePath& file) = 0;
|
||||||
virtual bool CanAccessDataForOrigin(const url::Origin& origin) = 0;
|
virtual bool CanAccessDataForOrigin(const url::Origin& origin) = 0;
|
||||||
|
virtual file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
GetAccessCallback() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
BlobRegistryImpl(base::WeakPtr<BlobStorageContext> context,
|
BlobRegistryImpl(base::WeakPtr<BlobStorageContext> context,
|
||||||
|
@ -530,8 +530,8 @@ void BlobStorageContext::FinishBuilding(BlobEntry* entry) {
|
|||||||
scoped_refptr<BlobDataItem> new_item = BlobDataItem::CreateFile(
|
scoped_refptr<BlobDataItem> new_item = BlobDataItem::CreateFile(
|
||||||
source_item->path(),
|
source_item->path(),
|
||||||
source_item->offset() + copy.source_item_offset, dest_size,
|
source_item->offset() + copy.source_item_offset, dest_size,
|
||||||
source_item->expected_modification_time(),
|
source_item->expected_modification_time(), source_item->file_ref_,
|
||||||
source_item->file_ref_);
|
source_item->file_access_);
|
||||||
copy.dest_item->set_item(std::move(new_item));
|
copy.dest_item->set_item(std::move(new_item));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,11 @@
|
|||||||
#include "base/compiler_specific.h"
|
#include "base/compiler_specific.h"
|
||||||
#include "base/component_export.h"
|
#include "base/component_export.h"
|
||||||
#include "base/files/file.h"
|
#include "base/files/file.h"
|
||||||
|
#include "base/functional/callback_forward.h"
|
||||||
|
#include "base/functional/callback_helpers.h"
|
||||||
#include "base/memory/weak_ptr.h"
|
#include "base/memory/weak_ptr.h"
|
||||||
|
#include "components/file_access/scoped_file_access.h"
|
||||||
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "components/services/storage/public/cpp/filesystem/filesystem_proxy.h"
|
#include "components/services/storage/public/cpp/filesystem/filesystem_proxy.h"
|
||||||
#include "net/base/completion_once_callback.h"
|
#include "net/base/completion_once_callback.h"
|
||||||
|
|
||||||
@ -45,7 +49,9 @@ class FileStreamReader {
|
|||||||
scoped_refptr<base::TaskRunner> task_runner,
|
scoped_refptr<base::TaskRunner> task_runner,
|
||||||
const base::FilePath& file_path,
|
const base::FilePath& file_path,
|
||||||
int64_t initial_offset,
|
int64_t initial_offset,
|
||||||
const base::Time& expected_modification_time);
|
const base::Time& expected_modification_time,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access = base::NullCallback());
|
||||||
|
|
||||||
// Creates a new FileReader for a local file |file_path|, which is a
|
// Creates a new FileReader for a local file |file_path|, which is a
|
||||||
// relative path into |filesystem_proxy|. This function's behavior
|
// relative path into |filesystem_proxy|. This function's behavior
|
||||||
|
@ -16,7 +16,9 @@
|
|||||||
#include "base/files/file.h"
|
#include "base/files/file.h"
|
||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
#include "base/functional/callback_forward.h"
|
#include "base/functional/callback_forward.h"
|
||||||
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "storage/browser/file_system/file_permission_policy.h"
|
#include "storage/browser/file_system/file_permission_policy.h"
|
||||||
|
#include "storage/browser/file_system/file_stream_reader.h"
|
||||||
#include "storage/browser/file_system/open_file_system_mode.h"
|
#include "storage/browser/file_system/open_file_system_mode.h"
|
||||||
#include "storage/browser/file_system/task_runner_bound_observer_list.h"
|
#include "storage/browser/file_system/task_runner_bound_observer_list.h"
|
||||||
#include "storage/common/file_system/file_system_types.h"
|
#include "storage/common/file_system/file_system_types.h"
|
||||||
@ -121,13 +123,17 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemBackend {
|
|||||||
// ERR_UPLOAD_FILE_CHANGED error.
|
// ERR_UPLOAD_FILE_CHANGED error.
|
||||||
// This method itself does *not* check if the given path exists and is a
|
// This method itself does *not* check if the given path exists and is a
|
||||||
// regular file. At most |max_bytes_to_read| can be fetched from the file
|
// regular file. At most |max_bytes_to_read| can be fetched from the file
|
||||||
// stream reader.
|
// stream reader. The callback `file_access` grants access to dlp restricted
|
||||||
|
// files. If it is a NullCallback currently the access will be granted. This
|
||||||
|
// will change to being denied after b/265908846
|
||||||
virtual std::unique_ptr<FileStreamReader> CreateFileStreamReader(
|
virtual std::unique_ptr<FileStreamReader> CreateFileStreamReader(
|
||||||
const FileSystemURL& url,
|
const FileSystemURL& url,
|
||||||
int64_t offset,
|
int64_t offset,
|
||||||
int64_t max_bytes_to_read,
|
int64_t max_bytes_to_read,
|
||||||
const base::Time& expected_modification_time,
|
const base::Time& expected_modification_time,
|
||||||
FileSystemContext* context) const = 0;
|
FileSystemContext* context,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access) const = 0;
|
||||||
|
|
||||||
// Creates a new file stream writer for a given filesystem URL |url| with an
|
// Creates a new file stream writer for a given filesystem URL |url| with an
|
||||||
// offset |offset|.
|
// offset |offset|.
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "base/task/sequenced_task_runner.h"
|
#include "base/task/sequenced_task_runner.h"
|
||||||
#include "base/task/single_thread_task_runner.h"
|
#include "base/task/single_thread_task_runner.h"
|
||||||
#include "base/types/pass_key.h"
|
#include "base/types/pass_key.h"
|
||||||
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "components/services/storage/public/cpp/buckets/bucket_info.h"
|
#include "components/services/storage/public/cpp/buckets/bucket_info.h"
|
||||||
#include "components/services/storage/public/cpp/buckets/constants.h"
|
#include "components/services/storage/public/cpp/buckets/constants.h"
|
||||||
#include "components/services/storage/public/cpp/quota_client_callback_wrapper.h"
|
#include "components/services/storage/public/cpp/quota_client_callback_wrapper.h"
|
||||||
@ -595,14 +596,17 @@ std::unique_ptr<FileStreamReader> FileSystemContext::CreateFileStreamReader(
|
|||||||
const FileSystemURL& url,
|
const FileSystemURL& url,
|
||||||
int64_t offset,
|
int64_t offset,
|
||||||
int64_t max_bytes_to_read,
|
int64_t max_bytes_to_read,
|
||||||
const base::Time& expected_modification_time) {
|
const base::Time& expected_modification_time,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access) {
|
||||||
if (!url.is_valid())
|
if (!url.is_valid())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
FileSystemBackend* backend = GetFileSystemBackend(url.type());
|
FileSystemBackend* backend = GetFileSystemBackend(url.type());
|
||||||
if (!backend)
|
if (!backend)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return backend->CreateFileStreamReader(url, offset, max_bytes_to_read,
|
return backend->CreateFileStreamReader(url, offset, max_bytes_to_read,
|
||||||
expected_modification_time, this);
|
expected_modification_time, this,
|
||||||
|
std::move(file_access));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<FileStreamWriter> FileSystemContext::CreateFileStreamWriter(
|
std::unique_ptr<FileStreamWriter> FileSystemContext::CreateFileStreamWriter(
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "base/component_export.h"
|
#include "base/component_export.h"
|
||||||
#include "base/files/file.h"
|
#include "base/files/file.h"
|
||||||
#include "base/functional/callback.h"
|
#include "base/functional/callback.h"
|
||||||
|
#include "base/functional/callback_helpers.h"
|
||||||
#include "base/memory/ref_counted_delete_on_sequence.h"
|
#include "base/memory/ref_counted_delete_on_sequence.h"
|
||||||
#include "base/memory/scoped_refptr.h"
|
#include "base/memory/scoped_refptr.h"
|
||||||
#include "base/memory/weak_ptr.h"
|
#include "base/memory/weak_ptr.h"
|
||||||
@ -22,6 +23,7 @@
|
|||||||
#include "base/threading/sequence_bound.h"
|
#include "base/threading/sequence_bound.h"
|
||||||
#include "base/types/pass_key.h"
|
#include "base/types/pass_key.h"
|
||||||
#include "build/build_config.h"
|
#include "build/build_config.h"
|
||||||
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "components/services/storage/public/cpp/quota_error_or.h"
|
#include "components/services/storage/public/cpp/quota_error_or.h"
|
||||||
#include "components/services/storage/public/mojom/quota_client.mojom.h"
|
#include "components/services/storage/public/mojom/quota_client.mojom.h"
|
||||||
#include "mojo/public/cpp/bindings/receiver.h"
|
#include "mojo/public/cpp/bindings/receiver.h"
|
||||||
@ -281,7 +283,9 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) FileSystemContext
|
|||||||
const FileSystemURL& url,
|
const FileSystemURL& url,
|
||||||
int64_t offset,
|
int64_t offset,
|
||||||
int64_t max_bytes_to_read,
|
int64_t max_bytes_to_read,
|
||||||
const base::Time& expected_modification_time);
|
const base::Time& expected_modification_time,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access = base::NullCallback());
|
||||||
|
|
||||||
// Creates new FileStreamWriter instance to write into a file pointed by
|
// Creates new FileStreamWriter instance to write into a file pointed by
|
||||||
// `url` from `offset`.
|
// `url` from `offset`.
|
||||||
|
@ -129,10 +129,12 @@ IsolatedFileSystemBackend::CreateFileStreamReader(
|
|||||||
int64_t offset,
|
int64_t offset,
|
||||||
int64_t max_bytes_to_read,
|
int64_t max_bytes_to_read,
|
||||||
const base::Time& expected_modification_time,
|
const base::Time& expected_modification_time,
|
||||||
FileSystemContext* context) const {
|
FileSystemContext* context,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access) const {
|
||||||
return FileStreamReader::CreateForLocalFile(
|
return FileStreamReader::CreateForLocalFile(
|
||||||
context->default_file_task_runner(), url.path(), offset,
|
context->default_file_task_runner(), url.path(), offset,
|
||||||
expected_modification_time);
|
expected_modification_time, std::move(file_access));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<FileStreamWriter>
|
std::unique_ptr<FileStreamWriter>
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "storage/browser/file_system/file_system_backend.h"
|
#include "storage/browser/file_system/file_system_backend.h"
|
||||||
#include "storage/browser/file_system/task_runner_bound_observer_list.h"
|
#include "storage/browser/file_system/task_runner_bound_observer_list.h"
|
||||||
|
|
||||||
@ -44,7 +45,9 @@ class IsolatedFileSystemBackend : public FileSystemBackend {
|
|||||||
int64_t offset,
|
int64_t offset,
|
||||||
int64_t max_bytes_to_read,
|
int64_t max_bytes_to_read,
|
||||||
const base::Time& expected_modification_time,
|
const base::Time& expected_modification_time,
|
||||||
FileSystemContext* context) const override;
|
FileSystemContext* context,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access) const override;
|
||||||
std::unique_ptr<FileStreamWriter> CreateFileStreamWriter(
|
std::unique_ptr<FileStreamWriter> CreateFileStreamWriter(
|
||||||
const FileSystemURL& url,
|
const FileSystemURL& url,
|
||||||
int64_t offset,
|
int64_t offset,
|
||||||
|
@ -12,11 +12,14 @@
|
|||||||
#include "base/check_op.h"
|
#include "base/check_op.h"
|
||||||
#include "base/files/file_util.h"
|
#include "base/files/file_util.h"
|
||||||
#include "base/functional/bind.h"
|
#include "base/functional/bind.h"
|
||||||
|
#include "base/functional/callback.h"
|
||||||
|
#include "base/functional/callback_helpers.h"
|
||||||
#include "base/location.h"
|
#include "base/location.h"
|
||||||
#include "base/task/bind_post_task.h"
|
#include "base/task/bind_post_task.h"
|
||||||
#include "base/task/sequenced_task_runner.h"
|
#include "base/task/sequenced_task_runner.h"
|
||||||
#include "base/task/task_runner.h"
|
#include "base/task/task_runner.h"
|
||||||
#include "base/types/pass_key.h"
|
#include "base/types/pass_key.h"
|
||||||
|
#include "components/file_access/scoped_file_access.h"
|
||||||
#include "components/file_access/scoped_file_access_delegate.h"
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "net/base/file_stream.h"
|
#include "net/base/file_stream.h"
|
||||||
#include "net/base/io_buffer.h"
|
#include "net/base/io_buffer.h"
|
||||||
@ -46,10 +49,13 @@ std::unique_ptr<FileStreamReader> FileStreamReader::CreateForLocalFile(
|
|||||||
scoped_refptr<base::TaskRunner> task_runner,
|
scoped_refptr<base::TaskRunner> task_runner,
|
||||||
const base::FilePath& file_path,
|
const base::FilePath& file_path,
|
||||||
int64_t initial_offset,
|
int64_t initial_offset,
|
||||||
const base::Time& expected_modification_time) {
|
const base::Time& expected_modification_time,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access) {
|
||||||
return std::make_unique<LocalFileStreamReader>(
|
return std::make_unique<LocalFileStreamReader>(
|
||||||
std::move(task_runner), file_path, initial_offset,
|
std::move(task_runner), file_path, initial_offset,
|
||||||
expected_modification_time, base::PassKey<FileStreamReader>());
|
expected_modification_time, base::PassKey<FileStreamReader>(),
|
||||||
|
std::move(file_access));
|
||||||
}
|
}
|
||||||
|
|
||||||
LocalFileStreamReader::~LocalFileStreamReader() = default;
|
LocalFileStreamReader::~LocalFileStreamReader() = default;
|
||||||
@ -84,11 +90,14 @@ LocalFileStreamReader::LocalFileStreamReader(
|
|||||||
const base::FilePath& file_path,
|
const base::FilePath& file_path,
|
||||||
int64_t initial_offset,
|
int64_t initial_offset,
|
||||||
const base::Time& expected_modification_time,
|
const base::Time& expected_modification_time,
|
||||||
base::PassKey<FileStreamReader> /*pass_key*/)
|
base::PassKey<FileStreamReader> /*pass_key*/,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access)
|
||||||
: task_runner_(std::move(task_runner)),
|
: task_runner_(std::move(task_runner)),
|
||||||
file_path_(file_path),
|
file_path_(file_path),
|
||||||
initial_offset_(initial_offset),
|
initial_offset_(initial_offset),
|
||||||
expected_modification_time_(expected_modification_time) {}
|
expected_modification_time_(expected_modification_time),
|
||||||
|
file_access_(std::move(file_access)) {}
|
||||||
|
|
||||||
void LocalFileStreamReader::Open(net::CompletionOnceCallback callback) {
|
void LocalFileStreamReader::Open(net::CompletionOnceCallback callback) {
|
||||||
DCHECK(!has_pending_open_);
|
DCHECK(!has_pending_open_);
|
||||||
@ -98,8 +107,12 @@ void LocalFileStreamReader::Open(net::CompletionOnceCallback callback) {
|
|||||||
base::OnceCallback<void(file_access::ScopedFileAccess)> open_cb =
|
base::OnceCallback<void(file_access::ScopedFileAccess)> open_cb =
|
||||||
base::BindOnce(&LocalFileStreamReader::OnScopedFileAccessRequested,
|
base::BindOnce(&LocalFileStreamReader::OnScopedFileAccessRequested,
|
||||||
weak_factory_.GetWeakPtr(), std::move(callback));
|
weak_factory_.GetWeakPtr(), std::move(callback));
|
||||||
|
if (file_access_) {
|
||||||
|
file_access_.Run({file_path_}, std::move(open_cb));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(b/262199707 b/265908846): Replace with getting access through a
|
// TODO(b/265908846): Replace with getting access through a
|
||||||
// callback.
|
// callback.
|
||||||
file_access::ScopedFileAccessDelegate::RequestFilesAccessForSystemIO(
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessForSystemIO(
|
||||||
{file_path_}, std::move(open_cb));
|
{file_path_}, std::move(open_cb));
|
||||||
|
@ -12,10 +12,13 @@
|
|||||||
#include "base/component_export.h"
|
#include "base/component_export.h"
|
||||||
#include "base/files/file.h"
|
#include "base/files/file.h"
|
||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
|
#include "base/functional/callback_forward.h"
|
||||||
|
#include "base/functional/callback_helpers.h"
|
||||||
#include "base/memory/weak_ptr.h"
|
#include "base/memory/weak_ptr.h"
|
||||||
#include "base/time/time.h"
|
#include "base/time/time.h"
|
||||||
#include "base/types/pass_key.h"
|
#include "base/types/pass_key.h"
|
||||||
#include "components/file_access/scoped_file_access.h"
|
#include "components/file_access/scoped_file_access.h"
|
||||||
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "net/base/completion_once_callback.h"
|
#include "net/base/completion_once_callback.h"
|
||||||
#include "storage/browser/file_system/file_stream_reader.h"
|
#include "storage/browser/file_system/file_stream_reader.h"
|
||||||
|
|
||||||
@ -34,11 +37,14 @@ namespace storage {
|
|||||||
class COMPONENT_EXPORT(STORAGE_BROWSER) LocalFileStreamReader
|
class COMPONENT_EXPORT(STORAGE_BROWSER) LocalFileStreamReader
|
||||||
: public FileStreamReader {
|
: public FileStreamReader {
|
||||||
public:
|
public:
|
||||||
LocalFileStreamReader(scoped_refptr<base::TaskRunner> task_runner,
|
LocalFileStreamReader(
|
||||||
const base::FilePath& file_path,
|
scoped_refptr<base::TaskRunner> task_runner,
|
||||||
int64_t initial_offset,
|
const base::FilePath& file_path,
|
||||||
const base::Time& expected_modification_time,
|
int64_t initial_offset,
|
||||||
base::PassKey<FileStreamReader> pass_key);
|
const base::Time& expected_modification_time,
|
||||||
|
base::PassKey<FileStreamReader> pass_key,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access);
|
||||||
~LocalFileStreamReader() override;
|
~LocalFileStreamReader() override;
|
||||||
|
|
||||||
// FileStreamReader overrides.
|
// FileStreamReader overrides.
|
||||||
@ -76,6 +82,8 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) LocalFileStreamReader
|
|||||||
const int64_t initial_offset_;
|
const int64_t initial_offset_;
|
||||||
const base::Time expected_modification_time_;
|
const base::Time expected_modification_time_;
|
||||||
bool has_pending_open_ = false;
|
bool has_pending_open_ = false;
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access_;
|
||||||
base::WeakPtrFactory<LocalFileStreamReader> weak_factory_{this};
|
base::WeakPtrFactory<LocalFileStreamReader> weak_factory_{this};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "base/files/file_util.h"
|
#include "base/files/file_util.h"
|
||||||
#include "base/files/scoped_temp_dir.h"
|
#include "base/files/scoped_temp_dir.h"
|
||||||
#include "base/functional/bind.h"
|
#include "base/functional/bind.h"
|
||||||
|
#include "base/functional/callback_forward.h"
|
||||||
#include "base/functional/callback_helpers.h"
|
#include "base/functional/callback_helpers.h"
|
||||||
#include "base/location.h"
|
#include "base/location.h"
|
||||||
#include "base/run_loop.h"
|
#include "base/run_loop.h"
|
||||||
@ -70,14 +71,23 @@ class LocalFileStreamReaderTest : public FileStreamReaderTest {
|
|||||||
file_thread_.Stop();
|
file_thread_.Stop();
|
||||||
base::RunLoop().RunUntilIdle();
|
base::RunLoop().RunUntilIdle();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<FileStreamReader> CreateFileReader(
|
std::unique_ptr<FileStreamReader> CreateFileReader(
|
||||||
const std::string& file_name,
|
const std::string& file_name,
|
||||||
int64_t initial_offset,
|
int64_t initial_offset,
|
||||||
const base::Time& expected_modification_time) override {
|
const base::Time& expected_modification_time) override {
|
||||||
|
return CreateFileReader(file_name, initial_offset,
|
||||||
|
expected_modification_time, base::NullCallback());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<FileStreamReader> CreateFileReader(
|
||||||
|
const std::string& file_name,
|
||||||
|
int64_t initial_offset,
|
||||||
|
const base::Time& expected_modification_time,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access) {
|
||||||
return FileStreamReader::CreateForLocalFile(
|
return FileStreamReader::CreateForLocalFile(
|
||||||
file_task_runner(), test_dir().AppendASCII(file_name), initial_offset,
|
file_task_runner(), test_dir().AppendASCII(file_name), initial_offset,
|
||||||
expected_modification_time);
|
expected_modification_time, std::move(file_access));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteFile(const std::string& file_name,
|
void WriteFile(const std::string& file_name,
|
||||||
@ -124,7 +134,7 @@ INSTANTIATE_TYPED_TEST_SUITE_P(Local,
|
|||||||
FileStreamReaderTypedTest,
|
FileStreamReaderTypedTest,
|
||||||
LocalFileStreamReaderTest);
|
LocalFileStreamReaderTest);
|
||||||
|
|
||||||
// TODO(b/262199707 b/265908846): Replace direct call to
|
// TODO(b/265908846): Replace direct call to
|
||||||
// file_access::ScopedFileAccessDelegate with getting access through a callback.
|
// file_access::ScopedFileAccessDelegate with getting access through a callback.
|
||||||
TEST_F(LocalFileStreamReaderTest, ReadAllowedByDataLeakPrevention) {
|
TEST_F(LocalFileStreamReaderTest, ReadAllowedByDataLeakPrevention) {
|
||||||
this->WriteTestFile();
|
this->WriteTestFile();
|
||||||
@ -151,7 +161,7 @@ TEST_F(LocalFileStreamReaderTest, ReadAllowedByDataLeakPrevention) {
|
|||||||
ASSERT_EQ(this->kTestData, data);
|
ASSERT_EQ(this->kTestData, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(b/262199707 b/265908846): Replace direct call to
|
// TODO(b/265908846): Replace direct call to
|
||||||
// file_access::ScopedFileAccessDelegate with getting access through a callback.
|
// file_access::ScopedFileAccessDelegate with getting access through a callback.
|
||||||
TEST_F(LocalFileStreamReaderTest, ReadBlockedByDataLeakPrevention) {
|
TEST_F(LocalFileStreamReaderTest, ReadBlockedByDataLeakPrevention) {
|
||||||
this->WriteTestFile();
|
this->WriteTestFile();
|
||||||
@ -178,4 +188,50 @@ TEST_F(LocalFileStreamReaderTest, ReadBlockedByDataLeakPrevention) {
|
|||||||
ASSERT_EQ("", data);
|
ASSERT_EQ("", data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(LocalFileStreamReaderTest, ReadAllowedByDataLeakPreventionCallback) {
|
||||||
|
this->WriteTestFile();
|
||||||
|
base::MockRepeatingCallback<void(
|
||||||
|
const std::vector<base::FilePath>&,
|
||||||
|
base::OnceCallback<void(file_access::ScopedFileAccess)>)>
|
||||||
|
callback;
|
||||||
|
EXPECT_CALL(
|
||||||
|
callback,
|
||||||
|
Run(testing::ElementsAre(test_dir().AppendASCII(kTestFileName)), _))
|
||||||
|
.WillOnce(base::test::RunOnceCallback<1>(CreateScopedFileAccess(true)));
|
||||||
|
|
||||||
|
std::unique_ptr<FileStreamReader> reader(this->CreateFileReader(
|
||||||
|
std::string(this->kTestFileName), 0, this->test_file_modification_time(),
|
||||||
|
callback.Get()));
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
std::string data;
|
||||||
|
ReadFromReader(reader.get(), &data, this->kTestData.size(), &result);
|
||||||
|
ASSERT_EQ(net::OK, result);
|
||||||
|
ASSERT_EQ(this->kTestData, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(LocalFileStreamReaderTest, ReadBlockedByDataLeakPreventionCallback) {
|
||||||
|
this->WriteTestFile();
|
||||||
|
base::MockRepeatingCallback<void(
|
||||||
|
const std::vector<base::FilePath>&,
|
||||||
|
base::OnceCallback<void(file_access::ScopedFileAccess)>)>
|
||||||
|
callback;
|
||||||
|
file_access::ScopedFileAccessDelegate::
|
||||||
|
ScopedRequestFilesAccessCallbackForTesting file_access_callback(
|
||||||
|
callback.Get());
|
||||||
|
EXPECT_CALL(
|
||||||
|
callback,
|
||||||
|
Run(testing::ElementsAre(test_dir().AppendASCII(kTestFileName)), _))
|
||||||
|
.WillOnce(base::test::RunOnceCallback<1>(CreateScopedFileAccess(false)));
|
||||||
|
std::unique_ptr<FileStreamReader> reader(this->CreateFileReader(
|
||||||
|
std::string(this->kTestFileName), 0, this->test_file_modification_time(),
|
||||||
|
callback.Get()));
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
std::string data;
|
||||||
|
ReadFromReader(reader.get(), &data, this->kTestData.size(), &result);
|
||||||
|
ASSERT_EQ(net::ERR_ACCESS_DENIED, result);
|
||||||
|
ASSERT_EQ("", data);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace storage
|
} // namespace storage
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "base/files/file_util.h"
|
#include "base/files/file_util.h"
|
||||||
#include "base/functional/bind.h"
|
#include "base/functional/bind.h"
|
||||||
#include "base/metrics/histogram.h"
|
#include "base/metrics/histogram.h"
|
||||||
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "storage/browser/file_system/async_file_util_adapter.h"
|
#include "storage/browser/file_system/async_file_util_adapter.h"
|
||||||
#include "storage/browser/file_system/copy_or_move_file_validator.h"
|
#include "storage/browser/file_system/copy_or_move_file_validator.h"
|
||||||
#include "storage/browser/file_system/file_stream_reader.h"
|
#include "storage/browser/file_system/file_stream_reader.h"
|
||||||
@ -137,7 +138,9 @@ SandboxFileSystemBackend::CreateFileStreamReader(
|
|||||||
int64_t offset,
|
int64_t offset,
|
||||||
int64_t max_bytes_to_read,
|
int64_t max_bytes_to_read,
|
||||||
const base::Time& expected_modification_time,
|
const base::Time& expected_modification_time,
|
||||||
FileSystemContext* context) const {
|
FileSystemContext* context,
|
||||||
|
file_access::ScopedFileAccessDelegate::
|
||||||
|
RequestFilesAccessIOCallback /*file_access*/) const {
|
||||||
DCHECK(CanHandleType(url.type()));
|
DCHECK(CanHandleType(url.type()));
|
||||||
DCHECK(delegate_);
|
DCHECK(delegate_);
|
||||||
return delegate_->CreateFileStreamReader(url, offset,
|
return delegate_->CreateFileStreamReader(url, offset,
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "base/compiler_specific.h"
|
#include "base/compiler_specific.h"
|
||||||
#include "base/component_export.h"
|
#include "base/component_export.h"
|
||||||
#include "base/memory/raw_ptr.h"
|
#include "base/memory/raw_ptr.h"
|
||||||
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "storage/browser/file_system/file_system_backend.h"
|
#include "storage/browser/file_system/file_system_backend.h"
|
||||||
#include "storage/browser/file_system/file_system_quota_util.h"
|
#include "storage/browser/file_system/file_system_quota_util.h"
|
||||||
#include "storage/browser/file_system/sandbox_file_system_backend_delegate.h"
|
#include "storage/browser/file_system/sandbox_file_system_backend_delegate.h"
|
||||||
@ -58,7 +59,9 @@ class COMPONENT_EXPORT(STORAGE_BROWSER) SandboxFileSystemBackend
|
|||||||
int64_t offset,
|
int64_t offset,
|
||||||
int64_t max_bytes_to_read,
|
int64_t max_bytes_to_read,
|
||||||
const base::Time& expected_modification_time,
|
const base::Time& expected_modification_time,
|
||||||
FileSystemContext* context) const override;
|
FileSystemContext* context,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access) const override;
|
||||||
std::unique_ptr<FileStreamWriter> CreateFileStreamWriter(
|
std::unique_ptr<FileStreamWriter> CreateFileStreamWriter(
|
||||||
const FileSystemURL& url,
|
const FileSystemURL& url,
|
||||||
int64_t offset,
|
int64_t offset,
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
#include "storage/browser/test/mock_blob_registry_delegate.h"
|
#include "storage/browser/test/mock_blob_registry_delegate.h"
|
||||||
|
#include "base/functional/callback_helpers.h"
|
||||||
|
|
||||||
namespace storage {
|
namespace storage {
|
||||||
|
|
||||||
@ -15,4 +16,9 @@ bool MockBlobRegistryDelegate::CanAccessDataForOrigin(
|
|||||||
return can_access_data_for_origin;
|
return can_access_data_for_origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
MockBlobRegistryDelegate::GetAccessCallback() {
|
||||||
|
return base::DoNothing();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace storage
|
} // namespace storage
|
||||||
|
@ -19,6 +19,8 @@ class MockBlobRegistryDelegate
|
|||||||
|
|
||||||
bool CanReadFile(const base::FilePath& file) override;
|
bool CanReadFile(const base::FilePath& file) override;
|
||||||
bool CanAccessDataForOrigin(const url::Origin& origin) override;
|
bool CanAccessDataForOrigin(const url::Origin& origin) override;
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
GetAccessCallback() override;
|
||||||
|
|
||||||
bool can_read_file_result = true;
|
bool can_read_file_result = true;
|
||||||
bool can_access_data_for_origin = true;
|
bool can_access_data_for_origin = true;
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "base/memory/weak_ptr.h"
|
#include "base/memory/weak_ptr.h"
|
||||||
#include "base/observer_list.h"
|
#include "base/observer_list.h"
|
||||||
#include "base/task/sequenced_task_runner.h"
|
#include "base/task/sequenced_task_runner.h"
|
||||||
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "storage/browser/file_system/copy_or_move_file_validator.h"
|
#include "storage/browser/file_system/copy_or_move_file_validator.h"
|
||||||
#include "storage/browser/file_system/file_observers.h"
|
#include "storage/browser/file_system/file_observers.h"
|
||||||
#include "storage/browser/file_system/file_system_operation.h"
|
#include "storage/browser/file_system/file_system_operation.h"
|
||||||
@ -216,7 +217,9 @@ std::unique_ptr<FileStreamReader> TestFileSystemBackend::CreateFileStreamReader(
|
|||||||
int64_t offset,
|
int64_t offset,
|
||||||
int64_t max_bytes_to_read,
|
int64_t max_bytes_to_read,
|
||||||
const base::Time& expected_modification_time,
|
const base::Time& expected_modification_time,
|
||||||
FileSystemContext* context) const {
|
FileSystemContext* context,
|
||||||
|
file_access::ScopedFileAccessDelegate::
|
||||||
|
RequestFilesAccessIOCallback /*file_access*/) const {
|
||||||
return std::make_unique<SandboxFileStreamReader>(context, url, offset,
|
return std::make_unique<SandboxFileStreamReader>(context, url, offset,
|
||||||
expected_modification_time);
|
expected_modification_time);
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "base/files/file_path.h"
|
#include "base/files/file_path.h"
|
||||||
#include "base/memory/scoped_refptr.h"
|
#include "base/memory/scoped_refptr.h"
|
||||||
|
#include "components/file_access/scoped_file_access_delegate.h"
|
||||||
#include "storage/browser/file_system/async_file_util_adapter.h"
|
#include "storage/browser/file_system/async_file_util_adapter.h"
|
||||||
#include "storage/browser/file_system/file_system_backend.h"
|
#include "storage/browser/file_system/file_system_backend.h"
|
||||||
#include "storage/browser/file_system/task_runner_bound_observer_list.h"
|
#include "storage/browser/file_system/task_runner_bound_observer_list.h"
|
||||||
@ -61,7 +62,9 @@ class TestFileSystemBackend : public FileSystemBackend {
|
|||||||
int64_t offset,
|
int64_t offset,
|
||||||
int64_t max_bytes_to_read,
|
int64_t max_bytes_to_read,
|
||||||
const base::Time& expected_modification_time,
|
const base::Time& expected_modification_time,
|
||||||
FileSystemContext* context) const override;
|
FileSystemContext* context,
|
||||||
|
file_access::ScopedFileAccessDelegate::RequestFilesAccessIOCallback
|
||||||
|
file_access) const override;
|
||||||
std::unique_ptr<FileStreamWriter> CreateFileStreamWriter(
|
std::unique_ptr<FileStreamWriter> CreateFileStreamWriter(
|
||||||
const FileSystemURL& url,
|
const FileSystemURL& url,
|
||||||
int64_t offset,
|
int64_t offset,
|
||||||
|
Reference in New Issue
Block a user