1 // Copyright 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 "chrome/browser/chromeos/fileapi/file_system_backend.h"
9 #include "base/files/file_path.h"
10 #include "base/path_service.h"
11 #include "chromeos/dbus/cros_disks_client.h"
12 #include "content/public/test/mock_special_storage_policy.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "url/url_util.h"
15 #include "webkit/browser/fileapi/external_mount_points.h"
16 #include "webkit/browser/fileapi/file_system_url.h"
18 #define FPL(x) FILE_PATH_LITERAL(x)
20 using fileapi::ExternalMountPoints;
21 using fileapi::FileSystemURL;
25 FileSystemURL CreateFileSystemURL(const std::string& extension,
27 ExternalMountPoints* mount_points) {
28 return mount_points->CreateCrackedFileSystemURL(
29 GURL("chrome-extension://" + extension + "/"),
30 fileapi::kFileSystemTypeExternal,
31 base::FilePath::FromUTF8Unsafe(path));
34 TEST(ChromeOSFileSystemBackendTest, DefaultMountPoints) {
35 // Make sure no system-level mount points are registered before testing
36 // to avoid flakiness.
37 fileapi::ExternalMountPoints::GetSystemInstance()->RevokeAllFileSystems();
39 scoped_refptr<quota::SpecialStoragePolicy> storage_policy =
40 new content::MockSpecialStoragePolicy();
41 scoped_refptr<fileapi::ExternalMountPoints> mount_points(
42 fileapi::ExternalMountPoints::CreateRefCounted());
43 chromeos::FileSystemBackend backend(
44 NULL, // drive_delegate
45 NULL, // file_system_provider_delegate
49 fileapi::ExternalMountPoints::GetSystemInstance());
50 backend.AddSystemMountPoints();
51 std::vector<base::FilePath> root_dirs = backend.GetRootDirectories();
52 std::set<base::FilePath> root_dirs_set(root_dirs.begin(), root_dirs.end());
54 // By default there should be 3 mount points (in system mount points):
55 EXPECT_EQ(3u, root_dirs.size());
57 EXPECT_TRUE(root_dirs_set.count(
58 chromeos::CrosDisksClient::GetRemovableDiskMountPoint()));
59 EXPECT_TRUE(root_dirs_set.count(
60 chromeos::CrosDisksClient::GetArchiveMountPoint()));
61 EXPECT_TRUE(root_dirs_set.count(base::FilePath(FPL("/usr/share/oem"))));
64 TEST(ChromeOSFileSystemBackendTest, GetRootDirectories) {
65 scoped_refptr<quota::SpecialStoragePolicy> storage_policy =
66 new content::MockSpecialStoragePolicy();
67 scoped_refptr<fileapi::ExternalMountPoints> mount_points(
68 fileapi::ExternalMountPoints::CreateRefCounted());
70 scoped_refptr<fileapi::ExternalMountPoints> system_mount_points(
71 fileapi::ExternalMountPoints::CreateRefCounted());
73 chromeos::FileSystemBackend backend(NULL, // drive_delegate
74 NULL, // file_system_provider_delegate
78 system_mount_points.get());
80 const size_t initial_root_dirs_size = backend.GetRootDirectories().size();
82 // Register 'local' test mount points.
83 mount_points->RegisterFileSystem("c",
84 fileapi::kFileSystemTypeNativeLocal,
85 fileapi::FileSystemMountOption(),
86 base::FilePath(FPL("/a/b/c")));
87 mount_points->RegisterFileSystem("d",
88 fileapi::kFileSystemTypeNativeLocal,
89 fileapi::FileSystemMountOption(),
90 base::FilePath(FPL("/b/c/d")));
92 // Register system test mount points.
93 system_mount_points->RegisterFileSystem("d",
94 fileapi::kFileSystemTypeNativeLocal,
95 fileapi::FileSystemMountOption(),
96 base::FilePath(FPL("/g/c/d")));
97 system_mount_points->RegisterFileSystem("e",
98 fileapi::kFileSystemTypeNativeLocal,
99 fileapi::FileSystemMountOption(),
100 base::FilePath(FPL("/g/d/e")));
102 std::vector<base::FilePath> root_dirs = backend.GetRootDirectories();
103 std::set<base::FilePath> root_dirs_set(root_dirs.begin(), root_dirs.end());
104 EXPECT_EQ(initial_root_dirs_size + 4, root_dirs.size());
105 EXPECT_TRUE(root_dirs_set.count(base::FilePath(FPL("/a/b/c"))));
106 EXPECT_TRUE(root_dirs_set.count(base::FilePath(FPL("/b/c/d"))));
107 EXPECT_TRUE(root_dirs_set.count(base::FilePath(FPL("/g/c/d"))));
108 EXPECT_TRUE(root_dirs_set.count(base::FilePath(FPL("/g/d/e"))));
111 TEST(ChromeOSFileSystemBackendTest, AccessPermissions) {
112 url::AddStandardScheme("chrome-extension");
114 scoped_refptr<content::MockSpecialStoragePolicy> storage_policy =
115 new content::MockSpecialStoragePolicy();
116 scoped_refptr<fileapi::ExternalMountPoints> mount_points(
117 fileapi::ExternalMountPoints::CreateRefCounted());
118 scoped_refptr<fileapi::ExternalMountPoints> system_mount_points(
119 fileapi::ExternalMountPoints::CreateRefCounted());
120 chromeos::FileSystemBackend backend(NULL, // drive_delegate
121 NULL, // file_system_provider_delegate
122 NULL, // mtp_delegate
125 system_mount_points.get());
127 std::string extension("ddammdhioacbehjngdmkjcjbnfginlla");
129 storage_policy->AddFileHandler(extension);
131 // Initialize mount points.
132 ASSERT_TRUE(system_mount_points->RegisterFileSystem(
134 fileapi::kFileSystemTypeNativeLocal,
135 fileapi::FileSystemMountOption(),
136 base::FilePath(FPL("/g/system"))));
137 ASSERT_TRUE(mount_points->RegisterFileSystem(
139 fileapi::kFileSystemTypeNativeLocal,
140 fileapi::FileSystemMountOption(),
141 base::FilePath(FPL("/media/removable"))));
142 ASSERT_TRUE(mount_points->RegisterFileSystem(
144 fileapi::kFileSystemTypeRestrictedNativeLocal,
145 fileapi::FileSystemMountOption(),
146 base::FilePath(FPL("/usr/share/oem"))));
148 // Backend specific mount point access.
149 EXPECT_FALSE(backend.IsAccessAllowed(
150 CreateFileSystemURL(extension, "removable/foo", mount_points.get())));
152 backend.GrantFileAccessToExtension(extension,
153 base::FilePath(FPL("removable/foo")));
154 EXPECT_TRUE(backend.IsAccessAllowed(
155 CreateFileSystemURL(extension, "removable/foo", mount_points.get())));
156 EXPECT_FALSE(backend.IsAccessAllowed(
157 CreateFileSystemURL(extension, "removable/foo1", mount_points.get())));
159 // System mount point access.
160 EXPECT_FALSE(backend.IsAccessAllowed(
161 CreateFileSystemURL(extension, "system/foo", system_mount_points.get())));
163 backend.GrantFileAccessToExtension(extension,
164 base::FilePath(FPL("system/foo")));
165 EXPECT_TRUE(backend.IsAccessAllowed(
166 CreateFileSystemURL(extension, "system/foo", system_mount_points.get())));
167 EXPECT_FALSE(backend.IsAccessAllowed(
168 CreateFileSystemURL(extension, "system/foo1",
169 system_mount_points.get())));
171 // oem is restricted file system.
172 backend.GrantFileAccessToExtension(
173 extension, base::FilePath(FPL("oem/foo")));
174 // The extension should not be able to access the file even if
175 // GrantFileAccessToExtension was called.
176 EXPECT_FALSE(backend.IsAccessAllowed(
177 CreateFileSystemURL(extension, "oem/foo", mount_points.get())));
179 backend.GrantFullAccessToExtension(extension);
180 // The extension should be able to access restricted file system after it was
181 // granted full access.
182 EXPECT_TRUE(backend.IsAccessAllowed(
183 CreateFileSystemURL(extension, "oem/foo", mount_points.get())));
184 // The extension which was granted full access should be able to access any
185 // path on current file systems.
186 EXPECT_TRUE(backend.IsAccessAllowed(
187 CreateFileSystemURL(extension, "removable/foo1", mount_points.get())));
188 EXPECT_TRUE(backend.IsAccessAllowed(
189 CreateFileSystemURL(extension, "system/foo1",
190 system_mount_points.get())));
192 // The extension cannot access new mount points.
193 // TODO(tbarzic): This should probably be changed.
194 ASSERT_TRUE(mount_points->RegisterFileSystem(
196 fileapi::kFileSystemTypeNativeLocal,
197 fileapi::FileSystemMountOption(),
198 base::FilePath(FPL("/foo/test"))));
199 EXPECT_FALSE(backend.IsAccessAllowed(
200 CreateFileSystemURL(extension, "test_/foo", mount_points.get())));
202 backend.RevokeAccessForExtension(extension);
203 EXPECT_FALSE(backend.IsAccessAllowed(
204 CreateFileSystemURL(extension, "removable/foo", mount_points.get())));
207 TEST(ChromeOSFileSystemBackendTest, GetVirtualPathConflictWithSystemPoints) {
208 scoped_refptr<content::MockSpecialStoragePolicy> storage_policy =
209 new content::MockSpecialStoragePolicy();
210 scoped_refptr<fileapi::ExternalMountPoints> mount_points(
211 fileapi::ExternalMountPoints::CreateRefCounted());
212 scoped_refptr<fileapi::ExternalMountPoints> system_mount_points(
213 fileapi::ExternalMountPoints::CreateRefCounted());
214 chromeos::FileSystemBackend backend(NULL, // drive_delegate
215 NULL, // file_system_provider_delegate
216 NULL, // mtp_delegate
219 system_mount_points.get());
221 const fileapi::FileSystemType type = fileapi::kFileSystemTypeNativeLocal;
222 const fileapi::FileSystemMountOption option =
223 fileapi::FileSystemMountOption();
225 // Backend specific mount points.
226 ASSERT_TRUE(mount_points->RegisterFileSystem(
227 "b", type, option, base::FilePath(FPL("/a/b"))));
228 ASSERT_TRUE(mount_points->RegisterFileSystem(
229 "y", type, option, base::FilePath(FPL("/z/y"))));
230 ASSERT_TRUE(mount_points->RegisterFileSystem(
231 "n", type, option, base::FilePath(FPL("/m/n"))));
233 // System mount points
234 ASSERT_TRUE(system_mount_points->RegisterFileSystem(
235 "gb", type, option, base::FilePath(FPL("/a/b"))));
237 system_mount_points->RegisterFileSystem(
238 "gz", type, option, base::FilePath(FPL("/z"))));
239 ASSERT_TRUE(system_mount_points->RegisterFileSystem(
240 "gp", type, option, base::FilePath(FPL("/m/n/o/p"))));
243 const base::FilePath::CharType* const local_path;
245 const base::FilePath::CharType* const virtual_path;
248 const TestCase kTestCases[] = {
249 // Same paths in both mount points.
250 { FPL("/a/b/c/d"), true, FPL("b/c/d") },
251 // System mount points path more specific.
252 { FPL("/m/n/o/p/r/s"), true, FPL("n/o/p/r/s") },
253 // System mount points path less specific.
254 { FPL("/z/y/x"), true, FPL("y/x") },
255 // Only system mount points path matches.
256 { FPL("/z/q/r/s"), true, FPL("gz/q/r/s") },
258 { FPL("/foo/xxx"), false, FPL("") },
261 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
262 // Initialize virtual path with a value.
263 base::FilePath virtual_path(FPL("/mount"));
264 base::FilePath local_path(kTestCases[i].local_path);
265 EXPECT_EQ(kTestCases[i].success,
266 backend.GetVirtualPath(local_path, &virtual_path))
267 << "Resolving " << kTestCases[i].local_path;
269 // There are no guarantees for |virtual_path| value if |GetVirtualPath|
271 if (!kTestCases[i].success)
274 base::FilePath expected_virtual_path(kTestCases[i].virtual_path);
275 EXPECT_EQ(expected_virtual_path, virtual_path)
276 << "Resolving " << kTestCases[i].local_path;