// Copyright 2018 The Chromium OS 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 "cros-disks/drivefs_helper.h"

#include <sys/mount.h>

#include <base/files/file_util.h>
#include <base/files/scoped_temp_dir.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/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 MockPlatform : public Platform {
 public:
  MockPlatform() {
    ON_CALL(*this, GetRealPath(_, _))
        .WillByDefault(Invoke(this, &MockPlatform::GetRealPathImpl));
    ON_CALL(*this, DirectoryExists(_)).WillByDefault(Return(true));
    ON_CALL(*this, GetOwnership(_, _, _))
        .WillByDefault(DoAll(SetArgPointee<1>(kChronosUID), Return(true)));
  }

  MOCK_METHOD(bool,
              GetRealPath,
              (const std::string&, std::string*),
              (const, override));
  MOCK_METHOD(bool, PathExists, (const std::string&), (const, override));
  MOCK_METHOD(bool, DirectoryExists, (const std::string&), (const, override));
  MOCK_METHOD(bool, CreateDirectory, (const std::string&), (const, override));
  MOCK_METHOD(bool,
              RemoveEmptyDirectory,
              (const std::string&),
              (const, override));
  MOCK_METHOD(bool,
              GetOwnership,
              (const std::string&, uid_t*, gid_t*),
              (const, override));
  MOCK_METHOD(bool,
              SetPermissions,
              (const std::string&, mode_t),
              (const, override));

  bool GetRealPathImpl(const std::string& path, std::string* real_path) const {
    std::vector<std::string> components;
    base::FilePath(path).GetComponents(&components);
    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:
  MockPlatform 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
