1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "webkit/chromeos/fileapi/cros_mount_point_provider.h"
9 #include "base/files/file_path.h"
10 #include "chromeos/dbus/cros_disks_client.h"
11 #include "googleurl/src/url_util.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "webkit/fileapi/external_mount_points.h"
14 #include "webkit/fileapi/file_permission_policy.h"
15 #include "webkit/fileapi/file_system_url.h"
16 #include "webkit/fileapi/isolated_context.h"
17 #include "webkit/quota/mock_special_storage_policy.h"
19 #define FPL(x) FILE_PATH_LITERAL(x)
21 using fileapi::ExternalMountPoints
;
22 using fileapi::FileSystemURL
;
26 FileSystemURL
CreateFileSystemURL(const std::string
& extension
,
28 ExternalMountPoints
* mount_points
) {
29 return mount_points
->CreateCrackedFileSystemURL(
30 GURL("chrome-extension://" + extension
+ "/"),
31 fileapi::kFileSystemTypeExternal
,
32 base::FilePath::FromUTF8Unsafe(path
));
35 TEST(CrosMountPointProviderTest
, DefaultMountPoints
) {
36 scoped_refptr
<quota::SpecialStoragePolicy
> storage_policy
=
37 new quota::MockSpecialStoragePolicy();
38 scoped_refptr
<fileapi::ExternalMountPoints
> mount_points(
39 fileapi::ExternalMountPoints::CreateRefCounted());
40 chromeos::CrosMountPointProvider
provider(
43 fileapi::ExternalMountPoints::GetSystemInstance());
44 std::vector
<base::FilePath
> root_dirs
= provider
.GetRootDirectories();
45 std::set
<base::FilePath
> root_dirs_set(root_dirs
.begin(), root_dirs
.end());
47 // By default there should be 3 mount points (in system mount points):
48 EXPECT_EQ(3u, root_dirs
.size());
49 EXPECT_TRUE(root_dirs_set
.count(
50 chromeos::CrosDisksClient::GetRemovableDiskMountPoint()));
51 EXPECT_TRUE(root_dirs_set
.count(
52 chromeos::CrosDisksClient::GetArchiveMountPoint()));
53 EXPECT_TRUE(root_dirs_set
.count(base::FilePath(FPL("/usr/share/oem"))));
56 TEST(CrosMountPointProviderTest
, GetRootDirectories
) {
57 scoped_refptr
<quota::SpecialStoragePolicy
> storage_policy
=
58 new quota::MockSpecialStoragePolicy();
59 scoped_refptr
<fileapi::ExternalMountPoints
> mount_points(
60 fileapi::ExternalMountPoints::CreateRefCounted());
62 scoped_refptr
<fileapi::ExternalMountPoints
> system_mount_points(
63 fileapi::ExternalMountPoints::CreateRefCounted());
65 chromeos::CrosMountPointProvider
provider(
68 system_mount_points
.get());
70 const size_t initial_root_dirs_size
= provider
.GetRootDirectories().size();
72 // Register 'local' test mount points.
73 mount_points
->RegisterFileSystem("c",
74 fileapi::kFileSystemTypeNativeLocal
,
75 base::FilePath(FPL("/a/b/c")));
76 mount_points
->RegisterFileSystem("d",
77 fileapi::kFileSystemTypeNativeLocal
,
78 base::FilePath(FPL("/b/c/d")));
80 // Register system test mount points.
81 system_mount_points
->RegisterFileSystem("d",
82 fileapi::kFileSystemTypeNativeLocal
,
83 base::FilePath(FPL("/g/c/d")));
84 system_mount_points
->RegisterFileSystem("e",
85 fileapi::kFileSystemTypeNativeLocal
,
86 base::FilePath(FPL("/g/d/e")));
88 std::vector
<base::FilePath
> root_dirs
= provider
.GetRootDirectories();
89 std::set
<base::FilePath
> root_dirs_set(root_dirs
.begin(), root_dirs
.end());
90 EXPECT_EQ(initial_root_dirs_size
+ 4, root_dirs
.size());
91 EXPECT_TRUE(root_dirs_set
.count(base::FilePath(FPL("/a/b/c"))));
92 EXPECT_TRUE(root_dirs_set
.count(base::FilePath(FPL("/b/c/d"))));
93 EXPECT_TRUE(root_dirs_set
.count(base::FilePath(FPL("/g/c/d"))));
94 EXPECT_TRUE(root_dirs_set
.count(base::FilePath(FPL("/g/d/e"))));
97 TEST(CrosMountPointProviderTest
, AccessPermissions
) {
98 const int kPermission
= fileapi::kReadFilePermissions
;
100 url_util::AddStandardScheme("chrome-extension");
102 scoped_refptr
<quota::MockSpecialStoragePolicy
> storage_policy
=
103 new quota::MockSpecialStoragePolicy();
104 scoped_refptr
<fileapi::ExternalMountPoints
> mount_points(
105 fileapi::ExternalMountPoints::CreateRefCounted());
106 scoped_refptr
<fileapi::ExternalMountPoints
> system_mount_points(
107 fileapi::ExternalMountPoints::CreateRefCounted());
108 chromeos::CrosMountPointProvider
provider(
111 system_mount_points
.get());
113 std::string
extension("ddammdhioacbehjngdmkjcjbnfginlla");
115 storage_policy
->AddFileHandler(extension
);
117 // Initialize mount points.
118 ASSERT_TRUE(system_mount_points
->RegisterFileSystem(
120 fileapi::kFileSystemTypeNativeLocal
,
121 base::FilePath(FPL("/g/system"))));
122 ASSERT_TRUE(mount_points
->RegisterFileSystem(
124 fileapi::kFileSystemTypeNativeLocal
,
125 base::FilePath(FPL("/media/removable"))));
126 ASSERT_TRUE(mount_points
->RegisterFileSystem(
128 fileapi::kFileSystemTypeRestrictedNativeLocal
,
129 base::FilePath(FPL("/usr/share/oem"))));
131 // Provider specific mount point access.
133 fileapi::FILE_PERMISSION_ALWAYS_DENY
,
134 provider
.GetPermissionPolicy(
135 CreateFileSystemURL(extension
, "removable/foo", mount_points
.get()),
138 provider
.GrantFileAccessToExtension(extension
,
139 base::FilePath(FPL("removable/foo")));
141 fileapi::FILE_PERMISSION_USE_FILE_PERMISSION
,
142 provider
.GetPermissionPolicy(
143 CreateFileSystemURL(extension
, "removable/foo", mount_points
.get()),
146 fileapi::FILE_PERMISSION_ALWAYS_DENY
,
147 provider
.GetPermissionPolicy(
148 CreateFileSystemURL(extension
, "removable/foo1", mount_points
.get()),
151 // System mount point access.
153 fileapi::FILE_PERMISSION_ALWAYS_DENY
,
154 provider
.GetPermissionPolicy(
155 CreateFileSystemURL(extension
, "system/foo",
156 system_mount_points
.get()),
159 provider
.GrantFileAccessToExtension(extension
,
160 base::FilePath(FPL("system/foo")));
162 fileapi::FILE_PERMISSION_USE_FILE_PERMISSION
,
163 provider
.GetPermissionPolicy(
164 CreateFileSystemURL(extension
, "system/foo",
165 system_mount_points
.get()),
168 fileapi::FILE_PERMISSION_ALWAYS_DENY
,
169 provider
.GetPermissionPolicy(
170 CreateFileSystemURL(extension
, "system/foo1",
171 system_mount_points
.get()),
174 // oem is restricted file system.
175 provider
.GrantFileAccessToExtension(extension
, base::FilePath(FPL("oem/foo")));
176 // The extension should not be able to access the file even if
177 // GrantFileAccessToExtension was called.
179 fileapi::FILE_PERMISSION_ALWAYS_DENY
,
180 provider
.GetPermissionPolicy(
181 CreateFileSystemURL(extension
, "oem/foo", mount_points
.get()),
184 provider
.GrantFullAccessToExtension(extension
);
185 // The extension should be able to access restricted file system after it was
186 // granted full access.
188 fileapi::FILE_PERMISSION_USE_FILE_PERMISSION
,
189 provider
.GetPermissionPolicy(
190 CreateFileSystemURL(extension
, "oem/foo", mount_points
.get()),
192 // The extension which was granted full access should be able to access any
193 // path on current file systems.
195 fileapi::FILE_PERMISSION_USE_FILE_PERMISSION
,
196 provider
.GetPermissionPolicy(
197 CreateFileSystemURL(extension
, "removable/foo1", mount_points
.get()),
200 fileapi::FILE_PERMISSION_USE_FILE_PERMISSION
,
201 provider
.GetPermissionPolicy(
202 CreateFileSystemURL(extension
, "system/foo1",
203 system_mount_points
.get()),
206 // The extension cannot access new mount points.
207 // TODO(tbarzic): This should probably be changed.
208 ASSERT_TRUE(mount_points
->RegisterFileSystem(
210 fileapi::kFileSystemTypeNativeLocal
,
211 base::FilePath(FPL("/foo/test"))));
213 fileapi::FILE_PERMISSION_ALWAYS_DENY
,
214 provider
.GetPermissionPolicy(
215 CreateFileSystemURL(extension
, "test_/foo", mount_points
.get()),
218 provider
.RevokeAccessForExtension(extension
);
220 fileapi::FILE_PERMISSION_ALWAYS_DENY
,
221 provider
.GetPermissionPolicy(
222 CreateFileSystemURL(extension
, "removable/foo", mount_points
.get()),
225 fileapi::FileSystemURL internal_url
= FileSystemURL::CreateForTest(
226 GURL("chrome://foo"),
227 fileapi::kFileSystemTypeExternal
,
228 base::FilePath(FPL("removable/")));
229 // Internal WebUI should have full access.
231 fileapi::FILE_PERMISSION_ALWAYS_ALLOW
,
232 provider
.GetPermissionPolicy(internal_url
, kPermission
));
235 TEST(CrosMountPointProvider
, GetVirtualPathConflictWithSystemPoints
) {
236 scoped_refptr
<quota::MockSpecialStoragePolicy
> storage_policy
=
237 new quota::MockSpecialStoragePolicy();
238 scoped_refptr
<fileapi::ExternalMountPoints
> mount_points(
239 fileapi::ExternalMountPoints::CreateRefCounted());
240 scoped_refptr
<fileapi::ExternalMountPoints
> system_mount_points(
241 fileapi::ExternalMountPoints::CreateRefCounted());
242 chromeos::CrosMountPointProvider
provider(storage_policy
,
244 system_mount_points
.get());
246 const fileapi::FileSystemType type
= fileapi::kFileSystemTypeNativeLocal
;
248 // Provider specific mount points.
250 mount_points
->RegisterFileSystem("b", type
, base::FilePath(FPL("/a/b"))));
252 mount_points
->RegisterFileSystem("y", type
, base::FilePath(FPL("/z/y"))));
254 mount_points
->RegisterFileSystem("n", type
, base::FilePath(FPL("/m/n"))));
256 // System mount points
257 ASSERT_TRUE(system_mount_points
->RegisterFileSystem(
258 "gb", type
, base::FilePath(FPL("/a/b"))));
260 system_mount_points
->RegisterFileSystem("gz", type
, base::FilePath(FPL("/z"))));
261 ASSERT_TRUE(system_mount_points
->RegisterFileSystem(
262 "gp", type
, base::FilePath(FPL("/m/n/o/p"))));
265 const base::FilePath::CharType
* const local_path
;
267 const base::FilePath::CharType
* const virtual_path
;
270 const TestCase kTestCases
[] = {
271 // Same paths in both mount points.
272 { FPL("/a/b/c/d"), true, FPL("b/c/d") },
273 // System mount points path more specific.
274 { FPL("/m/n/o/p/r/s"), true, FPL("n/o/p/r/s") },
275 // System mount points path less specific.
276 { FPL("/z/y/x"), true, FPL("y/x") },
277 // Only system mount points path matches.
278 { FPL("/z/q/r/s"), true, FPL("gz/q/r/s") },
280 { FPL("/foo/xxx"), false, FPL("") },
283 for (size_t i
= 0; i
< ARRAYSIZE_UNSAFE(kTestCases
); ++i
) {
284 // Initialize virtual path with a value.
285 base::FilePath
virtual_path(FPL("/mount"));
286 base::FilePath
local_path(kTestCases
[i
].local_path
);
287 EXPECT_EQ(kTestCases
[i
].success
,
288 provider
.GetVirtualPath(local_path
, &virtual_path
))
289 << "Resolving " << kTestCases
[i
].local_path
;
291 // There are no guarantees for |virtual_path| value if |GetVirtualPath|
293 if (!kTestCases
[i
].success
)
296 base::FilePath
expected_virtual_path(kTestCases
[i
].virtual_path
);
297 EXPECT_EQ(expected_virtual_path
, virtual_path
)
298 << "Resolving " << kTestCases
[i
].local_path
;