Commit c5aef007 authored by Joel Hockey's avatar Joel Hockey Committed by Commit Bot

Add support for CrOS drivefs in SanitizeDownloadTargetPath

Clean up all checks to use IsParent which is simpler to understand
than AppendRelativePath.

Also fixes linux files to allow root mount point as valid downloads dir.

Change-Id: Ie7d688949a69262b35bf999f0fc661a4633356c2
Reviewed-on: https://chromium-review.googlesource.com/c/1286235
Commit-Queue: Joel Hockey <joelhockey@chromium.org>
Reviewed-by: default avatarMin Qin <qinmin@chromium.org>
Reviewed-by: default avatarSam McNally <sammc@chromium.org>
Cr-Commit-Position: refs/heads/master@{#600581}
parent 674715b7
...@@ -303,17 +303,6 @@ bool DownloadPrefs::IsFromTrustedSource(const download::DownloadItem& item) { ...@@ -303,17 +303,6 @@ bool DownloadPrefs::IsFromTrustedSource(const download::DownloadItem& item) {
} }
base::FilePath DownloadPrefs::DownloadPath() const { base::FilePath DownloadPrefs::DownloadPath() const {
#if defined(OS_CHROMEOS)
// If the download path is under /drive, and DriveIntegrationService isn't
// available (which it isn't for incognito mode, for instance), use the
// default download directory (/Downloads).
if (drive::util::IsUnderDriveMountPoint(*download_path_)) {
drive::DriveIntegrationService* integration_service =
drive::DriveIntegrationServiceFactory::FindForProfile(profile_);
if (!integration_service || !integration_service->is_enabled())
return GetDefaultDownloadDirectoryForProfile();
}
#endif
return SanitizeDownloadTargetPath(*download_path_); return SanitizeDownloadTargetPath(*download_path_);
} }
...@@ -456,43 +445,34 @@ base::FilePath DownloadPrefs::SanitizeDownloadTargetPath( ...@@ -456,43 +445,34 @@ base::FilePath DownloadPrefs::SanitizeDownloadTargetPath(
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
// If |path| isn't absolute, fall back to the default directory. // If |path| isn't absolute, fall back to the default directory.
base::FilePath profile_download_dir = GetDefaultDownloadDirectoryForProfile(); base::FilePath profile_download_dir = GetDefaultDownloadDirectoryForProfile();
if (!path.IsAbsolute()) if (!path.IsAbsolute() || path.ReferencesParent())
return profile_download_dir; return profile_download_dir;
// Allow paths that are under the default download directory. // Allow default download directory and subdirs.
base::FilePath relative; if (profile_download_dir == path || profile_download_dir.IsParent(path))
if (profile_download_dir.AppendRelativePath(path, &relative) && return path;
!relative.ReferencesParent()) {
return profile_download_dir.Append(relative);
}
// Allow paths under the drive mount point. // Allow paths under the drive mount point.
if (drive::util::IsUnderDriveMountPoint(path) && !path.ReferencesParent()) drive::DriveIntegrationService* integration_service =
drive::DriveIntegrationServiceFactory::FindForProfile(profile_);
if (integration_service && integration_service->is_enabled() &&
integration_service->GetMountPointPath().IsParent(path)) {
return path; return path;
}
// Allow removable media. // Allow removable media.
base::FilePath media_mount_point = if (chromeos::CrosDisksClient::GetRemovableDiskMountPoint().IsParent(path))
chromeos::CrosDisksClient::GetRemovableDiskMountPoint(); return path;
if (media_mount_point.AppendRelativePath(path, &relative) &&
!relative.ReferencesParent()) {
return media_mount_point.Append(relative);
}
// Allow paths under the Android files mount point. // Allow paths under the Android files mount point.
base::FilePath android_files_mount_point( if (base::FilePath(file_manager::util::kAndroidFilesPath).IsParent(path))
file_manager::util::kAndroidFilesPath); return path;
if (android_files_mount_point.AppendRelativePath(path, &relative) &&
!relative.ReferencesParent()) {
return android_files_mount_point.Append(relative);
}
// Allow paths under the Linux files mount point. // Allow Linux files mount point and subdirs.
base::FilePath linux_files_mount_point = base::FilePath linux_files =
file_manager::util::GetCrostiniMountDirectory(profile_); file_manager::util::GetCrostiniMountDirectory(profile_);
if (linux_files_mount_point.AppendRelativePath(path, &relative) && if (linux_files == path || linux_files.IsParent(path))
!relative.ReferencesParent()) { return path;
return linux_files_mount_point.Append(relative);
}
// Fall back to the default download directory for all other paths. // Fall back to the default download directory for all other paths.
return profile_download_dir; return profile_download_dir;
......
...@@ -12,6 +12,16 @@ ...@@ -12,6 +12,16 @@
#include "content/public/test/test_browser_thread_bundle.h" #include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#if defined(OS_CHROMEOS)
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/chromeos/drive/drive_integration_service.h"
#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chromeos/chromeos_features.h"
#include "components/drive/drive_pref_names.h"
#include "content/public/test/test_service_manager_context.h"
#endif
using safe_browsing::FileTypePolicies; using safe_browsing::FileTypePolicies;
TEST(DownloadPrefsTest, Prerequisites) { TEST(DownloadPrefsTest, Prerequisites) {
...@@ -119,45 +129,114 @@ TEST(DownloadPrefsTest, AutoOpenCheckIsCaseInsensitive) { ...@@ -119,45 +129,114 @@ TEST(DownloadPrefsTest, AutoOpenCheckIsCaseInsensitive) {
} }
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
void ExpectValidDownloadDir(Profile* profile,
DownloadPrefs* prefs,
base::FilePath path) {
profile->GetPrefs()->SetString(prefs::kDownloadDefaultDirectory,
path.value());
EXPECT_TRUE(prefs->DownloadPath().IsAbsolute());
EXPECT_EQ(prefs->DownloadPath(), path);
}
TEST(DownloadPrefsTest, DownloadDirSanitization) { TEST(DownloadPrefsTest, DownloadDirSanitization) {
content::TestBrowserThreadBundle threads_are_required_for_testing_profile; content::TestBrowserThreadBundle threads_are_required_for_testing_profile;
TestingProfile profile; content::TestServiceManagerContext service_manager_context;
TestingProfile profile(base::FilePath("/home/chronos/u-0123456789abcdef"));
DownloadPrefs prefs(&profile); DownloadPrefs prefs(&profile);
const base::FilePath default_dir = const base::FilePath default_dir =
prefs.GetDefaultDownloadDirectoryForProfile(); prefs.GetDefaultDownloadDirectoryForProfile();
// Test a valid path. // Test a valid path.
base::FilePath testdir = default_dir.AppendASCII("testdir"); ExpectValidDownloadDir(&profile, &prefs, default_dir.AppendASCII("testdir"));
profile.GetPrefs()->SetString(prefs::kDownloadDefaultDirectory,
testdir.value());
EXPECT_TRUE(prefs.DownloadPath().IsAbsolute());
EXPECT_EQ(prefs.DownloadPath(), testdir);
// Test a valid path for Android files. // Test a valid path for Android files.
testdir = base::FilePath("/run/arc/sdcard/write/emulated/0/Documents"); ExpectValidDownloadDir(
profile.GetPrefs()->SetString(prefs::kDownloadDefaultDirectory, &profile, &prefs,
testdir.value()); base::FilePath("/run/arc/sdcard/write/emulated/0/Documents"));
EXPECT_TRUE(prefs.DownloadPath().IsAbsolute());
EXPECT_EQ(prefs.DownloadPath(), testdir); // Linux files root.
ExpectValidDownloadDir(
// Test a valid path for Linux files. &profile, &prefs,
testdir = base::FilePath("/media/fuse/crostini_test_termina_penguin/testdir"); base::FilePath("/media/fuse/crostini_0123456789abcdef_termina_penguin"));
profile.GetPrefs()->SetString(prefs::kDownloadDefaultDirectory, // Linux files/testdir.
testdir.value()); ExpectValidDownloadDir(
EXPECT_TRUE(prefs.DownloadPath().IsAbsolute()); &profile, &prefs,
EXPECT_EQ(prefs.DownloadPath(), testdir); base::FilePath(
"/media/fuse/crostini_0123456789abcdef_termina_penguin/testdir"));
// Test with an invalid path outside the download directory. // Test with an invalid path outside the download directory.
profile.GetPrefs()->SetString(prefs::kDownloadDefaultDirectory, profile.GetPrefs()->SetString(prefs::kDownloadDefaultDirectory,
"/home/chronos"); "/home/chronos");
EXPECT_TRUE(prefs.DownloadPath().IsAbsolute());
EXPECT_EQ(prefs.DownloadPath(), default_dir); EXPECT_EQ(prefs.DownloadPath(), default_dir);
// Test with an invalid path containing parent references. // Test with an invalid path containing parent references.
base::FilePath parent_reference = default_dir.AppendASCII(".."); base::FilePath parent_reference = default_dir.AppendASCII("..");
profile.GetPrefs()->SetString(prefs::kDownloadDefaultDirectory, profile.GetPrefs()->SetString(prefs::kDownloadDefaultDirectory,
parent_reference.value()); parent_reference.value());
EXPECT_TRUE(prefs.DownloadPath().IsAbsolute());
EXPECT_EQ(prefs.DownloadPath(), default_dir); EXPECT_EQ(prefs.DownloadPath(), default_dir);
// Drive
{
base::test::ScopedFeatureList features;
features.InitAndDisableFeature(chromeos::features::kDriveFs);
auto* integration_service =
drive::DriveIntegrationServiceFactory::GetForProfile(&profile);
integration_service->SetEnabled(true);
// My Drive root.
ExpectValidDownloadDir(
&profile, &prefs,
base::FilePath("/special/drive-0123456789abcdef/root"));
// My Drive/foo.
ExpectValidDownloadDir(
&profile, &prefs,
base::FilePath("/special/drive-0123456789abcdef/root/foo"));
// Invalid path without one of the drive roots.
profile.GetPrefs()->SetString(prefs::kDownloadDefaultDirectory,
"/special/drive-0123456789abcdef");
EXPECT_EQ(prefs.DownloadPath(), default_dir);
}
// DriveFS
{
base::test::ScopedFeatureList features;
features.InitAndEnableFeature(chromeos::features::kDriveFs);
// Create new profile for enabled feature to work.
TestingProfile profile2(base::FilePath("/home/chronos/u-0123456789abcdef"));
chromeos::FakeChromeUserManager user_manager;
DownloadPrefs prefs2(&profile2);
AccountId account_id =
AccountId::FromUserEmailGaiaId(profile2.GetProfileUserName(), "12345");
const auto* user = user_manager.AddUser(account_id);
chromeos::ProfileHelper::Get()->SetUserToProfileMappingForTesting(
user, &profile2);
chromeos::ProfileHelper::Get()->SetProfileToUserMappingForTesting(
const_cast<user_manager::User*>(user));
profile2.GetPrefs()->SetString(drive::prefs::kDriveFsProfileSalt, "a");
auto* integration_service =
drive::DriveIntegrationServiceFactory::GetForProfile(&profile2);
integration_service->SetEnabled(true);
// My Drive root.
ExpectValidDownloadDir(
&profile2, &prefs2,
base::FilePath(
"/media/fuse/drivefs-84675c855b63e12f384d45f033826980/root"));
// My Drive/foo.
ExpectValidDownloadDir(
&profile2, &prefs2,
base::FilePath(
"/media/fuse/drivefs-84675c855b63e12f384d45f033826980/root/foo"));
// Invalid path without one of the drive roots.
const base::FilePath default_dir2 =
prefs2.GetDefaultDownloadDirectoryForProfile();
profile2.GetPrefs()->SetString(
prefs::kDownloadDefaultDirectory,
"/media/fuse/drivefs-84675c855b63e12f384d45f033826980");
EXPECT_EQ(prefs2.DownloadPath(), default_dir2);
profile2.GetPrefs()->SetString(prefs::kDownloadDefaultDirectory,
"/media/fuse/drivefs-something-else/root");
EXPECT_EQ(prefs2.DownloadPath(), default_dir2);
}
} }
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment