// Copyright 2018 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "cros-disks/drivefs_helper.h"

#include <sys/mount.h>

#include <base/check_op.h>
#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.h>
#include <base/notreached.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include <brillo/process/process_reaper.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>

#include "cros-disks/fuse_mounter.h"
#include "cros-disks/mock_platform.h"
#include "cros-disks/mount_options.h"
#include "cros-disks/platform.h"
#include "cros-disks/uri.h"
#include "cros-disks/user.h"

namespace cros_disks {
namespace {

using testing::_;
using testing::DoAll;
using testing::EndsWith;
using testing::HasSubstr;
using testing::Invoke;
using testing::IsSupersetOf;
using testing::Return;
using testing::SaveArg;
using testing::SetArgPointee;
using testing::StrEq;
using testing::UnorderedElementsAre;

constexpr char kSource[] = "drivefs://id";
constexpr char kDataDir[] = "/home/chronos/user/GCache/foo";
constexpr char kMountPath[] = "/media/fuse/drivefs/id";

constexpr char kPrefixParam[] = "prefix=/media/fuse/drivefs/id";
constexpr char kDataDirParam[] = "datadir=/home/chronos/user/GCache/foo";
constexpr char kMyFilesParam[] = "myfiles=/home/chronos/user/MyFiles";

std::vector<std::string> ParseOptions(const SandboxedProcess& sandbox) {
  CHECK_EQ(2, sandbox.arguments().size());
  CHECK_EQ("-o", sandbox.arguments()[0]);
  return base::SplitString(sandbox.arguments()[1], ",",
                           base::WhitespaceHandling::KEEP_WHITESPACE,
                           base::SplitResult::SPLIT_WANT_ALL);
}

// Mock Platform implementation for testing.
class PlatformForTest : public MockPlatform {
 public:
  PlatformForTest() {
    ON_CALL(*this, GetRealPath(_, _))
        .WillByDefault(Invoke(this, &PlatformForTest::GetRealPathImpl));
    ON_CALL(*this, DirectoryExists(_)).WillByDefault(Return(true));
    ON_CALL(*this, GetOwnership(_, _, _))
        .WillByDefault(DoAll(SetArgPointee<1>(kChronosUID), Return(true)));
  }

  bool GetRealPathImpl(const std::string& path, std::string* real_path) const {
    std::vector<std::string> components = base::FilePath(path).GetComponents();
    base::FilePath result(components[0]);
    components.erase(components.begin());
    for (const auto& part : components) {
      if (part != ".")
        result = result.Append(part);
    }
    *real_path = result.value();
    return true;
  }

  bool GetUserAndGroupId(const std::string& user,
                         uid_t* user_id,
                         gid_t* group_id) const override {
    NOTREACHED();
    return false;
  }

  bool GetGroupId(const std::string& group, gid_t* group_id) const override {
    NOTREACHED();
    return false;
  }

  bool SetOwnership(const std::string&, uid_t, gid_t) const override {
    NOTREACHED();
    return false;
  }
};

class TestDrivefsHelper : public DrivefsHelper {
 public:
  TestDrivefsHelper(const Platform* platform,
                    brillo::ProcessReaper* process_reaper)
      : DrivefsHelper(platform, process_reaper) {
  }
  using DrivefsHelper::ConfigureSandbox;
};

class DrivefsHelperTest : public ::testing::Test {
 public:
  DrivefsHelperTest() : helper_(&platform_, &process_reaper_) {}

 protected:
  PlatformForTest platform_;
  brillo::ProcessReaper process_reaper_;
  TestDrivefsHelper helper_;
};

TEST_F(DrivefsHelperTest, ConfigureSandbox) {
  FakeSandboxedProcess sandbox;
  auto error = helper_.ConfigureSandbox(
      kSource, base::FilePath(kMountPath),
      {"datadir=/home/chronos//user/GCache//foo/./"}, &sandbox);

  EXPECT_EQ(MOUNT_ERROR_NONE, error);
  auto options = ParseOptions(sandbox);
  EXPECT_THAT(options,
              UnorderedElementsAre(kDataDirParam, "identity=id", "uid=1000",
                                   "gid=1001", kPrefixParam));
}

TEST_F(DrivefsHelperTest, ConfigureSandboxWithMyFiles) {
  FakeSandboxedProcess sandbox;
  auto error = helper_.ConfigureSandbox(
      kSource, base::FilePath(kMountPath),
      {kDataDirParam, "myfiles=/home/chronos//user/.//MyFiles"}, &sandbox);

  EXPECT_EQ(MOUNT_ERROR_NONE, error);
  auto options = ParseOptions(sandbox);
  EXPECT_THAT(options, IsSupersetOf({StrEq(kMyFilesParam)}));
}

TEST_F(DrivefsHelperTest, ConfigureSandboxFailsIfInvalidSource) {
  FakeSandboxedProcess sandbox;
  auto error = helper_.ConfigureSandbox(
      "drive://id", base::FilePath(kMountPath), {kDataDirParam}, &sandbox);
  EXPECT_NE(MOUNT_ERROR_NONE, error);

  error = helper_.ConfigureSandbox("/dev/block", base::FilePath(kMountPath),
                                   {kDataDirParam}, &sandbox);
  EXPECT_NE(MOUNT_ERROR_NONE, error);

  error = helper_.ConfigureSandbox("drivefs:/foo", base::FilePath(kMountPath),
                                   {kDataDirParam}, &sandbox);
  EXPECT_NE(MOUNT_ERROR_NONE, error);
}

TEST_F(DrivefsHelperTest, ConfigureSandboxFailsIfDataDirInvalid) {
  FakeSandboxedProcess sandbox;
  auto error = helper_.ConfigureSandbox(kSource, base::FilePath(kMountPath), {},
                                        &sandbox);
  EXPECT_NE(MOUNT_ERROR_NONE, error);

  error = helper_.ConfigureSandbox(kSource, base::FilePath(kMountPath),
                                   {"datadir=dodgy/path"}, &sandbox);
  EXPECT_NE(MOUNT_ERROR_NONE, error);

  error = helper_.ConfigureSandbox(kSource, base::FilePath(kMountPath),
                                   {"datadir=/nonhome/dir"}, &sandbox);
  EXPECT_NE(MOUNT_ERROR_NONE, error);

  error = helper_.ConfigureSandbox(kSource, base::FilePath(kMountPath),
                                   {"datadir=/home/chronos/../../etc/passwd"},
                                   &sandbox);
  EXPECT_NE(MOUNT_ERROR_NONE, error);
}

TEST_F(DrivefsHelperTest, ConfigureSandboxFailsIfDataDirDoesntExist) {
  EXPECT_CALL(platform_, DirectoryExists(kDataDir)).WillOnce(Return(false));
  FakeSandboxedProcess sandbox;
  auto error = helper_.ConfigureSandbox(kSource, base::FilePath(kMountPath),
                                        {kDataDirParam}, &sandbox);
  EXPECT_NE(MOUNT_ERROR_NONE, error);
}

TEST_F(DrivefsHelperTest, ConfigureSandboxFailsWhenCantStat) {
  EXPECT_CALL(platform_, GetOwnership(kDataDir, _, _)).WillOnce(Return(false));
  FakeSandboxedProcess sandbox;
  auto error = helper_.ConfigureSandbox(kSource, base::FilePath(kMountPath),
                                        {kDataDirParam}, &sandbox);
  EXPECT_NE(MOUNT_ERROR_NONE, error);
}

TEST_F(DrivefsHelperTest, ConfigureSandboxFailsWhenWrongOwner) {
  EXPECT_CALL(platform_, GetOwnership(kDataDir, _, _))
      .WillOnce(DoAll(SetArgPointee<1>(kChronosUID + 100), Return(false)));
  FakeSandboxedProcess sandbox;
  auto error = helper_.ConfigureSandbox(kSource, base::FilePath(kMountPath),
                                        {kDataDirParam}, &sandbox);
  EXPECT_NE(MOUNT_ERROR_NONE, error);
}

}  // namespace
}  // namespace cros_disks
