OLD | NEW |
(Empty) | |
| 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. |
| 4 |
| 5 #include "webkit/chromeos/fileapi/cros_mount_point_provider.h" |
| 6 |
| 7 #include <set> |
| 8 |
| 9 #include "base/file_path.h" |
| 10 #include "googleurl/src/url_util.h" |
| 11 #include "testing/gtest/include/gtest/gtest.h" |
| 12 #include "webkit/fileapi/external_mount_points.h" |
| 13 #include "webkit/fileapi/file_system_url.h" |
| 14 #include "webkit/fileapi/isolated_context.h" |
| 15 #include "webkit/quota/mock_special_storage_policy.h" |
| 16 |
| 17 #define FPL(x) FILE_PATH_LITERAL(x) |
| 18 |
| 19 namespace { |
| 20 |
| 21 fileapi::FileSystemURL CreateFileSystemURL(const std::string& extension, |
| 22 const char* path) { |
| 23 return fileapi::FileSystemURL(GURL("chrome-extension://" + extension + "/"), |
| 24 fileapi::kFileSystemTypeNativeLocal, |
| 25 FilePath::FromUTF8Unsafe(path)); |
| 26 } |
| 27 |
| 28 TEST(CrosMountPointProviderTest, DefaultMountPoints) { |
| 29 scoped_refptr<quota::SpecialStoragePolicy> storage_policy = |
| 30 new quota::MockSpecialStoragePolicy(); |
| 31 scoped_refptr<fileapi::ExternalMountPoints> mount_points( |
| 32 fileapi::ExternalMountPoints::CreateRefCounted()); |
| 33 chromeos::CrosMountPointProvider provider( |
| 34 storage_policy, |
| 35 mount_points.get(), |
| 36 fileapi::ExternalMountPoints::GetSystemInstance()); |
| 37 // By default there should be 4 mount points. |
| 38 std::vector<FilePath> root_dirs = provider.GetRootDirectories(); |
| 39 std::set<FilePath> root_dirs_set(root_dirs.begin(), root_dirs.end()); |
| 40 EXPECT_EQ(4u, root_dirs.size()); |
| 41 EXPECT_TRUE(root_dirs_set.count(FilePath(FPL("/media/removable")))); |
| 42 EXPECT_TRUE(root_dirs_set.count(FilePath(FPL("/media/archive")))); |
| 43 EXPECT_TRUE(root_dirs_set.count(FilePath(FPL("/usr/share/oem")))); |
| 44 // Fourth mount point is Downloads, but its local path is device specific. |
| 45 } |
| 46 |
| 47 TEST(CrosMountPointProviderTest, GetRootDirectories) { |
| 48 scoped_refptr<quota::SpecialStoragePolicy> storage_policy = |
| 49 new quota::MockSpecialStoragePolicy(); |
| 50 scoped_refptr<fileapi::ExternalMountPoints> mount_points( |
| 51 fileapi::ExternalMountPoints::CreateRefCounted()); |
| 52 |
| 53 scoped_refptr<fileapi::ExternalMountPoints> system_mount_points( |
| 54 fileapi::ExternalMountPoints::CreateRefCounted()); |
| 55 |
| 56 chromeos::CrosMountPointProvider provider( |
| 57 storage_policy, |
| 58 mount_points.get(), |
| 59 system_mount_points.get()); |
| 60 |
| 61 // Register 'local' test mount points. |
| 62 mount_points->RegisterFileSystem("c", |
| 63 fileapi::kFileSystemTypeNativeLocal, |
| 64 FilePath(FPL("/a/b/c"))); |
| 65 mount_points->RegisterFileSystem("d", |
| 66 fileapi::kFileSystemTypeNativeLocal, |
| 67 FilePath(FPL("/b/c/d"))); |
| 68 |
| 69 // Register system test mount points. |
| 70 system_mount_points->RegisterFileSystem("d", |
| 71 fileapi::kFileSystemTypeNativeLocal, |
| 72 FilePath(FPL("/g/c/d"))); |
| 73 system_mount_points->RegisterFileSystem("e", |
| 74 fileapi::kFileSystemTypeNativeLocal, |
| 75 FilePath(FPL("/g/d/e"))); |
| 76 |
| 77 std::vector<FilePath> root_dirs = provider.GetRootDirectories(); |
| 78 std::set<FilePath> root_dirs_set(root_dirs.begin(), root_dirs.end()); |
| 79 EXPECT_EQ(4u, root_dirs.size()); |
| 80 EXPECT_TRUE(root_dirs_set.count(FilePath(FPL("/a/b/c")))); |
| 81 EXPECT_TRUE(root_dirs_set.count(FilePath(FPL("/b/c/d")))); |
| 82 EXPECT_TRUE(root_dirs_set.count(FilePath(FPL("/g/c/d")))); |
| 83 EXPECT_TRUE(root_dirs_set.count(FilePath(FPL("/g/d/e")))); |
| 84 } |
| 85 |
| 86 TEST(CrosMountPointProviderTest, MountPointsVisibility) { |
| 87 scoped_refptr<quota::SpecialStoragePolicy> storage_policy = |
| 88 new quota::MockSpecialStoragePolicy(); |
| 89 scoped_refptr<fileapi::ExternalMountPoints> mount_points( |
| 90 fileapi::ExternalMountPoints::CreateRefCounted()); |
| 91 scoped_refptr<fileapi::ExternalMountPoints> sibling_mount_points( |
| 92 fileapi::ExternalMountPoints::CreateRefCounted()); |
| 93 |
| 94 scoped_refptr<fileapi::ExternalMountPoints> system_mount_points( |
| 95 fileapi::ExternalMountPoints::CreateRefCounted()); |
| 96 |
| 97 chromeos::CrosMountPointProvider provider( |
| 98 storage_policy, |
| 99 mount_points.get(), |
| 100 system_mount_points.get()); |
| 101 |
| 102 // A provider that shares system_mount_points with |provider|. |
| 103 chromeos::CrosMountPointProvider sibling_provider( |
| 104 storage_policy, |
| 105 sibling_mount_points.get(), |
| 106 system_mount_points.get()); |
| 107 |
| 108 FilePath ignored; |
| 109 |
| 110 // Adding empty mount point should fail. |
| 111 EXPECT_FALSE(provider.AddLocalMountPoint(FilePath())); |
| 112 |
| 113 // Add mount point to the provider. |
| 114 EXPECT_TRUE(provider.AddLocalMountPoint(FilePath(FPL("/a/b/c")))); |
| 115 |
| 116 EXPECT_TRUE(provider.HasMountPoint(FilePath(FPL("/a/b/c")))); |
| 117 // The mount point with the same name exists, but path is different. |
| 118 EXPECT_FALSE(provider.HasMountPoint(FilePath(FPL("/x/a/b/c")))); |
| 119 EXPECT_FALSE(sibling_provider.HasMountPoint(FilePath(FPL("/a/b/c")))); |
| 120 EXPECT_TRUE(mount_points->GetRegisteredPath("c", &ignored)); |
| 121 EXPECT_FALSE(system_mount_points->GetRegisteredPath("c", &ignored)); |
| 122 |
| 123 // Add mount point directly to |mount_points|. It should be seen by |
| 124 // |provider|. |
| 125 EXPECT_TRUE(mount_points->RegisterFileSystem( |
| 126 "d", fileapi::kFileSystemTypeNativeLocal, FilePath(FPL("/b/c/d")))); |
| 127 |
| 128 EXPECT_TRUE(provider.HasMountPoint(FilePath(FPL("/b/c/d")))); |
| 129 EXPECT_FALSE(sibling_provider.HasMountPoint(FilePath(FPL("/b/c/d")))); |
| 130 |
| 131 // Add mount point to system mount points. |
| 132 EXPECT_TRUE(system_mount_points->RegisterFileSystem( |
| 133 "e", fileapi::kFileSystemTypeNativeLocal, FilePath(FPL("/g/c/d/e")))); |
| 134 |
| 135 EXPECT_FALSE(provider.HasMountPoint(FilePath(FPL("/g/c/d/e")))); |
| 136 EXPECT_FALSE(sibling_provider.HasMountPoint(FilePath(FPL("/g/c/d/e")))); |
| 137 |
| 138 // Can't remove system mount point. |
| 139 provider.RemoveMountPoint(FilePath(FPL("/g/c/d/e"))); |
| 140 EXPECT_TRUE(system_mount_points->GetRegisteredPath("e", &ignored)); |
| 141 |
| 142 // Add a mount points whose paths overlap with the system one's. |
| 143 // The same path: |
| 144 EXPECT_TRUE(provider.AddLocalMountPoint(FilePath(FPL("/g/c/d/e")))); |
| 145 EXPECT_TRUE(provider.HasMountPoint(FilePath(FPL("/g/c/d/e")))); |
| 146 provider.RemoveMountPoint(FilePath(FPL("/g/c/d/e"))); |
| 147 EXPECT_FALSE(provider.HasMountPoint(FilePath(FPL("/g/c/d/e")))); |
| 148 // Parent path: |
| 149 EXPECT_TRUE(provider.AddLocalMountPoint(FilePath(FPL("/g")))); |
| 150 EXPECT_TRUE(provider.HasMountPoint(FilePath(FPL("/g")))); |
| 151 provider.RemoveMountPoint(FilePath(FPL("/g"))); |
| 152 // Child path: |
| 153 EXPECT_TRUE(provider.AddLocalMountPoint(FilePath(FPL("/g/c/d/e/f/g")))); |
| 154 EXPECT_TRUE(provider.HasMountPoint(FilePath(FPL("/g/c/d/e/f/g")))); |
| 155 provider.RemoveMountPoint(FilePath(FPL("/g/c/d/e/f/g"))); |
| 156 |
| 157 // Add mount point with the same name as a global one. Should succeed. |
| 158 EXPECT_TRUE(provider.AddLocalMountPoint(FilePath(FPL("/d/e")))); |
| 159 |
| 160 EXPECT_TRUE(provider.HasMountPoint(FilePath(FPL("/d/e")))); |
| 161 |
| 162 // Remove system mount point with the same name as the added one. |
| 163 // Should fail. |
| 164 provider.RemoveMountPoint(FilePath(FPL("/g/c/d/e"))); |
| 165 |
| 166 EXPECT_TRUE(provider.HasMountPoint(FilePath(FPL("/d/e")))); |
| 167 EXPECT_TRUE(system_mount_points->GetRegisteredPath("e", &ignored)); |
| 168 |
| 169 // Remove mount point. |
| 170 provider.RemoveMountPoint(FilePath(FPL("/d/e"))); |
| 171 |
| 172 EXPECT_FALSE(provider.HasMountPoint(FilePath(FPL("/d/e")))); |
| 173 } |
| 174 |
| 175 TEST(CrosMountPointProviderTest, AccessPermissions) { |
| 176 url_util::AddStandardScheme("chrome-extension"); |
| 177 |
| 178 scoped_refptr<quota::MockSpecialStoragePolicy> storage_policy = |
| 179 new quota::MockSpecialStoragePolicy(); |
| 180 scoped_refptr<fileapi::ExternalMountPoints> mount_points( |
| 181 fileapi::ExternalMountPoints::CreateRefCounted()); |
| 182 scoped_refptr<fileapi::ExternalMountPoints> system_mount_points( |
| 183 fileapi::ExternalMountPoints::CreateRefCounted()); |
| 184 chromeos::CrosMountPointProvider provider( |
| 185 storage_policy, |
| 186 mount_points.get(), |
| 187 system_mount_points.get()); |
| 188 |
| 189 std::string extension("ddammdhioacbehjngdmkjcjbnfginlla"); |
| 190 |
| 191 storage_policy->AddFileHandler(extension); |
| 192 |
| 193 // Initialize mount points. |
| 194 system_mount_points->RegisterFileSystem("system", |
| 195 fileapi::kFileSystemTypeNativeLocal, |
| 196 FilePath(FPL("/g/system"))); |
| 197 ASSERT_TRUE(provider.AddLocalMountPoint(FilePath(FPL("/media/removable")))); |
| 198 ASSERT_TRUE(provider.AddRestrictedLocalMountPoint( |
| 199 FilePath(FPL("/usr/share/oem")))); |
| 200 |
| 201 // Provider specific mount point access. |
| 202 EXPECT_FALSE(provider.IsAccessAllowed( |
| 203 CreateFileSystemURL(extension, "removable/foo"))); |
| 204 |
| 205 provider.GrantFileAccessToExtension(extension, |
| 206 FilePath(FPL("removable/foo"))); |
| 207 EXPECT_TRUE(provider.IsAccessAllowed( |
| 208 CreateFileSystemURL(extension, "removable/foo"))); |
| 209 EXPECT_FALSE(provider.IsAccessAllowed( |
| 210 CreateFileSystemURL(extension, "removable/foo1"))); |
| 211 |
| 212 // System mount point access. |
| 213 EXPECT_FALSE(provider.IsAccessAllowed( |
| 214 CreateFileSystemURL(extension, "system/foo"))); |
| 215 |
| 216 provider.GrantFileAccessToExtension(extension, FilePath(FPL("system/foo"))); |
| 217 EXPECT_TRUE(provider.IsAccessAllowed( |
| 218 CreateFileSystemURL(extension, "system/foo"))); |
| 219 EXPECT_FALSE(provider.IsAccessAllowed( |
| 220 CreateFileSystemURL(extension, "system/foo1"))); |
| 221 |
| 222 // oem is restricted file system. |
| 223 provider.GrantFileAccessToExtension(extension, FilePath(FPL("oem/foo"))); |
| 224 // The extension should not be able to access the file even if |
| 225 // GrantFileAccessToExtension was called. |
| 226 EXPECT_FALSE(provider.IsAccessAllowed( |
| 227 CreateFileSystemURL(extension, "oem/foo"))); |
| 228 |
| 229 provider.GrantFullAccessToExtension(extension); |
| 230 // The extension should be able to access restricted file system after it was |
| 231 // granted full access. |
| 232 EXPECT_TRUE(provider.IsAccessAllowed( |
| 233 CreateFileSystemURL(extension, "oem/foo"))); |
| 234 // The extension which was granted full access should be able to access any |
| 235 // path on current file systems. |
| 236 EXPECT_TRUE(provider.IsAccessAllowed( |
| 237 CreateFileSystemURL(extension, "removable/foo1"))); |
| 238 EXPECT_TRUE(provider.IsAccessAllowed( |
| 239 CreateFileSystemURL(extension, "system/foo1"))); |
| 240 |
| 241 // The extension still cannot access new mount points. |
| 242 ASSERT_TRUE(provider.AddLocalMountPoint(FilePath(FPL("/foo/test")))); |
| 243 EXPECT_FALSE(provider.IsAccessAllowed( |
| 244 CreateFileSystemURL(extension, "test_/foo"))); |
| 245 |
| 246 provider.RevokeAccessForExtension(extension); |
| 247 EXPECT_FALSE(provider.IsAccessAllowed( |
| 248 CreateFileSystemURL(extension, "removable/foo"))); |
| 249 |
| 250 fileapi::FileSystemURL internal_url(GURL("chrome://foo"), |
| 251 fileapi::kFileSystemTypeExternal, |
| 252 FilePath(FPL("removable/"))); |
| 253 // Internal WebUI should have full access. |
| 254 EXPECT_TRUE(provider.IsAccessAllowed(internal_url)); |
| 255 } |
| 256 |
| 257 TEST(CrosMountPointProvider, GetVirtualPathConflictWithSystemPoints) { |
| 258 scoped_refptr<quota::MockSpecialStoragePolicy> storage_policy = |
| 259 new quota::MockSpecialStoragePolicy(); |
| 260 scoped_refptr<fileapi::ExternalMountPoints> mount_points( |
| 261 fileapi::ExternalMountPoints::CreateRefCounted()); |
| 262 scoped_refptr<fileapi::ExternalMountPoints> system_mount_points( |
| 263 fileapi::ExternalMountPoints::CreateRefCounted()); |
| 264 chromeos::CrosMountPointProvider provider(storage_policy, |
| 265 mount_points.get(), |
| 266 system_mount_points.get()); |
| 267 |
| 268 const fileapi::FileSystemType type = fileapi::kFileSystemTypeNativeLocal; |
| 269 |
| 270 // Provider specific mount points. |
| 271 ASSERT_TRUE( |
| 272 mount_points->RegisterFileSystem("b", type, FilePath(FPL("/a/b")))); |
| 273 ASSERT_TRUE( |
| 274 mount_points->RegisterFileSystem("y", type, FilePath(FPL("/z/y")))); |
| 275 ASSERT_TRUE( |
| 276 mount_points->RegisterFileSystem("n", type, FilePath(FPL("/m/n")))); |
| 277 |
| 278 // System mount points |
| 279 ASSERT_TRUE(system_mount_points->RegisterFileSystem( |
| 280 "gb", type, FilePath(FPL("/a/b")))); |
| 281 ASSERT_TRUE( |
| 282 system_mount_points->RegisterFileSystem("gz", type, FilePath(FPL("/z")))); |
| 283 ASSERT_TRUE(system_mount_points->RegisterFileSystem( |
| 284 "gp", type, FilePath(FPL("/m/n/o/p")))); |
| 285 |
| 286 struct TestCase { |
| 287 const FilePath::CharType* const local_path; |
| 288 bool success; |
| 289 const FilePath::CharType* const virtual_path; |
| 290 }; |
| 291 |
| 292 const TestCase kTestCases[] = { |
| 293 // Same paths in both mount points. |
| 294 { FPL("/a/b/c/d"), true, FPL("b/c/d") }, |
| 295 // System mount points path more specific. |
| 296 { FPL("/m/n/o/p/r/s"), true, FPL("n/o/p/r/s") }, |
| 297 // System mount points path less specific. |
| 298 { FPL("/z/y/x"), true, FPL("y/x") }, |
| 299 // Only system mount points path matches. |
| 300 { FPL("/z/q/r/s"), true, FPL("gz/q/r/s") }, |
| 301 // No match. |
| 302 { FPL("/foo/xxx"), false, FPL("") }, |
| 303 }; |
| 304 |
| 305 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) { |
| 306 // Initialize virtual path with a value. |
| 307 FilePath virtual_path(FPL("/mount")); |
| 308 FilePath local_path(kTestCases[i].local_path); |
| 309 EXPECT_EQ(kTestCases[i].success, |
| 310 provider.GetVirtualPath(local_path, &virtual_path)) |
| 311 << "Resolving " << kTestCases[i].local_path; |
| 312 |
| 313 // There are no guarantees for |virtual_path| value if |GetVirtualPath| |
| 314 // fails. |
| 315 if (!kTestCases[i].success) |
| 316 continue; |
| 317 |
| 318 FilePath expected_virtual_path(kTestCases[i].virtual_path); |
| 319 EXPECT_EQ(expected_virtual_path, virtual_path) |
| 320 << "Resolving " << kTestCases[i].local_path; |
| 321 } |
| 322 } |
| 323 |
| 324 } // namespace |
| 325 |
OLD | NEW |