-
Notifications
You must be signed in to change notification settings - Fork 6.6k
/
fmpi_get_volume_root_function.cc
90 lines (77 loc) · 3.58 KB
/
fmpi_get_volume_root_function.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/chromeos/extensions/file_manager/fmpi_get_volume_root_function.h"
#include "ash/webui/file_manager/url_constants.h"
#include "base/files/file.h"
#include "base/strings/string_number_conversions.h"
#include "chrome/browser/ash/file_manager/fileapi_util.h"
#include "chrome/browser/ash/file_manager/volume_manager.h"
#include "chrome/browser/extensions/chrome_extension_function_details.h"
#include "chrome/common/extensions/api/file_manager_private_internal.h"
#include "content/public/browser/child_process_security_policy.h"
#include "content/public/browser/storage_partition.h"
namespace extensions {
ExtensionFunction::ResponseAction
FileManagerPrivateInternalGetVolumeRootFunction::Run() {
using extensions::api::file_manager_private_internal::GetVolumeRoot::Params;
const std::unique_ptr<Params> params(Params::Create(args()));
EXTENSION_FUNCTION_VALIDATE(params);
const std::string& volume_id = params->options.volume_id;
if (volume_id.empty()) {
return RespondNow(Error("Volume ID must be provided."));
}
file_manager::VolumeManager* const volume_manager =
file_manager::VolumeManager::Get(
Profile::FromBrowserContext(browser_context()));
DCHECK(volume_manager);
base::WeakPtr<file_manager::Volume> volume =
volume_manager->FindVolumeById(volume_id);
if (!volume.get()) {
return RespondNow(Error("Volume with ID '*' not found", volume_id));
}
content::ChildProcessSecurityPolicy* policy =
content::ChildProcessSecurityPolicy::GetInstance();
DCHECK(policy);
const auto process_id = source_process_id();
// Read-only permisisons.
policy->GrantReadFile(process_id, volume->mount_path());
if (params->options.writable.get() && *params->options.writable.get()) {
// Additional write permissions.
policy->GrantCreateReadWriteFile(process_id, volume->mount_path());
policy->GrantCopyInto(process_id, volume->mount_path());
}
// Convert volume's mount path to a virtual path.
scoped_refptr<storage::FileSystemContext> file_system_context =
render_frame_host()->GetStoragePartition()->GetFileSystemContext();
DCHECK(file_system_context.get());
storage::ExternalFileSystemBackend* const backend =
file_system_context->external_backend();
DCHECK(backend);
file_manager::util::FileDefinition fd;
if (!backend->GetVirtualPath(volume->mount_path(), &fd.virtual_path)) {
return RespondNow(
Error("Cannot get virtual path for volume with ID '*'", volume_id));
}
// Grant the caller right rights to crack URLs based on the virtual path.
const url::Origin origin = url::Origin::Create(source_url());
backend->GrantFileAccessToOrigin(origin, fd.virtual_path);
// Convert volume's mount path to an EntryDefinition.
file_manager::util::ConvertFileDefinitionToEntryDefinition(
file_system_context, origin, fd,
base::BindOnce(
&FileManagerPrivateInternalGetVolumeRootFunction::OnRequestDone,
this));
return RespondLater();
}
void FileManagerPrivateInternalGetVolumeRootFunction::OnRequestDone(
const file_manager::util::EntryDefinition& entry_definition) {
if (entry_definition.error != base::File::FILE_OK) {
Respond(Error("Failed to resolve volume's root directory: *",
base::NumberToString(entry_definition.error)));
} else {
Respond(OneArgument(base::Value::FromUniquePtrValue(
ConvertEntryDefinitionToValue(entry_definition))));
}
}
} // namespace extensions