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