// 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/cros_mount_point_provider.h" #include "base/logging.h" #include "base/memory/scoped_callback_factory.h" #include "base/memory/scoped_ptr.h" #include "base/message_loop.h" #include "base/message_loop_proxy.h" #include "base/stringprintf.h" #include "base/synchronization/lock.h" #include "base/utf_string_conversions.h" #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 { typedef struct { const char* local_root_path; const char* web_root_path; } FixedExposedPaths; const char kChromeUIScheme[] = "chrome"; // Top level file system elements exposed in FileAPI in ChromeOS: FixedExposedPaths fixed_exposed_paths[] = { {"/home/chronos/user/", "Downloads"}, {"/", "media"}, }; CrosMountPointProvider::CrosMountPointProvider( scoped_refptr special_storage_policy) : 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(fixed_exposed_paths[i].web_root_path), FilePath(std::string(fixed_exposed_paths[i].local_root_path)))); } } CrosMountPointProvider::~CrosMountPointProvider() { } // TODO(zelidrag) share with SandboxMountPointProvider impl. std::string GetOriginIdentifierFromURL( const GURL& url) { WebKit::WebSecurityOrigin web_security_origin = WebKit::WebSecurityOrigin::createFromString(UTF8ToUTF16(url.spec())); return web_security_origin.databaseIdentifier().utf8(); } bool CrosMountPointProvider::GetRootForVirtualPath( const FilePath& virtual_path, FilePath* root_path) { std::vector components; virtual_path.GetComponents(&components); if (components.size() < 1) { return false; } base::AutoLock locker(lock_); // Check if this root mount point is exposed by this provider. MountPointMap::iterator iter = mount_point_map_.find(components[0]); if (iter == mount_point_map_.end()) { return false; } *root_path = iter->second; return true; } void CrosMountPointProvider::ValidateFileSystemRootAndGetURL( const GURL& origin_url, fileapi::FileSystemType type, bool create, fileapi::FileSystemPathManager::GetRootPathCallback* callback_ptr) { DCHECK(type == fileapi::kFileSystemTypeExternal); std::string name(GetOriginIdentifierFromURL(origin_url)); name += ':'; name += fileapi::kExternalName; FilePath root_path; root_path = FilePath(fileapi::kExternalDir); callback_ptr->Run(true, root_path, name); } FilePath CrosMountPointProvider::ValidateFileSystemRootAndGetPathOnFileThread( const GURL& origin_url, fileapi::FileSystemType type, const FilePath& virtual_path, bool create) { DCHECK(type == fileapi::kFileSystemTypeExternal); FilePath root_path; if (!GetRootForVirtualPath(virtual_path, &root_path)) return FilePath(); return root_path; } // TODO(zelidrag): Share this code with SandboxMountPointProvider impl. bool CrosMountPointProvider::IsRestrictedFileName(const FilePath& path) const { return false; } bool CrosMountPointProvider::IsAccessAllowed(const GURL& origin_url, fileapi::FileSystemType type, const FilePath& virtual_path) { if (type != fileapi::kFileSystemTypeExternal) return false; // Permit access to mount points from internal WebUI. if (origin_url.SchemeIs(kChromeUIScheme)) return true; 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::AddMountPoint(FilePath mount_point) { base::AutoLock locker(lock_); mount_point_map_.insert(std::pair( mount_point.BaseName().value(), mount_point.DirName())); } void CrosMountPointProvider::RemoveMountPoint(FilePath mount_point) { base::AutoLock locker(lock_); mount_point_map_.erase(mount_point.BaseName().value()); } 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 CrosMountPointProvider::GetRootDirectories() const { std::vector 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