1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
57dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chromeos/fileapi/file_system_backend.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <set>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/path_service.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chromeos/dbus/cros_disks_client.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/url_util.h"
1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/external_mount_points.h"
1590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_system_url.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/quota/mock_special_storage_policy.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define FPL(x) FILE_PATH_LITERAL(x)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using fileapi::ExternalMountPoints;
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using fileapi::FileSystemURL;
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace {
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FileSystemURL CreateFileSystemURL(const std::string& extension,
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  const char* path,
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  ExternalMountPoints* mount_points) {
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return mount_points->CreateCrackedFileSystemURL(
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GURL("chrome-extension://" + extension + "/"),
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fileapi::kFileSystemTypeExternal,
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath::FromUTF8Unsafe(path));
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
347dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochTEST(ChromeOSFileSystemBackendTest, DefaultMountPoints) {
35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Make sure no system-level mount points are registered before testing
36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // to avoid flakiness.
37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  fileapi::ExternalMountPoints::GetSystemInstance()->RevokeAllFileSystems();
38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<quota::SpecialStoragePolicy> storage_policy =
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new quota::MockSpecialStoragePolicy();
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<fileapi::ExternalMountPoints> mount_points(
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fileapi::ExternalMountPoints::CreateRefCounted());
437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  chromeos::FileSystemBackend backend(
447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      NULL,  // drive_delegate
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      storage_policy,
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      mount_points.get(),
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fileapi::ExternalMountPoints::GetSystemInstance());
487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  backend.AddSystemMountPoints();
497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::vector<base::FilePath> root_dirs = backend.GetRootDirectories();
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::set<base::FilePath> root_dirs_set(root_dirs.begin(), root_dirs.end());
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // By default there should be 3 mount points (in system mount points):
530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_EQ(3u, root_dirs.size());
54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(root_dirs_set.count(
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      chromeos::CrosDisksClient::GetRemovableDiskMountPoint()));
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(root_dirs_set.count(
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      chromeos::CrosDisksClient::GetArchiveMountPoint()));
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(root_dirs_set.count(base::FilePath(FPL("/usr/share/oem"))));
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
627dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochTEST(ChromeOSFileSystemBackendTest, GetRootDirectories) {
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<quota::SpecialStoragePolicy> storage_policy =
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new quota::MockSpecialStoragePolicy();
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<fileapi::ExternalMountPoints> mount_points(
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fileapi::ExternalMountPoints::CreateRefCounted());
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<fileapi::ExternalMountPoints> system_mount_points(
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fileapi::ExternalMountPoints::CreateRefCounted());
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  chromeos::FileSystemBackend backend(
727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      NULL,  // drive_delegate
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      storage_policy,
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      mount_points.get(),
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      system_mount_points.get());
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  const size_t initial_root_dirs_size = backend.GetRootDirectories().size();
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Register 'local' test mount points.
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mount_points->RegisterFileSystem("c",
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   fileapi::kFileSystemTypeNativeLocal,
82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                   fileapi::FileSystemMountOption(),
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   base::FilePath(FPL("/a/b/c")));
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mount_points->RegisterFileSystem("d",
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   fileapi::kFileSystemTypeNativeLocal,
86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                   fileapi::FileSystemMountOption(),
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   base::FilePath(FPL("/b/c/d")));
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Register system test mount points.
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  system_mount_points->RegisterFileSystem("d",
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          fileapi::kFileSystemTypeNativeLocal,
92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                          fileapi::FileSystemMountOption(),
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          base::FilePath(FPL("/g/c/d")));
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  system_mount_points->RegisterFileSystem("e",
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          fileapi::kFileSystemTypeNativeLocal,
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                          fileapi::FileSystemMountOption(),
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                          base::FilePath(FPL("/g/d/e")));
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  std::vector<base::FilePath> root_dirs = backend.GetRootDirectories();
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::set<base::FilePath> root_dirs_set(root_dirs.begin(), root_dirs.end());
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(initial_root_dirs_size + 4, root_dirs.size());
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(root_dirs_set.count(base::FilePath(FPL("/a/b/c"))));
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(root_dirs_set.count(base::FilePath(FPL("/b/c/d"))));
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(root_dirs_set.count(base::FilePath(FPL("/g/c/d"))));
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(root_dirs_set.count(base::FilePath(FPL("/g/d/e"))));
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1087dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochTEST(ChromeOSFileSystemBackendTest, AccessPermissions) {
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  url_util::AddStandardScheme("chrome-extension");
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<quota::MockSpecialStoragePolicy> storage_policy =
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new quota::MockSpecialStoragePolicy();
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<fileapi::ExternalMountPoints> mount_points(
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fileapi::ExternalMountPoints::CreateRefCounted());
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<fileapi::ExternalMountPoints> system_mount_points(
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fileapi::ExternalMountPoints::CreateRefCounted());
1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  chromeos::FileSystemBackend backend(
1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      NULL,  // drive_delegate
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      storage_policy,
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      mount_points.get(),
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      system_mount_points.get());
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string extension("ddammdhioacbehjngdmkjcjbnfginlla");
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  storage_policy->AddFileHandler(extension);
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Initialize mount points.
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(system_mount_points->RegisterFileSystem(
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "system",
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fileapi::kFileSystemTypeNativeLocal,
131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      fileapi::FileSystemMountOption(),
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath(FPL("/g/system"))));
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(mount_points->RegisterFileSystem(
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "removable",
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fileapi::kFileSystemTypeNativeLocal,
136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      fileapi::FileSystemMountOption(),
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath(FPL("/media/removable"))));
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(mount_points->RegisterFileSystem(
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "oem",
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fileapi::kFileSystemTypeRestrictedNativeLocal,
141a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      fileapi::FileSystemMountOption(),
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath(FPL("/usr/share/oem"))));
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Backend specific mount point access.
1457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(backend.IsAccessAllowed(
146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CreateFileSystemURL(extension, "removable/foo", mount_points.get())));
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  backend.GrantFileAccessToExtension(extension,
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      base::FilePath(FPL("removable/foo")));
1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(backend.IsAccessAllowed(
151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CreateFileSystemURL(extension, "removable/foo", mount_points.get())));
1527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(backend.IsAccessAllowed(
153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CreateFileSystemURL(extension, "removable/foo1", mount_points.get())));
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // System mount point access.
1567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(backend.IsAccessAllowed(
157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CreateFileSystemURL(extension, "system/foo", system_mount_points.get())));
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  backend.GrantFileAccessToExtension(extension,
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      base::FilePath(FPL("system/foo")));
1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(backend.IsAccessAllowed(
162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CreateFileSystemURL(extension, "system/foo", system_mount_points.get())));
1637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(backend.IsAccessAllowed(
164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CreateFileSystemURL(extension, "system/foo1",
165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                          system_mount_points.get())));
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // oem is restricted file system.
1687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  backend.GrantFileAccessToExtension(
16990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      extension, base::FilePath(FPL("oem/foo")));
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The extension should not be able to access the file even if
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // GrantFileAccessToExtension was called.
1727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(backend.IsAccessAllowed(
173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CreateFileSystemURL(extension, "oem/foo", mount_points.get())));
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  backend.GrantFullAccessToExtension(extension);
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The extension should be able to access restricted file system after it was
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // granted full access.
1787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(backend.IsAccessAllowed(
179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CreateFileSystemURL(extension, "oem/foo", mount_points.get())));
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The extension which was granted full access should be able to access any
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // path on current file systems.
1827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(backend.IsAccessAllowed(
183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CreateFileSystemURL(extension, "removable/foo1", mount_points.get())));
1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(backend.IsAccessAllowed(
185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CreateFileSystemURL(extension, "system/foo1",
186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                          system_mount_points.get())));
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The extension cannot access new mount points.
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(tbarzic): This should probably be changed.
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(mount_points->RegisterFileSystem(
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      "test",
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fileapi::kFileSystemTypeNativeLocal,
193a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      fileapi::FileSystemMountOption(),
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath(FPL("/foo/test"))));
1957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(backend.IsAccessAllowed(
196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CreateFileSystemURL(extension, "test_/foo", mount_points.get())));
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  backend.RevokeAccessForExtension(extension);
1997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_FALSE(backend.IsAccessAllowed(
200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      CreateFileSystemURL(extension, "removable/foo", mount_points.get())));
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  fileapi::FileSystemURL internal_url = FileSystemURL::CreateForTest(
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      GURL("chrome://foo"),
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fileapi::kFileSystemTypeExternal,
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath(FPL("removable/")));
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Internal WebUI should have full access.
2077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  EXPECT_TRUE(backend.IsAccessAllowed(internal_url));
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochTEST(ChromeOSFileSystemBackendTest, GetVirtualPathConflictWithSystemPoints) {
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<quota::MockSpecialStoragePolicy> storage_policy =
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new quota::MockSpecialStoragePolicy();
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<fileapi::ExternalMountPoints> mount_points(
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fileapi::ExternalMountPoints::CreateRefCounted());
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_refptr<fileapi::ExternalMountPoints> system_mount_points(
2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      fileapi::ExternalMountPoints::CreateRefCounted());
2177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  chromeos::FileSystemBackend backend(
2187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      NULL,  // drive_delegate
2197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      storage_policy,
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      mount_points.get(),
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      system_mount_points.get());
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const fileapi::FileSystemType type = fileapi::kFileSystemTypeNativeLocal;
224a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  const fileapi::FileSystemMountOption option =
225a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      fileapi::FileSystemMountOption();
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Backend specific mount points.
228a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(mount_points->RegisterFileSystem(
229a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "b", type, option, base::FilePath(FPL("/a/b"))));
230a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(mount_points->RegisterFileSystem(
231a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "y", type, option, base::FilePath(FPL("/z/y"))));
232a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  ASSERT_TRUE(mount_points->RegisterFileSystem(
233a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "n", type, option, base::FilePath(FPL("/m/n"))));
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // System mount points
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(system_mount_points->RegisterFileSystem(
237a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "gb", type, option, base::FilePath(FPL("/a/b"))));
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(
23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      system_mount_points->RegisterFileSystem(
240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          "gz", type, option, base::FilePath(FPL("/z"))));
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(system_mount_points->RegisterFileSystem(
242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)       "gp", type, option, base::FilePath(FPL("/m/n/o/p"))));
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  struct TestCase {
2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath::CharType* const local_path;
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool success;
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::FilePath::CharType* const virtual_path;
2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const TestCase kTestCases[] = {
2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Same paths in both mount points.
2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { FPL("/a/b/c/d"), true, FPL("b/c/d") },
2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // System mount points path more specific.
2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { FPL("/m/n/o/p/r/s"), true, FPL("n/o/p/r/s") },
2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // System mount points path less specific.
2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { FPL("/z/y/x"), true, FPL("y/x") },
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Only system mount points path matches.
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { FPL("/z/q/r/s"), true, FPL("gz/q/r/s") },
2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // No match.
2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { FPL("/foo/xxx"), false, FPL("") },
2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) {
2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Initialize virtual path with a value.
2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath virtual_path(FPL("/mount"));
2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath local_path(kTestCases[i].local_path);
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(kTestCases[i].success,
2687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              backend.GetVirtualPath(local_path, &virtual_path))
2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "Resolving " << kTestCases[i].local_path;
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // There are no guarantees for |virtual_path| value if |GetVirtualPath|
2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // fails.
2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!kTestCases[i].success)
2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath expected_virtual_path(kTestCases[i].virtual_path);
2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    EXPECT_EQ(expected_virtual_path, virtual_path)
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        << "Resolving " << kTestCases[i].local_path;
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace
283