15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/fileapi/browser_file_system_helper.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/sequenced_task_runner.h" 137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/threading/sequenced_worker_pool.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/browser/child_process_security_policy_impl.h" 157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/public/browser/browser_context.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/content_browser_client.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/common/content_client.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_switches.h" 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/external_mount_points.h" 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_permission_policy.h" 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_backend.h" 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_context.h" 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation_runner.h" 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_options.h" 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/quota/quota_manager.h" 27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "url/url_constants.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)using storage::FileSystemOptions; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FileSystemOptions CreateBrowserFileSystemOptions(bool is_incognito) { 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) FileSystemOptions::ProfileMode profile_mode = 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) is_incognito ? FileSystemOptions::PROFILE_MODE_INCOGNITO 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : FileSystemOptions::PROFILE_MODE_NORMAL; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<std::string> additional_allowed_schemes; 40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GetContentClient()->browser()->GetAdditionalAllowedSchemesForFileSystem( 41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) &additional_allowed_schemes); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CommandLine::ForCurrentProcess()->HasSwitch( 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switches::kAllowFileAccessFromFiles)) { 44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) additional_allowed_schemes.push_back(url::kFileScheme); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return FileSystemOptions(profile_mode, additional_allowed_schemes, NULL); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)scoped_refptr<storage::FileSystemContext> CreateFileSystemContext( 527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch BrowserContext* browser_context, 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath& profile_path, 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool is_incognito, 5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::QuotaManagerProxy* quota_manager_proxy) { 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool(); 577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> file_task_runner = 583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) pool->GetSequencedTaskRunnerWithShutdownBehavior( 593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) pool->GetNamedSequenceToken("FileAPI"), 603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); 617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 6258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch // Setting up additional filesystem backends. 6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ScopedVector<storage::FileSystemBackend> additional_backends; 647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch GetContentClient()->browser()->GetAdditionalFileSystemBackends( 657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch browser_context, 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_path, 6758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch &additional_backends); 68eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) // Set up the auto mount handlers for url requests. 7003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::vector<storage::URLRequestAutoMountHandler> 7123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) url_request_auto_mount_handlers; 7223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) GetContentClient()->browser()->GetURLRequestAutoMountHandlers( 7323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) &url_request_auto_mount_handlers); 7423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 7503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) scoped_refptr<storage::FileSystemContext> file_system_context = 7603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) new storage::FileSystemContext( 77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get(), 78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) file_task_runner.get(), 797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch BrowserContext::GetMountPoints(browser_context), 807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch browser_context->GetSpecialStoragePolicy(), 81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch quota_manager_proxy, 8258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch additional_backends.Pass(), 8323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) url_request_auto_mount_handlers, 84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch profile_path, 85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CreateBrowserFileSystemOptions(is_incognito)); 86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 8703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) std::vector<storage::FileSystemType> types; 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch file_system_context->GetFileSystemTypes(&types); 89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (size_t i = 0; i < types.size(); ++i) { 9003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ChildProcessSecurityPolicyImpl::GetInstance() 9103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) ->RegisterFileSystemPermissionPolicy( 92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch types[i], 9303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::FileSystemContext::GetPermissionPolicy(types[i])); 94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return file_system_context; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool FileSystemURLIsValid(storage::FileSystemContext* context, 10003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) const storage::FileSystemURL& url) { 101558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (!url.is_valid()) 102558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return false; 103558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 104558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch return context->GetFileSystemBackend(url.type()) != NULL; 105558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch} 106558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void SyncGetPlatformPath(storage::FileSystemContext* context, 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int process_id, 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& path, 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath* platform_path) { 111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(context->default_file_task_runner()-> 1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) RunsTasksOnCurrentThread()); 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(platform_path); 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *platform_path = base::FilePath(); 11503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) storage::FileSystemURL url(context->CrackURL(path)); 116558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (!FileSystemURLIsValid(context, url)) 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make sure if this file is ok to be read (in the current architecture 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // which means roughly same as the renderer is allowed to get the platform 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // path to the file). 122558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ChildProcessSecurityPolicyImpl* policy = 123558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch ChildProcessSecurityPolicyImpl::GetInstance(); 124558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (!policy->CanReadFileSystemFile(process_id, url)) 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) context->operation_runner()->SyncGetPlatformPath(url, platform_path); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The path is to be attached to URLLoader so we grant read permission 130558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // for the file. (We need to check first because a parent directory may 131558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch // already have the permissions and we don't need to grant it to the file.) 132558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch if (!policy->CanReadFile(process_id, *platform_path)) 133558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch policy->GrantReadFile(process_id, *platform_path); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 137