// Copyright 2020 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 "smbfs/smbfs_bootstrap_impl.h"

#include <memory>
#include <utility>
#include <vector>

#include <base/check.h>
#include <base/files/file_util.h>
#include <base/files/scoped_file.h>
#include <base/files/scoped_temp_dir.h>
#include <base/run_loop.h>
#include <base/test/bind.h>
#include <base/test/task_environment.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <mojo/core/embedder/embedder.h>
#include <mojo/public/cpp/bindings/pending_remote.h>
#include <mojo/public/cpp/bindings/pending_receiver.h>
#include <mojo/public/cpp/bindings/remote.h>
#include <mojo/public/cpp/bindings/receiver.h>
#include <mojo/public/cpp/system/platform_handle.h>
#include <libpasswordprovider/password.h>

#include "smbfs/smb_filesystem.h"
#include "smbfs/smbfs_impl.h"

namespace smbfs {
namespace {

using ::testing::_;
using ::testing::Return;
using ::testing::Unused;
using ::testing::WithArg;

const char kSharePath[] = "smb://server/share";
const char kWorkgroup[] = "my-workgroup";
const char kUsername[] = "my-username";
const char kPassword[] = "my-super-secret-password";
const char kKerberosGuid[] = "1234-5678-my-guid";
const char kAccountHash[] = "00112233445566778899aa";

class MockSmbFilesystemDelegate : public SmbFilesystem::Delegate {
 public:
  MOCK_METHOD(void,
              RequestCredentials,
              (RequestCredentialsCallback),
              (override));
};

class MockSmbFilesystem : public SmbFilesystem {
 public:
  MockSmbFilesystem() : SmbFilesystem(&delegate_, kSharePath) {}

  MOCK_METHOD(ConnectError, EnsureConnected, (), (override));
  MOCK_METHOD(void,
              SetResolvedAddress,
              (const std::vector<uint8_t>&),
              (override));

 private:
  MockSmbFilesystemDelegate delegate_;
};

class MockBootstrapDelegate : public SmbFsBootstrapImpl::Delegate {
 public:
  MOCK_METHOD(void,
              SetupKerberos,
              (mojom::KerberosConfigPtr,
               base::OnceCallback<void(bool success)>),
              (override));
  MOCK_METHOD(void, OnPasswordFilePathSet, (const base::FilePath&), (override));
};

class MockSmbFsDelegate : public mojom::SmbFsDelegate {
 public:
  explicit MockSmbFsDelegate(
      mojo::PendingReceiver<mojom::SmbFsDelegate> receiver)
      : receiver_(this, std::move(receiver)) {}

  MOCK_METHOD(void,
              RequestCredentials,
              (RequestCredentialsCallback),
              (override));

 private:
  mojo::Receiver<mojom::SmbFsDelegate> receiver_;
};

std::unique_ptr<password_provider::Password> MakePassword(
    const std::string& password) {
  int fds[2];
  CHECK(base::CreateLocalNonBlockingPipe(fds));
  base::ScopedFD read_fd(fds[0]);
  base::ScopedFD write_fd(fds[1]);
  CHECK(base::WriteFileDescriptor(write_fd.get(), password.data(),
                                  password.size()));
  return password_provider::Password::CreateFromFileDescriptor(read_fd.get(),
                                                               password.size());
}

class TestSmbFsBootstrapImpl : public testing::Test {
 public:
  void SetUp() override {
    ResetDelegate();

    ASSERT_TRUE(daemon_store_dir_.CreateUniqueTempDir());
  }

  void ResetDelegate() {
    smbfs_delegate_.reset();
    mock_smbfs_delegate_ = std::make_unique<MockSmbFsDelegate>(
        smbfs_delegate_.InitWithNewPipeAndPassReceiver());
  }

 protected:
  base::test::TaskEnvironment task_environment{
      base::test::TaskEnvironment::ThreadingMode::MAIN_THREAD_ONLY,
      base::test::TaskEnvironment::MainThreadType::IO};
  MockBootstrapDelegate mock_delegate_;

  mojo::PendingRemote<mojom::SmbFsDelegate> smbfs_delegate_;
  std::unique_ptr<MockSmbFsDelegate> mock_smbfs_delegate_;

  base::ScopedTempDir daemon_store_dir_;
};

TEST_F(TestSmbFsBootstrapImpl, GuestAuth) {
  mojo::Remote<mojom::SmbFsBootstrap> bootstrap;

  auto fs_factory = base::BindLambdaForTesting(
      [](SmbFilesystem::Options options) -> std::unique_ptr<SmbFilesystem> {
        EXPECT_EQ(options.share_path, kSharePath);
        EXPECT_FALSE(options.allow_ntlm);
        EXPECT_TRUE(options.credentials->workgroup.empty());
        EXPECT_TRUE(options.credentials->username.empty());
        EXPECT_FALSE(options.credentials->password);

        std::unique_ptr<MockSmbFilesystem> fs =
            std::make_unique<MockSmbFilesystem>();
        EXPECT_CALL(*fs, EnsureConnected())
            .WillOnce(Return(SmbFilesystem::ConnectError::kOk));
        EXPECT_CALL(*fs, SetResolvedAddress(std::vector<uint8_t>({1, 2, 3, 4})))
            .Times(1);
        return fs;
      });
  SmbFsBootstrapImpl boostrap_impl(bootstrap.BindNewPipeAndPassReceiver(),
                                   fs_factory, &mock_delegate_,
                                   daemon_store_dir_.GetPath());
  bool bootstrap_done = false;
  boostrap_impl.Start(base::BindLambdaForTesting(
      [&bootstrap_done](std::unique_ptr<SmbFilesystem> fs,
                        mojo::PendingReceiver<mojom::SmbFs> smbfs_receiver,
                        mojo::PendingRemote<mojom::SmbFsDelegate> delegate) {
        EXPECT_TRUE(fs);
        bootstrap_done = true;
      }));

  mojom::MountOptionsPtr mount_options = mojom::MountOptions::New();
  mount_options->share_path = kSharePath;
  mount_options->resolved_host =
      mojom::IPAddress::New(std::vector<uint8_t>({1, 2, 3, 4}));

  base::RunLoop run_loop;
  bootstrap->MountShare(
      std::move(mount_options), std::move(smbfs_delegate_),
      base::BindLambdaForTesting(
          [&run_loop](mojom::MountError mount_error,
                      mojo::PendingRemote<mojom::SmbFs> smbfs) {
            EXPECT_EQ(mojom::MountError::kOk, mount_error);
            EXPECT_TRUE(smbfs);
            run_loop.Quit();
          }));
  run_loop.Run();
  EXPECT_TRUE(bootstrap_done);
}

TEST_F(TestSmbFsBootstrapImpl, UsernamePasswordAuth) {
  mojo::Remote<mojom::SmbFsBootstrap> bootstrap;

  auto fs_factory = base::BindLambdaForTesting(
      [](SmbFilesystem::Options options) -> std::unique_ptr<SmbFilesystem> {
        EXPECT_EQ(options.share_path, kSharePath);
        EXPECT_TRUE(options.allow_ntlm);
        EXPECT_EQ(options.credentials->workgroup, kWorkgroup);
        EXPECT_EQ(options.credentials->username, kUsername);
        EXPECT_EQ(options.credentials->password->GetRaw(),
                  std::string(kPassword));

        std::unique_ptr<MockSmbFilesystem> fs =
            std::make_unique<MockSmbFilesystem>();
        EXPECT_CALL(*fs, EnsureConnected())
            .WillOnce(Return(SmbFilesystem::ConnectError::kOk));
        EXPECT_CALL(*fs, SetResolvedAddress(_)).Times(0);
        return fs;
      });
  SmbFsBootstrapImpl boostrap_impl(bootstrap.BindNewPipeAndPassReceiver(),
                                   fs_factory, &mock_delegate_,
                                   daemon_store_dir_.GetPath());
  bool bootstrap_done = false;
  boostrap_impl.Start(base::BindLambdaForTesting(
      [&bootstrap_done](std::unique_ptr<SmbFilesystem> fs,
                        mojo::PendingReceiver<mojom::SmbFs> smbfs_receiver,
                        mojo::PendingRemote<mojom::SmbFsDelegate> delegate) {
        EXPECT_TRUE(fs);
        bootstrap_done = true;
      }));

  mojom::MountOptionsPtr mount_options = mojom::MountOptions::New();
  mount_options->share_path = kSharePath;
  mount_options->workgroup = kWorkgroup;
  mount_options->username = kUsername;
  mount_options->password = MakePassword(kPassword);
  mount_options->allow_ntlm = true;

  base::RunLoop run_loop;
  bootstrap->MountShare(
      std::move(mount_options), std::move(smbfs_delegate_),
      base::BindLambdaForTesting(
          [&run_loop](mojom::MountError mount_error,
                      mojo::PendingRemote<mojom::SmbFs> smbfs) {
            EXPECT_EQ(mojom::MountError::kOk, mount_error);
            EXPECT_TRUE(smbfs);
            run_loop.Quit();
          }));
  run_loop.Run();
  EXPECT_TRUE(bootstrap_done);
}

TEST_F(TestSmbFsBootstrapImpl, KerberosAuth) {
  mojo::Remote<mojom::SmbFsBootstrap> bootstrap;

  auto fs_factory = base::BindLambdaForTesting(
      [](SmbFilesystem::Options options) -> std::unique_ptr<SmbFilesystem> {
        EXPECT_EQ(options.share_path, kSharePath);
        EXPECT_FALSE(options.allow_ntlm);
        EXPECT_EQ(options.credentials->workgroup, kWorkgroup);
        EXPECT_EQ(options.credentials->username, kUsername);
        EXPECT_FALSE(options.credentials->password);

        std::unique_ptr<MockSmbFilesystem> fs =
            std::make_unique<MockSmbFilesystem>();
        EXPECT_CALL(*fs, EnsureConnected())
            .WillOnce(Return(SmbFilesystem::ConnectError::kOk));
        EXPECT_CALL(*fs, SetResolvedAddress(_)).Times(0);
        return fs;
      });
  SmbFsBootstrapImpl boostrap_impl(bootstrap.BindNewPipeAndPassReceiver(),
                                   fs_factory, &mock_delegate_,
                                   daemon_store_dir_.GetPath());

  EXPECT_CALL(mock_delegate_, SetupKerberos(_, _))
      .WillOnce([](mojom::KerberosConfigPtr config,
                   base::OnceCallback<void(bool success)> callback) {
        EXPECT_EQ(config->source, mojom::KerberosConfig::Source::kKerberos);
        EXPECT_EQ(config->identity, kKerberosGuid);
        std::move(callback).Run(true);
      });
  bool bootstrap_done = false;
  boostrap_impl.Start(base::BindLambdaForTesting(
      [&bootstrap_done](std::unique_ptr<SmbFilesystem> fs,
                        mojo::PendingReceiver<mojom::SmbFs> smbfs_receiver,
                        mojo::PendingRemote<mojom::SmbFsDelegate> delegate) {
        EXPECT_TRUE(fs);
        bootstrap_done = true;
      }));

  mojom::MountOptionsPtr mount_options = mojom::MountOptions::New();
  mount_options->share_path = kSharePath;
  mount_options->workgroup = kWorkgroup;
  mount_options->username = kUsername;
  mount_options->kerberos_config = mojom::KerberosConfig::New(
      mojom::KerberosConfig::Source::kKerberos, kKerberosGuid);
  // These two options will be ignored when Kerberos is being used.
  mount_options->password = MakePassword(kPassword);
  mount_options->resolved_host =
      mojom::IPAddress::New(std::vector<uint8_t>({1, 2, 3, 4}));

  base::RunLoop run_loop;
  bootstrap->MountShare(
      std::move(mount_options), std::move(smbfs_delegate_),
      base::BindLambdaForTesting(
          [&run_loop](mojom::MountError mount_error,
                      mojo::PendingRemote<mojom::SmbFs> smbfs) {
            EXPECT_EQ(mojom::MountError::kOk, mount_error);
            EXPECT_TRUE(smbfs);
            run_loop.Quit();
          }));
  run_loop.Run();
  EXPECT_TRUE(bootstrap_done);
}

TEST_F(TestSmbFsBootstrapImpl, SkipConnect) {
  mojo::Remote<mojom::SmbFsBootstrap> bootstrap;

  auto fs_factory = base::BindLambdaForTesting(
      [](SmbFilesystem::Options options) -> std::unique_ptr<SmbFilesystem> {
        EXPECT_EQ(options.share_path, kSharePath);
        EXPECT_FALSE(options.allow_ntlm);

        std::unique_ptr<MockSmbFilesystem> fs =
            std::make_unique<MockSmbFilesystem>();
        // Expect that EnsureConnected() is never called when skip_connect mount
        // option is set.
        EXPECT_CALL(*fs, EnsureConnected()).Times(0);
        return fs;
      });
  SmbFsBootstrapImpl boostrap_impl(bootstrap.BindNewPipeAndPassReceiver(),
                                   fs_factory, &mock_delegate_,
                                   daemon_store_dir_.GetPath());

  bool bootstrap_done = false;
  boostrap_impl.Start(base::BindLambdaForTesting(
      [&bootstrap_done](std::unique_ptr<SmbFilesystem> fs,
                        mojo::PendingReceiver<mojom::SmbFs> smbfs_receiver,
                        mojo::PendingRemote<mojom::SmbFsDelegate> delegate) {
        EXPECT_TRUE(fs);
        bootstrap_done = true;
      }));

  mojom::MountOptionsPtr mount_options = mojom::MountOptions::New();
  mount_options->share_path = kSharePath;
  mount_options->skip_connect = true;

  base::RunLoop run_loop;
  bootstrap->MountShare(
      std::move(mount_options), std::move(smbfs_delegate_),
      base::BindLambdaForTesting(
          [&run_loop](mojom::MountError mount_error,
                      mojo::PendingRemote<mojom::SmbFs> smbfs) {
            EXPECT_EQ(mojom::MountError::kOk, mount_error);
            EXPECT_TRUE(smbfs);
            run_loop.Quit();
          }));
  run_loop.Run();
  EXPECT_TRUE(bootstrap_done);
}

TEST_F(TestSmbFsBootstrapImpl, Disconnect) {
  mojo::Remote<mojom::SmbFsBootstrap> bootstrap;

  auto fs_factory = base::BindLambdaForTesting(
      [](SmbFilesystem::Options options) -> std::unique_ptr<SmbFilesystem> {
        // FAIL() can only be used in a function that returns void.
        ADD_FAILURE();
        return nullptr;
      });
  SmbFsBootstrapImpl boostrap_impl(bootstrap.BindNewPipeAndPassReceiver(),
                                   fs_factory, &mock_delegate_,
                                   daemon_store_dir_.GetPath());

  base::RunLoop run_loop;
  boostrap_impl.Start(base::BindLambdaForTesting(
      [&run_loop](std::unique_ptr<SmbFilesystem> fs,
                  mojo::PendingReceiver<mojom::SmbFs> smbfs,
                  mojo::PendingRemote<mojom::SmbFsDelegate> delegate) {
        EXPECT_FALSE(fs);
        run_loop.Quit();
      }));

  bootstrap.reset();
  run_loop.Run();
}

TEST_F(TestSmbFsBootstrapImpl, InvalidPath) {
  mojo::Remote<mojom::SmbFsBootstrap> bootstrap;

  auto fs_factory = base::BindLambdaForTesting(
      [](SmbFilesystem::Options options) -> std::unique_ptr<SmbFilesystem> {
        ADD_FAILURE();
        return nullptr;
      });
  SmbFsBootstrapImpl boostrap_impl(bootstrap.BindNewPipeAndPassReceiver(),
                                   fs_factory, &mock_delegate_,
                                   daemon_store_dir_.GetPath());

  boostrap_impl.Start(base::BindOnce(
      [](std::unique_ptr<SmbFilesystem> fs,
         mojo::PendingReceiver<mojom::SmbFs> smbfs,
         mojo::PendingRemote<mojom::SmbFsDelegate> delegate) { FAIL(); }));

  mojom::MountOptionsPtr mount_options = mojom::MountOptions::New();
  mount_options->share_path = "bad-path";

  base::RunLoop run_loop;
  bootstrap->MountShare(
      std::move(mount_options), std::move(smbfs_delegate_),
      base::BindLambdaForTesting(
          [&run_loop](mojom::MountError mount_error,
                      mojo::PendingRemote<mojom::SmbFs> smbfs) {
            EXPECT_EQ(mojom::MountError::kInvalidUrl, mount_error);
            EXPECT_FALSE(smbfs);
            run_loop.Quit();
          }));
  run_loop.Run();
}

TEST_F(TestSmbFsBootstrapImpl, KerberosSetupFailure) {
  mojo::Remote<mojom::SmbFsBootstrap> bootstrap;

  auto fs_factory = base::BindLambdaForTesting(
      [](SmbFilesystem::Options options) -> std::unique_ptr<SmbFilesystem> {
        ADD_FAILURE();
        return nullptr;
      });
  SmbFsBootstrapImpl boostrap_impl(bootstrap.BindNewPipeAndPassReceiver(),
                                   fs_factory, &mock_delegate_,
                                   daemon_store_dir_.GetPath());

  EXPECT_CALL(mock_delegate_, SetupKerberos(_, _))
      .WillOnce([](mojom::KerberosConfigPtr config,
                   base::OnceCallback<void(bool success)> callback) {
        std::move(callback).Run(false);
      });
  boostrap_impl.Start(base::BindOnce(
      [](std::unique_ptr<SmbFilesystem> fs,
         mojo::PendingReceiver<mojom::SmbFs> smbfs,
         mojo::PendingRemote<mojom::SmbFsDelegate> delegate) { FAIL(); }));

  mojom::MountOptionsPtr mount_options = mojom::MountOptions::New();
  mount_options->share_path = kSharePath;
  mount_options->workgroup = kWorkgroup;
  mount_options->username = kUsername;
  mount_options->kerberos_config = mojom::KerberosConfig::New(
      mojom::KerberosConfig::Source::kKerberos, kKerberosGuid);

  base::RunLoop run_loop;
  bootstrap->MountShare(
      std::move(mount_options), std::move(smbfs_delegate_),
      base::BindLambdaForTesting(
          [&run_loop](mojom::MountError mount_error,
                      mojo::PendingRemote<mojom::SmbFs> smbfs) {
            EXPECT_EQ(mojom::MountError::kUnknown, mount_error);
            EXPECT_FALSE(smbfs);
            run_loop.Quit();
          }));
  run_loop.Run();
}

TEST_F(TestSmbFsBootstrapImpl, ConnectionAuthFailure) {
  mojo::Remote<mojom::SmbFsBootstrap> bootstrap;

  auto fs_factory = base::BindLambdaForTesting(
      [](SmbFilesystem::Options options) -> std::unique_ptr<SmbFilesystem> {
        EXPECT_EQ(options.share_path, kSharePath);

        std::unique_ptr<MockSmbFilesystem> fs =
            std::make_unique<MockSmbFilesystem>();
        EXPECT_CALL(*fs, EnsureConnected())
            .WillOnce(Return(SmbFilesystem::ConnectError::kAccessDenied));
        return fs;
      });
  SmbFsBootstrapImpl boostrap_impl(bootstrap.BindNewPipeAndPassReceiver(),
                                   fs_factory, &mock_delegate_,
                                   daemon_store_dir_.GetPath());

  boostrap_impl.Start(base::BindOnce(
      [](std::unique_ptr<SmbFilesystem> fs,
         mojo::PendingReceiver<mojom::SmbFs> smbfs,
         mojo::PendingRemote<mojom::SmbFsDelegate> delegate) { FAIL(); }));

  mojom::MountOptionsPtr mount_options = mojom::MountOptions::New();
  mount_options->share_path = kSharePath;

  base::RunLoop run_loop;
  bootstrap->MountShare(
      std::move(mount_options), std::move(smbfs_delegate_),
      base::BindLambdaForTesting(
          [&run_loop](mojom::MountError mount_error,
                      mojo::PendingRemote<mojom::SmbFs> smbfs) {
            EXPECT_EQ(mojom::MountError::kAccessDenied, mount_error);
            EXPECT_FALSE(smbfs);
            run_loop.Quit();
          }));
  run_loop.Run();
}

TEST_F(TestSmbFsBootstrapImpl, UnsupportedProtocolSmb1) {
  mojo::Remote<mojom::SmbFsBootstrap> bootstrap;

  auto fs_factory = base::BindLambdaForTesting(
      [](SmbFilesystem::Options options) -> std::unique_ptr<SmbFilesystem> {
        EXPECT_EQ(options.share_path, kSharePath);

        std::unique_ptr<MockSmbFilesystem> fs =
            std::make_unique<MockSmbFilesystem>();
        EXPECT_CALL(*fs, EnsureConnected())
            .WillOnce(Return(SmbFilesystem::ConnectError::kSmb1Unsupported));
        return fs;
      });
  SmbFsBootstrapImpl boostrap_impl(bootstrap.BindNewPipeAndPassReceiver(),
                                   fs_factory, &mock_delegate_,
                                   daemon_store_dir_.GetPath());

  boostrap_impl.Start(base::BindOnce(
      [](std::unique_ptr<SmbFilesystem> fs,
         mojo::PendingReceiver<mojom::SmbFs> smbfs,
         mojo::PendingRemote<mojom::SmbFsDelegate> delegate) { FAIL(); }));

  mojom::MountOptionsPtr mount_options = mojom::MountOptions::New();
  mount_options->share_path = kSharePath;

  base::RunLoop run_loop;
  bootstrap->MountShare(
      std::move(mount_options), std::move(smbfs_delegate_),
      base::BindLambdaForTesting(
          [&run_loop](mojom::MountError mount_error,
                      mojo::PendingRemote<mojom::SmbFs> smbfs) {
            EXPECT_EQ(mojom::MountError::kInvalidProtocol, mount_error);
            EXPECT_FALSE(smbfs);
            run_loop.Quit();
          }));
  run_loop.Run();
}

TEST_F(TestSmbFsBootstrapImpl, SaveRestorePassword) {
  const std::vector<uint8_t> salt(
      mojom::CredentialStorageOptions::kMinSaltLength, 'a');

  const base::FilePath user_directory =
      daemon_store_dir_.GetPath().Append(kAccountHash);
  ASSERT_TRUE(base::CreateDirectory(user_directory));
  EXPECT_TRUE(base::IsDirectoryEmpty(user_directory));

  {
    mojo::Remote<mojom::SmbFsBootstrap> bootstrap;
    auto fs_factory = base::BindLambdaForTesting(
        [](SmbFilesystem::Options options) -> std::unique_ptr<SmbFilesystem> {
          std::unique_ptr<MockSmbFilesystem> fs =
              std::make_unique<MockSmbFilesystem>();
          EXPECT_CALL(*fs, EnsureConnected())
              .WillOnce(Return(SmbFilesystem::ConnectError::kOk));
          return fs;
        });
    EXPECT_CALL(mock_delegate_, OnPasswordFilePathSet(_))
        .WillOnce([user_directory](const base::FilePath& path) {
          EXPECT_TRUE(user_directory.IsParent(path));
        });
    SmbFsBootstrapImpl boostrap_impl(bootstrap.BindNewPipeAndPassReceiver(),
                                     fs_factory, &mock_delegate_,
                                     daemon_store_dir_.GetPath());
    boostrap_impl.Start(base::BindLambdaForTesting(
        [](std::unique_ptr<SmbFilesystem> fs,
           mojo::PendingReceiver<mojom::SmbFs> smbfs,
           mojo::PendingRemote<mojom::SmbFsDelegate> delegate) {
          EXPECT_TRUE(fs);
        }));

    mojom::MountOptionsPtr mount_options = mojom::MountOptions::New();
    mount_options->share_path = kSharePath;
    mount_options->workgroup = kWorkgroup;
    mount_options->username = kUsername;
    mount_options->password = MakePassword(kPassword);
    mount_options->credential_storage_options =
        mojom::CredentialStorageOptions::New(kAccountHash, salt);

    base::RunLoop run_loop;
    bootstrap->MountShare(
        std::move(mount_options), std::move(smbfs_delegate_),
        base::BindLambdaForTesting(
            [&run_loop](mojom::MountError mount_error,
                        mojo::PendingRemote<mojom::SmbFs> smbfs) {
              EXPECT_EQ(mojom::MountError::kOk, mount_error);
              EXPECT_TRUE(smbfs);
              run_loop.Quit();
            }));
    run_loop.Run();
  }

  // There should be a file in the user's daemon-store directory.
  EXPECT_FALSE(base::IsDirectoryEmpty(user_directory));

  // Since the file's name and contents are obfuscated, don't check them
  // directly. Instead, do another mount operation which uses the saved
  // password.
  {
    mojo::Remote<mojom::SmbFsBootstrap> bootstrap;
    auto fs_factory = base::BindLambdaForTesting(
        [](SmbFilesystem::Options options) -> std::unique_ptr<SmbFilesystem> {
          EXPECT_EQ(options.credentials->workgroup, kWorkgroup);
          EXPECT_EQ(options.credentials->username, kUsername);
          EXPECT_EQ(options.credentials->password->GetRaw(),
                    std::string(kPassword));

          std::unique_ptr<MockSmbFilesystem> fs =
              std::make_unique<MockSmbFilesystem>();
          EXPECT_CALL(*fs, EnsureConnected())
              .WillOnce(Return(SmbFilesystem::ConnectError::kOk));
          return fs;
        });
    EXPECT_CALL(mock_delegate_, OnPasswordFilePathSet(_))
        .WillOnce([user_directory](const base::FilePath& path) {
          EXPECT_TRUE(user_directory.IsParent(path));
        });
    SmbFsBootstrapImpl boostrap_impl(bootstrap.BindNewPipeAndPassReceiver(),
                                     fs_factory, &mock_delegate_,
                                     daemon_store_dir_.GetPath());
    boostrap_impl.Start(base::BindLambdaForTesting(
        [](std::unique_ptr<SmbFilesystem> fs,
           mojo::PendingReceiver<mojom::SmbFs> smbfs,
           mojo::PendingRemote<mojom::SmbFsDelegate> delegate) {
          EXPECT_TRUE(fs);
        }));

    mojom::MountOptionsPtr mount_options = mojom::MountOptions::New();
    mount_options->share_path = kSharePath;
    mount_options->workgroup = kWorkgroup;
    mount_options->username = kUsername;
    // When there's no password field, implicitly restore the password from a
    // file.
    mount_options->credential_storage_options =
        mojom::CredentialStorageOptions::New(kAccountHash, salt);

    base::RunLoop run_loop;
    ResetDelegate();
    bootstrap->MountShare(
        std::move(mount_options), std::move(smbfs_delegate_),
        base::BindLambdaForTesting(
            [&run_loop](mojom::MountError mount_error,
                        mojo::PendingRemote<mojom::SmbFs> smbfs) {
              EXPECT_EQ(mojom::MountError::kOk, mount_error);
              EXPECT_TRUE(smbfs);
              run_loop.Quit();
            }));
    run_loop.Run();
  }
}

TEST_F(TestSmbFsBootstrapImpl, NoSavePasswordOnMountFailure) {
  const std::vector<uint8_t> salt(
      mojom::CredentialStorageOptions::kMinSaltLength, 'a');

  const base::FilePath user_directory =
      daemon_store_dir_.GetPath().Append(kAccountHash);
  ASSERT_TRUE(base::CreateDirectory(user_directory));
  EXPECT_TRUE(base::IsDirectoryEmpty(user_directory));

  {
    mojo::Remote<mojom::SmbFsBootstrap> bootstrap;
    auto fs_factory = base::BindLambdaForTesting(
        [](SmbFilesystem::Options options) -> std::unique_ptr<SmbFilesystem> {
          std::unique_ptr<MockSmbFilesystem> fs =
              std::make_unique<MockSmbFilesystem>();
          EXPECT_CALL(*fs, EnsureConnected())
              .WillOnce(Return(SmbFilesystem::ConnectError::kAccessDenied));
          return fs;
        });
    SmbFsBootstrapImpl boostrap_impl(bootstrap.BindNewPipeAndPassReceiver(),
                                     fs_factory, &mock_delegate_,
                                     daemon_store_dir_.GetPath());
    boostrap_impl.Start(base::BindLambdaForTesting(
        [](std::unique_ptr<SmbFilesystem> fs,
           mojo::PendingReceiver<mojom::SmbFs> smbfs,
           mojo::PendingRemote<mojom::SmbFsDelegate> delegate) {
          EXPECT_TRUE(fs);
        }));

    mojom::MountOptionsPtr mount_options = mojom::MountOptions::New();
    mount_options->share_path = kSharePath;
    mount_options->workgroup = kWorkgroup;
    mount_options->username = kUsername;
    mount_options->password = MakePassword(kPassword);
    mount_options->credential_storage_options =
        mojom::CredentialStorageOptions::New(kAccountHash, salt);

    base::RunLoop run_loop;
    bootstrap->MountShare(
        std::move(mount_options), std::move(smbfs_delegate_),
        base::BindLambdaForTesting(
            [&run_loop](mojom::MountError mount_error,
                        mojo::PendingRemote<mojom::SmbFs> smbfs) {
              EXPECT_EQ(mojom::MountError::kAccessDenied, mount_error);
              run_loop.Quit();
            }));
    run_loop.Run();
  }

  // There should be no files in the user's daemon-store.
  EXPECT_TRUE(base::IsDirectoryEmpty(user_directory));
}

}  // namespace
}  // namespace smbfs
