summaryrefslogtreecommitdiffstats
path: root/webkit/chromeos
diff options
context:
space:
mode:
authorzelidrag@chromium.org <zelidrag@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-16 04:01:08 +0000
committerzelidrag@chromium.org <zelidrag@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-16 04:01:08 +0000
commitb777b3386e10d38944cc717e4192b7858cbdc7fe (patch)
tree85d37a15e729df855d81e0973d9ed1bb3f90d347 /webkit/chromeos
parent4b59a325a589190ab95622be4e1b6a70bc02914f (diff)
downloadchromium_src-b777b3386e10d38944cc717e4192b7858cbdc7fe.zip
chromium_src-b777b3386e10d38944cc717e4192b7858cbdc7fe.tar.gz
chromium_src-b777b3386e10d38944cc717e4192b7858cbdc7fe.tar.bz2
File API changes needed for safely passing user selected file entities from the file browser component extension to a 3rd party extension.
BUG=chromium-os:11996 TEST=FileAccessPermissionsTest.FileAccessChecks Review URL: http://codereview.chromium.org/6810037 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@81860 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/chromeos')
-rw-r--r--webkit/chromeos/fileapi/cros_mount_point_provider.cc88
-rw-r--r--webkit/chromeos/fileapi/cros_mount_point_provider.h31
-rw-r--r--webkit/chromeos/fileapi/file_access_permissions.cc58
-rw-r--r--webkit/chromeos/fileapi/file_access_permissions.h44
-rw-r--r--webkit/chromeos/fileapi/file_access_permissions_unittest.cc67
5 files changed, 245 insertions, 43 deletions
diff --git a/webkit/chromeos/fileapi/cros_mount_point_provider.cc b/webkit/chromeos/fileapi/cros_mount_point_provider.cc
index 159dc3b..9efc5cc 100644
--- a/webkit/chromeos/fileapi/cros_mount_point_provider.cc
+++ b/webkit/chromeos/fileapi/cros_mount_point_provider.cc
@@ -14,14 +14,13 @@
#include "third_party/WebKit/Source/WebKit/chromium/public/WebCString.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFileSystem.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
+#include "webkit/chromeos/fileapi/file_access_permissions.h"
#include "webkit/fileapi/file_system_path_manager.h"
+#include "webkit/fileapi/file_system_util.h"
#include "webkit/glue/webkit_glue.h"
namespace chromeos {
-const char CrosMountPointProvider::kLocalName[] = "Local";
-const char CrosMountPointProvider::kLocalDirName[] = "/local/";
-
typedef struct {
const char* local_root_path;
const char* web_root_path;
@@ -36,28 +35,12 @@ FixedExposedPaths fixed_exposed_paths[] = {
CrosMountPointProvider::CrosMountPointProvider(
scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy)
- : local_dir_name_(kLocalName),
- special_storage_policy_(special_storage_policy) {
-
- // TODO(zelidrag): There's got to be a better way to generate UUID.
- srand(time(NULL));
- std::string virtual_root;
- virtual_root.append(base::StringPrintf("%hx%hx-%hx-%hx-%hx-%hx%hx%hx",
- static_cast<unsigned short>(rand()), static_cast<unsigned short>(rand()),
- static_cast<unsigned short>(rand()),
- static_cast<unsigned short>(rand()),
- static_cast<unsigned short>(rand()),
- static_cast<unsigned short>(rand()), static_cast<unsigned short>(rand()),
- static_cast<unsigned short>(rand())));
-
- // Create virtual root node.
- virtual_root_path_ = FilePath(virtual_root);
- base_path_ = virtual_root_path_.Append(local_dir_name_);
-
+ : special_storage_policy_(special_storage_policy),
+ file_access_permissions_(new FileAccessPermissions()) {
for (size_t i = 0; i < arraysize(fixed_exposed_paths); i++) {
- mount_point_map_.insert(std::pair<std::string, std::string>(
+ mount_point_map_.insert(std::pair<std::string, FilePath>(
std::string(fixed_exposed_paths[i].web_root_path),
- std::string(fixed_exposed_paths[i].local_root_path)));
+ FilePath(std::string(fixed_exposed_paths[i].local_root_path))));
}
}
@@ -77,13 +60,13 @@ void CrosMountPointProvider::GetFileSystemRootPath(
fileapi::FileSystemType type,
bool create,
fileapi::FileSystemPathManager::GetRootPathCallback* callback_ptr) {
- DCHECK(type == fileapi::kFileSystemTypeLocal);
+ DCHECK(type == fileapi::kFileSystemTypeExternal);
std::string name(GetOriginIdentifierFromURL(origin_url));
name += ':';
- name += CrosMountPointProvider::kLocalName;
+ name += fileapi::kExternalName;
- FilePath root_path = FilePath(CrosMountPointProvider::kLocalDirName);
+ FilePath root_path = FilePath(fileapi::kExternalDir);
callback_ptr->Run(!root_path.empty(), root_path, name);
}
@@ -94,7 +77,7 @@ FilePath CrosMountPointProvider::GetFileSystemRootPathOnFileThread(
fileapi::FileSystemType type,
const FilePath& virtual_path,
bool create) {
- DCHECK(type == fileapi::kFileSystemTypeLocal);
+ DCHECK(type == fileapi::kFileSystemTypeExternal);
std::vector<FilePath::StringType> components;
virtual_path.GetComponents(&components);
@@ -108,7 +91,7 @@ FilePath CrosMountPointProvider::GetFileSystemRootPathOnFileThread(
return FilePath();
}
- return FilePath(iter->second);
+ return iter->second;
}
// TODO(zelidrag): Share this code with SandboxMountPointProvider impl.
@@ -116,8 +99,53 @@ bool CrosMountPointProvider::IsRestrictedFileName(const FilePath& path) const {
return false;
}
-bool CrosMountPointProvider::IsAccessAllowed(const GURL& origin_url) {
- return special_storage_policy_->IsLocalFileSystemAccessAllowed(origin_url);
+bool CrosMountPointProvider::IsAccessAllowed(const GURL& origin_url,
+ fileapi::FileSystemType type,
+ const FilePath& virtual_path) {
+ if (type != fileapi::kFileSystemTypeExternal)
+ return false;
+ std::string extension_id = origin_url.host();
+ // Check first to make sure this extension has fileBrowserHander permissions.
+ if (!special_storage_policy_->IsFileHandler(extension_id))
+ return false;
+ return file_access_permissions_->HasAccessPermission(extension_id,
+ virtual_path);
+}
+
+void CrosMountPointProvider::GrantFullAccessToExtension(
+ const std::string& extension_id) {
+ DCHECK(special_storage_policy_->IsFileHandler(extension_id));
+ if (!special_storage_policy_->IsFileHandler(extension_id))
+ return;
+ for (MountPointMap::const_iterator iter = mount_point_map_.begin();
+ iter != mount_point_map_.end();
+ ++iter) {
+ GrantFileAccessToExtension(extension_id, FilePath(iter->first));
+ }
+}
+
+void CrosMountPointProvider::GrantFileAccessToExtension(
+ const std::string& extension_id, const FilePath& virtual_path) {
+ // All we care about here is access from extensions for now.
+ DCHECK(special_storage_policy_->IsFileHandler(extension_id));
+ if (!special_storage_policy_->IsFileHandler(extension_id))
+ return;
+ file_access_permissions_->GrantAccessPermission(extension_id, virtual_path);
+}
+
+void CrosMountPointProvider::RevokeAccessForExtension(
+ const std::string& extension_id) {
+ file_access_permissions_->RevokePermissions(extension_id);
+}
+
+std::vector<FilePath> CrosMountPointProvider::GetRootDirectories() const {
+ std::vector<FilePath> root_dirs;
+ for (MountPointMap::const_iterator iter = mount_point_map_.begin();
+ iter != mount_point_map_.end();
+ ++iter) {
+ root_dirs.push_back(iter->second.Append(iter->first));
+ }
+ return root_dirs;
}
} // namespace chromeos
diff --git a/webkit/chromeos/fileapi/cros_mount_point_provider.h b/webkit/chromeos/fileapi/cros_mount_point_provider.h
index 5ac8f37..23af15f 100644
--- a/webkit/chromeos/fileapi/cros_mount_point_provider.h
+++ b/webkit/chromeos/fileapi/cros_mount_point_provider.h
@@ -6,51 +6,56 @@
#define WEBKIT_CHROMEOS_FILEAPI_CROS_MOUNT_POINT_PROVIDER_H_
#include <map>
-#include <set>
#include <string>
+#include <vector>
+#include "base/file_path.h"
#include "webkit/fileapi/file_system_mount_point_provider.h"
#include "webkit/quota/special_storage_policy.h"
namespace chromeos {
+class FileAccessPermissions;
+
// An interface to provide local filesystem paths.
class CrosMountPointProvider
- : public fileapi::FileSystemMountPointProvider {
+ : public fileapi::ExternalFileSystemMountPointProvider {
public:
CrosMountPointProvider(
scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy);
virtual ~CrosMountPointProvider();
// fileapi::FileSystemMountPointProvider overrides.
- virtual bool IsAccessAllowed(const GURL& origin_url) OVERRIDE;
-
+ virtual bool IsAccessAllowed(const GURL& origin_url,
+ fileapi::FileSystemType type,
+ const FilePath& virtual_path) OVERRIDE;
virtual void GetFileSystemRootPath(
const GURL& origin_url,
fileapi::FileSystemType type,
bool create,
fileapi::FileSystemPathManager::GetRootPathCallback* callback) OVERRIDE;
-
virtual FilePath GetFileSystemRootPathOnFileThread(
const GURL& origin_url,
fileapi::FileSystemType type,
const FilePath& virtual_path,
bool create);
-
virtual bool IsRestrictedFileName(const FilePath& filename) const OVERRIDE;
+ virtual std::vector<FilePath> GetRootDirectories() const OVERRIDE;
+
+ // fileapi::ExternalFileSystemMountPointProvider overrides.
+ virtual void GrantFullAccessToExtension(
+ const std::string& extension_id) OVERRIDE;
+ virtual void GrantFileAccessToExtension(
+ const std::string& extension_id, const FilePath& virtual_path) OVERRIDE;
+ void RevokeAccessForExtension(const std::string& extension_id) OVERRIDE;
private:
class GetFileSystemRootPathTask;
- typedef std::map<std::string, std::string> MountPointMap;
+ typedef std::map<std::string, FilePath> MountPointMap;
- static const char kLocalDirName[];
- static const char kLocalName[];
- FilePath virtual_root_path_;
- FilePath base_path_;
- std::string local_dir_name_;
MountPointMap mount_point_map_;
scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy_;
-
+ scoped_ptr<FileAccessPermissions> file_access_permissions_;
DISALLOW_COPY_AND_ASSIGN(CrosMountPointProvider);
};
diff --git a/webkit/chromeos/fileapi/file_access_permissions.cc b/webkit/chromeos/fileapi/file_access_permissions.cc
new file mode 100644
index 0000000..6ab5a04
--- /dev/null
+++ b/webkit/chromeos/fileapi/file_access_permissions.cc
@@ -0,0 +1,58 @@
+// Copyright (c) 2011 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 "webkit/chromeos/fileapi/file_access_permissions.h"
+
+#include "base/command_line.h"
+#include "base/logging.h"
+
+namespace chromeos {
+
+FileAccessPermissions::FileAccessPermissions() {}
+
+FileAccessPermissions::~FileAccessPermissions() {}
+
+
+void FileAccessPermissions::GrantAccessPermission(
+ const std::string& extension_id, const FilePath& path) {
+ base::AutoLock locker(lock_);
+ PathAccessMap::iterator path_map_iter = path_map_.find(extension_id);
+ if (path_map_iter == path_map_.end()) {
+ PathSet path_set;
+ path_set.insert(path);
+ path_map_.insert(PathAccessMap::value_type(extension_id, path_set));
+ } else {
+ if (path_map_iter->second.find(path) != path_map_iter->second.end())
+ return;
+ path_map_iter->second.insert(path);
+ }
+}
+
+bool FileAccessPermissions::HasAccessPermission(
+ const std::string& extension_id, const FilePath& path) {
+ base::AutoLock locker(lock_);
+ PathAccessMap::const_iterator path_map_iter = path_map_.find(extension_id);
+ if (path_map_iter == path_map_.end())
+ return false;
+
+ // Check this file and walk up its directory tree to find if this extension
+ // has access to it.
+ FilePath current_path = path.StripTrailingSeparators();
+ FilePath last_path;
+ while (current_path != last_path) {
+ if (path_map_iter->second.find(current_path) != path_map_iter->second.end())
+ return true;
+ last_path = current_path;
+ current_path = current_path.DirName();
+ }
+ return false;
+}
+
+void FileAccessPermissions::RevokePermissions(
+ const std::string& extension_id) {
+ base::AutoLock locker(lock_);
+ path_map_.erase(extension_id);
+}
+
+}
diff --git a/webkit/chromeos/fileapi/file_access_permissions.h b/webkit/chromeos/fileapi/file_access_permissions.h
new file mode 100644
index 0000000..e946634
--- /dev/null
+++ b/webkit/chromeos/fileapi/file_access_permissions.h
@@ -0,0 +1,44 @@
+// Copyright (c) 2011 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.
+
+#ifndef WEBKIT_CHROMEOS_FILEAPI_FILE_ACCESS_PERMISSIONS_H_
+#define WEBKIT_CHROMEOS_FILEAPI_FILE_ACCESS_PERMISSIONS_H_
+#pragma once
+
+#include <map>
+#include <set>
+#include <string>
+
+#include "base/file_path.h"
+#include "base/synchronization/lock.h"
+
+class Extension;
+
+namespace chromeos {
+
+class FileAccessPermissions {
+ public:
+ FileAccessPermissions();
+ virtual ~FileAccessPermissions();
+
+ // Grants |extension_id| access to |path|.
+ void GrantAccessPermission(const std::string& extension_id,
+ const FilePath& path);
+ // Checks id |extension_id| has permission to access to |path|.
+ bool HasAccessPermission(const std::string& extension_id,
+ const FilePath& path);
+ // Revokes all file permissions for |extension_id|.
+ void RevokePermissions(const std::string& extension_id);
+
+ private:
+ typedef std::set<FilePath> PathSet;
+ typedef std::map<std::string, PathSet> PathAccessMap;
+
+ base::Lock lock_; // Synchronize all access to path_map_.
+ PathAccessMap path_map_;
+};
+
+};
+
+#endif // WEBKIT_CHROMEOS_FILEAPI_FILE_ACCESS_PERMISSIONS_H_
diff --git a/webkit/chromeos/fileapi/file_access_permissions_unittest.cc b/webkit/chromeos/fileapi/file_access_permissions_unittest.cc
new file mode 100644
index 0000000..b3efbfe
--- /dev/null
+++ b/webkit/chromeos/fileapi/file_access_permissions_unittest.cc
@@ -0,0 +1,67 @@
+// Copyright (c) 2011 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 "webkit/chromeos/fileapi/file_access_permissions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+
+class FileAccessPermissionsTest : public testing::Test {
+};
+
+TEST_F(FileAccessPermissionsTest, FileAccessChecks) {
+#if defined(OS_WIN)
+ FilePath good_dir(FILE_PATH_LITERAL("c:\\root\\dir"));
+ FilePath bad_dir(FILE_PATH_LITERAL("c:\\root"));
+ FilePath good_file(FILE_PATH_LITERAL("c:\\root\\dir\\good_file.txt"));
+ FilePath bad_file(FILE_PATH_LITERAL("c:\\root\\dir\\bad_file.txt"));
+#elif defined(OS_POSIX)
+ FilePath good_dir(FILE_PATH_LITERAL("/root/dir"));
+ FilePath bad_dir(FILE_PATH_LITERAL("/root"));
+ FilePath good_file(FILE_PATH_LITERAL("/root/dir/good_file.txt"));
+ FilePath bad_file(FILE_PATH_LITERAL("/root/dir/bad_file.txt"));
+#endif
+ std::string extension1("ddammdhioacbehjngdmkjcjbnfginlla");
+ std::string extension2("jkhdjkhkhsdkfhsdkhrterwmtermeter");
+
+ chromeos::FileAccessPermissions permissions;
+ // By default extension have no access to any local file.
+ EXPECT_FALSE(permissions.HasAccessPermission(extension1, good_dir));
+ EXPECT_FALSE(permissions.HasAccessPermission(extension1, good_file));
+ EXPECT_FALSE(permissions.HasAccessPermission(extension1, bad_file));
+ EXPECT_FALSE(permissions.HasAccessPermission(extension2, good_dir));
+ EXPECT_FALSE(permissions.HasAccessPermission(extension2, good_file));
+ EXPECT_FALSE(permissions.HasAccessPermission(extension2, bad_file));
+
+ // After granting file access to the handler extension for a given file, it
+ // can only access that file an nothing else.
+ permissions.GrantAccessPermission(extension1, good_file);
+ EXPECT_FALSE(permissions.HasAccessPermission(extension1, good_dir));
+ EXPECT_TRUE(permissions.HasAccessPermission(extension1, good_file));
+ EXPECT_FALSE(permissions.HasAccessPermission(extension1, bad_file));
+ EXPECT_FALSE(permissions.HasAccessPermission(extension2, good_dir));
+ EXPECT_FALSE(permissions.HasAccessPermission(extension2, good_file));
+ EXPECT_FALSE(permissions.HasAccessPermission(extension2, bad_file));
+
+
+ // After granting file access to the handler extension for a given directory,
+ // it can access that directory and all files within it.
+ permissions.GrantAccessPermission(extension2, good_dir);
+ EXPECT_FALSE(permissions.HasAccessPermission(extension1, good_dir));
+ EXPECT_TRUE(permissions.HasAccessPermission(extension1, good_file));
+ EXPECT_FALSE(permissions.HasAccessPermission(extension1, bad_file));
+ EXPECT_FALSE(permissions.HasAccessPermission(extension2, good_dir));
+ EXPECT_FALSE(permissions.HasAccessPermission(extension2, good_file));
+ EXPECT_FALSE(permissions.HasAccessPermission(extension2, bad_file));
+
+ // After revoking rights for extensions, they should not be able to access
+ // any file system element anymore.
+ permissions.RevokePermissions(extension1);
+ permissions.RevokePermissions(extension2);
+ EXPECT_FALSE(permissions.HasAccessPermission(extension1, good_dir));
+ EXPECT_FALSE(permissions.HasAccessPermission(extension1, good_file));
+ EXPECT_FALSE(permissions.HasAccessPermission(extension1, bad_file));
+ EXPECT_FALSE(permissions.HasAccessPermission(extension2, good_dir));
+ EXPECT_FALSE(permissions.HasAccessPermission(extension2, good_file));
+ EXPECT_FALSE(permissions.HasAccessPermission(extension2, bad_file));
+}